我是系统安全性的新手,我正在尝试实现一个简单的返回LIBC漏洞利用。使用GCC的-fno-stack-protector
集,现在我知道如何通过使用缓冲区溢出错误来粉碎返回地址。现在,我想通过用system()
的地址覆盖函数的正确返回地址将目标程序的控制流引导到C的system()
函数(我使用-static
选项设置编译程序,以便所有C的标准函数都在可执行代码(。例如,目标程序就像:
int main(int argc, char *argv[]) {
char buffer[8];
gets(buffer);
return 0;
}
i可以使用GDB的拆卸功能找到的main()
的返回地址覆盖CC_5的返回地址。我想提供"/bin/sh"作为system()
的参数,但我不知道system()
函数的参数在地址空间上。谁能帮我找出我可以在哪里找到论点?
x86-64上使用的调用约定在寄存器中通过参数。第一个论点是在RDI中通过的。这是与x86的主要区别,其中通常在堆栈上传递参数。
要将精心设计的论点传递给函数,您需要在RDI中存在,要么是:
-
使
main()
将该值放在此处。(在这种情况下可能不可能。( -
使用ROP小工具。在内存中找到指令序列
。pop %rdi; retq
,然后以该顺序返回使用"/bin/sh"
和system()
的地址的地址。如果找不到确切的序列,则可以使用包括RDI在内的其他流行和返回序列,并推动额外的垃圾值来适应它。例如,如果您找到
pop %rdi; pop %rbp; retq
,则在精心设计的RDI之后推出一个额外的价值。