Câu hỏi Làm thế nào để giải mã sao lưu Apple iTunes iPhone được mã hóa?


Tôi đã được yêu cầu bởi một số người dùng iPhone không may để giúp họ khôi phục dữ liệu từ bản sao lưu iTunes của họ. Điều này rất dễ dàng khi chúng không được mã hóa, nhưng không phải khi chúng được mã hóa, cho dù mật khẩu có được biết hay không.

Như vậy, tôi đang cố gắng tìm ra sơ đồ mã hóa được sử dụng trên các tệp mddata và mdinfo khi được mã hóa. Tôi không gặp vấn đề gì khi đọc các tệp này và đã xây dựng một số thư viện C # mạnh mẽ để làm như vậy. (Nếu bạn có thể giúp, tôi không quan tâm bạn sử dụng ngôn ngữ nào. Đó là nguyên tắc tôi ở đây!)

Apple "iPhone OS Enterprise Deployment Guide" nói rằng "Sao lưu thiết bị có thể được lưu trữ ở định dạng mã hóa bằng cách chọn mã hóa iPhone Tùy chọn sao lưu trong ngăn tóm tắt thiết bị của iTunes. Các tệp được mã hóa bằng AES128 với khóa 256 bit. Chìa khóa được lưu trữ an toàn trong keychain iPhone. "

Đó là một đầu mối khá tốt, và có một số thông tin tốt ở đây trên Stackoverflow trên iPhone Khả năng tương tác AES / Rijndael đề xuất một khóa của chế độ 128 và CBC có thể được sử dụng.

Ngoài bất kỳ obfuscation khác, một vector quan trọng và initialisation (IV) / muối được yêu cầu.

Người ta có thể giả định rằng chìa khóa là một thao tác của "mật khẩu sao lưu" mà người dùng được nhắc nhở để nhập bằng iTunes và được chuyển đến "AppleMobileBackup.exeTuy nhiên, với tham chiếu đến móc khóa iPhone, tôi tự hỏi liệu "mật khẩu sao lưu" có thể không được sử dụng làm mật khẩu trên chứng chỉ X509 hoặc khóa riêng đối xứng hay không, và chứng chỉ hoặc riêng tư chính nó có thể được sử dụng như là chìa khóa. (AES và quá trình mã hóa / giải mã iTunes là đối xứng.)

IV là một vấn đề khác, và nó có thể là một vài điều. Có lẽ đó là một trong những chìa khóa mã hóa cứng vào iTunes hoặc vào bản thân thiết bị.

Mặc dù nhận xét của Apple ở trên cho thấy chìa khóa hiện diện trên móc khóa của thiết bị, tôi nghĩ điều này không quan trọng. Người ta có thể khôi phục bản sao lưu được mã hóa thành khác nhau thiết bị, cho thấy tất cả thông tin có liên quan đến giải mã có mặt trong cấu hình sao lưu và iTunes và bất kỳ thứ gì chỉ trên thiết bị đều không liên quan và có thể thay thế trong ngữ cảnh này. Vì vậy, nơi có thể là chìa khóa được?

Tôi đã liệt kê các đường dẫn bên dưới từ một máy tính Windows nhưng nó là một phần lớn của bất kỳ hệ điều hành nào chúng ta sử dụng.

