Şifrelenmiş bir Apple iTunes iPhone yedeklemesinin şifresi nasıl çözülür?


84

Bir dizi talihsiz iPhone kullanıcısı benden, iTunes yedeklemelerindeki verileri geri yüklemelerine yardımcı olmamı istedi. Bu, şifrelenmemiş olduklarında kolaydır, ancak şifreli olduklarında, şifre bilinse de bilinmese de değil.

Bu nedenle, şifreli olduğunda mddata ve mdinfo dosyalarında kullanılan şifreleme düzenini anlamaya çalışıyorum. Aksi takdirde bu dosyaları okurken sorun yaşamıyorum ve bunu yapmak için bazı sağlam C # kitaplıkları oluşturdum. (Eğer yardım edebilirsen, hangi dili kullandığın umurumda değil. Burada peşinde olduğum ilke bu!)

Apple "iPhone OS Kurumsal Dağıtım Kılavuzu", "Cihaz yedeklemelerinin, iTunes'un aygıt özeti bölmesindeki iPhone Yedeklemesini Şifrele seçeneği seçilerek şifrelenmiş biçimde depolanabileceğini belirtir. Dosyalar, 256 bit anahtarla AES128 kullanılarak şifrelenir. Anahtar şu şekildedir: iPhone anahtar zincirinde güvenli bir şekilde saklanır. "

Bu oldukça iyi bir ipucu ve burada Stackoverflow'da iPhone AES / Rijndael birlikte çalışabilirliği hakkında 128 ve CBC modunun kullanılabileceğini düşündüren bazı iyi bilgiler var .

Diğer gizlemelerin yanı sıra, bir anahtar ve başlatma vektörü (IV) / tuz gereklidir.

Anahtarın, kullanıcılardan iTunes tarafından girmeleri istenen ve CBC tarafından dikte edilen bir şekilde " AppleMobileBackup.exe " ye geçirilen "yedekleme şifresinin" bir manipülasyonu olduğu varsayılabilir . Bununla birlikte, iPhone anahtar zincirine atıfta bulunulduğunda, "yedekleme parolasının" bir X509 sertifikasında veya simetrik özel anahtarda parola olarak kullanılıp kullanılmayacağını ve sertifika veya özel anahtarın anahtar olarak kullanılabileceğini merak ediyorum. ( AES ve iTunes şifreleme / şifre çözme işlemi simetriktir.)

IV başka bir konudur ve birkaç şey olabilir. Belki de iTunes'a veya aygıtların kendisine sabit kodlanmış anahtarlardan biridir .

Apple'ın yukarıdaki yorumu, anahtarın cihazın anahtar zincirinde bulunduğunu öne sürse de, bunun o kadar da önemli olmadığını düşünüyorum. Şifrelenmiş bir yedek, farklı bir cihaza geri yüklenebilir , bu da şifre çözmeyle ilgili tüm bilgilerin yedeklemede ve iTunes yapılandırmasında mevcut olduğunu ve yalnızca cihazdaki herhangi bir şeyin bu bağlamda alakasız ve değiştirilemez olduğunu gösterir. O halde anahtar nerede olabilir?

Bir Windows makinesinden aşağıdaki yolları listeledim, ancak hangi işletim sistemini kullanırsak kullanalım bu çok şey.

