我已经读到,要成功返回lib-c攻击,攻击者应该将命令的地址(例如"bin/sh")存储在堆栈上,正好位于返回"system"函数的地址之后(例如)。
因此,"system()"函数读取该地址作为其"参数"并执行该命令。但现在,在分解了一个调用system()的程序后,我注意到它没有使用堆栈来获取该字符串的地址("bin/sh")。相反,地址存储在EDI或RDI寄存器中。只要攻击者不能访问寄存器,怎么可能进行这样的攻击?
实际上,攻击者可能很容易在RDI
中存储正确的值,而无需直接访问寄存器。
以一个典型的易受攻击的C函数为例,它可能会导致返回libc攻击:
void f(const char* str)
{
char buf[BUF_LEN];
strcpy(buf, str);
}
在我的机器上,为调用strcpy
:生成以下程序集
movq %rdi, -24(%rbp)
movq -24(%rbp), %rdx
leaq -16(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call strcpy
如您所见,strcpy
的目标缓冲区,即易受攻击的缓冲区,存储在RDI
中。这意味着,如果我们设法用system
的地址覆盖返回地址,则将使用指向易受攻击缓冲区的指针作为其参数来调用它。
一个小的免责声明:这个特定的例子只是为了说明,在寄存器中拥有正确的值可以通过其他方式实现,而不是直接访问寄存器。该示例本身实际上很难利用,因为strcpy
将在第一个空字节之后停止。