"\ Appdata \ Roaming \ Apple Computer \ iTunes \ itunesprefs.xml" chứa một PList có mục nhập dict "Keychain" trong đó. "\ Programdata \ apple \ Lockdown \ 09037027da8f4bdefdea97d706703ca034c88bab.plist" chứa một PList với "DeviceCertificate", "HostCertificate" và "RootCertificate", tất cả đều xuất hiện là các chứng chỉ X509 hợp lệ. Cùng một tập tin cũng xuất hiện để chứa các phím bất đối xứng "RootPrivateKey" và "HostPrivateKey" (đọc của tôi cho thấy đây có thể là PKCS # 7-enveloped). Ngoài ra, trong mỗi bản sao lưu có các giá trị "AuthSignature" và "AuthData" trong tệp Manifest.plist, mặc dù chúng xuất hiện để xoay khi mỗi tệp được sao lưu gia tăng, chúng cho rằng chúng không hữu ích như một khóa, trừ khi khá tham gia đang được thực hiện.

Có rất nhiều công cụ gây hiểu lầm trên mạng cho thấy việc nhận dữ liệu từ các bản sao lưu được mã hóa rất dễ dàng. Nó không phải, và với kiến ​​thức của tôi nó đã không được thực hiện. Bỏ qua hoặc vô hiệu hóa mã hóa sao lưu là một vấn đề khác hoàn toàn, và không phải là những gì tôi đang tìm kiếm.

Đây không phải là về hack iPhone hoặc bất cứ điều gì như thế. Tất cả tôi sau đây là một phương tiện để trích xuất dữ liệu (hình ảnh, địa chỉ liên lạc, vv) từ bản sao lưu iTunes được mã hóa như tôi có thể không được mã hóa. Tôi đã thử tất cả các loại hoán vị với thông tin tôi đã đặt ở trên nhưng không có nơi nào. Tôi đánh giá cao bất kỳ suy nghĩ hoặc kỹ thuật tôi có thể đã bỏ lỡ.


76
2017-09-30 14:07


gốc


Cập nhật từ ba năm sau: Tôi đã tìm ra và cuộn nó thành một sản phẩm có sẵn miễn phí. Tôi đã đi đúng hướng ở trên, nhưng thật khó. - afit
bạn có liên kết cho sản phẩm đó không? - Thilo
Như bạn đã hỏi, đó là Trình sao lưu iPhone Sao lưu. Trong khi bạn sẽ thấy có phiên bản trả tiền của chương trình, phiên bản miễn phí cũ đồng bằng sẽ cho phép bạn để có được các tập tin được mã hóa ra 4 tại một thời điểm. - afit
Tôi thấy rằng bạn đã quản lý để giải mã bản sao lưu 10.2. Bạn có thể chia sẻ cách bạn đạt được điều đó không? - Niki
@Niki Tôi đã cập nhật câu trả lời của mình dưới đây cho iOS 10 - andrewdotn


Các câu trả lời:


Các nhà nghiên cứu bảo mật Jean-Baptiste Bédrune và Jean Sigwald trình bày cách để làm điều này tại Hack-in-the-box Amsterdam 2011.

Kể từ đó, Apple đã phát hành Báo cáo chính thức về bảo mật iOS với các chi tiết về khóa và thuật toán, và Charlie Miller et al. có phát hành Sổ tay Hacker của iOS, bao gồm một số nền tảng trong cách thức thời trang. Khi iOS 10 xuất hiện lần đầu có những thay đổi sang định dạng sao lưu mà Apple đã không công bố lúc đầu, nhưng khác nhau những người thiết kế ngược thay đổi định dạng.

Sao lưu được mã hóa rất tuyệt

Điều tuyệt vời về sao lưu iPhone được mã hóa là chúng chứa mọi thứ như mật khẩu WiFi không có trong bản sao lưu không được mã hóa thông thường. Như thảo luận trong Báo cáo chính thức về bảo mật iOS, sao lưu được mã hóa được coi là "an toàn hơn", do đó, Apple cho rằng nó ok để bao gồm nhiều hơn thông tin nhạy cảm trong đó.

Một cảnh báo quan trọng: rõ ràng, giải mã bản sao lưu thiết bị iOS của bạn loại bỏ mã hóa của nó. Để bảo vệ quyền riêng tư và bảo mật của bạn, bạn nên chỉ chạy các tập lệnh này trên máy có mã hóa toàn bộ đĩa. Trong khi đó có thể cho chuyên gia bảo mật viết phần mềm bảo vệ khóa bộ nhớ, ví dụ: bằng cách sử dụng các chức năng như VirtualLock() và SecureZeroMemory() trong số nhiều thứ khác, những Các tập lệnh Python sẽ lưu trữ các khóa mã hóa và mật khẩu của bạn bằng chuỗi được thu gom rác bằng Python. Điều này có nghĩa là các khóa và mật khẩu bí mật của bạn sẽ sống trong RAM một thời gian, từ đâu họ sẽ bị rò rỉ vào trao đổi của bạn và vào đĩa của bạn, nơi đối thủ có thể khôi phục chúng. Điều này hoàn toàn đánh bại điểm có bản sao lưu được mã hóa.

Cách giải mã các bản sao lưu: theo lý thuyết

Các Báo cáo chính thức về bảo mật iOS giải thích các khái niệm cơ bản các khóa cho mỗi tệp, lớp bảo vệ, khóa lớp bảo vệ và các túi khóa tốt hơn tôi có thể. Nếu bạn chưa quen với những điều này, hãy dành một vài phút để đọc các phần liên quan.

Bây giờ bạn biết rằng mọi tệp trong iOS được mã hóa với ngẫu nhiên của riêng nó khóa mã hóa mỗi tệp, thuộc về lớp bảo vệ và tệp trên mỗi tệp các khóa mã hóa được lưu trữ trong siêu dữ liệu hệ thống tập tin, được bao bọc trong khóa lớp bảo vệ.

Để giải mã:

  1. Giải mã keybag được lưu trữ trong BackupKeyBag mục nhập của Manifest.plist. Một tổng quan cấp cao về cấu trúc này được đưa ra các giấy trắng. Các iPhone Wiki mô tả định dạng nhị phân: trường loại chuỗi 4 byte, 4 byte trường độ dài lớn nhất và sau đó là giá trị.

    Các giá trị quan trọng là PBKDF2 ITERhành và SALT, đôi muối bảo vệ DPSL và số lần lặp DPICvà sau đó cho mỗi sự bảo vệ CLS, các WPKY bọc khóa.

  2. Sử dụng mật khẩu sao lưu lấy được khóa 32 byte bằng cách sử dụng đúng PBKDF2 muối và số lần lặp lại. Đầu tiên sử dụng vòng SHA256 với DPSL và DPIC, sau đó là vòng SHA1 với ITER và SALT.

    Unwrap mỗi phím bọc theo RFC 3394.

  3. Giải mã cơ sở dữ liệu tệp kê khai bằng cách kéo lớp bảo vệ 4 byte và khóa dài hơn từ ManifestKey trong Manifest.plistvà mở nó ra. Bây giờ bạn có một Cơ sở dữ liệu SQLite với tất cả siêu dữ liệu tệp.

  4. Đối với mỗi tệp quan tâm, nhận mã hóa mỗi tệp được mã hóa lớp học mã lớp khóa và bảo vệ bằng cách tìm trong Files.file cơ sở dữ liệu cột cho một plist nhị phân có chứa EncryptionKey và ProtectionClass mục. Dải thẻ dài 4 byte ban đầu từ EncryptionKey trước khi sử dụng.

    Sau đó, lấy khóa giải mã cuối cùng bằng cách mở khóa bằng lớp khóa đã được mở bằng mật khẩu sao lưu. Sau đó giải mã tệp sử dụng AES ở chế độ CBC với số không IV.

Cách giải mã các bản sao lưu: trong thực tế

Trong biểu mẫu mã nguồn có thể chạy được, dưới đây là cách giải mã máy tính tệp tùy chọn từ bản sao lưu iPhone được mã hóa:

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

Sau đó in kết quả này:

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}

