Esempio n. 1
0
    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)
Esempio n. 2
0
    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.'
Esempio n. 3
0
        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 == '-c':
            device = recovery.acquire_device()
            try:
                recovery.send_command(device, arg)
            except usb.core.USBError:
                print 'WARNING: Caught USBError after running command.'
            recovery.release_device(device)

        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 = recovery.acquire_device()
            recovery.send_data(device, data)
            recovery.release_device(device)

        if opt == '--exit-recovery-loop':
            device = recovery.acquire_device()
Esempio n. 4
0
    def ibshell(self):
        while (1):
            cmd = raw_input("iBPFI: ")
            if cmd == "shell":
                pwn = 0
                cont = 1
                dev = usb.core.find(
                    idVendor=0x5AC,
                    idProduct=0x1281)  # fill in your own device, of course
                if dev != None:
                    print("found device in recovery mode")
                    cont = 1
                if cont != 0:
                    while (1):
                        cmd = raw_input("iShell: ")
                        cm = str(cmd.split(" ")[0])
                        if cm != "bgcolor" and cm != "kernelcache" and cm != "setenv" and cm != "saveenv" and cm != "bootx" and cm != "devicetree" and cm != "ramdisk" and cm != "setpicture" and cm != "reset" and cm != "reboot" and cm != "exit" and cmd != "send" and cm != "go":
                            print("invalid command")
                        else:
                            if cm == "exit":
                                exit()
                            elif cm == "reset" or cm == "reboot":
                                if usb.core.find(idVendor=0x5AC,
                                                 idProduct=0x1281) != None:
                                    os.system(
                                        "cd ./bin/; python ./reboot.py 2>/dev/null; cd ../"
                                    )
                                    exit()
                                exit()
                            elif cmd == "send":
                                device = recovery.acquire_device()
                                recovery.send_data(
                                    device,
                                    open(raw_input("File to send: "),
                                         "r").read())
                                recovery.release_device(device)
                            else:
                                recovery.acquire_device().ctrl_transfer(
                                    0x40, 0, 0, 0,
                                    str(cmd) + '\x00', 30000)

            if cmd == "checkm8":
                checkm8.exploit()
            if cmd == "exit":
                return
            if cmd == "sig":
                os.system("python ./bin/rmsigchks.py")
            if cmd == "help":
                print(
                    """checkm8 | puts device into pwned dfu mode using checkm8 exploit
sig | patch signiture checks on s5l8960x and t8011 devices
prec | sends ibss and ibec to device in pwned dfu mode
shell | opens recovery shell (like irecovery) for use with device in pwed recovery or regular recovery mode
rainbow | cycles through some colors with bgcolor. must have used prec on device before use
rainbowloop | does the same thing as rainbow but in a infinite loop
checkra1n | jailbreaks device with checkra1n jailbreak""")
            if cmd == "rainbow":
                r = 0
                g = 0
                b = 0
                while r != 255:
                    recovery.acquire_device().ctrl_transfer(
                        0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                        " " + str(b) + '\x00', 30000)
                    r = r + 1
                while g != 255:
                    recovery.acquire_device().ctrl_transfer(
                        0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                        " " + str(b) + '\x00', 30000)
                    g = g + 1
                while b != 255:
                    recovery.acquire_device().ctrl_transfer(
                        0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                        " " + str(b) + '\x00', 30000)
                    b = b + 1
                r = 0
                g = 0
                b = 0
                while r != 255:
                    recovery.acquire_device().ctrl_transfer(
                        0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                        " " + str(b) + '\x00', 30000)
                    r = r + 1
                r = 0
                while g != 255:
                    recovery.acquire_device().ctrl_transfer(
                        0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                        " " + str(b) + '\x00', 30000)
                    g = g + 1
                g = 0
                while b != 255:
                    recovery.acquire_device().ctrl_transfer(
                        0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                        " " + str(b) + '\x00', 30000)
                    b = b + 1
                b = 0
            if cmd == "rainbowloop":
                while 1:
                    r = 0
                    g = 0
                    b = 0
                    while r != 255:
                        recovery.acquire_device().ctrl_transfer(
                            0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                            " " + str(b) + '\x00', 30000)
                        r = r + 1
                    while g != 255:
                        recovery.acquire_device().ctrl_transfer(
                            0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                            " " + str(b) + '\x00', 30000)
                        g = g + 1
                    while b != 255:
                        recovery.acquire_device().ctrl_transfer(
                            0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                            " " + str(b) + '\x00', 30000)
                        b = b + 1
                    r = 0
                    g = 0
                    b = 0
                    while r != 255:
                        recovery.acquire_device().ctrl_transfer(
                            0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                            " " + str(b) + '\x00', 30000)
                        r = r + 1
                    r = 0
                    while g != 255:
                        recovery.acquire_device().ctrl_transfer(
                            0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                            " " + str(b) + '\x00', 30000)
                        g = g + 1
                    g = 0
                    while b != 255:
                        recovery.acquire_device().ctrl_transfer(
                            0x40, 0, 0, 0, "bgcolor " + str(r) + " " + str(g) +
                            " " + str(b) + '\x00', 30000)
                        b = b + 1
                    b = 0
            if cmd == "dfusend":
                os.system("./bin/bin/irecovery -f " +
                          str(raw_input("File Path: ")))
            if cmd == "prec":
                os.system("./bin/bin/irecovery -f " +
                          str(raw_input("iBSS Path: ")))
                os.system("./bin/bin/irecovery -f " +
                          str(raw_input("iBEC Path: ")))
            if cmd == "checkra1n":
                os.system("cd ./bin/check; ./checkra1n_gui -")
Esempio n. 5
0
    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