Pertanyaan Bagaimana cara mendekripsi cadangan iPhone iTunes Apple yang dienkripsi?


Saya telah ditanya oleh sejumlah pengguna iPhone yang malang untuk membantu mereka memulihkan data dari cadangan iTunes mereka. Ini mudah ketika mereka tidak dienkripsi, tetapi tidak ketika mereka dienkripsi, apakah kata sandi diketahui atau tidak.

Dengan demikian, saya mencoba mencari tahu skema enkripsi yang digunakan pada file mddata dan mdinfo ketika dienkripsi. Saya tidak punya masalah membaca file-file ini sebaliknya, dan telah membangun beberapa pustaka C # yang kuat untuk melakukannya. (Jika Anda dapat membantu, saya tidak peduli bahasa apa yang Anda gunakan. Ini adalah prinsip yang saya kejar di sini!)

Apple "iPhone OS Enterprise Deployment Guide" menyatakan bahwa "Pencadangan perangkat dapat disimpan dalam format terenkripsi dengan memilih Enkripsi iPhone Opsi cadangan di panel ringkasan perangkat iTunes. File dienkripsi menggunakan AES128 dengan kunci 256-bit. Kunci disimpan dengan aman di keychain iPhone. "

Itu petunjuk yang cukup bagus, dan ada beberapa info bagus di sini tentang Stackoverflow di iPhone Kemampuan interoperabilitas AES / Rijndael menyarankan keysize dari 128 dan CBC mode dapat digunakan.

Selain dari obfuscation lainnya, diperlukan vektor kunci dan inisialisasi (IV) / garam.

Orang mungkin berasumsi bahwa kuncinya adalah manipulasi "kata sandi cadangan" yang diminta pengguna untuk dimasukkan oleh iTunes dan diteruskan ke "AppleMobileBackup.exe", padded dalam mode yang ditentukan oleh CBC. Namun, mengingat referensi ke keychain iPhone, saya bertanya-tanya apakah" kata sandi cadangan "mungkin tidak digunakan sebagai kata sandi pada sertifikat X509 atau kunci pribadi simetrik, dan bahwa sertifikat atau pribadi kunci itu sendiri mungkin digunakan sebagai kunci.AES dan proses enkripsi / dekripsi iTunes simetris.)

IV adalah masalah lain, dan itu bisa menjadi beberapa hal. Mungkin itu salah satu kunci kode keras ke iTunes, atau ke dalam perangkat itu sendiri.

Meskipun komentar Apple di atas menunjukkan bahwa kuncinya ada pada keychain perangkat, saya pikir ini tidak begitu penting. Satu dapat mengembalikan cadangan terenkripsi ke berbeda perangkat, yang menunjukkan semua informasi yang relevan dengan dekripsi ada dalam cadangan dan konfigurasi iTunes, dan bahwa apa pun hanya pada perangkat tidak relevan dan dapat diganti dalam konteks ini. Jadi di mana mungkin kuncinya?

Saya telah mencantumkan jalur di bawah ini dari mesin Windows, tetapi ini merupakan suatu kelebihan OS mana saja yang kami gunakan.