Tín dụng thêm

Các mã iphone-dataprotection đăng bởi Bédrune và Sigwald có thể giải mã móc khóa từ bản sao lưu, bao gồm những thứ thú vị như wifi đã lưu và mật khẩu trang 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|
...

Mã đó không còn hoạt động trên các bản sao lưu từ điện thoại sử dụng iOS mới nhất, nhưng không phải tất cả những gì đã thay đổi ... để lại nhận xét nếu bạn muốn tôi cập nhật mã trên để loại bỏ mật khẩu đã lưu, P


84
2017-12-09 23:34



Tôi đã thử nó và nó hoạt động ở nơi mọi công cụ khác đều thất bại. Tôi cũng phải thêm một mô-đun python còn thiếu: pip install --user pycrypto  Cảm ơn! - ALoopingIcon
Đăng tuyệt vời! Lời giải thích ấn tượng. Cảm ơn. - Ricardo Sanchez-Saez
Tuyệt vời! Sử dụng macports tôi đã cài đặt các phụ thuộc này: py27-m2crypto py27-cryptography - hyperspasm
Nếu bạn cập nhật mã, bạn sẽ gần gũi với một vị thần cho tôi! - Jonas Zaugg
@ JonasZaugg Tôi đã cập nhật mã mẫu cho iOS 10. Tôi hy vọng bạn thấy nó hữu ích. - andrewdotn


Xin lỗi, nhưng nó thậm chí có thể phức tạp hơn, liên quan đến pbkdf2, hoặc thậm chí là một biến thể của nó. Nghe phiên WWDC 2010 # 209, chủ yếu nói về các biện pháp bảo mật trong iOS 4, nhưng cũng đề cập ngắn gọn về việc mã hóa các bản sao lưu riêng biệt và cách chúng liên quan.

