考虑Linux中的堆缓冲区溢出漏洞程序的示例,直接取自“缓冲区溢出攻击”(第248页)一书:
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char *A, *B;
A = malloc(128);
B = malloc(32);
strcpy(A, argv[1]);
free(A);
free(B);
return 0;
}
由于unlink()已被更改以防止使用带有健全性检查的FD和BK指针的最简单形式的漏洞利用,我使用的是一个非常旧的系统,我使用旧版本的glibc(版本2.3.2) )。我也为此测试设置了MALLOC_CHECK_ = 0.
这个玩具示例的目标是简单地看看我是否可以将4个字节写入我指定的任意地址。我能想到的最简单的测试是尝试写一些东西到0x41414141,这是一个非法的地址,应该让程序崩溃,只是向我确认它确实试图写入这个地址(我应该能够观察到的东西)在GDB中。)
所以我尝试使用参数perl -e 'print "A"x128 . "\xf8\xff\xff\xff" . "\xf8\xff\xff\xff" . "\x41\x41\x41\x41" . "\x41\x41\x41\x41" '
所以我有:
Buffer A: 128 bytes of 0x41.
prev_size: 0xfffffff8
size: 0xfffffff8
FD: 0x41414141
BK: 0x41414141
我正在使用0xfffffff8而不是0xfffffffc,因为有一条注意到glibc 2.3的第三个最低位NON_MAIN_AREA用于竞技场的管理目的,必须为0。
这应该尝试将0x41414141写入0x41414141(+ 12更正确,但仍然是非法地址),对吗?但是,当我执行它时,程序只是正常终止。
我在这里缺少什么?这看起来很简单,不应该那么难上班。
我尝试过各种各样的事情,例如使用0xfffffffc代替prev_size和size,使用FD的合法地址(堆上的某个地址)。我已经尝试交换顺序A和B是免费的()'d,我试图进入free()看看GDB中发生了什么,但我迷路了。请注意,此系统上不应该有任何其他安全功能,因为它很老,并且不会有NX位,ASLR等(并不是因为只是将4个字节写入非法地址)
有关如何使这项工作的任何想法?
我可以补充一点,如果使用MALLOC_CHECK_ = 3我得到了这个:
malloc: using debugging hooks
malloc: using debugging hooks
free(): invalid pointer 0x8049688!
Program received signal SIGABRT, Aborted.
0x4004a1b1 in kill () from /lib/libc.so.6