diff --git a/ipwndfu b/ipwndfu deleted file mode 100755 index c90d17b3..00000000 --- a/ipwndfu +++ /dev/null @@ -1,415 +0,0 @@ -#!/usr/bin/python -# ipwndfu: open-source jailbreaking tool for older iOS devices -# Author: axi0mX - -import binascii, datetime, getopt, hashlib, struct, sys, time -import dfu, nor, utilities -import alloc8, checkm8, image3_24Kpwn, limera1n, SHAtter, steaks4uce, usbexec -from dfuexec import * - -def print_help(): - print 'USAGE: ipwndfu [options]' - print 'Interact with an iOS device in DFU Mode.\n' - print 'Basic options:' - print ' -p\t\t\t\tUSB exploit for pwned DFU Mode' - print ' -x\t\t\t\tinstall alloc8 exploit to NOR' - 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' - print ' --dump-nor=file\t\tdump NOR to file' - print ' --flash-nor=file\t\tflash NOR (header and firmware only) from file' - print ' --24kpwn\t\t\tinstall 24Kpwn exploit to NOR' - print ' --remove-24kpwn\t\tremove 24Kpwn exploit from NOR' - print ' --remove-alloc8\t\tremove alloc8 exploit from NOR' - print ' --decrypt-gid=hexdata\t\tAES decrypt with GID key' - print ' --encrypt-gid=hexdata\t\tAES encrypt with GID key' - print ' --decrypt-uid=hexdata\t\tAES decrypt with UID key' - print ' --encrypt-uid=hexdata\t\tAES encrypt with UID key' - -if __name__ == '__main__': - try: - 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.' - print_help() - sys.exit(2) - - if len(opts) == 0: - print_help() - sys.exit(2) - - for opt, arg in opts: - if opt == '-p': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'CPID:8720' in serial_number: - steaks4uce.exploit() - elif 'CPID:8920' in serial_number: - limera1n.exploit() - elif 'CPID:8922' in serial_number: - limera1n.exploit() - elif 'CPID:8930' in serial_number: - SHAtter.exploit() - elif 'CPID:8947' in serial_number: - checkm8.exploit() - elif 'CPID:8950' in serial_number: - checkm8.exploit() - elif 'CPID:8955' in serial_number: - checkm8.exploit() - elif 'CPID:8960' in serial_number: - checkm8.exploit() - elif 'CPID:8002' in serial_number: - checkm8.exploit() - elif 'CPID:8004' in serial_number: - checkm8.exploit() - elif 'CPID:8010' in serial_number: - checkm8.exploit() - elif 'CPID:8011' in serial_number: - checkm8.exploit() - elif 'CPID:8015' in serial_number: - checkm8.exploit() - else: - print 'Found:', serial_number - print 'ERROR: This device is not supported.' - sys.exit(1) - - if opt == '-x': - device = PwnedDFUDevice() - if device.config.cpid != '8920': - print 'This is not a compatible device. alloc8 exploit is for iPhone 3GS only.' - sys.exit(1) - - if device.config.version == '359.3': - print 'WARNING: iPhone 3GS (old bootrom) was detected. Use 24Kpwn exploit for faster boots, alloc8 exploit is for testing purposes only.' - raw_input("Press ENTER to continue.") - - print 'Installing alloc8 exploit to NOR.' - - dump = device.nor_dump(saveBackup=True) - - nor = nor.NorData(dump) - - for byte in nor.parts[1]: - if byte != '\x00': - print 'ERROR: Bytes following IMG2 header in NOR are not zero. alloc8 exploit was likely previously installed. Exiting.' - sys.exit(1) - if len(nor.images) == 0 or len(nor.images[0]) < 0x24000: - print 'ERROR: 24Kpwn LLB was not found. You must restore a custom 24Kpwn IPSW before using this exploit.' - sys.exit(1) - - print 'Preparing modified NOR with alloc8 exploit.' - # Remove 24Kpwn first. - nor.images[0] = image3_24Kpwn.remove_exploit(nor.images[0]) - new_nor = alloc8.exploit(nor, device.config.version) - device.flash_nor(new_nor.dump()) - - if opt == '-f': - try: - with open(arg, 'rb') as f: - data = f.read() - except IOError: - print 'ERROR: Could not read file:', arg - sys.exit(1) - - device = dfu.acquire_device() - dfu.reset_counters(device) - dfu.send_data(device, data) - dfu.request_image_validation(device) - dfu.release_device(device) - - if opt == '--demote': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - pwned = usbexec.PwnedUSBDevice() - old_value = pwned.read_memory_uint32(pwned.platform.demotion_reg) - print 'Demotion register: 0x%x' % old_value - if old_value & 1: - print 'Attempting to demote device.' - pwned.write_memory_uint32(pwned.platform.demotion_reg, old_value & 0xFFFFFFFE) - new_value = pwned.read_memory_uint32(pwned.platform.demotion_reg) - print 'Demotion register: 0x%x' % new_value - if old_value != new_value: - print 'Success!' - else: - print 'Failed.' - else: - print 'WARNING: Device is already demoted.' - else: - print 'ERROR: Demotion is only supported on devices pwned with checkm8 exploit.' - sys.exit(1) - - if opt == '--dump': - if arg.count(',') != 1: - print 'ERROR: You must provide exactly 2 comma separated values: address,length' - sys.exit(1) - raw_address, raw_length = arg.split(',') - address = int(raw_address, 16) if raw_address.startswith('0x') else int(raw_address, 10) - length = int(raw_length, 16) if raw_length.startswith('0x') else int(raw_length, 10) - - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - device = usbexec.PwnedUSBDevice() - sys.stdout.write(device.read_memory(address, length)) - else: - device = PwnedDFUDevice() - print device.read_memory(address, length) - - if opt == '--hexdump': - if arg.count(',') != 1: - print 'ERROR: You must provide exactly 2 comma separated values: address,length' - sys.exit(1) - raw_address, raw_length = arg.split(',') - address = int(raw_address, 16) if raw_address.startswith('0x') else int(raw_address, 10) - length = int(raw_length, 16) if raw_length.startswith('0x') else int(raw_length, 10) - - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - device = usbexec.PwnedUSBDevice() - dump = device.read_memory(address, length) - for line in utilities.hex_dump(dump, address).splitlines(): - print '%x: %s' % (address, line[10:]) - address += 16 - else: - device = PwnedDFUDevice() - dump = device.read_memory(address, length) - print utilities.hex_dump(dump, address), - - if opt == '--dump-rom': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - pwned = usbexec.PwnedUSBDevice() - securerom = pwned.read_memory(pwned.platform.rom_base, pwned.platform.rom_size) - if hashlib.sha1(securerom).hexdigest() != pwned.platform.rom_sha1: - print hashlib.sha1(securerom).hexdigest() - print 'ERROR: SecureROM was dumped, but the SHA1 hash does not match. Exiting.' - sys.exit(1) - chip = securerom[0x200:0x240].split(' ')[2][:-1] - kind = securerom[0x240:0x280].split('\0')[0] - version = securerom[0x280:0x2C0].split('\0')[0][6:] - filename = 'SecureROM-%s-%s-%s.dump' % (chip, version, kind) - with open(filename, 'wb') as f: - f.write(securerom) - print 'Saved:', filename - else: - device = PwnedDFUDevice() - securerom = device.securerom_dump() - filename = 'SecureROM-%s-RELEASE.dump' % device.config.version - f = open(filename, 'wb') - f.write(securerom) - f.close() - print 'SecureROM dumped to file:', filename - - if opt == '--dump-nor': - device = PwnedDFUDevice() - if device.config.cpid != '8920': - print 'This is not a compatible device. Dumping NOR is only supported on iPhone 3GS.' - sys.exit(1) - nor = device.nor_dump(saveBackup=False) - f = open(arg, 'wb') - f.write(nor) - f.close() - print 'NOR dumped to file: %s' % arg - - if opt == '--flash-nor': - print 'Flashing NOR from file:', arg - f = open(arg, 'rb') - new_nor = f.read() - f.close() - if new_nor[:4] != 'IMG2'[::-1]: - print 'ERROR: Bad IMG2 header magic. This is not a valid NOR. Exiting.' - sys.exit(1) - - device = PwnedDFUDevice() - if device.config.cpid != '8920': - print 'This is not a compatible device. Flashing NOR is only supported on iPhone 3GS.' - sys.exit(1) - device.nor_dump(saveBackup=True) - device.flash_nor(new_nor) - - if opt == '--24kpwn': - print '*** based on 24Kpwn exploit (segment overflow) by chronic, CPICH, ius, MuscleNerd, Planetbeing, pod2g, posixninja, et al. ***' - - device = PwnedDFUDevice() - if device.config.version != '359.3': - print 'Only iPhone 3GS (old bootrom) is supported.' - sys.exit(1) - - dump = device.nor_dump(saveBackup=True) - - print 'Preparing modified NOR with 24Kpwn exploit.' - nor = nor.NorData(dump) - for byte in nor.parts[1]: - if byte != '\x00': - print 'ERROR: Bytes following IMG2 header in NOR are not zero. alloc8 exploit was likely previously installed. Exiting.' - sys.exit(1) - if len(nor.images) == 0: - print 'ERROR: 24Kpwn exploit cannot be installed, because NOR has no valid LLB. Exiting.' - sys.exit(1) - - # Remove existing 24Kpwn exploit. - if len(nor.images[0]) > 0x24000: - nor.images[0] = image3_24Kpwn.remove_exploit(nor.images[0]) - nor.images[0] = image3_24Kpwn.exploit(nor.images[0], device.securerom_dump()) - device.flash_nor(nor.dump()) - - if opt == '--remove-24kpwn': - device = PwnedDFUDevice() - if device.config.cpid != '8920': - print 'This is not a compatible device. 24Kpwn exploit is only supported on iPhone 3GS.' - sys.exit(1) - - print 'WARNING: This feature is for researchers only. Device will probably not boot into iOS until it is restored in iTunes.' - raw_input("Press ENTER to continue.") - - dump = device.nor_dump(saveBackup=True) - - nor = nor.NorData(dump) - - if len(nor.images) == 0: - print 'ERROR: NOR has no valid LLB. It seems that 24Kpwn exploit is not installed. Exiting.' - sys.exit(1) - if len(nor.images[0]) <= 0x24000: - print 'ERROR: LLB is not oversized. It seems that 24Kpwn exploit is not installed. Exiting.' - sys.exit(1) - - print 'Preparing modified NOR without 24Kpwn exploit.' - nor.images[0] = image3_24Kpwn.remove_exploit(nor.images[0]) - device.flash_nor(nor.dump()) - - if opt == '--remove-alloc8': - device = PwnedDFUDevice() - if device.config.cpid != '8920': - print 'This is not a compatible device. alloc8 exploit is for iPhone 3GS only.' - sys.exit(1) - - print 'WARNING: This feature is for researchers only. Device will probably not boot into iOS until it is restored in iTunes.' - raw_input("Press ENTER to continue.") - - dump = device.nor_dump(saveBackup=True) - - nor = nor.NorData(dump) - - if len(nor.images) < 700: - print 'ERROR: It seems that alloc8 exploit is not installed. There are less than 700 images in NOR. Exiting.' - sys.exit(1) - - print 'Preparing modified NOR without alloc8 exploit.' - new_nor = alloc8.remove_exploit(nor) - device.flash_nor(new_nor.dump()) - - if opt == '--decrypt-gid': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - pwned = usbexec.PwnedUSBDevice() - print 'Decrypting with %s GID key.' % pwned.platform.name() - print pwned.aes(arg.decode('hex'), usbexec.AES_DECRYPT, usbexec.AES_GID_KEY).encode('hex') - else: - device = PwnedDFUDevice() - print 'Decrypting with S5L%s GID key.' % device.config.cpid - print device.aes_hex(arg, AES_DECRYPT, AES_GID_KEY) - - if opt == '--encrypt-gid': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - pwned = usbexec.PwnedUSBDevice() - print 'Encrypting with %s GID key.' % pwned.platform.name() - print pwned.aes(arg.decode('hex'), usbexec.AES_ENCRYPT, usbexec.AES_GID_KEY).encode('hex') - else: - device = PwnedDFUDevice() - print 'Encrypting with S5L%s GID key.' % device.config.cpid - print device.aes_hex(arg, AES_ENCRYPT, AES_GID_KEY) - - if opt == '--decrypt-uid': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - pwned = usbexec.PwnedUSBDevice() - print 'Decrypting with %s device-specific UID key.' % pwned.platform.name() - print pwned.aes(arg.decode('hex'), usbexec.AES_DECRYPT, usbexec.AES_UID_KEY).encode('hex') - else: - device = PwnedDFUDevice() - print 'Decrypting with device-specific UID key.' - print device.aes_hex(arg, AES_DECRYPT, AES_UID_KEY) - - if opt == '--encrypt-uid': - device = dfu.acquire_device() - serial_number = device.serial_number - dfu.release_device(device) - - if 'PWND:[checkm8]' in serial_number: - pwned = usbexec.PwnedUSBDevice() - print 'Encrypting with %s device-specific UID key.' % pwned.platform.name() - print pwned.aes(arg.decode('hex'), usbexec.AES_ENCRYPT, usbexec.AES_UID_KEY).encode('hex') - else: - 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.'