v8-学习-练习题
2019-数字经济大赛决赛-Browser
diff分析
1 | diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc |
这里就不分析了,大家可以参考:(´∇`) 天亮啦~ 2019-数字经济大赛决赛-Browser | A1ex’s Blog
ToNumber()函数
1 | MaybeHandle<Object> Object::ToNumber(Isolate* isolate, Handle<Object> input) { |
1 | // static |
1 | MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver, |
1 | MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive( |
1.可以看到,当input不是Number的时候,会调用ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber)
2.在这个函数里会对input进行判断,当input不是那几个判断的基本类型的时候,就会进入
JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,ToPrimitiveHint hint)
3.根据注释看
接下来写几个测试代码测试一下
1 | const obj = { |
可以看到有tostring和valueOf属性名的时候会优先调用valueOf,这是由于参数决定的,但是当没有valueOf属性名的时候
1 | const obj = { |
就会调用toString了
1 | const obj = { |
但是当有 [Symbol.toPrimitive]方法的时候,就会调用这个方法,传进来的参数是Number,所以会return 666
测试攻击
攻击脚本
1 | function hexx(str, value) |
1.先创建一个arr,然后在调用coin函数的时候,会在ToNumber(val)的时候创建victim,这个对象的length正好就是arr的elements的索引为37的地方,然后将arr的length修改为大于37的数,绕过检测,但是
1 | //将elements保存到局部变量 |
这个局部变量还是保存着之前的elements的地址,所以就可以实现越界写,这里选择将victim的length写成一个超大的数,这样就可以实现越界写和越界读了

之后的攻击就简单了,和之前的oob差不多
完整exp
1 | function hexx(str, value) |
评论