Remote or Local Format String Çϱâ Àü ¹Ýµå½Ã ¾Ë°í ³Ñ¾î °¡¾ß ÇÒ ¿ä¼Òµé By dibi Remote Daemon °ø°ÝÀº ÀÚ½ÅÀÇ Ç÷§Æû¿¡¼­ Å×½ºÆ®ÇÏ¿© ºñ½ÁÇÑ ½Ã½ºÅÛ¿¡°Ô °ø°Ý ÇÏ´Â ¹æ½ÄÀ¸·Î ExploitÀ» ÀÛ¼º ÇÒ ¼ö ÀÖ´Ù. Áï, ÀÓÀÇ·Î ¸¸µé¾îÁø DaemonÀº °ø°ÝÇϱ⠹«Ã´ ±î´Ù·Î¿ï ¼ö ÀÖÀ¸¸ç ¸¸¾à, ÀÓÀÇÀÇ Ãë¾à¼º DaemonÀÇ source°¡ °ø°³ µÇ¾î ÀÖ´Ù¸é ±×°ÍÀ» ºñ½ÁÇÑ ½Ã½ºÅÛ¿¡ °®´Ù ³õ°í Å×½ºÆ® ÇØ º¼ ¼ö ÀÖÀ» °ÍÀÌ´Ù. ÇØÅ· ´ëȸ ¶§ ÀÓÀÇÀÇ Ãë¾àÇÑ Daemon source¸¦ openÇÑ ÀÌÀ¯µµ ºñ½ÁÇÑ ¸Æ¶ôÀ̶ó ÇÒ ¼ö ÀÖ´Ù. ´Ù½Ã ¸»ÇØ ±× source¸¦ °¡Áö°í ºñ½ÁÇÑ °ø°ÝÀÚÀÇ local ½Ã½ºÅÛ¿¡¼­ compileÀ» ÇÏ°í dump¸¦ ½ÃÄÑ º¸°í exploitÀ» ÀÛ¼º ÇÏ¿© real ÇØÅ· ¼­¹ö¿¡ Àû¿ë ½ÃÅ°´Â ¹æ¹ýÀÌ´Ù. GCC 2.96 ±â¹ÝÀÇ Stack Format StringÀ» °øºÎÇÏ¸ç ºÐ¸íÇÏ°Ô Return Address¸¦ µ¤¾î ¾º¿üÀ½¿¡µµ ºÒ±¸ÇÏ°í ½±°Ô ÇØÅ·¿¡ ¼º°ø Çϱ⠾î·Á¿üÀ» °ÍÀÌ´Ù. ¾ó¸¶ ÀüÀÇ Buffer overflow ÇØÅ· °­ÀÇ¿¡¼­µµ Return Address¿¡¼­ ¾à 100¸¸Å­À» EGG ÁÖ¼Ò·Î µ¤¾î ¾º¿ö ¹ö¸®´Â ¹æ¹ýÀ» ½è´Ù. ÇÏÁö¸¸, Format String¿¡¼­´Â ¾ÕÀÇ ±æÀ̸¦ ÀÌ¿ëÇÏ¿© ¹Î°¨ÇÏ°Ô °è»êÇØ¾ß Çϱ⠶§¹®¿¡ ¸·¹«°¡³» µ¤¾î¾º¿ì±â°¡ ½±Áö´Â ¾Ê´Ù. (Â÷¶ó¸® .dtors ¿µ¿ªÀ» µ¤¾î ¾º¿ì´Â °ÍÀÌ ÈξÀ ½¬¿ï °ÍÀÌ´Ù.) ÀÌ·¸°Ô Return Address¸¦ ã±â°¡ ¾î·Á¿ü°í, ±× ÀÌÀ¯Á¶Â÷ ¾Ë ¼ö ¾ø¾ú´Ù. ±×·¯³ª, ¾Ë°í º¸´Ï ±× ÀÌÀ¯ÀÎÁï 2.96ÀÇ StackÀº ±× ÀÌÇÏ ¹öÀü°ú Ʋ¸®°Ô »ç¿ë µÈ´Ù. 2.96±â¹ÝÀÇ StackÀº ¿Ö ÀÌ·¸°Ô ¾²·¹±â(garbage)°ªÀÌ ±ºµ¥±ºµ¥ »ý°Ü ³ª¼­ StackÀ» »ç¿ëÇÏ´ÂÁö µµ¹«Áö ÀÌÇØ°¡ ¾È °¬Áö¸¸, ÀÚ¼¼ÇÏ°Ô ±× ±ÔÄ¢¼º¿¡ ´ëÇØ µ¹¾Æ º¸´Ï ´õ ±ú²ý(?)ÇÏ°Ô Á¤¸® ÇÏ¸ç »ç¿ë µÇ´Â °Í °°´Ù. ±×·³, ±×·± ±ÔÄ¢¼ºÀ̳ª StackÀÇ ±¸Á¶¸¦ ´Ù½Ã Çѹø »ó±â ÇÏ¸ç ¾Ë¾Æ º¸°Ú´Ù. (2.96 ÀÌÈÄ ¹öÀü¿¡¼­ Å×½ºÆ® Çغ¸Áö ¸øÇÔ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~¼Ò½º È­¸é~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;¿ì¸®¸¦ ÀÌÇØ Çϱ⠽±µµ·Ï ¸¸µç ¼Ò½º #include #include "dumpcode.h" #define X 20 /* buffer1 */ #define Y 20 /* buffer2 */ main(int argc, char *argv[]) { long offset, garbage; char buffer1[X]; char buffer2[Y]; offset = (buffer1 - buffer2); garbage = offset - Y; fgets(buffer2, 100, stdin); printf("[buffer2][buffer1][ebp][ret]\n"); printf("buffer2 : 0x%x, buffer1 : 0x%x, (buffer2-buffer1) : %d, garbage : %dbyte.\n\n", buffer2, buffer1, offset, garbage); printf("[buffer2(%dbyte)][garbage1(%dbyte)][buffer1(%dbyte)][ebp(4byte)][ret(4byte)]\n",Y, garbage, X); printf("|_________________________________|\n"); printf(" (%dbyte) \n", offset); printf("\n"); dumpcode((char*)buffer2, 200); printf("\n"); printf("[buffer2(%dbyte)][garbage1(%dbyte)][buffer1(%dbyte)][garbage2(??byte)][garbage3(8byte)][ebp(4byte)][ret(4byte)]\n",Y, garbage, X); printf("|_________________________________|\n"); printf(" (%dbyte) \n", offset); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~½ÇÇà È­¸é~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [buffer2][buffer1][ebp][ret] buffer2 : 0xbffff910, buffer1 : 0xbffff930, (buffer2-buffer1) : 32, garbage : 12byte. [buffer2(20byte)][garbage1(12byte)][buffer1(20byte)][ebp(4byte)][ret(4byte)] |_________________________________| (32byte) 0xbffff910 0a 00 00 00 00 00 00 00 98 70 01 40 f0 72 01 40 .........p.@.r.@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0xbffff920 60 f9 ff bf 16 d8 00 40 d0 9a 04 08 95 82 04 08 `......@........ ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 byte 12byte 0xbffff930 3c 91 03 40 e4 89 15 40 64 6b 01 40 6e 1c 14 40 <..@...@dk.@n..@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0xbffff940 78 f9 ff bf b0 d9 00 40 20 e4 05 40 e4 89 15 40 x......@ ..@...@ ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 byte 12byte 0xbffff950 64 6b 01 40 dc f9 ff bf 0c 00 00 00 20 00 00 00 dk.@........ ... ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~ ~~~~~~~~~~~ 8 byte ebp ret 0xbffff960 b0 9a 04 08 94 9b 04 08 a8 f9 ff bf 77 a1 04 40 ............w..@ 0xbffff970 01 00 00 00 dc f9 ff bf e4 f9 ff bf 66 83 04 08 ............f... 0xbffff980 60 88 04 08 00 00 00 00 a8 f9 ff bf 61 a1 04 40 `...........a..@ 0xbffff990 00 00 00 00 e4 f9 ff bf dc 74 15 40 f8 65 01 40 .........t.@.e.@ 0xbffff9a0 01 00 00 00 f0 83 04 08 00 00 00 00 11 84 04 08 ................ 0xbffff9b0 14 87 04 08 01 00 00 00 dc f9 ff bf 50 83 04 08 ............P... 0xbffff9c0 60 88 04 08 84 e1 00 40 cc f9 ff bf c0 6b 01 40 `......@.....k.@ 0xbffff9d0 01 1e 00 40 e4 f9 ff bf ...@.... [buffer2(20byte)][garbage1(12byte)][buffer1(20byte)][garbage2(??byte)][garbage3(8byte)][ebp(4byte)][ret(4byte)] |_________________________________| (32byte) ;¿Í µü º¸¸é ÀÌÇØ°¡ µÇÁö ¾Ê´Â°¡. ³­ °¡Áö·±È÷ ÀÖ°í ½Í´Ù°í ¸öºÎ¸² Ä¡´Â µíÇÑ ÀÌ ±ÔÄ¢¼º... ±×·¸´Ù¸é À̹ø¿£ ¹öÆÛ Å©±â¸¦ ¹Ù²ã ½ÇÇà È­¸éÀ» º¸µµ·Ï ÇÏÀÚ. [buffer2][buffer1][ebp][ret] buffer2 : 0xbffff920, buffer1 : 0xbffff940, (buffer2-buffer1) : 32, garbage : 9byte. [buffer2(23byte)][garbage1(9byte)][buffer1(12byte)][ebp(4byte)][ret(4byte)] |_________________________________| (32byte) 0xbffff920 0a 00 ff bf 16 d8 00 40 d0 9a 04 08 95 82 04 08 .......@........ 0xbffff930 3c 91 03 40 e4 89 15 40 64 6b 01 40 6e 1c 14 40 <..@...@dk.@n..@ 0xbffff940 78 f9 ff bf b0 d9 00 40 20 e4 05 40 e4 89 15 40 x......@ ..@...@ 0xbffff950 64 6b 01 40 dc f9 ff bf 09 00 00 00 20 00 00 00 dk.@........ ... 0xbffff960 b0 9a 04 08 94 9b 04 08 a8 f9 ff bf 77 a1 04 40 ............w..@ 0xbffff970 01 00 00 00 dc f9 ff bf e4 f9 ff bf 66 83 04 08 ............f... 0xbffff980 60 88 04 08 00 00 00 00 a8 f9 ff bf 61 a1 04 40 `...........a..@ 0xbffff990 00 00 00 00 e4 f9 ff bf dc 74 15 40 f8 65 01 40 .........t.@.e.@ 0xbffff9a0 01 00 00 00 f0 83 04 08 00 00 00 00 11 84 04 08 ................ 0xbffff9b0 14 87 04 08 01 00 00 00 dc f9 ff bf 50 83 04 08 ............P... 0xbffff9c0 60 88 04 08 84 e1 00 40 cc f9 ff bf c0 6b 01 40 `......@.....k.@ 0xbffff9d0 01 1e 00 40 e4 f9 ff bf 01 00 00 00 02 fb ff bf ...@............ 0xbffff9e0 00 00 00 00 09 fb ff bf ........ ;Á÷Á¢ ½ÎÀÎÆæÀ¸·Î ±×¾î º¸¸ç È®ÀÎ Çغ¸±æ. ±×·³ ¿Í Á¤¸» ±ò²ûÇÏ°Ô Á¤¸® µÇ¾î º¸ÀÎ´Ù°í °¨Åº ÇÒ °ÍÀÌ´Ù. ±×·¡µµ ¿ª½Ã ÇØÅ·Çϱ⿡ °è»êÇÏ°Ô ¸¸µé¾î ½È±ä ½È´Ù. [buffer2(23byte)][garbage1(9byte)][buffer1(12byte)][garbage2(??byte)][garbage3(8byte)][ebp(4byte)][ret(4byte)] |_________________________________| (32byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;offsetÀÌ ¾î¶»°Ô ±ÔÄ¢ÀûÀ¸·Î ¿òÁ÷À̳ª ´õ ÀÚ¼¼ÇÏ°Ô Á¤ÀǸ¦ ³»·Á º¸ÀÚ ---------------buffer1----------------> 4 8 12 16 20 ... 4 4 4 4 4 4 8 12 8 8 8 8 12 28 24 16 16 16 16 28 24 16 16 16 ----------------------------------------------------- 20 44 40 32 32 32 24 44 40 32 32 32 28 44 40 32 32 32 32 44 40 32 32 32 ----------------------------------------------------- 36 60 56 48 48 48 40 60 56 48 48 48 44 60 56 48 48 48 48 60 56 48 48 48 ----------------------------------------------------- 52 76 72 64 64 64 56 76 72 64 64 64 60 76 72 64 64 64 64 76 72 64 64 64 ----------------------------------------------------- 68 88 84 80 80 80 ... [buffer2] ;ÀÌ Ç¥¸¦ ÀÚ¼¼È÷ º¸¾Æ ÇÏ´Ï buffer2 ÂÊ¿¡¼­ 16ÀÇ ¹è¼ö¿¡ 4¹­À½Àº °ªÀÌ ¶È°°´Ù. (´Ü, ¹öÆÛÀÇ °ªµéÀÌ 16 º¸´Ù ÀÛÀ» ¶§´Â Á¦¿Ü) ½Ä --> buf / 16 == v ... ³ª¸ÓÁö(¹ö¸²) 16 * v == a 16 * v == b a < buf <= b ~~~~~~~~~~~~~~ µû¶ó¼­ bÀÇ °ªÀÌ offset°ªÀÌ µÇ´Â °ÍÀÌ´Ù. ¹®Á¦ ---------------------------------------------- [buffer2] 100 [buffer1] 12 ±×·¸´Ù¸é buffer2¿¡¼­ buffer1±îÁöÀÇ offset°ªÀº? --------------------------------------------------- OK, ±×·³ buffer°¡ Çϳª ¼±¾ð µÇ¾î ÀÖÀ» ¶§ RET ±îÁöÀÇ °Å¸®´Â ¾î¶»°Ô °è»ê ÇÒ±î. RET´Â 12¹ø°ÀÇ ÀÚ¸®¸¦ °íÁýÇϱ⠶§¹®¿¡, Ç×»ó ebp¾Õ¿¡´Â ¾²·¹±â °ª 8byte°¡ ¿Â´Ù. À̰͸¸ ¾Ë°í À§ÀÇ °è»ê ¹æ¹ý°ú ¶È°°´Ù. [....][....][....][garbage3(8byte)][ebp(4byte)][ret(4byte)] È®½ÇÇÏ°Ô ¾Ë°í ³Ñ¾î °¡±â À§Çؼ­ ´Ù½Ã Çѹø ¿¹¸¦ µé¾î »ìÆì º»´Ù. ¿¹Á¦ source #include #include "dumpcode.h" main() { char buffer[20]; fgets(buffer, 128, stdin); dumpcode((char *)buffer, 128); } ½ÇÇà È­¸é AAAAAA 0xbffff950 41 41 41 41 41 41 0a 00 20 e4 05 40 e4 89 15 40 AAAAAA.. ..@...@ 0xbffff960 64 6b 01 40 ec f9 ff bf 88 f9 ff bf d1 84 04 08 dk.@............ 0xbffff970 e4 97 04 08 c8 98 04 08 b8 f9 ff bf 77 a1 04 40 ............w..@ 0xbffff980 01 00 00 00 ec f9 ff bf f4 f9 ff bf 66 83 04 08 ............f... 0xbffff990 90 87 04 08 00 00 00 00 b8 f9 ff bf 61 a1 04 40 ............a..@ 0xbffff9a0 00 00 00 00 f4 f9 ff bf dc 74 15 40 f8 65 01 40 .........t.@.e.@ 0xbffff9b0 01 00 00 00 f0 83 04 08 00 00 00 00 11 84 04 08 ................ 0xbffff9c0 14 87 04 08 01 00 00 00 ec f9 ff bf 50 83 04 08 ............P... gdb¸¦ ÀÌ¿ëÇÏ¿© retÀÇ °ªÀ» ¾Ë¾Æ º¸ÀÚ. GNU gdb 5.0rh-5 Red Hat Linux 7.1 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or 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. This GDB was configured as "i386-redhat-linux"... (gdb) disassemble main Dump of assembler code for function main: 0x8048714
: push %ebp 0x8048715 : mov %esp,%ebp 0x8048717 : sub $0x28,%esp 0x804871a : sub $0x4,%esp 0x804871d : pushl 0x80498c4 0x8048723 : push $0x80 0x8048728 : lea 0xffffffd8(%ebp),%eax 0x804872b : push %eax 0x804872c : call 0x80483a8 0x8048731 : add $0x10,%esp 0x8048734 : sub $0x8,%esp 0x8048737 : push $0x80 0x804873c : lea 0xffffffd8(%ebp),%eax 0x804873f : push %eax 0x8048740 : call 0x8048540 0x8048745 : add $0x10,%esp 0x8048748 : leave 0x8048749 : ret 0x804874a : mov %esi,%esi 0x804874c : nop 0x804874d : nop 0x804874e : nop 0x804874f : nop End of assembler dump. (gdb) break *0x8048717 Breakpoint 1 at 0x8048717 (gdb) run Starting program: /root/Documents/what/ret Breakpoint 1, 0x08048717 in main () (gdb) info registers ebp ebp 0xbffff968 0xbffff968 (gdb) x/10 0xbffff968 0xbffff968: 0xbffff9a8 0x4004a177 0x00000001 0xbffff9dc ~~~~~~~~~~ ~~~~~~~~~~ ebp ret 0xbffff978: 0xbffff9e4 0x08048366 0x08048790 0x00000000 0xbffff988: 0xbffff9a8 0x4004a161 (gdb) 77 a1 04 40 ---> RET (DUMPCODE¿Í ºñ±³ ÇÏ¿© ã¾Æ º¸¶ó. ¿ì¸®°¡ ¿¹»óÇß´ø À§Ä¡¿¡ ÀÖ´Â °ÍÀ» ¹ß°ß ÇÒ ¼ö ÀÖ´Ù.) 0xbfff96c --> À½. ¿ø·¡´Â ÀÌ°ÍÀÌ ¿ì¸®°¡ »ý°¢ Çß´ø RET ÁÖ¼Ò ¿´´ø °ÍÀÌ°í + 10 0xbfff97c --> ÀÌ°ÍÀÌ ¿ì¸®ÀÇ »ý°¢À» ¹Ù²Ù°Ô ÇÑ RET ÁÖ¼Ò´Ù. offset 10ÀÇ Â÷ÀÌ°¡ ³ª´Â °ÍÀ» ¿ì¸®´Â È®ÀÎÇÏ°í ÀÌ°Í ¶ÇÇÑ »ý°¢ ÇصÎÀÚ. buffer = 20 20 / 16 = 1 ... xx 16 * 1 = 16 16 * 2 = 32 16 < buffer <= 32 ---> µû¶ó¼­ garbage3(8byte)±îÁöÀÇ °Å¸®´Â 32 ±×·³ ¹öÆÛ°¡ ¾î¶»°Ô µÇ³Ä ±×¸²À¸·Î »ìÆì º»´Ù. [buffer(20)][garbage(12)][garbage3(8)][ebp(4)][ret(4)] ÀÌÁ¦ °ø°Ý ÇØ º¸´Â°ÍÀº ¿©·¯ºÐÀÇ ¸ò! Çà¿îÀ» º÷´Ï´Ù.