Wielu niefortunnych użytkowników iPhone'a poprosiło mnie o pomoc w przywróceniu danych z kopii zapasowych iTunes. Jest to łatwe, gdy są niezaszyfrowane, ale nie wtedy, gdy są zaszyfrowane, niezależnie od tego, czy hasło jest znane.
W związku z tym próbuję ustalić schemat szyfrowania używany w plikach mddata i mdinfo podczas szyfrowania. W przeciwnym razie nie mam problemów z odczytaniem tych plików i stworzyłem do tego solidne biblioteki C #. (Jeśli możesz pomóc, nie obchodzi mnie, jakiego języka używasz. Oto zasada, której tu szukam!)
W Apple „iPhone OS Enterprise Deployment Guide” stwierdza się, że „Kopie zapasowe urządzeń można przechowywać w formacie zaszyfrowanym, wybierając opcję Szyfruj kopię zapasową iPhone'a w panelu podsumowania urządzenia w iTunes. Pliki są szyfrowane przy użyciu AES128 z 256-bitowym kluczem. Kluczem jest bezpiecznie przechowywane w pęku kluczy iPhone'a ”.
To całkiem dobra wskazówka i jest tutaj kilka dobrych informacji na temat współdziałania Stackoverflow na iPhone AES / Rijndael, sugerujących użycie rozmiaru klucza 128 i trybu CBC.
Oprócz wszelkich innych zaciemnień wymagany jest klucz i wektor inicjujący (IV) / sól.
Można by przypuszczać, że kluczem jest manipulacja „hasłem zapasowym”, o które użytkownicy są proszeni przez iTunes i przekazywani do „ AppleMobileBackup.exe ”, dopełniony w sposób podyktowany przez CBC. Jednak biorąc pod uwagę odniesienie do pęku kluczy iPhone'a, zastanawiam się, czy „hasło zapasowe” nie może być używane jako hasło w certyfikacie X509 lub symetrycznym kluczu prywatnym oraz czy sam certyfikat lub klucz prywatny może być użyty jako klucz. ( Proces szyfrowania / odszyfrowywania AES i iTunes jest symetryczny).
IV to inna sprawa i może to być kilka rzeczy. Być może jest to jeden z kluczy zakodowanych na stałe w iTunes lub w samych urządzeniach .
Chociaż powyższy komentarz Apple sugeruje, że klucz jest obecny na pęku kluczy urządzenia, myślę, że nie jest to takie ważne. Można przywrócić zaszyfrowaną kopię zapasową na inne urządzenie, co sugeruje, że wszystkie informacje związane z odszyfrowaniem są obecne w kopii zapasowej i konfiguracji iTunes, a wszystko, co znajduje się wyłącznie na urządzeniu, jest w tym kontekście nieistotne i możliwe do zastąpienia. Więc gdzie może być klucz?
Poniżej wymieniłem ścieżki z komputera z systemem Windows, ale jest to dużo, niezależnie od używanego systemu operacyjnego.
„\ Appdata \ Roaming \ Apple Computer \ iTunes \ itunesprefs.xml” zawiera listę PList z wpisem „Keychain”. Lista „\ programdata \ apple \ Lockdown \ 09037027da8f4bdefdea97d706703ca034c88bab.plist” zawiera listę PList z „DeviceCertificate”, „HostCertificate” i „RootCertificate”, z których wszystkie wydają się być ważnymi certyfikatami X509. Ten sam plik wydaje się również zawierać asymetryczne klucze „RootPrivateKey” i „HostPrivateKey” (mój odczyt sugeruje, że mogą to być klucze PKCS # 7). Ponadto każda kopia zapasowa zawiera wartości „AuthSignature” i „AuthData” w pliku Manifest.plist, chociaż wydaje się, że są one obracane, gdy każdy plik jest zapisywany przyrostowo, co sugeruje, że nie są one tak przydatne jako klucz, chyba że coś naprawdę dość zaangażowany.
Istnieje wiele wprowadzających w błąd rzeczy, które sugerują, że uzyskanie danych z zaszyfrowanych kopii zapasowych jest łatwe. Tak nie jest i o ile wiem, nie zostało to zrobione. Omijanie lub wyłączanie szyfrowania kopii zapasowej to zupełnie inna sprawa i nie jest tym, co chcę zrobić.
Tu nie chodzi o rozłupywanie iPhone'a czy coś w tym rodzaju. Jedyne, czego tutaj szukam, to wyodrębnienie danych (zdjęć, kontaktów itp.) Z zaszyfrowanych kopii zapasowych iTunes, ponieważ mogę je niezaszyfrować. Próbowałem różnych permutacji z informacjami, które zapisałem powyżej, ale do niczego nie doszedłem. Byłbym wdzięczny za wszelkie myśli lub techniki, które mogłem przegapić.
źródło
Odpowiedzi:
Badacze bezpieczeństwa Jean-Baptiste Bédrune i Jean Sigwald przedstawili, jak to zrobić podczas Hack-in-the-box Amsterdam 2011 .
Od tego czasu firma Apple wydała raport dotyczący bezpieczeństwa systemu iOS zawierający więcej szczegółów na temat kluczy i algorytmów, a Charlie Miller i in. wydali Poradnik iOS Hackera , który omawia niektóre z tych samych zagadnień w sposób praktyczny. Kiedy iOS 10 pojawił się po raz pierwszy, nastąpiły zmiany w formacie kopii zapasowej, których Apple początkowo nie opublikował, ale różne osoby dokonały inżynierii wstecznej zmian formatu .
Zaszyfrowane kopie zapasowe są świetne
Wspaniałą rzeczą w zaszyfrowanych kopiach zapasowych iPhone'a jest to, że zawierają one takie rzeczy, jak hasła Wi-Fi, których nie ma w zwykłych niezaszyfrowanych kopiach zapasowych. Jak omówiono w raporcie dotyczącym zabezpieczeń systemu iOS , zaszyfrowane kopie zapasowe są uważane za bardziej „bezpieczne”, więc Apple uważa, że umieszczanie w nich bardziej poufnych informacji jest w porządku.
Ważne ostrzeżenie: oczywiście odszyfrowanie kopii zapasowej urządzenia z systemem iOS usuwa jej szyfrowanie. Aby chronić swoją prywatność i bezpieczeństwo, powinieneś uruchamiać te skrypty tylko na komputerze z pełnym szyfrowaniem dysku. Podczas gdy ekspert ds. Bezpieczeństwa może napisać oprogramowanie, które chroni klucze w pamięci, np. Za pomocą funkcji takich jak
VirtualLock()
iSecureZeroMemory()
między innymi, te skrypty Pythona będą przechowywać klucze szyfrowania i hasła w łańcuchach, aby Python zbierał je jako śmieci. Oznacza to, że twoje tajne klucze i hasła pozostaną przez jakiś czas w pamięci RAM, skąd wyciekną do twojego pliku wymiany i na twój dysk, gdzie przeciwnik może je odzyskać. To całkowicie omija sens posiadania zaszyfrowanej kopii zapasowej.Jak odszyfrować kopie zapasowe: w teorii
Raport na temat zabezpieczeń systemu iOS lepiej niż ja wyjaśnia podstawowe pojęcia dotyczące kluczy dla poszczególnych plików, klas ochrony, kluczy klas ochrony i pakietów kluczy. Jeśli jeszcze ich nie znasz, poświęć kilka minut na przeczytanie odpowiednich części.
Teraz wiesz, że każdy plik w systemie iOS jest zaszyfrowany własnym, losowym kluczem szyfrowania dla pliku, należy do klasy ochrony, a klucze szyfrowania dla pliku są przechowywane w metadanych systemu plików, opakowanych w klucz klasy ochrony.
Aby odszyfrować:
Odszyfruj torebkę na klucze przechowywaną we
BackupKeyBag
wpisieManifest.plist
. Ogólny przegląd tej struktury przedstawiono w białej księdze . IPhone Wiki opisuje format binarny: typ ciąg pola 4-bajtowy, 4-bajtowy grubokońcej pole długości, a następnie samą wartość.Ważnymi wartościami są PBKDF2
ITER
ations iSALT
, sól podwójna ochronaDPSL
i iteracja liczyćDPIC
, a następnie dla każdego z ochronąCLS
, zWPKY
owiniętym klucza.Używając hasła zapasowego, wyprowadź 32-bajtowy klucz, używając poprawnej soli PBKDF2 i liczby iteracji. Najpierw użyj rundy SHA256 z
DPSL
iDPIC
, a następnie rundy SHA1 zITER
iSALT
.Rozpakuj każdy opakowany klucz zgodnie z RFC 3394 .
Odszyfruj bazę danych manifestu, wyciągając 4-bajtową klasę ochrony i dłuższy klucz z pliku
ManifestKey
inManifest.plist
i rozpakowując go. Masz teraz bazę danych SQLite ze wszystkimi metadanymi plików.Dla każdego interesującego pliku uzyskaj zaszyfrowany klasą klucz szyfrowania dla każdego pliku i kod klasy ochrony, sprawdzając w
Files.file
kolumnie bazy danych binarną listę plist zawierającąEncryptionKey
iProtectionClass
wpisy. Usuń początkowy czterobajtowy znacznik długościEncryptionKey
przed użyciem.Następnie wyprowadź ostateczny klucz odszyfrowywania, rozpakowując go za pomocą klucza klasy, który został rozpakowany wraz z hasłem zapasowym. Następnie odszyfruj plik za pomocą AES w trybie CBC z zerowym IV.
Jak odszyfrować kopie zapasowe: w praktyce
Najpierw będziesz potrzebować pewnych zależności bibliotecznych. Jeśli korzystasz z komputera Mac z zainstalowanym przez homebrew Pythonem 2.7 lub 3.7, możesz zainstalować zależności za pomocą:
CFLAGS="-I$(brew --prefix)/opt/openssl/include" \ LDFLAGS="-L$(brew --prefix)/opt/openssl/lib" \ pip install biplist fastpbkdf2 pycrypto
W formie kodu źródłowego, który można uruchomić, oto jak odszyfrować pojedynczy plik preferencji z zaszyfrowanej kopii zapasowej iPhone'a:
#!/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()
Który następnie drukuje ten wynik:
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}
Dodatkowy kredyt
Kod iphone-dataprotection wysłane przez Bédrune i Sigwald może odszyfrować pęk kluczy z kopii zapasowej, w tym zabawnych rzeczy, takich jak WiFi i witryn zapisanych haseł:
Ten kod nie działa już w przypadku kopii zapasowych z telefonów z najnowszym systemem iOS, ale istnieje kilka portów golang , które są aktualizowane, umożliwiając dostęp do pęku kluczy .
źródło
pip install --user pycrypto
Dzięki!Przepraszamy, ale może to być nawet bardziej skomplikowane, obejmujące pbkdf2 lub nawet jego odmianę. Posłuchaj sesji WWDC 2010 nr 209, która głównie mówi o środkach bezpieczeństwa w iOS 4, ale także krótko wspomina o oddzielnym szyfrowaniu kopii zapasowych i ich powiązaniach.
Możesz być prawie pewien, że bez znajomości hasła nie można go odszyfrować, nawet przy użyciu brutalnej siły.
Załóżmy tylko, że chcesz spróbować umożliwić osobom, które ZNAJĄ hasło, uzyskanie dostępu do danych ich kopii zapasowych.
Obawiam się, że nie da się obejść rzeczywistego kodu w iTunes, aby dowiedzieć się, które algorytmy są używane.
W czasach Newtona musiałem odszyfrować dane z programu i byłem w stanie bezpośrednio wywołać jego funkcję deszyfrującą (oczywiście znając hasło) bez potrzeby nawet rozumienia jego algorytmu. Niestety nie jest to już takie proste.
Jestem pewien, że są wokół wykwalifikowani ludzie, którzy mogliby odtworzyć kod iTunes - wystarczy ich zainteresować.
Teoretycznie algorytmy Apple powinny być zaprojektowane w taki sposób, aby dane były nadal bezpieczne (tj. Praktycznie niemożliwe do złamania metodami brutalnej siły) dla każdego atakującego znającego dokładną metodę szyfrowania. Podczas sesji WWDC 209 zagłębili się w szczegóły tego, co robią, aby to osiągnąć. Może faktycznie uda Ci się uzyskać odpowiedzi bezpośrednio od zespołu bezpieczeństwa Apple, jeśli powiesz im swoje dobre intencje. W końcu nawet oni powinni wiedzieć, że ochrona przez zaciemnianie nie jest naprawdę skuteczna. Wypróbuj ich listę mailingową dotyczącą bezpieczeństwa. Nawet jeśli nie odpowiedzą, może ktoś inny po cichu na liście odpowie z jakąś pomocą.
Powodzenia!
źródło
Nie próbowałem tego, ale Elcomsoft wypuścił produkt, który, jak twierdzą, jest w stanie odszyfrować kopie zapasowe do celów kryminalistycznych. Może nie tak fajne, jak samodzielne zaprojektowanie rozwiązania, ale może być szybsze.
http://www.elcomsoft.com/eppb.html
źródło
Powinieneś pobrać kopię narzędzia wiersza poleceń mdhelper Erica Sadun ( plik binarny i kod źródłowy OS X ). Obsługuje wyświetlanie i wyodrębnianie zawartości kopii zapasowych iPhone / iPod Touch, w tym książek adresowych i baz danych SMS oraz innych metadanych i ustawień aplikacji.
źródło