/* http://beist.org */ Á¦¸ñ : dummy Å©±â Á¤È®È÷ ÆľÇÇϱâ. gcc ÄÄÆÄÀÏ·¯ÀÇ ¹öÀüÀÌ Á¡Á¡ ³ô¾ÆÁö¸é¼­ ÇÁ·Î±×·¥ÀÌ ÄÄÆÄÀÏ µÉ ¶§ »ý±â´Â ¸Þ¸ð¸® °ø°£¿¡ dummy °ªÀÌ »ý±â´Â °ÍÀº ¾Ë°í °è½Ç °Ì´Ï´Ù. (dummy °ªÀÌ »ý±â´Â ÄÄÆÄÀÏ·¯ ¹öÀüÀÌ ³ª¿ÂÁö´Â ²Ï ¿À·¡ µÇ¾ú½À´Ï´Ù.) ±×·±µ¥ ÀÌ »ý¼º µÇ´Â dummy ÀÇ Å©±â¸¦ ÆľÇÇÏ´Â °ÍÀ» Çò°¥¸®½Ã´Â ºÐµéÀÌ °è½Ã´Â °Í °°¾Æ¼­ À̸¦ ¾Ë ¼ö ÀÖ´Â °£´ÜÇÑ ¹æ¹ýÀ» ¾Ë·Áµå¸®°Ú½À´Ï´Ù. °³³äÀ» Àâ´Âµ¥ µµ¿òÀÌ µÇ¾úÀ¸¸é ÁÁ°Ú½À´Ï´Ù. Âü°í·Î dummy ¿¡ ´ëÇؼ­ hackerleon´ÔÀÌ ºÐ¼®ÇÑ ±ÛÀÌ ÀÖÀ¸´Ï ´ÙÀ½ URL ¿¡¼­ ÂüÁ¶ÇϽñ⠹ٶø´Ï´Ù. http://hackerleon.cybersoldier.net/next-board/board.cgi?db=hack&mode=read&num=36 ¸ÕÀú ´ë·«ÀûÀ¸·Î dummyÀÇ ¹üÀ§¸¦ À¯ÃßÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀº ÇØ´ç ÇÁ·Î½ÃÁ®¿¡¼­ stack pointer¸¦ ¾ó¸¶³ª °¨¼ÒÇÏ¿´³ª º¸½Ã¸é µË´Ï´Ù. ÇÁ·Î½ÃÁ®ÀÇ ÇÁ·Ñ·Î±×¿¡¼­ stack pointer¸¦ °¨¼ÒÇÏ´Â ÀÌÀ¯´Â ÇÁ·Î½ÃÁ®¿¡¼­ »ç¿ëÇÒ Áö¿ª º¯¼ö¸¦ À§Çؼ­ ¹Ì¸® ÇÒ´çÀ» ÇÏ´Â °ÍÀÔ´Ï´Ù. ±×·¯¹Ç·Î sub ¸í·ÉÀÇ ÀÎÀÚ·Î ¾ó¸¶¸¸Å­ÀÇ ¼öÄ¡¸¦ °¨¼ÒÇÏ¿´´À³Ä¿¡ µû¶ó¼­ »ç¿ëÇÑ ¹öÆÛÀÇ Å©±â¸¦ ÁüÀÛÇÒ ¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ÀÌ ¹æ¹ýÀº ÃßÃøÀ» ÇÒ ¼ö ÀÖ´Â °ÍÀÌÁö Á¤È®ÇÑ Å©±â¸¦ ¾Ë¾Æ³¾ ¼ø ¾ø½À´Ï´Ù. Á¤È®ÇÏ°Ô ÆľÇÀ» Çϱâ À§Çؼ­´Â µð¹ö±ëÀ» Çغ¸´Â ¹æ¹ýÀÌ °¡Àå ÆíÇÕ´Ï´Ù. ´ÙÀ½Àº »ùÇà ÇÁ·Î±×·¥ÀÔ´Ï´Ù. (Âü°í·Î Å×½ºÆ®ÇÑ GCC ÀÇ ¹öÀüÀº 3.2.2 ÀÔ´Ï´Ù.) 8byte.c int main(int argc, char *argv[]) { char buf[8]; strcpy(buf, argv[1]); } [root@localhost dummy]# gcc -o 8byte 8byte.c [root@localhost dummy]# gdb 8byte GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 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-gnu"... (gdb) disassemble main Dump of assembler code for function main: 0x08048328 : push %ebp 0x08048329 : mov %esp,%ebp 0x0804832b : sub $0x8,%esp 0x0804832e : and $0xfffffff0,%esp 0x08048331 : mov $0x0,%eax 0x08048336 : sub %eax,%esp 0x08048338 : sub $0x8,%esp 0x0804833b : mov 0xc(%ebp),%eax 0x0804833e : add $0x4,%eax 0x08048341 : pushl (%eax) 0x08048343 : lea 0xfffffff8(%ebp),%eax 0x08048346 : push %eax 0x08048347 : call 0x8048268 0x0804834c : add $0x10,%esp 0x0804834f : leave 0x08048350 : ret 0x08048351 : nop 0x08048352 : nop 0x08048353 : nop End of assembler dump. (gdb) ¸ÕÀú (1) 0x804832b ¿Í (2) 0x8048347 À§Ä¡¿¡ break point¸¦ Àâ½À´Ï´Ù. (1) ¿¡ Àâ´Â ÀÌÀ¯´Â sfp °ªÀ» ¾Ë¾Æº¸±â À§ÇÔÀÌ°í, (2) ¿¡ Àâ´Â ÀÌÀ¯´Â buf ÀÇ °ªÀ» ¾Ë¾Æº¸±â À§ÇÔ ÀÔ´Ï´Ù. (gdb) b *0x804832b Breakpoint 1 at 0x804832b (gdb) b *0x8048347 Breakpoint 2 at 0x8048347 (gdb) r aaaa Starting program: /root/dummy/8byte aaaa Breakpoint 1, 0x0804832b in main () (gdb) x/x $ebp 0xbfffecd8: 0xbfffecf8 (gdb) c Continuing. Breakpoint 2, 0x08048347 in main () (gdb) x/x $eax 0xbfffecd0: 0x42130a14 (gdb) ù¹ø° break point ¸¦ Àâ°í ÇÁ·¹ÀÓ Æ÷ÀÎÅÍ°¡ ÀúÀåµÇ¾î ÀÖ´Â ebp ¸¦ È®ÀÎÇÑ °á°ú 0xbfffecd8 ÀÌ ³ª¿Ô½À´Ï´Ù. µÎ¹ø°, strcpy Àü¿¡ push µÇ´Â eax ´Â buf ÀÇ ÁÖ¼ÒÀÔ´Ï´Ù. eax ¸¦ È®ÀÎÇÑ °á°ú 0xbfffecd0 À¸·Î ³ª¿Ô½À´Ï´Ù. stack ÀÌ ¾Æ·¡·Î ÀÚ¶ó³­´Ù´Â °ÍÀ» »ý°¢Çϸé 0xbfffecd8 - 0xbfffecd0 = 8 À̶õ °ªÀÌ ³ª¿À°í, ÀÌ °ÍÀº ÇÁ·Î½ÃÁ®ÀÇ ½ºÅà Æ÷ÀÎÅͷκÎÅÍ ÇÏÀ§ 8 ¹ÙÀÌÆ®, Áï buf ÀÇ Å©±â°¡ 8 ¹ÙÀÌÆ®°¡ ÇÒ´çµÇ¾ú´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù. ÀÌÁ¦ bufÀÇ Å©±â¸¦ 100¹ÙÀÌÆ®·Î Àâ°í ´Ù½Ã È®ÀÎÀ» Çغ¸°Ú½À´Ï´Ù. 100byte.c int main(int argc, char *argv[]) { char buf[100]; strcpy(buf, argv[1]); } [root@localhost dummy]# gcc -o 100byte 100byte.c [root@localhost dummy]# gdb 100byte GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 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-gnu"... (gdb) disassemble main Dump of assembler code for function main: 0x08048328 : push %ebp 0x08048329 : mov %esp,%ebp 0x0804832b : sub $0x78,%esp 0x0804832e : and $0xfffffff0,%esp 0x08048331 : mov $0x0,%eax 0x08048336 : sub %eax,%esp 0x08048338 : sub $0x8,%esp 0x0804833b : mov 0xc(%ebp),%eax 0x0804833e : add $0x4,%eax 0x08048341 : pushl (%eax) 0x08048343 : lea 0xffffff88(%ebp),%eax 0x08048346 : push %eax 0x08048347 : call 0x8048268 0x0804834c : add $0x10,%esp 0x0804834f : leave 0x08048350 : ret 0x08048351 : nop 0x08048352 : nop 0x08048353 : nop End of assembler dump. (gdb) b *0x804832b Breakpoint 1 at 0x804832b (gdb) b *0x8048347 Breakpoint 2 at 0x8048347 (gdb) r aaaa Starting program: /root/dummy/100byte aaaa Breakpoint 1, 0x0804832b in main () (gdb) x/x $ebp 0xbfffe8d8: 0xbfffe8f8 (gdb) c Continuing. Breakpoint 2, 0x08048347 in main () (gdb) x/x $eax 0xbfffe860: 0x42130a14 (gdb) break point ¸¦ Àâ´Â À§Ä¡³ª ·¹Áö½ºÅÍ °ªÀ» Á¶»çÇÑ ¹æ¹ýÀº 8byte.c ¸¦ ´Ù·ê ¶§¿Í µ¿ÀÏÇÕ´Ï´Ù. ¿©±â¼­ ³ª¿Â ebp ÀÇ ÁÖ¼Ò´Â 0xbfffe8d8 ÀÌ°í buf ÀÇ ÁÖ¼Ò´Â 0xbfffe860 ÀÎ °ÍÀ» È®ÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù. 0xbfffe8d8 - 0xbfffe860 Àº 0x78 ÀÌ°í 0x78 Àº 10 Áø¼ö·Î 120ÀÔ´Ï´Ù. °è»êÀ» Çغ¸¸é [buf 100 byte] - [dummy 20 byte] - [sfp] - [ret] ¿Í °°Àº ±¸Á¶·Î ½ºÅÃÀÌ »ý¼ºµÈ °ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù. Áï, ½ÇÁ¦·Î overflow ½Ã¿¡ ret ¸¦ µ¤¾î ¾²±â À§Çؼ­´Â 100 + 20 + 4 + 4 = 128. ÃÑ 128 ¹ÙÀÌÆ®¸¦ »ç¿ëÇØ¾ß ÇÕ´Ï´Ù. ±×·³ À̸¸~! - vangelis´Ô ´ñ±Û Á¶±Ý ´õ Ãß°¡Çϵµ·Ï ÇÏ°Ú½À´Ï´Ù. word(4 byte) ´ÜÀ§·Î µ¥ÀÌÅÍ°¡ ¸Þ¸ð¸®¿¡ ÀûÀçµÈ´Ù´Â °ÍÀ» ´Ùµé ¾Ë°í ÀÖÀ» °Ì´Ï´Ù. gcc 2.96 ¹öÀü ÀÌÈĺÎÅÍ ½ºÅÃÀÇ Á¤·ÄÀÌ 16 ¹ÙÀÌÆ®¸¦ À¯ÁöÇÕ´Ï´Ù. ±×·¡¼­ ÇÔ¼ö°¡ È£ÃâµÉ ¶§ Áö¿ªº¯¼ö¸¦ À§ÇÑ °ø°£¿¡ ÇÒ´çµÇ´Â µ¥ÀÌÅÍÀÇ ¾çÀº 16 ¹ÙÀÌÆ®¸¦ ä¿ó´Ï´Ù. ¾Æ·¡ÀÇ Å×½ºÆ® °á°ú¸¦ º¸½Ã±â ¹Ù¶ø´Ï´Ù. ---------------------------------------------------- int main(int argc, char *argv[]) { char buffer[n]; strcpy(buffer, argv[1]); } ---------------------------------------------------- À§ÀÇ ¼Ò½º¿¡¼­ buffer[n]¿¡¼­ nÀÇ Å©±â¿Í ÇÒ´çµÇ´Â ¾çÀº ´ÙÀ½°ú °°½À´Ï´Ù. --------------------------------------------- nÀÇ Å©±â | ÇÒ´ç¾ç --------------------------------------------- 1 - 16 | 24 ¹ÙÀÌÆ® 17 - 32 | 40 ¹ÙÀÌÆ® 33 - 48 | 56 ¹ÙÀÌÆ® 49 - 64 | 72 ¹ÙÀÌÆ® 65 - 80 | 88 ¹ÙÀÌÆ® 81 - 96 | 104 ¹ÙÀÌÆ® 97 -112 | 120 ¹ÙÀÌÆ® --------------------------------------------- À§ÀÇ °á°ú¸¦ º¸¸é, 16+16(=32)+16(=48)+16(=64)+16(=80)+16(=96)+16(=112)....... 24 40 56 72 88 104 120 16 + 16 + 16 + 16 + 16 + 16....... À§ÀÇ °ÍÀ» Á¤¸®Çغ¸¸é 16¾¿ ´õÇØÁú ¶§ ¸Þ¸ð¸®ÀÇ ÇÒ´ç¾çÀÌ º¯È­°í ÀÖ½À´Ï´Ù. ±×·¯³ª 1-16 »çÀÌ¿¡´Â ºÒ±ÔÄ¢ÇÔÀÌ º¸ÀÔ´Ï´Ù. ÀÌ°Í¿¡ ´ëÇÑ °ÍÀº Á¦ÀÏ ¾Æ·¡ ¸µÅ©¸¦ Âü°íÇϽñ⠹ٶø´Ï´Ù. ¿¹¸¦ µé¸é, ---------------------------------------------------- int main(int argc, char *argv[]) { char buffer[10]; strcpy(buffer, argv[1]); } ---------------------------------------------------- À§ÀÇ ¼Ò½º´Â 2.96 ¹öÀü ÀÌÇÏÀÇ °æ¿ì ´ÙÀ½°ú °°À» °ÍÀÔ´Ï´Ù. buffer(12) - sfp(4) - ret(4) ½ÇÁ¦´Â 10¹ÙÀÌÆ®°¡ ÇÒ´çµÇ¾î ÀÖÁö¸¸ word ´ÜÀ§·Î ÇÒ´çµÇ±â ¶§¹®¿¡ 12¹ÙÀÌÆ®°¡ ÇÒ´çµË´Ï´Ù. ±×·¯³ª 2.96¹öÀü ÀÌ»óÀÇ °æ¿ì, buffer(16) - sfp(4) - ret(4) =========== 24 byte(24-16=8, 8 ¹ÙÀÌÆ®ÀÇ ´õ¹Ì) ¼Ò½º¿¡¼­ buffer[10] ÀÌ ºÎºÐÀ» º¸¸é, 2.96 ÀÌÈÄ ¹öÀüÀÇ °æ¿ì 16 ¹ÙÀÌÆ®¾¿ alignment¸¦ ¸ÂÃ߱⠶§¹®¿¡ Àüü 12¹ÙÀÌÆ®°¡ ¾Æ´Ï¶ó 16 ¹ÙÀÌÆ®°¡ ÇÒ´çµË´Ï´Ù. gdb¸¦ ÀÌ¿ëÇØ È®ÀÎÇغ¸¸é prolog ºÎºÐÀº ´ÙÀ½°ú °°½À´Ï´Ù. 0x80482f4
: push %ebp 0x80482f5 : mov %esp,%ebp 0x80482f7 : sub $0x18,%esp 16Áø¼ö 0x18Àº 24ÀÔ´Ï´Ù. °á±¹ buffer¿¡ 16¹ÙÀÌÆ®°¡ ÇÒ´çµÇ¹Ç·Î, 8¹ÙÀÌÆ®ÀÇ ´õ¹Ì°¡ ¹ß»ýÇÏ´Â °ÍÀÔ´Ï´Ù. À§¿¡¼­ ½ÂÁøÀÌ°¡ Á¦½ÃÇÑ ¼Ò½º¸¦ º¸¸é, int main(int argc, char *argv[]) { char buf[100]; strcpy(buf, argv[1]); } ¾ÕÀÇ Ç¥¿¡¼­ 97-112±îÁö´Â 120 byte°¡ ÇÒ´çµÇ´Â °ÍÀ» º¸¾Ò½À´Ï´Ù. gdbÀÇ °á°úµµ ´ÙÀ½°ú °°½À´Ï´Ù. 0x78Àº ½ÊÁø¼ö·Î 120 byteÀÔ´Ï´Ù. 0x08048328 : push %ebp 0x08048329 : mov %esp,%ebp 0x0804832b : sub $0x78,%esp ÀÌ°ÍÀ» µµ½ÄÈ­ÇÏ¸é ´ÙÀ½°ú °°½À´Ï´Ù. buffer(100) - sfp(4) - ret(4) ============ 120 byte(120-100=20, 20 ¹ÙÀÌÆ®ÀÇ ´õ¹Ì) Á¶±Ý ´õ ÀÚ¼¼ÇÑ °ÍÀº(?) Àú°¡ ¾´ ±Û 41-43 ÆäÀÌÁö±îÁö Âü°íÇϽñ⠹ٶø´Ï´Ù.