Wie entschlüssele ich ein verschlüsseltes Apple iTunes iPhone Backup?

84

Ich wurde von einer Reihe unglücklicher iPhone-Benutzer gebeten, ihnen bei der Wiederherstellung von Daten aus ihren iTunes-Backups zu helfen. Dies ist einfach, wenn sie unverschlüsselt sind, aber nicht, wenn sie verschlüsselt sind, unabhängig davon, ob das Kennwort bekannt ist oder nicht.

Daher versuche ich, das Verschlüsselungsschema herauszufinden, das bei der Verschlüsselung für mddata- und mdinfo-Dateien verwendet wird. Ich habe keine Probleme, diese Dateien ansonsten zu lesen, und habe dafür einige robuste C # -Bibliotheken erstellt. (Wenn Sie helfen können, ist es mir egal, welche Sprache Sie verwenden. Es ist das Prinzip, nach dem ich hier bin!)

Im Apple "iPhone OS Enterprise-Bereitstellungshandbuch" heißt es: "Gerätesicherungen können in verschlüsseltem Format gespeichert werden, indem Sie im Bereich" Geräteübersicht "von iTunes die Option" iPhone-Sicherung verschlüsseln "auswählen. Dateien werden mit AES128 mit einem 256-Bit-Schlüssel verschlüsselt sicher im iPhone-Schlüsselbund gespeichert. "

Das ist ein ziemlich guter Hinweis, und hier gibt es einige gute Informationen zur Interoperabilität von Stackoverflow auf dem iPhone AES / Rijndael, die darauf hindeuten, dass eine Schlüsselgröße von 128 und der CBC-Modus verwendet werden können.

Neben jeder anderen Verschleierung sind ein Schlüssel und ein Initialisierungsvektor (IV) / Salz erforderlich.

Man könnte annehmen, dass der Schlüssel eine Manipulation des "Sicherungskennworts" ist, das Benutzer von iTunes zur Eingabe aufgefordert und an " AppleMobileBackup.exe " übergeben werden, aufgefüllt auf eine von CBC vorgegebene Weise. Angesichts des Verweises auf den iPhone-Schlüsselbund frage ich mich jedoch, ob das "Sicherungskennwort" möglicherweise nicht als Kennwort für ein X509-Zertifikat oder einen symmetrischen privaten Schlüssel verwendet wird und ob das Zertifikat oder der private Schlüssel selbst möglicherweise als Schlüssel verwendet wird. ( AES und der iTunes-Verschlüsselungs- / Entschlüsselungsprozess sind symmetrisch.)

Die IV ist eine andere Sache, und es könnte ein paar Dinge sein. Vielleicht ist es einer der Schlüssel, die in iTunes oder in den Geräten selbst fest codiert sind .

Obwohl der obige Kommentar von Apple darauf hinweist, dass der Schlüssel am Schlüsselbund des Geräts vorhanden ist, denke ich, dass dies nicht so wichtig ist. Man kann ein verschlüsseltes Backup auf einem anderen Gerät wiederherstellen , was darauf hindeutet, dass alle für die Entschlüsselung relevanten Informationen in der Backup- und iTunes-Konfiguration vorhanden sind und dass alles, was sich ausschließlich auf dem Gerät befindet, in diesem Zusammenhang irrelevant und ersetzbar ist. Wo könnte also der Schlüssel sein?

Ich habe unten Pfade von einem Windows-Computer aufgelistet, aber es ist sehr viel, welches Betriebssystem wir verwenden.