"\ Appdata \ Roaming \ Apple Computer \ iTunes \ itunesprefs.xml", içinde "Keychain" dikt girişi olan bir PList içerir. "\ Programdata \ apple \ Lockdown \ 09037027da8f4bdefdea97d706703ca034c88bab.plist", tümü geçerli X509 sertifikaları gibi görünen "DeviceCertificate", "HostCertificate" ve "RootCertificate" öğelerine sahip bir PList içerir. Aynı dosya aynı zamanda asimetrik anahtarlar "RootPrivateKey" ve "HostPrivateKey" içeriyor gibi görünüyor (okumam bunların PKCS # 7 zarflı olabileceğini gösteriyor). Ayrıca, her yedeklemede Manifest.plist dosyasında "AuthSignature" ve "AuthData" değerleri vardır, ancak bunlar her dosya artımlı olarak yedeklendikçe döndürülmüş gibi görünse de, gerçekten bir şey olmadıkça bir anahtar olarak o kadar yararlı olmadıklarını önerdiler. oldukça ilgili yapılıyor.

Şifrelenmiş yedeklemelerden veri almanın kolay olduğunu düşündüren birçok yanıltıcı şey var. Değil ve bildiğim kadarıyla yapılmadı. Yedek şifrelemeyi atlamak veya devre dışı bırakmak tamamen başka bir konudur ve benim yapmak istediğim şey bu değil.

Bu, iPhone'u veya benzeri bir şeyi parçalamakla ilgili değil. Burada peşinde olduğum tek şey, şifrelenmemiş olanları yapabildiğim için şifrelenmiş iTunes yedeklerinden veri (fotoğraflar, kişiler vb.) Ayıklamanın bir yolu. Yukarıda verdiğim bilgilerle her türlü permütasyonu denedim ama hiçbir yere varamadım. Kaçırmış olabileceğim herhangi bir düşünce veya tekniği takdir ederim.


3
Üç yıldan itibaren güncelleme: Bunu çözdüm ve ücretsiz olarak satılan bir ürün haline getirdim. Yukarıda doğru yoldaydım ama zordu.
Aidan Fitzpatrick

bu ürün için bir bağlantınız var mı?
Thilo

1
Sorduğunuz gibi, bu iPhone Backup Extractor . Programın ücretli sürümleri olduğunu göreceksiniz, ancak eski düz ücretsiz sürüm, şifrelenmiş dosyaları bir seferde 4 taneden almanıza izin verecektir.
Aidan Fitzpatrick

1
10.2 yedeğinin şifresini çözdüğünüzü görüyorum. Bunu nasıl başardığınızı lütfen paylaşır mısınız?
Niki

@Niki Aşağıdaki cevabımı iOS 10 için güncelledim
andrewdotn

Yanıtlar:


107

Güvenlik araştırmacıları Jean-Baptiste Bédrune ve Jean Sigwald , Hack-in-the-box Amsterdam 2011'de bunun nasıl yapılacağını anlattılar .

O zamandan beri Apple, anahtarlar ve algoritmalar hakkında daha fazla ayrıntı içeren bir iOS Güvenlik Teknik Raporu yayınladı ve Charlie Miller ve diğerleri. aynı zeminin bir kısmını nasıl yapılır tarzında ele alan iOS Hacker's Handbook'u yayınladı . İOS 10 ilk çıktığında, yedekleme biçiminde Apple'ın ilk başta duyurmadığı değişiklikler oldu, ancak çeşitli insanlar biçim değişikliklerini tersine mühendislik yaptı .

Şifrelenmiş yedeklemeler harika

Şifreli iPhone yedeklemelerinin en güzel yanı, düzenli şifrelenmemiş yedeklemelerde olmayan WiFi şifreleri gibi şeyler içermeleridir. İOS Güvenlik Teknik Raporunda tartışıldığı gibi , şifrelenmiş yedeklemeler daha "güvenli" olarak kabul edilir, bu nedenle Apple bunlara daha hassas bilgiler eklemenin uygun olduğunu düşünür.

Önemli bir uyarı: Açıkçası, iOS cihazınızın yedeklemesinin şifresini çözmek, şifrelemesini kaldırır. Gizliliğinizi ve güvenliğinizi korumak için, bu komut dosyalarını yalnızca tam disk şifrelemeli bir makinede çalıştırmalısınız. O gibi işlevleri kullanarak örneğin bellek, anahtarlar korur yazma yazılımı için bir güvenlik uzmanı için mümkün olsa VirtualLock()ve SecureZeroMemory()birçok diğer şeyler arasında, dizelerinde şifreleme anahtarları ve şifreleri saklamak olacak bu Python komut çöp toplama işlemine Python tarafından olmak. Bu, gizli anahtarlarınızın ve parolalarınızın bir süre RAM'de yaşayacağı ve buradan takas dosyanıza ve bir rakibin onları kurtarabileceği diskinize sızacağı anlamına gelir. Bu, şifrelenmiş bir yedeklemeye sahip olma noktasını tamamen ortadan kaldırır.

Yedeklemelerin şifresi nasıl çözülür: teoride

İOS Güvenlik Raporu benden daha dosya başına tuşları, koruma sınıfları, koruma sınıfı tuşları ve daha iyi keybags temel kavramları açıklar. Bunlara aşina değilseniz, ilgili bölümleri okumak için birkaç dakikanızı ayırın.

Artık iOS'taki her dosyanın kendi rasgele dosya başına şifreleme anahtarıyla şifrelendiğini, bir koruma sınıfına ait olduğunu ve dosya başına şifreleme anahtarlarının, koruma sınıfı anahtarına sarılmış dosya sistemi meta verilerinde saklandığını biliyorsunuz.

Şifresini çözmek için:

  1. Saklanan keybag Decode BackupKeyBaggirişi Manifest.plist. Bu yapıya üst düzey bir genel bakış whitepaper'da verilmektedir . İPhone Wiki 4 baytlık dize türü alanını, 4 bayt big-endian uzunluk alanını ve ardından değeri kendisi: ikili biçimi açıklanmaktadır.

    Önemli değerler, PBKDF2 ITERasyonları ve SALTçift ​​koruma tuzu DPSLve yineleme sayısı DPICve ardından her koruma CLSiçin WPKYsarılmış anahtardır.

  2. Yedek parolayı kullanarak, doğru PBKDF2 tuzunu ve yineleme sayısını kullanarak 32 baytlık bir anahtar türetin. Öncelikle bir SHA256 yuvarlak kullanmak DPSLve DPICdaha sonra birlikte bir SHA1 yuvarlak ITERve SALT.

    Sarılmış her anahtarı RFC 3394'e göre açın .

  3. 4 baytlık koruma sınıfı ve uzun bir anahtar çekerek, bildirge veritabanı azalmak ManifestKeyin Manifest.plistve unwrapping. Artık tüm dosya meta verilerini içeren bir SQLite veritabanınız var.

  4. İlgili her dosya Files.fileiçin , veri tabanı sütununda EncryptionKeyve ProtectionClassgirişlerini içeren ikili bir liste olup olmadığına bakarak sınıf şifreli dosya başına şifreleme anahtarını ve koruma sınıfı kodunu alın . EncryptionKeyKullanmadan önce ilk dört bayt uzunluk etiketini çıkarın .

    Ardından, son şifre çözme anahtarını, yedek parolayla açılmamış sınıf anahtarıyla açarak türetin. Ardından sıfır IV ile CBC modunda AES kullanarak dosyanın şifresini çözün.

Yedeklemelerin şifresi nasıl çözülür: pratikte

Öncelikle bazı kütüphane bağımlılıklarına ihtiyacınız olacak. Homebrew yüklü Python 2.7 veya 3.7 kullanan bir mac kullanıyorsanız, bağımlılıkları şununla yükleyebilirsiniz:

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

Çalıştırılabilir kaynak kodu biçiminde, şifrelenmiş bir iPhone yedeklemesinden tek bir tercihler dosyasının şifresinin nasıl çözüleceği aşağıda açıklanmıştır:

#!/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()

Daha sonra bu çıktıyı yazdırır:

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}

