pwn入门(2):ROP攻击的原理,缓冲区溢出漏洞利用(ret2text+ret2shellcode)

本文介绍了ROP攻击的基本原理,包括利用程序中的gadgets改变执行流程,以及需要满足的条件。讨论了二进制程序的保护机制,如RELRO、StackCanary、ASLR、PIE和NX,并通过ret2text和ret2shellcode两个实例展示了如何利用这些技术进行溢出攻击。文章还提供了利用工具如IDApro、gdb-peda和pwntools进行分析和利用的步骤。

本节将介绍基本的ROP(Return-Oriented Programming,返回导向编程的)的攻击原理、二进制程序的保护机制,并通过两个实例ret2text、ret2shellcode,为读者简介基本的ROP攻击过程。本节所使用的实例可在CTF wiki上进行下载,链接为:基本 ROP - CTF Wiki (ctf-wiki.org)

本节使用的工具包括IDA pro、gdb-peda、pwntools,已在上一篇博客中进行了介绍,详情请见:(58条消息) pwn入门(1):kali配置相关环境(pwntools+gdb+peda)_Bossfrank的博客-优快云博客

ROP攻击原理

ROP的全称为 Return-oriented programming,即返回导向编程,其主要思想是在栈缓冲区溢出的基础上,通过利用程序中已有的小片段 (gadgets) 来改变某些寄存器或者变量的值,从而控制程序的执行流程。所谓 gadgets 就是以 ret 结尾的指令序列,通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行流程。 是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御,比如内存不可执行和代码签名等。ROP攻击执行需要满足如下两个条件:

  • 程序存在溢出点(如C语言的gets等不安全的函数),并且可以控制返回地址。

  • 可以找到满足条件的 gadgets 以及相应 gadgets 的地址(如系统调用相关函数system等)

 简单的将,ROP攻击的思想就是:在栈溢出的基础上,努力去代码段(可执行区域)拼凑出机器指令的片段,完成要执行攻击的逻辑。

二进制程序保护机制

拿到二进制程序后,使用checksec即可查看该程序开启了哪些保护机制,包括以下几种:

RELRO     

全称为Relocation Read-Only,重定位表只读。设置符号重定向表格为只读或在程序启动时就解析并绑 定所有动态符号,从而减少对 GOT 表的攻击。如果 RELRO 为“Partial RELRO”,说明对 GOT 表具有写权限。

Stack Canary

cannary单词本意是“金丝雀”,我的理解这里将该词引申为“标记位置”。函数开始执行时先在栈帧基址 (如 EBP 位置) 附近插入 cookie 信息(标记),当函数返回后验证 cookie 信息是否合法, 如果不合法就停止程序运行。攻击者在执行溢出时,在覆盖返回地址的时候往往也会覆盖 cookie 信息,导致栈保护检查失败从而阻止 shellcode 的执行。

ASLR

全程为Address Space Layout Randomization,地址空间布局随机化。通过对堆、栈、共享库等加载地址随机化,增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置。随机化影响的是程序加载的 基地址,页内偏移不会发生变化。

PIE

全称为Position Independent Executable,地址无关的可执行文件,每次加载程序时都变换 text、 data、bss 等段的加载基地址,使得

### ret2shellcode题目的解题方法 ret2shellcode的目标是将一段用于获取系统控制权的机器语言代码(shellcode)放置在内存的某个位置(通常是栈上),然后修改程序的返回地址,使程序返回到shellcode并执行,从而获取系统控制权,通常是开启一个可以执行任意命令的shell[^2]。 依赖条件为向可执行内存写入并执行Shellcode,需要内存可写且可执行(NX关闭)[^4]。 以一个具体例题为例,先用`checksec`查看程序保护机制,若没有开启任何保护机制,且是一个32位的程序,使用IDA分析程序,若发现`gets`函数没有对输入长度做限制,存在溢出,且将输入的值复制到了`buf2`的内存空间里,`buf2`是一块为`64h`字节大小的`.bss`段内的空间,就可以构造如下的Python利用脚本: ```python from pwn import * context.binary = './ret2shellcode' p = process('./ret2shellcode') p.sendline(asm(shellcraft.sh()).ljust(112, 'a') + p32(0x0804A080)) p.interactive() ``` 上述代码中,`asm(shellcraft.sh())`生成了一段执行`/bin/sh`的shellcode,`ljust(112, 'a')`将shellcode填充到112字节,`p32(0x0804A080)`是shellcode所在的地址,最后通过`p.sendline`将构造好的payload发送给程序,`p.interactive()`进入交互模式,获取shell[^5]。 ### ret2syscall题目的解题方法 ret2syscall主要目标是通过控制程序流程,使程序执行系统调用(syscall)指令来获取系统控制权或者执行特定的操作。系统调用是操作系统提供给用户程序的接口,用于请求内核服务[^2]。 依赖条件是构造ROP链触发系统调用,需要足够的Gadgets。 一般步骤为,先使用`checksec`检查程序保护机制,再使用IDA等工具分析程序,找出可用的Gadgets,然后构造ROP链,触发系统调用。例如,要调用`execve("/bin/sh", NULL, NULL)`系统调用,需要找到合适的Gadgets来设置寄存器的值,将`/bin/sh`字符串地址放入`eax`,`NULL`放入`ebx`、`ecx`和`edx`,最后触发`syscall`指令。 ### ret2system的难度分析 ret2system的核心思路是跳转到程序已有的`system`函数,执行`system("/bin/sh")`来获取shell,依赖条件是存在可利用的`system`函数[^4]。 其难度主要取决于程序中是否存在`system`函数以及能否找到`/bin/sh`字符串的地址。如果程序中存在`system`函数和`/bin/sh`字符串,且可以通过溢出漏洞控制程序的返回地址,那么难度相对较低。但如果程序中没有直接的`system`函数,或者`/bin/sh`字符串需要通过其他方式构造或查找,难度就会增加。此外,如果程序开启了较高的保护机制,如PIE、Canary等,也会增加利用的难度。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Boss_frank

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值