ROP和Ret2libc漏洞

一、ROP攻击原理

ROP全称为Return-oriented Programming(返回导向式编程)是一种新型的基于代码复用技术的攻击,攻击者从已有的库或可执行文件中提取指令片段,构建恶意代码。

ROP攻击同缓冲区溢出攻击,格式化字符串漏洞攻击不同,是一种全新的攻击方式,它利用代码复用技术。

ROP的核心思想:攻击者扫描已有的动态链接库和可执行文件,提取出可以利用的指令片段(gadget),这些指令片段均以ret指令结尾,即用ret指令实现指令片段执行流的衔接。操作系统通过栈来进行函数的调用和返回。函数的调用和返回就是通过压栈和出栈来实现的。每个程序都会维护一个程序运行栈,栈为所有函数共享,每次函数调用,系统会分配一个栈桢给当前被调用函数,用于参数的传递、局部变量的维护、返回地址的填入等。栈帧是程序运行栈的一部分 ,在Linux中 ,通过%esp和 %ebp寄存器维护栈顶指针和栈帧的起始地址 ,%eip是程序计数器寄存器 [1]  。而ROP攻击则是利用以ret结尾的程序片段 ,操作这些栈相关寄存器,控制程序的流程,执行相应的gadget,实施攻击者预设目标 。ROP不同于retum-to-libc攻击之处在于,ROP攻击以ret指令结尾的函数代码片段 ,而不是整个函数本身去完成预定的操作。从广义角度讲 ,return-to-libc攻击是ROP攻的特例。最初ROP攻击实现在x86体系结构下,随后扩展到各种体系结构.。与以往攻击技术不同的是,ROP恶意代码不包含任何指令,将自己的恶意代码隐藏在正常代码中。因而,它可以绕过W⊕X的防御技术。

ret2libc 这种攻击方式主要是针对 动态链接(Dynamic linking) 编译的程序,因为正常情况下是无法在程序中找到像 system() 、execve() 这种系统级函数(如果程序中直接包含了这种函数就可以直接控制返回地址指向他们,而不用通过这种麻烦的方式)。因为程序是动态链接生成的,所以在程序运行时会调用 libc.so (程序被装载时,动态链接器会将程序所有所需的动态链接库加载至进程空间,libc.so 就是其中最基本的一个),libc.so 是 linux 下 C 语言库中的运行库glibc 的动态链接版,并且 libc.so 中包含了大量的可以利用的函数,包括 system() 、execve() 等系统级函数,我们可以通过找到这些函数在内存中的地址覆盖掉返回地址来获得当前进程的控制权。通常情况下,我们会选择执行 system("/bin/sh") 来打开 shell,

如此就需要解决两个问题:

1) 找到 system() 函数的地址;

2) 在内存中找到 "/bin/sh" 这个字符串的地址。  

为了找到system() 函数和 "/bin/sh" 字符串的地址,可以通过直接传送大量的字符覆盖返回地址使其在动态调试时报错的方法来确定偏移。

几个gdb的常用命令:

-q 参数不显示欢迎信息等

-n 不加载任何插件,使用原生 gdb

info 后面跟上想要查看的信息,如函数信息 info functions

b/breakpoint 设置断点

del/delete br

### 关于 pwn 中 ret2libc 技术的实现方法 #### 概述 ret2libc 是一种利用栈溢出漏洞的技术,通过覆盖返回地址来执行 libc 库中的函数。这种方式不需要注入额外的 shellcode,而是重定向程序流到已有库函数,从而绕过一些安全机制。 #### 原理说明 当发生缓冲区溢出时,攻击者可以控制 EIP 寄存器指向任意位置。如果能够计算出标准 C 函数如 `system()` 的确切内存地址,则可以通过设置参数并调用该函数达到特定目的[^1]。 #### 实现步骤详解 为了成功实施 ret2libc 攻击,通常需要满足以下几个条件: - **获取目标机器上 libc 版本及其加载基址** 这一点非常重要因为不同版本之间函数偏移量会有所差异。对于远程服务器来说这一步可能会变得复杂,但在本地测试环境中相对容易完成[^2]。 - **找到合适的 gadget 链接点** Gadget 是一小段可重复使用的汇编代码片段,它们存在于二进制文件内部并且以 `ret` 结束。理想情况下应该寻找那些可以直接跳转至所需功能入口处的 gadgets 或者构建一系列连续操作最终导向 system() 调用链路[^3]。 - **构造 payload 数据包** Payload 构建是整个过程中最核心的部分之一。它由多个部分组成:首先是填充物用来触发溢出;其次是精心挑选的目标地址(通常是 system@plt 或其他有用函数);最后是要传递给所选函数的实际参数列表,比如 "/bin/sh" 字符串的位置等信息。 ```python from struct import pack # Example of constructing a simple ROP chain for educational purposes only. offset = b"A"*76 # Offset to reach the saved return address on stack system_addr = pack("<I", 0xb7ecffb0) # Address of 'system' function from known libc version exit_addr = pack("<I", 0xb7ecfa80) # Address of 'exit' function, used as next instruction after calling system() sh_str_addr = pack("<I", 0xbffffc9a) # Memory location containing string '/bin/sh' payload = offset + system_addr + exit_addr + sh_str_addr ``` 上述 Python 代码展示了如何创建一个简单的 ROP (Return-Oriented Programming) 链条用于教学演示用途。实际应用中还需要考虑更多因素,例如 ASLR 地址空间布局随机化防护措施的影响等问题。 #### 安全建议与预防措施 现代操作系统已经引入了许多缓解此类攻击安全特性,例如 DEP ASLR 。因此,在真实世界里单纯依靠传统意义上的 ret2libc 已经难以奏效。不过了解这项技术仍然是非常有价值的,有助于加深对计算机体系结构的理解,并为更高级别的逆向工程打下坚实基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值