"\ Appdata \ Roaming \ Apple Computer \ iTunes \ itunesprefs.xml" berisi sebuah PList dengan entri "Keychain" di dalamnya. "\ Programdata \ apple \ Lockdown \ 09037027da8f4bdefdea97d706703ca034c88bab.plist" berisi PList dengan "DeviceCertificate", "HostCertificate", dan "RootCertificate", yang semuanya tampaknya merupakan sertifikat X509 yang valid. File yang sama juga tampaknya mengandung kunci asimetris "RootPrivateKey" dan "HostPrivateKey" (pembacaan saya menunjukkan ini mungkin PKCS # 7-enveloped). Juga, dalam setiap cadangan ada nilai "AuthSignature" dan "AuthData" dalam file Manifest.plist, meskipun ini tampaknya diputar karena setiap file secara bertahap didukung, menyarankan mereka tidak begitu berguna sebagai kunci, kecuali sesuatu yang benar-benar cukup terlibat sedang dilakukan.

Ada banyak hal yang menyesatkan di luar sana menyarankan mendapatkan data dari backup terenkripsi adalah mudah. Bukan, dan setahu saya itu belum selesai. Melewati atau melumpuhkan enkripsi cadangan adalah masalah lain sepenuhnya, dan bukan apa yang ingin saya lakukan.

Ini bukan tentang meretas iPhone atau apa pun seperti itu. Semua yang saya cari di sini adalah sarana untuk mengekstrak data (foto, kontak, dll.) Dari cadangan iTunes terenkripsi yang saya dapat yang tidak terenkripsi. Saya sudah mencoba segala macam permutasi dengan informasi yang saya berikan di atas tetapi tidak mendapat tempat. Saya menghargai semua pemikiran atau teknik yang mungkin saya lewatkan.


76
2017-09-30 14:07


asal


Jawaban:


Peneliti keamanan Jean-Baptiste Bédrune dan Jean Sigwald disajikan bagaimana untuk melakukan ini di Hack-in-the-box Amsterdam 2011.

Sejak itu, Apple telah merilis sebuah Buku Putih Keamanan iOS dengan rincian lebih lanjut tentang kunci dan algoritma, dan Charlie Miller dkk. memiliki merilis Buku Pegangan Peretas iOS, yang mencakup beberapa hal yang sama dasar dalam mode bagaimana caranya. Ketika iOS 10 pertama kali muncul, ada perubahan ke format cadangan yang Apple tidak publikasikan pada awalnya, tetapi beragam orang-orang reverse-engineered perubahan format.

Cadangan terenkripsi sangat bagus

Hal hebat tentang backup iPhone terenkripsi adalah mereka mengandung banyak hal seperti kata sandi WiFi yang tidak ada dalam cadangan tidak terenkripsi secara teratur. Sebagai dibahas dalam Buku Putih Keamanan iOS, backup terenkripsi dianggap lebih "aman," jadi Apple menganggap itu ok untuk memasukkan lebih banyak informasi sensitif di dalamnya.

Peringatan penting: jelas, mendekripsi cadangan perangkat iOS Anda menghapus enkripsinya. Untuk melindungi privasi dan keamanan Anda, kamu harus jalankan skrip ini di mesin dengan enkripsi disk penuh. Sementara itu mungkin bagi ahli keamanan untuk menulis perangkat lunak yang melindungi kunci memori, mis. dengan menggunakan fungsi seperti VirtualLock() dan SecureZeroMemory() di antara banyak hal lainnya, ini Skrip Python akan menyimpan kunci dan kata sandi enkripsi Anda dalam string menjadi sampah yang dikumpulkan oleh Python. Ini berarti kunci rahasia dan kata sandi Anda akan tinggal di RAM untuk sementara waktu, dari mana mereka akan bocor ke swap Anda file dan ke disk Anda, di mana musuh dapat memulihkannya. Ini sepenuhnya mengalahkan titik memiliki cadangan terenkripsi.

Cara mendekripsi cadangan: dalam teori

Itu Buku Putih Keamanan iOS menjelaskan konsep dasar kunci per file, kelas perlindungan, kunci kelas perlindungan, dan kantung kunci lebih baik dari yang aku bisa. Jika Anda belum terbiasa dengan ini, ambillah beberapa menit untuk membaca bagian yang relevan.

Sekarang Anda tahu bahwa setiap file di iOS dienkripsi dengan acaknya sendiri kunci enkripsi per file, termasuk kelas perlindungan, dan per file kunci enkripsi disimpan dalam metadata filesystem, terbungkus dalam kunci kelas perlindungan.

Untuk mendekripsi:

  1. Decode keybag yang tersimpan dalam BackupKeyBag masuknya Manifest.plist. Gambaran tingkat tinggi dari struktur ini diberikan itu kertas putih. Itu Wiki iPhone menjelaskan format biner: bidang tipe string 4-byte, 4-byte bidang panjang big-endian, dan kemudian nilai itu sendiri.

    Nilai-nilai penting adalah PBKDF2 ITERations dan SALT, ganda garam perlindungan DPSL dan jumlah iterasi DPIC, lalu untuk masing-masing perlindungan CLS, yang WPKY kunci dibungkus.

  2. Menggunakan kata sandi cadangan mengambil kunci 32-byte menggunakan PBKDF2 yang benar garam dan jumlah iterasi. Pertama gunakan putaran SHA256 dengan DPSL dan DPIC, kemudian babak SHA1 dengan ITER dan SALT.

    Buka kunci yang dibungkus sesuai dengan RFC 3394.

  3. Dekripsi database manifes dengan menarik kelas proteksi 4-byte dan kunci yang lebih panjang dari ManifestKey di Manifest.plist, dan membukanya. Anda sekarang memiliki Database SQLite dengan semua metadata file.

  4. Untuk setiap file yang menarik, dapatkan enkripsi per file kelas terenkripsi kode kelas kunci dan perlindungan dengan mencari di Files.file database kolom untuk sebuah plist biner yang berisi EncryptionKey dan ProtectionClass entri. Strip tag panjang empat-byte awal dari EncryptionKey sebelum menggunakan.

    Kemudian, dapatkan kunci dekripsi akhir dengan membukanya dengan kelas kunci yang dibuka dengan kata sandi cadangan. Kemudian dekripsi file menggunakan AES dalam mode CBC dengan nol IV.

Cara mendekripsi cadangan: dalam praktik

Dalam bentuk kode sumber runnable, berikut ini cara mendekripsi kalkulator file preferensi dari cadangan iPhone terenkripsi:

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

import argparse
import base64
import getpass
import hashlib
import os.path
import pprint
import random
import shutil
import sqlite3
import stat
import string
import struct
import sys
import tempfile

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

def main():
    ## Parse options
    parser = argparse.ArgumentParser()
    parser.add_argument('--backup-directory', dest='backup_directory',
                      default='data/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')
    parser.add_argument('--base64-passcode-key-pipe', dest='passcode_key_pipe',
                        help="""\
Provide a previously derived passcode key to save time doing PBDKF2 when
developing""")
    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)
    else:
        password = getpass.getpass('Backup password: ')

    if args.passcode_key_pipe:
        passcode_key = base64.decodestring(readpipe(args.passcode_key_pipe))
    else:
        passcode_key = None

    ## Unlock keybag with password
    if not keybag.unlockWithPasscode(password, passcode_key):
        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'), 'r') 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, 'w') as db_file:
            db_file.write(decrypted_data)
        conn = sqlite3.connect(db_filename)
        c = conn.cursor()
        c.execute("""
            SELECT fileID, domain, relativePath, file
            FROM Files
            WHERE relativePath LIKE '%/Preferences/com.apple.calculator.plist'
            ORDER BY 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 calculator preferences'
        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 = ["CLAS","WRAP","WPKY", "KTYP", "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 == "TYPE":
                self.type = data
                if self.type > 3:
                    print "FAIL: keybag type > 3 : %d" % self.type
            elif tag == "UUID" and self.uuid is None:
                self.uuid = data
            elif tag == "WRAP" and self.wrap is None:
                self.wrap = data
            elif tag == "UUID":
                if currentClassKey:
                    self.classKeys[currentClassKey["CLAS"]] = currentClassKey
                currentClassKey = {"UUID": data}
            elif tag in CLASSKEY_TAGS:
                currentClassKey[tag] = data
            else:
                self.attrs[tag] = data
        if currentClassKey:
            self.classKeys[currentClassKey["CLAS"]] = currentClassKey

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

    def unwrapKeyForClass(self, protection_class, persistent_key):
        ck = self.classKeys[protection_class]["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["VERS"]
        print "Keybag UUID: %s" % anonymize(self.uuid.encode("hex"))
        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("WRAP","")).ljust(5),
                 KEY_TYPES[ck.get("KTYP",0)].ljust(11),
                 anonymize(ck.get("KEY", "").encode("hex")).ljust(65),
                 anonymize(ck.get("WPKY", "").encode("hex")).ljust(65),
                 ck.get("PBKY", "").encode("hex")])
        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 xrange(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 xrange(1,n+1):
        R[i] = C[i]

    for j in reversed(xrange(0,6)):
        for i in reversed(xrange(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 = "".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):
    global anon_random, memo
    if ANONYMIZE_OUTPUT:
        if s in memo:
            return memo[s]
        possible_alphabets = [
            string.digits,
            string.digits + 'abcdef',
            string.letters,
            "".join(chr(x) for x in range(0, 256)),
        ]
        for a in possible_alphabets:
            if all(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()

Yang kemudian mencetak output ini:

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
VNfSPwXOK8mvKxTtmZ51JppAzrsG7gkWSiY8W7xnRX4=

== 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:
'bplist00\xd3\x01\x02\x03\x04\x05\x06\\DisplayValue[MemoryValue_\x10\x14Trigono'
'metricModeKey_\x10%3.14159265358979323846264338327950288_\x10#2.71828182845904'
'5235360287471352662\x08\x08\x0f\x1c(?g\x8d\x00\x00\x00\x00\x00\x00\x01\x01\x00'
'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x8e'

== pretty-printed calculator preferences
{'DisplayValue': '3.14159265358979323846264338327950288',
 'MemoryValue': '2.718281828459045235360287471352662',
 'TrigonometricModeKey': False}

Kredit tambahan

Itu kode iphone-dataprotection diposting oleh Bédrune dan Sigwald dapat mendekripsi gantungan kunci dari cadangan, termasuk hal-hal menyenangkan seperti wifi yang disimpan dan kata sandi situs web:

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

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

Kode itu tidak lagi berfungsi pada cadangan dari ponsel yang menggunakan iOS terbaru, namun tidak banyak yang berubah ... berikan komentar jika Anda menginginkan saya perbarui kode di atas untuk membuang kata sandi yang tersimpan juga;


84
2017-12-09 23:34



Maaf, tapi itu mungkin lebih rumit, melibatkan pbkdf2, atau bahkan variasi darinya. Dengarkan sesi WWDC 2010 # 209, yang terutama berbicara tentang langkah-langkah keamanan di iOS 4, tetapi juga menyebutkan secara singkat enkripsi terpisah dari cadangan dan bagaimana mereka terkait.

Anda bisa sangat yakin bahwa tanpa mengetahui kata sandi, tidak ada cara Anda dapat mendekripsi, bahkan dengan kekerasan.

Anggap saja Anda ingin mencoba untuk memungkinkan orang-orang yang MENGETAHUI kata sandi untuk mendapatkan data dari cadangan mereka.

Saya khawatir tidak ada cara untuk melihat kode aktual di iTunes untuk mengetahui algos mana yang digunakan.

Kembali pada hari-hari Newton, saya harus mendekripsi data dari sebuah program dan mampu memanggil fungsi dekripsinya secara langsung (mengetahui kata sandi, tentu saja) tanpa perlu bahkan menguraikan algoritmanya. Tidak semudah itu lagi, sayangnya.

Saya yakin ada orang-orang terampil di sekitar yang dapat merekayasa kode iTunes itu - Anda hanya perlu membuat mereka tertarik.

Secara teori, algos Apple harus dirancang dengan cara yang membuat data tetap aman (yaitu hampir tidak bisa dipecahkan dengan metode brute force) kepada penyerang yang mengetahui metode enkripsi yang tepat. Dan di sesi WWDC, mereka membahas detail tentang apa yang mereka lakukan untuk mencapai hal ini. Mungkin Anda benar-benar dapat memperoleh jawaban langsung dari tim keamanan Apple jika Anda memberi tahu mereka niat baik Anda. Lagi pula, bahkan mereka harus tahu bahwa keamanan dengan obfuscation tidak benar-benar efisien. Coba milis keamanan mereka. Bahkan jika mereka tidak menjawab, mungkin orang lain dalam daftar itu akan menjawab dengan bantuan.

Semoga berhasil!


5
2017-09-26 18:09



Belum mencobanya, tetapi Elcomsoft merilis produk yang diklaimnya mampu mendekripsi cadangan, untuk keperluan forensik. Mungkin tidak sekeren solusi sendiri, tetapi mungkin lebih cepat.

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


1
2017-09-24 13:21



Anda harus mengambil salinan utilitas baris perintah mdhelper Erica Sadun (OS X biner & sumber). Ini mendukung daftar dan mengekstrak isi cadangan iPhone / iPod Touch, termasuk basis data buku alamat & SMS, dan metadata aplikasi lainnya dan pengaturan.


-3
2017-10-01 13:13