1

考虑这个 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 是 free()'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
4

0 回答 0