Ekstra kredi

İphone-DataProtection kodu şifresini çözebilir Bédrune ve Sigwald tarafından gönderildi anahtarlık kurtardı wifi ve web sitesi şifreleri gibi eğlenceli şeyler de dahil olmak üzere, bir yedekten:

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

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

Bu kod artık en son iOS kullanan telefonlardan yapılan yedeklemelerde çalışmıyor, ancak anahtar zincirine erişime izin veren güncel tutulan bazı golang bağlantı noktaları var .


2
Denedim ve diğer tüm araçların başarısız olduğu yerde çalıştı. Ayrıca başka bir eksik python modülü eklemek zorunda kaldım: pip install --user pycrypto Teşekkürler!
ALoopingIcon

2
Olağanüstü! Macports kullanarak şu bağımlılıkları yükledim: py27-m2crypto py27-cryptography
hyperspasm

2
Code.google.com bağlantısı benim için 404ing'di, ancak aracın güncellenmiş bir sürümünü (OS X 10.10 için) github.com/dinosec/iphone-dataprotection adresinde buldum . OS X 10.11.5 üzerinde çalıştı.
Aaron Brager

2
Kodu güncellerseniz, benim için bir tanrıya yakın olurdunuz!
Jonas Zaugg

3
@JonasZaugg iOS 10 için örnek kodu güncelledim. Umarım faydalı bulursunuz.
andrewdotn

6

