我正在阅读Shellcoder's Handbook以了解有关漏洞利用和溢出的更多信息。我读到了堆溢出的章节。这本书提到堆被分成多个块,每个块包含两个重要的信息:
- 前一个块的大小(如果已分配)
- 当前块的大小
- 数据
下图取自Blackhat 演示文稿
我做了一个小演示来测试这个。下面是代码:
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 int
6 main (int argc, char *argv[]){
7 char *buf, *buf2;
8
9 buf = (char *) malloc(1024);
10 buf2 = (char *) malloc(1024);
11
12 printf("buf=%p\n", buf);
13 printf("buf2=%p\n", buf2);
14 strcpy(buf, argv[1]);
15 strcpy(buf2, argv[2]);
16 printf("buf=%s\n", buf);
17 printf("buf2=%s\n", buf2);
18 free(buf2);
19 return 0;
20 }
我在第 18 行放置了一个断点并检查了内存。这是运行以下命令后的转储:
./basicheap $(python -c 'print("A"*1000 + " " +"XXXXABCDEFGH")')
这是内存转储buf1
:
[0x08048543]> pxw 0x50 @ [fcnvar.local_1ch]-8
0x0804b158 0x00000000 0x00000411 0x41414141 0x41414141 ........AAAAAAAA
0x0804b168 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
0x0804b178 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
0x0804b188 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
0x0804b198 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
这是内存转储buf2
:
[0x08048543]> pxw 0x50 @ [fcnvar.local_20h]-8
0x0804b568 0x00000000 0x00000411 0x58585858 0x44434241 ........XXXXABCD
0x0804b578 0x48474645 0x00000000 0x00000000 0x00000000 EFGH............
0x0804b588 0x00000000 0x00000000 0x00000000 0x00000000 ................
0x0804b598 0x00000000 0x00000000 0x00000000 0x00000000 ................
0x0804b5a8 0x00000000 0x00000000 0x00000000 0x00000000 ................
输出显示0x411
为两个块的大小,无论是 1024 + 17 位。这是两个块的标头中的第一条(也是唯一一条)信息。
但是,我没有看到与任何以前的块相关的任何信息。在Shellcoder 的 中,作者试图演示如何溢出buf1
以覆盖buf2
.
glibc 的作者是否放弃了标题信息中前一个块的大小,还是我遗漏了什么?
PS:我使用的构建命令是 gcc -no-pie -g basicheap.c -o basicheap