我是系统安全的新手,我正在尝试实现一个简单的return-to-libc漏洞。使用GCC的-fno-stack-protector
设置,现在我知道如何利用缓冲区溢出错误来粉碎返回地址。现在我想通过覆盖地址为system()
的函数的正确返回地址,将目标程序的控制流程指向C的system()
函数(我用{{1}编译程序}选项设置,以便所有C的标准函数都在可执行代码中)。例如,目标程序如下:
-static
我可以使用gdb的反汇编函数找到的地址int main(int argc, char *argv[]) {
char buffer[8];
gets(buffer);
return 0;
}
覆盖main()
的返回地址。我想提供“/ bin / sh”作为system()
的参数,但我不知道system()
函数的参数在地址空间中的位置。任何人都可以帮我弄清楚我能在哪里找到这个论点吗?
答案 0 :(得分:5)
x86-64上使用的调用约定在寄存器中传递参数。第一个参数在RDI中传递。这是与x86的主要区别,其中参数通常在堆栈上传递。
要将精心设计的参数传递给函数,您需要通过以下方式使其出现在RDI中:
让main()
将该值放在那里。 (在这种情况下可能是不可能的。)
使用ROP小工具。在内存中找到指令序列pop %rdi; retq
,然后按顺序返回堆栈中"/bin/sh"
和system()
地址的序列地址。
如果找不到确切的序列,则可以使用包含RDI的不同弹出和返回序列,并推送额外的垃圾值以容纳它。例如,如果您找到pop %rdi; pop %rbp; retq
,则会在精心设计的RDI之后推送额外的值。