繁体   English   中英

堆溢出问题-可以覆盖块头,Corrupt Free(),但程序不会崩溃

[英]Heap Overflow Issue - Can Overwrite Chunk Header, Corrupt Free(), But Program Doesn't Crash

我一直在研究计算机漏洞,并且已经研究了无数个小时。 我似乎无法正确使堆溢出。 尽管glibc检测到内存损坏,但是在禁用MALLOC_CHECK_之后,我的程序仍会执行并正确退出,好像覆盖块头无关紧要。 我正在运行Kubuntu 12.04。

此练习摘自《 The Shellcoder's Handbook,第二版》,并且在在线堆溢出教程中也有介绍。 我已经多次将指令遵循到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,然后转储该值。

经过许多Google搜索后,我无法在mem2chunk_check()函数上找到任何文档。

这些堆溢出在现代系统上是否已过时?

在过去的几年中,供应商默认使用任何内存操作功能的“增强”版本。 例如,您将获得'builtin_memset_chk'而不是memset,而获得'strcpy_chk'而不是strcpy

为了使您的简单溢出程序正常工作,您必须使用以下方法构建程序:

-fno-stack-protector -D_FORTIFY_SOURCE=0

首先,当今,Linux中的堆利用确实非常困难。 好吧,如果不同的缓冲区溢出,很容易覆盖它们,但是困难的是执行任意代码。

如果您想了解堆利用的内部工作原理,则应该阅读我在这篇文章中提到的文章: 使用堆溢出写入任意数据

一旦您理解了这些概念,我会警告您说,malloc malleficarum中使用/解释的大多数方法都是(静默)修补的。 我不知道这些方法是否仍然有效。

另一方面,如果您真的想提高自己的知识,建议您下载ptmalloc实现(从http://www.malloc.de/en/ ),该实现是Linux中基于分配器的实现,编译它(“使共享”,添加“ -g”标志也很有用)并用LD_PRELOAD加载它。 这样,您将可以逐步使用gdb调试malloc代码。

祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM