几天前,我想知道如何教自己如何进行基于堆的溢出利用。

因此,我搜索了文档,随后练习了所阅读的内容,以更好地了解堆的工作原理在Linux下。

我们被告知malloc()/ free()函数可用于Doug Lea的内存分配器,但是,尽管链接给出了很好的解释,但我还是无法弄清楚调试我的程序。

给出以下示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int n = 5;

int main(int argc, char** argv) {

        char* p;
        char* q;

        p = malloc(1024);
        q = malloc(1024);

        printf("real size = %d\n",*(((int*)p)-1) & 0xFFFFFFF8);

        if(argc >= 2) {
                strcpy(p, argv[1]);
        }

        free(q);
        printf("n = 0x%08X\n", n);
        free(p);

        return EXIT_SUCCESS;
}


我想将此结构转储到内存中:

struct chunk {
        int prev_size;
        int size;
        struct chunk *fd;
        struct chunk *bk;
};


这是我的工作流程:

geo@lilith:~/c/vuln_malloc$ gcc -o vuln vuln.c -m32 -ggdb
geo@lilith:~/c/vuln_malloc$ gdb ./vuln
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/geo/c/vuln_malloc/vuln...done.
(gdb) b 21
Breakpoint 1 at 0x804850f: file vuln.c, line 21.
(gdb) r `perl -e 'print "A" x 1024'`
Starting program: /home/geo/c/vuln_malloc/vuln `perl -e 'print "A" x 1024'`
real size = 1032

Breakpoint 1, main (argc=2, argv=0xffffd414) at vuln.c:21
21              free(q);
(gdb) x/10x q-4
0x804a40c:      0x00000409      0x00000000      0x00000000      0x00000000
0x804a41c:      0x00000000      0x00000000      0x00000000      0x00000000
0x804a42c:      0x00000000      0x00000000
(gdb)


这里我可以看到大小字段的值,即0x409。我可以很容易地猜出我的块的实际大小是0x409&0xFFFFFF8 = 0x408 = 1032,正如文档所解释的(三个最低有效位实际上定义了一些标志)。然后我运行直到处理free()函数。

(gdb) b 22
Breakpoint 2 at 0x804851b: file vuln.c, line 22.
(gdb) c
Continuing.

Breakpoint 2, main (argc=2, argv=0xffffd414) at vuln.c:22
22              printf("n = 0x%08X\n", n);
(gdb) x/10x q-4
0x804a40c:      0x00020bf9      0x00000000      0x00000000      0x00000000
0x804a41c:      0x00000000      0x00000000      0x00000000      0x00000000
0x804a42c:      0x00000000      0x00000000


首先我完全不理解新值-0x20bf9-其次,我不理解为什么在fd和bk指针上也没有任何相关的值。

所有这些东西对我来说都没有多大意义,这就是为什么我想知道您是否可以为我提供一些线索所有这一切与否。 Doug Lea的实现是否仍存在于最新的glibc版本中,或者...?

评论

相关元讨论:meta.reverseengineering.stackexchange.com/questions/268/…

#1 楼

首先,我对你有个坏消息! Doug Lea的malloc几乎不再在任何C库实现中使用(即使了解dlmalloc可以对理解新的内容有很大帮助)。

使用最广泛的新实现是ptmalloc2和最佳方法要了解它是...阅读代码...因此,如果您像我一样使用Debian(-like)发行版,则只需要这样获取libc的源代码即可:

$> apt-get source libc6


请注意,glibc不再存在,并且已被eglibc项目包含。不久前,Debian发行版切换到eglibc(在这里和那里,甚至在glibc源代码包页面上)。因此,malloc的实现已发生了很大的变化(并且自dlmalloc以来已添加了一些安全保护措施)。

我说过,这里使用的算法是malloc(POSIX线程Malloc),但是做了很大的修改。因此,您最好阅读代码以更好地了解它。

总而言之,堆内存是通过内存块管理的,这些内存块以收集这些信息的元数据为前缀我只是引用ptmalloc2源文件中的注释,请参考整个文件以了解更多信息):

$> cd eglibc-2.17/malloc/
$> less malloc.c

...
/*
 This is a version (aka ptmalloc2) of malloc/free/realloc written by
 Doug Lea and adapted to multiple threads/arenas by Wolfram Gloger.

 There have been substantial changesmade after the integration into
 glibc in all parts of the code.  Do not look for much commonality
 with the ptmalloc2 version.
...


您还可以参考“基于堆的利用”这是Scott Hand关于堆管理和溢出利用的演讲。

仍然,您需要做很多工作来理解所有内容,我想花更多的时间来解释。但是,我希望它可以帮助您找到更深层次的方法(在这里下载源代码确实是关键)。

评论


基于堆的利用PDF的链接已失效。


13年6月6日在17:04

web.archive.org/web/20131206064115/http://www.utdallas.edu/…

– Bill B
2014年5月9日在9:41

更新。截至2015年10月,eglibc项目已死。大多数功能都合并到glibc中,Debian切换回glibc

– golem
2015年10月21日,0:10