我正在阅读 Hacking:剥削艺术,它显然充满了过时的信息(不考虑金丝雀,非可执行堆栈,ASLR)。我试图了解即使在现代系统上是否(以及如何)堆栈溢出攻击也是可能的。到目前为止,我发现的最好的论文是Stack smashing on a modern Linux system,至少从2012年开始。
似乎阻止堆栈溢出攻击执行任意代码的真实因素是canary和Position Independent Executable(在gcc中禁用哪些标记-fno-stack-protector
和-fPIE
)。 PIE使堆栈不可执行,因此即使设法用堆栈地址覆盖返回地址,程序也会崩溃,因为不允许执行堆栈上的代码。
显然,Linux终端命令readelf -l <filename>
允许知道是否使用PIE编译可执行文件。 GNU_STACK
标题是我们应该查看的标题:如果它是RWE
则允许执行,如果E
丢失,则不然。因此,检查堆栈是否可执行是很简单的。 (值得指出的是,在不拆卸或崩溃软件的情况下检查文件是否使用金丝雀保护编译并不容易)
但是,据我所知,GNU_STACK
标题可以通过名为execstack的小工具轻松调整为RWE
。它就像execstack -s <filename>
一样简单。它甚至不需要root权限(当然,只要文件的所有者不是root用户)。
现在,我的问题是:如果我们可以如此轻易地改变它的设置,PIE有什么意义呢?禁用金丝雀需要重新编译整个文件,因为金丝雀检查内置于汇编代码中,但GNU_STACK
标题看起来很容易错误......我错过了什么?
更新:“如果攻击者可以修改标头,则表示攻击者已经实现了代码注入。”
我不确定这是真的。如果攻击者想利用可执行文件中的漏洞,他可能需要另一个可执行文件。例如,在 Hacking:剥削艺术一书中,notesearch
中的缺陷是通过notesearch_exploit
来利用的。即使notesearch
具有非可执行堆栈,也可以通过对notesearch_exploit
中的execstack的apt调用轻松地使其可执行(假设没有root权限),从而绕过PIE限制。这不正确吗?