/* * fc4.c - 29-12-2005 andrewg@felinemenace.org * * Simple exploit-me for Fedora Core 4 systems... and others that use * execshield. * * Compile: * gcc -pie fc4.c -o fc4 * * You might need -fpie on some other systems etc bleh. * Make sure randomisation etc is enabled, and exec-shield etc.. * * -cs will restart the program until the data section of the binary is * executable, as an added bit of flexibility.. * * -ss disables forking and does a "single shot" mode.. might make some * debugging easier. */ #include #include #include #include #include #include #include #include int setup_socket() { int ret; struct sockaddr_in sin; if((ret = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Unable to socket\n"); exit(EXIT_FAILURE); } sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(5842); if(bind(ret, (void *)&sin, sizeof(struct sockaddr_in)) == -1) { printf("Unable to bind()\n"); exit(EXIT_FAILURE); } if(listen(ret, 5) == -1) { printf("Unable to listen\n"); exit(EXIT_FAILURE); } return ret; } char bleh[4192]; void bug() { int len; char buf[2048]; len = 0; read(0, &len, 2); read(0, buf, len); len = 0; read(0, &len, 2); read(0, bleh, len); } void check(char **argv, char **envp) { FILE *p; char line[128]; /* no, don't return to here, as its cheating :) */ p = fopen("/proc/self/status", "r"); if(p == NULL) exit(EXIT_FAILURE); // fuck it, exploit this on a real system while(fgets(line, sizeof(line)-1, p)) { if(strncmp(line, "ExecLim:", 8) == 0) { char *q; int lim; q = line + 9; while(*q == ' ') p++; lim = strtoul(q, NULL, 16); if(lim == 0) { printf("Didn't read in the buffer correctly\n"); exit(EXIT_FAILURE); } if((unsigned int)(bleh) > lim) { printf("Restarting..\n"); sleep(1); execve(argv[0], argv, envp); } fclose(p); return; } } printf("it appears your system doesn't have execlim in /proc/self/status.. are you sure execshield is enabled?\n"); exit(EXIT_FAILURE); } int main(int argc, char **argv, char **envp) { int fd, s; int i, ss; for(ss = 0, i = 1; i < argc; i++) { if(strcmp(argv[i], "-cs") == 0) check(argv, envp); if(strcmp(argv[i], "-ss") == 0) ss = 1; } if(ss) printf("--> Single shot mode enabled\n"); fd = setup_socket(); signal(SIGCHLD, SIG_IGN); printf("bleh is at @ 0x%08x\n", bleh); memset(bleh, 0xcc, sizeof(bleh)); while(1) { if((s = accept(fd, NULL, NULL)) == -1) continue; if(ss || fork() == 0) { close(fd); /* this is just to make life easier */ dup2(s, 0); dup2(s, 1); dup2(s, 2); if(s > 2) close(s); bug(); exit(EXIT_FAILURE); } close(s); } }