Die Datei "\ appdata \ Roaming \ Apple Computer \ iTunes \ itunesprefs.xml" enthält eine PList mit einem Diktateintrag "Schlüsselbund". Die Datei "\ programdata \ apple \ Lockdown \ 09037027da8f4bdefdea97d706703ca034c88bab.plist" enthält eine PList mit "DeviceCertificate", "HostCertificate" und "RootCertificate", die alle als gültige X509-Zertifikate erscheinen. Dieselbe Datei scheint auch asymmetrische Schlüssel "RootPrivateKey" und "HostPrivateKey" zu enthalten (meine Lektüre legt nahe, dass diese möglicherweise PKCS # 7-umhüllt sind). Außerdem gibt es in jeder Sicherung "AuthSignature" - und "AuthData" -Werte in der Manifest.plist-Datei, obwohl diese scheinbar gedreht werden, wenn jede Datei inkrementell gesichert wird, was darauf hindeutet, dass sie als Schlüssel nicht so nützlich sind, es sei denn, etwas wirklich ziemlich involviert wird getan.

Es gibt viele irreführende Dinge, die darauf hindeuten, dass das Abrufen von Daten aus verschlüsselten Backups einfach ist. Es ist nicht und meines Wissens wurde es nicht getan. Das Umgehen oder Deaktivieren der Sicherungsverschlüsselung ist eine ganz andere Sache und nicht das, was ich tun möchte.

Hier geht es nicht darum, das iPhone oder ähnliches auseinander zu hacken. Alles, was ich hier suche, ist ein Mittel, um Daten (Fotos, Kontakte usw.) aus verschlüsselten iTunes-Backups zu extrahieren, da ich unverschlüsselte Backups kann. Ich habe alle möglichen Permutationen mit den Informationen versucht, die ich oben notiert habe, bin aber nicht weitergekommen. Ich würde mich über Gedanken oder Techniken freuen, die ich möglicherweise übersehen habe.

Aidan Fitzpatrick
quelle
3
Update ab drei Jahren: Ich habe es herausgefunden und in ein frei verfügbares Produkt gerollt. Ich war oben auf dem richtigen Weg, aber es war schwer.
Aidan Fitzpatrick
Haben Sie einen Link für dieses Produkt?
Thilo
1
Wie du gefragt hast, ist es das iPhone Backup Extractor . Während Sie sehen werden, dass es kostenpflichtige Editionen des Programms gibt, können Sie mit der einfachen alten kostenlosen Edition jeweils 4 verschlüsselte Dateien herausholen.
Aidan Fitzpatrick
1
Ich sehe, dass Sie es geschafft haben, 10.2-Backup zu entschlüsseln. Können Sie uns bitte mitteilen, wie Sie dies erreicht haben?
Niki
@Niki Ich habe meine Antwort unten für iOS 10 aktualisiert
andrewdotn

Antworten:

102

Die Sicherheitsforscher Jean-Baptiste Bédrune und Jean Sigwald stellten dies auf der Hack-in-the-Box Amsterdam 2011 vor .

Seitdem hat Apple eine veröffentlicht iOS Security Whitepaper mit weiteren Details zu Schlüsseln und Algorithmen veröffentlicht, und Charlie Miller et al. haben das iOS-Hacker-Handbuch veröffentlicht , das einige der gleichen Themen auf eine Art und Weise abdeckt. Als iOS 10 herauskam, gab es Änderungen am Sicherungsformat, die Apple zunächst nicht veröffentlichte, aber verschiedene Leute haben die Formatänderungen rückentwickelt .

Verschlüsselte Backups sind großartig

Das Tolle an verschlüsselten iPhone-Backups ist, dass sie Dinge wie WiFi-Passwörter enthalten, die nicht in normalen unverschlüsselten Backups enthalten sind. Wie im Whitepaper zur iOS-Sicherheit erläutert , gelten verschlüsselte Sicherungen als „sicherer“. Apple hält es daher für in Ordnung, vertraulichere Informationen in sie aufzunehmen.

Eine wichtige Warnung: Wenn Sie das Backup Ihres iOS-Geräts entschlüsseln, wird die Verschlüsselung entfernt. Um Ihre Privatsphäre und Sicherheit zu schützen, sollten Sie diese Skripts nur auf einem Computer mit vollständiger Festplattenverschlüsselung ausführen. Während es einem Sicherheitsexperten möglich ist, Software zu schreiben, die Schlüssel im Speicher schützt, z. B. durch Verwendung von Funktionen wieVirtualLock() und SecureZeroMemory()unter anderem, speichern diese Python-Skripte Ihre Verschlüsselungsschlüssel und Kennwörter in Zeichenfolgen, die von Python im Müll gesammelt werden. Dies bedeutet, dass Ihre geheimen Schlüssel und Passwörter eine Weile im RAM verbleiben, von wo aus sie in Ihre Auslagerungsdatei und auf Ihre Festplatte gelangen, wo ein Gegner sie wiederherstellen kann. Dies macht den Punkt einer verschlüsselten Sicherung völlig zunichte.

So entschlüsseln Sie Backups: theoretisch

Das iOS-Sicherheits-Whitepaper erläutert die grundlegenden Konzepte von Schlüsseln pro Datei, Schutzklassen, Schutzklassenschlüsseln und Schlüsseltaschen besser als ich. Wenn Sie mit diesen noch nicht vertraut sind, nehmen Sie sich ein paar Minuten Zeit, um die entsprechenden Teile zu lesen.

Jetzt wissen Sie, dass jede Datei in iOS mit einem eigenen zufälligen Verschlüsselungsschlüssel pro Datei verschlüsselt ist, zu einer Schutzklasse gehört und die Verschlüsselungsschlüssel pro Datei in den Metadaten des Dateisystems gespeichert sind, die in den Schutzklassenschlüssel eingeschlossen sind.

So entschlüsseln Sie:

  1. Dekodieren Sie den im BackupKeyBagEintrag von gespeicherten Schlüsselbeutel Manifest.plist. Eine allgemeine Übersicht über diese Struktur finden Sie im Whitepaper . Das iPhone-Wiki beschreibt das Binärformat: ein 4-Byte-Zeichenfolgentypfeld, ein 4-Byte-Big-Endian-Längenfeld und dann den Wert selbst.

    Die wichtigen Werte sind die PBKDF2- ITERWerte und SALTdie doppelte Schutzsalz- und DPSLIterationszahl DPICsowie für jeden Schutz CLSder WPKYumschlossene Schlüssel.

  2. Verwenden Sie das Sicherungskennwort, um einen 32-Byte-Schlüssel mit dem richtigen PBKDF2-Salt und der richtigen Anzahl von Iterationen abzuleiten. Verwenden Sie zuerst eine SHA256-Runde mit DPSLund DPICdann eine SHA1-Runde mit ITERund SALT.

    Wickeln Sie jeden verpackten Schlüssel gemäß RFC 3394 aus .

  3. Entschlüsseln der Manifest - Datenbank , indem Sie die 4-Byte - Schutzklasse und längere Schlüssel aus dem Zug ManifestKeyin Manifest.plistund Abwickeln es. Sie haben jetzt eine SQLite-Datenbank mit allen Dateimetadaten.

  4. Rufen Sie für jede interessierende Datei den klassenverschlüsselten Verschlüsselungsschlüssel pro Datei und den Schutzklassencode ab, indem Sie in der Files.fileDatenbankspalte nach einer Binärliste suchen, die EncryptionKeyund enthält ProtectionClass Einträge. Entfernen Sie das anfängliche Tag mit einer Länge von vier Byte von EncryptionKey vor der Verwendung mit einer .

    Leiten Sie dann den endgültigen Entschlüsselungsschlüssel ab, indem Sie ihn mit dem Klassenschlüssel entpacken, der mit dem Sicherungskennwort entpackt wurde. Entschlüsseln Sie dann die Datei mit AES im CBC-Modus mit einer Null IV.

So entschlüsseln Sie Backups: in der Praxis

Zuerst benötigen Sie einige Bibliotheksabhängigkeiten. Wenn Sie mit einem von Homebrew installierten Python 2.7 oder 3.7 auf einem Mac arbeiten, können Sie die Abhängigkeiten installieren mit:

CFLAGS="-I$(brew --prefix)/opt/openssl/include" \
LDFLAGS="-L$(brew --prefix)/opt/openssl/lib" \    
    pip install biplist fastpbkdf2 pycrypto

In Form eines ausführbaren Quellcodes können Sie eine einzelne Voreinstellungsdatei aus einem verschlüsselten iPhone-Backup entschlüsseln:

#!/usr/bin/env python3.7
# coding: UTF-8

from __future__ import print_function
from __future__ import division

import argparse
import getpass
import os.path
import pprint
import random
import shutil
import sqlite3
import string
import struct
import tempfile
from binascii import hexlify

import Crypto.Cipher.AES # https://www.dlitz.net/software/pycrypto/
import biplist
import fastpbkdf2
from biplist import InvalidPlistException


def main():
    ## Parse options
    parser = argparse.ArgumentParser()
    parser.add_argument('--backup-directory', dest='backup_directory',
                    default='testdata/encrypted')
    parser.add_argument('--password-pipe', dest='password_pipe',
                        help="""\
Keeps password from being visible in system process list.
Typical use: --password-pipe=<(echo -n foo)
""")
    parser.add_argument('--no-anonymize-output', dest='anonymize',
                        action='store_false')
    args = parser.parse_args()
    global ANONYMIZE_OUTPUT
    ANONYMIZE_OUTPUT = args.anonymize
    if ANONYMIZE_OUTPUT:
        print('Warning: All output keys are FAKE to protect your privacy')

    manifest_file = os.path.join(args.backup_directory, 'Manifest.plist')
    with open(manifest_file, 'rb') as infile:
        manifest_plist = biplist.readPlist(infile)
    keybag = Keybag(manifest_plist['BackupKeyBag'])
    # the actual keys are unknown, but the wrapped keys are known
    keybag.printClassKeys()

    if args.password_pipe:
        password = readpipe(args.password_pipe)
        if password.endswith(b'\n'):
            password = password[:-1]
    else:
        password = getpass.getpass('Backup password: ').encode('utf-8')

    ## Unlock keybag with password
    if not keybag.unlockWithPasscode(password):
        raise Exception('Could not unlock keybag; bad password?')
    # now the keys are known too
    keybag.printClassKeys()

    ## Decrypt metadata DB
    manifest_key = manifest_plist['ManifestKey'][4:]
    with open(os.path.join(args.backup_directory, 'Manifest.db'), 'rb') as db:
        encrypted_db = db.read()

    manifest_class = struct.unpack('<l', manifest_plist['ManifestKey'][:4])[0]
    key = keybag.unwrapKeyForClass(manifest_class, manifest_key)
    decrypted_data = AESdecryptCBC(encrypted_db, key)

    temp_dir = tempfile.mkdtemp()
    try:
        # Does anyone know how to get Python’s SQLite module to open some
        # bytes in memory as a database?
        db_filename = os.path.join(temp_dir, 'db.sqlite3')
        with open(db_filename, 'wb') as db_file:
            db_file.write(decrypted_data)
        conn = sqlite3.connect(db_filename)
        conn.row_factory = sqlite3.Row
        c = conn.cursor()
        # c.execute("select * from Files limit 1");
        # r = c.fetchone()
        c.execute("""
            SELECT fileID, domain, relativePath, file
            FROM Files
            WHERE relativePath LIKE 'Media/PhotoData/MISC/DCIM_APPLE.plist'
            ORDER BY domain, relativePath""")
        results = c.fetchall()
    finally:
        shutil.rmtree(temp_dir)

    for item in results:
        fileID, domain, relativePath, file_bplist = item

        plist = biplist.readPlistFromString(file_bplist)
        file_data = plist['$objects'][plist['$top']['root'].integer]
        size = file_data['Size']

        protection_class = file_data['ProtectionClass']
        encryption_key = plist['$objects'][
            file_data['EncryptionKey'].integer]['NS.data'][4:]

        backup_filename = os.path.join(args.backup_directory,
                                    fileID[:2], fileID)
        with open(backup_filename, 'rb') as infile:
            data = infile.read()
            key = keybag.unwrapKeyForClass(protection_class, encryption_key)
            # truncate to actual length, as encryption may introduce padding
            decrypted_data = AESdecryptCBC(data, key)[:size]

        print('== decrypted data:')
        print(wrap(decrypted_data))
        print()

        print('== pretty-printed plist')
        pprint.pprint(biplist.readPlistFromString(decrypted_data))

##
# this section is mostly copied from parts of iphone-dataprotection
# http://code.google.com/p/iphone-dataprotection/

CLASSKEY_TAGS = [b"CLAS",b"WRAP",b"WPKY", b"KTYP", b"PBKY"]  #UUID
KEYBAG_TYPES = ["System", "Backup", "Escrow", "OTA (icloud)"]
KEY_TYPES = ["AES", "Curve25519"]
PROTECTION_CLASSES={
    1:"NSFileProtectionComplete",
    2:"NSFileProtectionCompleteUnlessOpen",
    3:"NSFileProtectionCompleteUntilFirstUserAuthentication",
    4:"NSFileProtectionNone",
    5:"NSFileProtectionRecovery?",

    6: "kSecAttrAccessibleWhenUnlocked",
    7: "kSecAttrAccessibleAfterFirstUnlock",
    8: "kSecAttrAccessibleAlways",
    9: "kSecAttrAccessibleWhenUnlockedThisDeviceOnly",
    10: "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly",
    11: "kSecAttrAccessibleAlwaysThisDeviceOnly"
}
WRAP_DEVICE = 1
WRAP_PASSCODE = 2

class Keybag(object):
    def __init__(self, data):
        self.type = None
        self.uuid = None
        self.wrap = None
        self.deviceKey = None
        self.attrs = {}
        self.classKeys = {}
        self.KeyBagKeys = None #DATASIGN blob
        self.parseBinaryBlob(data)

    def parseBinaryBlob(self, data):
        currentClassKey = None

        for tag, data in loopTLVBlocks(data):
            if len(data) == 4:
                data = struct.unpack(">L", data)[0]
            if tag == b"TYPE":
                self.type = data
                if self.type > 3:
                    print("FAIL: keybag type > 3 : %d" % self.type)
            elif tag == b"UUID" and self.uuid is None:
                self.uuid = data
            elif tag == b"WRAP" and self.wrap is None:
                self.wrap = data
            elif tag == b"UUID":
                if currentClassKey:
                    self.classKeys[currentClassKey[b"CLAS"]] = currentClassKey
                currentClassKey = {b"UUID": data}
            elif tag in CLASSKEY_TAGS:
                currentClassKey[tag] = data
            else:
                self.attrs[tag] = data
        if currentClassKey:
            self.classKeys[currentClassKey[b"CLAS"]] = currentClassKey

    def unlockWithPasscode(self, passcode):
        passcode1 = fastpbkdf2.pbkdf2_hmac('sha256', passcode,
                                        self.attrs[b"DPSL"],
                                        self.attrs[b"DPIC"], 32)
        passcode_key = fastpbkdf2.pbkdf2_hmac('sha1', passcode1,
                                            self.attrs[b"SALT"],
                                            self.attrs[b"ITER"], 32)
        print('== Passcode key')
        print(anonymize(hexlify(passcode_key)))
        for classkey in self.classKeys.values():
            if b"WPKY" not in classkey:
                continue
            k = classkey[b"WPKY"]
            if classkey[b"WRAP"] & WRAP_PASSCODE:
                k = AESUnwrap(passcode_key, classkey[b"WPKY"])
                if not k:
                    return False
                classkey[b"KEY"] = k
        return True

    def unwrapKeyForClass(self, protection_class, persistent_key):
        ck = self.classKeys[protection_class][b"KEY"]
        if len(persistent_key) != 0x28:
            raise Exception("Invalid key length")
        return AESUnwrap(ck, persistent_key)

    def printClassKeys(self):
        print("== Keybag")
        print("Keybag type: %s keybag (%d)" % (KEYBAG_TYPES[self.type], self.type))
        print("Keybag version: %d" % self.attrs[b"VERS"])
        print("Keybag UUID: %s" % anonymize(hexlify(self.uuid)))
        print("-"*209)
        print("".join(["Class".ljust(53),
                    "WRAP".ljust(5),
                    "Type".ljust(11),
                    "Key".ljust(65),
                    "WPKY".ljust(65),
                    "Public key"]))
        print("-"*208)
        for k, ck in self.classKeys.items():
            if k == 6:print("")

            print("".join(
                [PROTECTION_CLASSES.get(k).ljust(53),
                str(ck.get(b"WRAP","")).ljust(5),
                KEY_TYPES[ck.get(b"KTYP",0)].ljust(11),
                anonymize(hexlify(ck.get(b"KEY", b""))).ljust(65),
                anonymize(hexlify(ck.get(b"WPKY", b""))).ljust(65),
            ]))
        print()

def loopTLVBlocks(blob):
    i = 0
    while i + 8 <= len(blob):
        tag = blob[i:i+4]
        length = struct.unpack(">L",blob[i+4:i+8])[0]
        data = blob[i+8:i+8+length]
        yield (tag,data)
        i += 8 + length

def unpack64bit(s):
    return struct.unpack(">Q",s)[0]
def pack64bit(s):
    return struct.pack(">Q",s)

def AESUnwrap(kek, wrapped):
    C = []
    for i in range(len(wrapped)//8):
        C.append(unpack64bit(wrapped[i*8:i*8+8]))
    n = len(C) - 1
    R = [0] * (n+1)
    A = C[0]

    for i in range(1,n+1):
        R[i] = C[i]

    for j in reversed(range(0,6)):
        for i in reversed(range(1,n+1)):
            todec = pack64bit(A ^ (n*j+i))
            todec += pack64bit(R[i])
            B = Crypto.Cipher.AES.new(kek).decrypt(todec)
            A = unpack64bit(B[:8])
            R[i] = unpack64bit(B[8:])

    if A != 0xa6a6a6a6a6a6a6a6:
        return None
    res = b"".join(map(pack64bit, R[1:]))
    return res

ZEROIV = "\x00"*16
def AESdecryptCBC(data, key, iv=ZEROIV, padding=False):
    if len(data) % 16:
        print("AESdecryptCBC: data length not /16, truncating")
        data = data[0:(len(data)/16) * 16]
    data = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_CBC, iv).decrypt(data)
    if padding:
        return removePadding(16, data)
    return data

##
# here are some utility functions, one making sure I don’t leak my
# secret keys when posting the output on Stack Exchange

anon_random = random.Random(0)
memo = {}
def anonymize(s):
    if type(s) == str:
        s = s.encode('utf-8')
    global anon_random, memo
    if ANONYMIZE_OUTPUT:
        if s in memo:
            return memo[s]
        possible_alphabets = [
            string.digits,
            string.digits + 'abcdef',
            string.ascii_letters,
            "".join(chr(x) for x in range(0, 256)),
        ]
        for a in possible_alphabets:
            if all((chr(c) if type(c) == int else c) in a for c in s):
                alphabet = a
                break
        ret = "".join([anon_random.choice(alphabet) for i in range(len(s))])
        memo[s] = ret
        return ret
    else:
        return s

def wrap(s, width=78):
    "Return a width-wrapped repr(s)-like string without breaking on \’s"
    s = repr(s)
    quote = s[0]
    s = s[1:-1]
    ret = []
    while len(s):
        i = s.rfind('\\', 0, width)
        if i <= width - 4: # "\x??" is four characters
            i = width
        ret.append(s[:i])
        s = s[i:]
    return '\n'.join("%s%s%s" % (quote, line ,quote) for line in ret)

def readpipe(path):
    if stat.S_ISFIFO(os.stat(path).st_mode):
        with open(path, 'rb') as pipe:
            return pipe.read()
    else:
        raise Exception("Not a pipe: {!r}".format(path))

if __name__ == '__main__':
    main()

Welches druckt dann diese Ausgabe:

Warning: All output keys are FAKE to protect your privacy
== Keybag
Keybag type: Backup keybag (1)
Keybag version: 3
Keybag UUID: dc6486c479e84c94efce4bea7169ef7d
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Class                                                WRAP Type       Key                                                              WPKY                                                             Public key
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NSFileProtectionComplete                             2    AES                                                                         4c80b6da07d35d393fc7158e18b8d8f9979694329a71ceedee86b4cde9f97afec197ad3b13c5d12b
NSFileProtectionCompleteUnlessOpen                   2    AES                                                                         09e8a0a9965f00f213ce06143a52801f35bde2af0ad54972769845d480b5043f545fa9b66a0353a6
NSFileProtectionCompleteUntilFirstUserAuthentication 2    AES                                                                         e966b6a0742878ce747cec3fa1bf6a53b0d811ad4f1d6147cd28a5d400a8ffe0bbabea5839025cb5
NSFileProtectionNone                                 2    AES                                                                         902f46847302816561e7df57b64beea6fa11b0068779a65f4c651dbe7a1630f323682ff26ae7e577
NSFileProtectionRecovery?                            3    AES                                                                         a3935fed024cd9bc11d0300d522af8e89accfbe389d7c69dca02841df46c0a24d0067dba2f696072

kSecAttrAccessibleWhenUnlocked                       2    AES                                                                         09a1856c7e97a51a9c2ecedac8c3c7c7c10e7efa931decb64169ee61cb07a0efb115050fd1e33af1
kSecAttrAccessibleAfterFirstUnlock                   2    AES                                                                         0509d215f2f574efa2f192efc53c460201168b26a175f066b5347fc48bc76c637e27a730b904ca82
kSecAttrAccessibleAlways                             2    AES                                                                         b7ac3c4f1e04896144ce90c4583e26489a86a6cc45a2b692a5767b5a04b0907e081daba009fdbb3c
kSecAttrAccessibleWhenUnlockedThisDeviceOnly         3    AES                                                                         417526e67b82e7c6c633f9063120a299b84e57a8ffee97b34020a2caf6e751ec5750053833ab4d45
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly     3    AES                                                                         b0e17b0cf7111c6e716cd0272de5684834798431c1b34bab8d1a1b5aba3d38a3a42c859026f81ccc
kSecAttrAccessibleAlwaysThisDeviceOnly               3    AES                                                                         9b3bdc59ae1d85703aa7f75d49bdc600bf57ba4a458b20a003a10f6e36525fb6648ba70e6602d8b2

== Passcode key
ee34f5bb635830d698074b1e3e268059c590973b0f1138f1954a2a4e1069e612

== Keybag
Keybag type: Backup keybag (1)
Keybag version: 3
Keybag UUID: dc6486c479e84c94efce4bea7169ef7d
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Class                                                WRAP Type       Key                                                              WPKY                                                             Public key
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NSFileProtectionComplete                             2    AES        64e8fc94a7b670b0a9c4a385ff395fe9ba5ee5b0d9f5a5c9f0202ef7fdcb386f 4c80b6da07d35d393fc7158e18b8d8f9979694329a71ceedee86b4cde9f97afec197ad3b13c5d12b
NSFileProtectionCompleteUnlessOpen                   2    AES        22a218c9c446fbf88f3ccdc2ae95f869c308faaa7b3e4fe17b78cbf2eeaf4ec9 09e8a0a9965f00f213ce06143a52801f35bde2af0ad54972769845d480b5043f545fa9b66a0353a6
NSFileProtectionCompleteUntilFirstUserAuthentication 2    AES        1004c6ca6e07d2b507809503180edf5efc4a9640227ac0d08baf5918d34b44ef e966b6a0742878ce747cec3fa1bf6a53b0d811ad4f1d6147cd28a5d400a8ffe0bbabea5839025cb5
NSFileProtectionNone                                 2    AES        2e809a0cd1a73725a788d5d1657d8fd150b0e360460cb5d105eca9c60c365152 902f46847302816561e7df57b64beea6fa11b0068779a65f4c651dbe7a1630f323682ff26ae7e577
NSFileProtectionRecovery?                            3    AES        9a078d710dcd4a1d5f70ea4062822ea3e9f7ea034233e7e290e06cf0d80c19ca a3935fed024cd9bc11d0300d522af8e89accfbe389d7c69dca02841df46c0a24d0067dba2f696072

kSecAttrAccessibleWhenUnlocked                       2    AES        606e5328816af66736a69dfe5097305cf1e0b06d6eb92569f48e5acac3f294a4 09a1856c7e97a51a9c2ecedac8c3c7c7c10e7efa931decb64169ee61cb07a0efb115050fd1e33af1
kSecAttrAccessibleAfterFirstUnlock                   2    AES        6a4b5292661bac882338d5ebb51fd6de585befb4ef5f8ffda209be8ba3af1b96 0509d215f2f574efa2f192efc53c460201168b26a175f066b5347fc48bc76c637e27a730b904ca82
kSecAttrAccessibleAlways                             2    AES        c0ed717947ce8d1de2dde893b6026e9ee1958771d7a7282dd2116f84312c2dd2 b7ac3c4f1e04896144ce90c4583e26489a86a6cc45a2b692a5767b5a04b0907e081daba009fdbb3c
kSecAttrAccessibleWhenUnlockedThisDeviceOnly         3    AES        80d8c7be8d5103d437f8519356c3eb7e562c687a5e656cfd747532f71668ff99 417526e67b82e7c6c633f9063120a299b84e57a8ffee97b34020a2caf6e751ec5750053833ab4d45
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly     3    AES        a875a15e3ff901351c5306019e3b30ed123e6c66c949bdaa91fb4b9a69a3811e b0e17b0cf7111c6e716cd0272de5684834798431c1b34bab8d1a1b5aba3d38a3a42c859026f81ccc
kSecAttrAccessibleAlwaysThisDeviceOnly               3    AES        1e7756695d337e0b06c764734a9ef8148af20dcc7a636ccfea8b2eb96a9e9373 9b3bdc59ae1d85703aa7f75d49bdc600bf57ba4a458b20a003a10f6e36525fb6648ba70e6602d8b2

== decrypted data:
'<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD '
'PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist versi'
'on="1.0">\n<dict>\n\t<key>DCIMLastDirectoryNumber</key>\n\t<integer>100</integ'
'er>\n\t<key>DCIMLastFileNumber</key>\n\t<integer>3</integer>\n</dict>\n</plist'
'>\n'

== pretty-printed plist
{'DCIMLastDirectoryNumber': 100, 'DCIMLastFileNumber': 3}

Extra Gutschrift

Der von Bédrune und Sigwald veröffentlichte iPhone-Datenschutzcode kann den Schlüsselbund aus einem Backup entschlüsseln , einschließlich lustiger Dinge wie gespeichertem WLAN und Website-Passwörtern:

$ python iphone-dataprotection/python_scripts/keychain_tool.py ...

--------------------------------------------------------------------------------------
|                              Passwords                                             |
--------------------------------------------------------------------------------------
|Service           |Account          |Data           |Access group  |Protection class|
--------------------------------------------------------------------------------------
|AirPort           |Ed’s Coffee Shop |<3FrenchRoast  |apple         |AfterFirstUnlock|
...

Dieser Code funktioniert nicht mehr bei Backups von Telefonen mit dem neuesten iOS, aber es gibt einige Golang- Ports , die auf dem neuesten Stand gehalten wurden und den Zugriff auf den Schlüsselbund ermöglichen .

andrewdotn
quelle
2
Ich habe es versucht und es hat dort funktioniert, wo jedes andere Tool versagt hat. Ich musste noch ein weiteres fehlendes Python-Modul hinzufügen: pip install --user pycrypto Danke!
ALoopingIcon
2
Wunderbar! Mit Macports habe ich diese Abhängigkeiten installiert: py27-m2crypto py27-cryptography
Hyperspasmus
2
Der Code.google.com-Link war für mich 404, aber ich fand eine aktualisierte Version des Tools (für OS X 10.10) unter github.com/dinosec/iphone-dataprotection . Es funktionierte unter OS X 10.11.5.
Aaron Brager
2
Wenn Sie den Code aktualisieren würden, wären Sie für mich einer Gottheit nahe!
Jonas Zaugg
3
@ JonasZaugg Ich habe den Beispielcode für iOS 10 aktualisiert. Ich hoffe, Sie finden ihn nützlich.
Andrewdotn
6

Entschuldigung, aber es könnte noch komplizierter sein, pbkdf2 oder sogar eine Variation davon. Hören Sie sich die WWDC 2010-Sitzung Nr. 209 an, in der hauptsächlich die Sicherheitsmaßnahmen in iOS 4 behandelt werden, aber auch kurz die separate Verschlüsselung von Sicherungen und deren Beziehung erwähnt wird.

Sie können ziemlich sicher sein, dass Sie das Passwort ohne Kenntnis des Passworts auch mit brutaler Gewalt nicht entschlüsseln können.

Nehmen wir einfach an, Sie möchten versuchen, Personen, die das Kennwort kennen, den Zugriff auf die Daten ihrer Sicherungen zu ermöglichen.

Ich fürchte, es führt kein Weg daran vorbei, den tatsächlichen Code in iTunes zu betrachten, um herauszufinden, welche Algen verwendet werden.

In den Newton-Tagen musste ich Daten aus einem Programm entschlüsseln und konnte seine Entschlüsselungsfunktion direkt aufrufen (natürlich mit Kenntnis des Passworts), ohne den Algorithmus überhaupt verstehen zu müssen. Das ist leider nicht mehr so ​​einfach.

Ich bin sicher, es gibt qualifizierte Leute, die diesen iTunes-Code zurückentwickeln könnten - Sie müssen sie nur interessieren.

Theoretisch sollten Apples Algen so gestaltet sein, dass die Daten für jeden Angreifer, der die genaue Verschlüsselungsmethode kennt, immer noch sicher sind (dh mit Brute-Force-Methoden praktisch unzerbrechlich sind). Und in der WWDC-Sitzung 209 gingen sie ziemlich tief in Details darüber ein, was sie tun, um dies zu erreichen. Vielleicht können Sie Antworten direkt vom Apple-Sicherheitsteam erhalten, wenn Sie ihnen Ihre guten Absichten mitteilen. Schließlich sollten auch sie wissen, dass Sicherheit durch Verschleierung nicht wirklich effizient ist. Probieren Sie die Sicherheits-Mailingliste aus. Selbst wenn sie nicht antworten, antwortet möglicherweise jemand anderes, der still auf der Liste steht, mit etwas Hilfe.

Viel Glück!

Thomas Tempelmann
quelle
1

Ich habe es noch nicht ausprobiert, aber Elcomsoft hat ein Produkt veröffentlicht, von dem behauptet wird, dass es Backups für forensische Zwecke entschlüsseln kann. Vielleicht nicht so cool wie selbst eine Lösung zu entwickeln, aber es könnte schneller sein.

http://www.elcomsoft.com/eppb.html

Jablair
quelle
1
Vielen Dank. Dies entschlüsselt Backups nicht als solche: Es knackt nur die Schlüssel. Ich weiß bereits, wie das geht ... und das ist viel einfacher als das Backup zu entschlüsseln, sobald Sie den Schlüssel haben.
Aidan Fitzpatrick
-3

Sie sollten eine Kopie von Erica Sadun des mdhelper Befehlszeilenprogramm (greifen OS X binäre & Quelle ). Es unterstützt das Auflisten und Extrahieren des Inhalts von iPhone / iPod Touch-Sicherungen, einschließlich Adressbuch- und SMS-Datenbanken sowie anderer Anwendungsmetadaten und -einstellungen.

Nathan de Vries
quelle
1
Das ist nur ein PList-Leser: Ich kann das Zeug schon nativ machen. Es werden keine verschlüsselten Sicherungen unterstützt, nach denen ich suche und die den Rahmen dieses Dienstprogramms sprengen.
Aidan Fitzpatrick
Haben Sie sich die Zeit genommen, das Dienstprogramm auszuprobieren? Meine Backups sind verschlüsselt und genau das, was Sie versuchen.
Nathan de Vries
10
Ja, und ich habe auch die Quelle gelesen. Es verarbeitet keine verschlüsselten Sicherungen und wurde zuletzt vor der Veröffentlichung der iTunes-Unterstützung für verschlüsselte Sicherungen geändert. Ich vermute, Sie meinen, Ihre Backups sind verschlüsselt oder Ihr iPhone verwendet ein verschlüsseltes Dateisystem, was eine ganz andere Sache ist. Es gibt nicht nur keine Unterstützung für die Verschlüsselung im Code, sondern auch keine Möglichkeit, ein Kennwort in den Befehlszeilenoptionen einzugeben. Und der Code verwendet keine Zertifikate oder Schlüsselanhänger. Ich würde gerne das Gegenteil beweisen, aber ich glaube wirklich nicht, dass ich es bin! Ich schätze den Vorschlag jedoch.
Aidan Fitzpatrick