我一直在研究计算机漏洞,并且已经在无数个小时内解决了这个问题。 我似乎无法让堆正确溢出。尽管glibc检测到内存损坏,但在禁用MALLOC_CHECK_后,我的程序执行并正确退出,好像覆盖块头并不重要。我正在运行Kubuntu 12.04。
本练习来自“The Shellcoder's Handbook,2nd Edition”,也是在线的Heap Overflow教程。我多次按照说明操作了T,并收到了相同的结果。
以下是我的程序代码:
/*basicheap*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char ** argv){
char *buf;
char *buf2;
buf=(char*)malloc(1024);
buf2=(char*)malloc(1024);
printf("buf=%p buf2=%p\n", buf, buf2);
strcpy(buf,argv[1]);
free(buf2);
free(buf);
}
当我用glibc写入缓冲区时:
xxx@xxx-xxx:~/CProgs$ ./basicheap $(perl -e 'print "A"x1028')
buf=0x9356718 buf2=0x9356b20
*** glibc detected *** ./basicheap: double free or corruption (!prev): 0x09356b20 ***
======= Backtrace: =========
[0x804abff]
[0x8048f4a]
[0x80490d6]
[0x8048e29]
======= Memory map: ========
08048000-080ec000 r-xp 00000000 08:07 6816172 /home/xxx/CProgs/basicheap
080ec000-080ee000 rw-p 000a3000 08:07 6816172 /home/xxx/CProgs/basicheap
080ee000-080f0000 rw-p 00000000 00:00 0
09355000-09377000 rw-p 00000000 00:00 0 [heap]
b772a000-b772c000 rw-p 00000000 00:00 0
b772c000-b772d000 r-xp 00000000 00:00 0 [vdso]
bfc14000-bfc36000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
xxx@xxx-xxx:~/CProgs$
当我通过glibc关闭写缓冲区时:
xxx@xxx-xxx:~/CProgs$ MALLOC_CHECK_=0 ./basicheap $(perl -e 'print "A"x1028')
buf=0xa077718 buf2=0xa077b20
xxx@xxx-xxx:~/CProgs$
Chunk标头的GDB没有覆盖:
(gdb) run $(perl -e 'print "A"x1024')
Starting program: /home/xxx/CProgs/basicheap $(perl -e 'print "A"x1024')
buf=0x80f1718 buf2=0x80f1b20
Breakpoint 1, main (argc=2, argv=0xbfffedf4) at basicheap.c:16
16 free(buf2);
(gdb) x/x buf2-4
0x80f1b1c: 0x00000409
(gdb) x/x buf2-8
0x80f1b18: 0x00000000
(gdb) x/x buf2-12
0x80f1b14: 0x41414141
(gdb)
带有覆盖的块头的GDB:
(gdb) run $(perl -e 'print "A"x1032')
Starting program: /home/xxx/CProgs/basicheap $(perl -e 'print "A"x1032')
buf=0x80f1718 buf2=0x80f1b20
Breakpoint 1, main (argc=2, argv=0xbfffede4) at basicheap.c:16
16 free(buf2);
(gdb) x/x buf2-4
0x80f1b1c: 0x41414141
(gdb) x/x buf2-8
0x80f1b18: 0x41414141
(gdb) x/x buf2-12
0x80f1b14: 0x41414141
(gdb)
两次程序都正常退出。 我错过了什么?他们是否改变了堆在最新版本的Ubuntu上的工作方式? 任何帮助将不胜感激!
更新:我已经逐步完成了gdb中的程序集,并发现我的程序进入函数free_check()和函数mem2chunk_check()。
在mem2chunk_check()函数中,我的覆盖值在ESI寄存器中被拾取,EDI寄存器指向该值的地址。我唯一看到它在ESI中使用我的值的方法是减去1然后转储该值。
经过多次谷歌搜索后,我无法在mem2chunk_check()函数中找到任何文档。
这些堆溢出在现代系统上是否已过时?
答案 0 :(得分:1)
在过去几年中,供应商违反了使用任何内存操作功能的“强化”版本。例如,你得到的是'builtin_memset_chk',而不是strcpy,而不是memset,你得到'strcpy_chk'
要使您的简单溢出程序正常工作,您必须使用以下代码构建程序:
-fno-stack-protector -D_FORTIFY_SOURCE=0
答案 1 :(得分:0)
首先,现在Linux中的堆利用非常困难。好吧,如果它们溢出,很容易覆盖不同的缓冲区,但是难以执行任意代码。
如果你想知道堆利用的内部工作原理,你应该阅读我在这篇文章中提到的论文:Use a heap overflow to write arbitrary data
一旦你理解了这些概念,我就会警告你说在malloc malleficarum中使用/解释的大多数方法都是(默默地)修补的。我不知道其中任何一个今天是否仍有效。
另一方面,如果你真的想提高你的知识,我建议你下载ptmalloc实现(来自http://www.malloc.de/en/),该实现基于Linux中的分配器,编译它(“ make shared“,添加”-g“标志也很有用,并用LD_PRELOAD加载它。这样,您就可以逐步使用gdb调试malloc代码。
祝你好运!