Maalesef pbkdf2'yi veya hatta bir varyasyonunu içeren daha karmaşık olabilir. Esas olarak iOS 4'teki güvenlik önlemlerinden bahseden, aynı zamanda yedeklemelerin ayrı şifrelenmesinden ve bunların birbirleriyle nasıl bağlantılı olduğundan bahseden WWDC 2010 # 209 oturumunu dinleyin.

Parolayı bilmeden, kaba kuvvetle bile şifresini çözmenin bir yolu olmadığından oldukça emin olabilirsiniz.

Parolayı Bilen kişilerin yedeklerinin verilerine erişmesini sağlamaya çalışmak istediğinizi varsayalım.

Hangi algoritmaların kullanıldığını anlamak için iTunes'daki gerçek koda bakmanın bir yolu olmadığından korkuyorum.

Newton günlerinde, bir programdaki verilerin şifresini çözmek zorunda kaldım ve algoritmasının altını çizmeye bile gerek kalmadan doğrudan şifre çözme işlevini (elbette şifreyi bilerek) çağırabildim. Maalesef artık o kadar kolay değil.

Eminim etrafta bu iTunes kodunu tersine çevirebilecek yetenekli insanlar vardır - sadece onların ilgisini çekmeniz gerekir.

Teoride, Apple'ın algoları, verileri tam olarak şifreleme yöntemini bilen herhangi bir saldırgan için hala güvenli (yani kaba kuvvet yöntemleriyle pratik olarak kırılmaz) yapacak şekilde tasarlanmalıdır. WWDC 209 oturumunda, bunu başarmak için ne yaptıklarına dair oldukça derin ayrıntılara girdiler. Belki onlara iyi niyetinizi söylerseniz, yanıtları doğrudan Apple'ın güvenlik ekibinden alabilirsiniz. Ne de olsa, gizleme yoluyla güvenliğin gerçekten verimli olmadığını bilmeleri gerekir. Güvenlik posta listelerini deneyin. Cevap vermeseler bile, belki listedeki başka biri sessizce cevap verecektir.

İyi şanslar!


1

Denemedim, ancak Elcomsoft, adli tıp amacıyla yedeklerin şifresini çözebileceğini iddia ettikleri bir ürün yayınladı. Belki kendiniz bir çözüm üretmek kadar havalı değil, ama daha hızlı olabilir.

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


1
Teşekkürler. Bu, yedeklemelerin şifresini çözmez: yalnızca anahtarları kırar. Bunu nasıl yapacağımı zaten biliyorum ... ve bu, anahtarı aldıktan sonra yedeklemenin şifresini çözmekten çok daha basit.
Aidan Fitzpatrick

-3

Erica Sadun'un mdhelper komut satırı yardımcı programının ( OS X ikili ve kaynak ) bir kopyasını almalısınız . Adres defteri ve SMS veritabanları ve diğer uygulama meta verileri ve ayarları dahil olmak üzere iPhone / iPod Touch yedeklemelerinin içeriklerinin listelenmesini ve çıkarılmasını destekler.


1
Bu sadece bir PList okuyucusu: Bu şeyleri zaten yerel olarak yapabilirim. Peşinde olduğum şey olan ve bu yardımcı programın kapsamı dışında kalan şifreli yedeklemeleri desteklemiyor.
Aidan Fitzpatrick

Yardımcı programı denemek için zaman ayırdınız mı? Yedeklerim şifreli ve sizin yapmaya çalıştığınız şeyi tam olarak yapıyor.
Nathan de Vries

10
Evet, kaynağı da okudum. Şifrelenmiş yedeklemeleri işlemez ve en son iTunes'un şifreli yedeklemeler için desteğinin yayınlanmasından önce değiştirilmiştir. Yedeklerinizin kodlandığını veya iPhone'unuzun şifrelenmiş bir dosya sistemi kullandığından şüpheleniyorsunuz ki bu tamamen başka bir mesele. Kodda şifreleme için destek olmamasının yanı sıra, daha açık bir şekilde komut satırı seçeneklerinde bir parola geçirme seçeneği de yoktur. Ve kod herhangi bir sertifika veya anahtarlık kullanmıyor. Bu konuda yanıldığımı kanıtlamak isterdim, ama gerçekten öyle olduğumu sanmıyorum! Yine de önerin için minnettarım.
Aidan Fitzpatrick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.