Bạn có thể khá chắc chắn rằng nếu không biết mật khẩu, không có cách nào bạn có thể giải mã nó, ngay cả bằng vũ lực.

Hãy giả sử bạn muốn thử cho phép những người BIẾT mật khẩu truy cập dữ liệu của các bản sao lưu của họ.

Tôi lo sợ không có cách nào xung quanh nhìn vào mã thực tế trong iTunes để tìm ra các thuật toán được sử dụng.

Quay lại trong những ngày Newton, tôi đã phải giải mã dữ liệu từ một chương trình và có thể gọi trực tiếp chức năng giải mã của nó (biết mật khẩu, tất nhiên) mà không cần phải giải thích thuật toán của nó. Nó không phải là dễ dàng nữa, thật không may.

Tôi chắc chắn rằng có những người có kỹ năng xung quanh những người có thể đảo ngược kỹ sư mã iTunes - bạn chỉ cần có để làm cho họ quan tâm.

Về lý thuyết, thuật toán của Apple nên được thiết kế theo cách làm cho dữ liệu vẫn an toàn (nghĩa là thực tế không thể phá vỡ bằng phương pháp vũ phu) cho bất kỳ kẻ tấn công nào biết phương thức mã hóa chính xác. Và trong WWDC phiên 209 họ đã đi khá sâu vào chi tiết về những gì họ làm để thực hiện việc này. Có thể bạn thực sự có thể nhận được câu trả lời trực tiếp từ nhóm bảo mật của Apple nếu bạn nói với họ ý định tốt của bạn. Xét cho cùng, ngay cả họ cũng nên biết rằng an ninh bằng cách làm cho obfuscation không thực sự hiệu quả. Hãy thử danh sách gửi thư bảo mật của họ. Ngay cả khi họ không trả lời, có lẽ một người nào khác âm thầm trong danh sách sẽ trả lời với một số trợ giúp.

Chúc may mắn!


5
2017-09-26 18:09





Đã không thử nó, nhưng Elcomsoft phát hành một sản phẩm mà họ tuyên bố là có khả năng giải mã các bản sao lưu, vì mục đích pháp y. Có lẽ không phải là mát mẻ như kỹ thuật một giải pháp cho mình, nhưng nó có thể nhanh hơn.

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


1
2017-09-24 13:21



Cảm ơn. Điều này không giải mã các bản sao lưu như vậy: nó chỉ làm nứt các phím. Tôi biết làm thế nào để làm điều đó ... và đó là đơn giản hơn rất nhiều so với giải mã sao lưu một khi bạn có chìa khóa. - afit
Huh. Xin lỗi vì điều đó. Đoán tôi đọc các tài liệu. - Jablair


Bạn nên lấy một bản sao của tiện ích dòng lệnh mdhelper của Erica Sadun (OS X nhị phân & nguồn). Nó hỗ trợ danh sách và trích xuất nội dung của bản sao lưu iPhone / iPod Touch, bao gồm sổ địa chỉ và cơ sở dữ liệu SMS và các cài đặt và siêu dữ liệu ứng dụng khác.


-3
2017-10-01 13:13



Đó chỉ là một độc giả PList: Tôi đã có thể làm điều đó một cách tự nhiên. Nó không hỗ trợ sao lưu được mã hóa đó là những gì tôi đang sau, và đó là vượt ra ngoài phạm vi của tiện ích đó. - afit
Bạn đã dành thời gian thử tiện ích chưa? Sao lưu của tôi được mã hóa và nó thực hiện chính xác những gì bạn đang cố gắng làm. - Nathan de Vries
Có, và tôi cũng đã đọc nguồn. Nó không xử lý các bản sao lưu được mã hóa và được sửa đổi lần cuối trước khi phát hành hỗ trợ của iTunes cho các bản sao lưu được mã hóa. Tôi nghi ngờ bạn có nghĩa là sao lưu của bạn được mã hóa hoặc iPhone của bạn sử dụng một hệ thống tập tin được mã hóa, đó là một vấn đề hoàn toàn. Cũng như không có hỗ trợ cho mã hóa trong mã, rõ ràng là không có tùy chọn để vượt qua trong một mật khẩu trong các tùy chọn dòng lệnh. Và mã không sử dụng bất kỳ certs hoặc móc khóa nào. Tôi muốn được chứng minh là sai về điều này, nhưng tôi thực sự không nghĩ rằng tôi! Tôi đánh giá cao đề nghị, mặc dù. - afit