def getPasscodekeyFromPasscode(self, passcode): if self.type == BACKUP_KEYBAG or self.type == OTA_KEYBAG: a = PBKDF2(passcode, self.attrs["SALT"], iterations=self.attrs["ITER"]).read(32) print ":".join("{:02x}".format(ord(c)) for c in a) return a else: #Warning, need to run derivation on device with this result return PBKDF2(passcode, self.attrs["SALT"], iterations=1).read(32)
def getPasscodekeyFromPasscode(self, passcode): if self.type == BACKUP_KEYBAG or self.type == OTA_KEYBAG: if self.manifestKey == None: return PBKDF2(passcode, self.attrs["SALT"], iterations=self.attrs["ITER"]).read(32) else: #self.kek = binascii.unhexlify("1881657569b6df76f4a4c81f21c984a87a43f7afdf6a5da83d982c2a2e9720aa") #self.kek2 = binascii.unhexlify("7df00a6464383c20d8ac1f69d3908b8c3e1eee2039530d7dd8fb4aa095fa6c6b") if self.kek and self.kek2: print("predefined kek!") else: self.kek = PBKDF2(passcode, self.attrs["DPSL"], iterations=self.attrs["DPIC"], macmodule=hmac, digestmodule=sha256).read(32) self.kek2 = PBKDF2(self.kek, self.attrs["SALT"], iterations=self.attrs["ITER"], macmodule=hmac, digestmodule=sha1).read(32) return self.kek2 else: #Warning, need to run derivation on device with this result return PBKDF2(passcode, self.attrs["SALT"], iterations=1).read(32)
""" 0 1:MCSHA256DigestWithSalt 2:SecKeyFromPassphraseDataHMACSHA1 """ from crypto.PBKDF2 import PBKDF2 import plistlib import hashlib SALT1 = "F92F024CA2CB9754".decode("hex") hashMethods = { 1: (lambda p, salt: hashlib.sha256(SALT1 + p)), 2: (lambda p, salt: PBKDF2(p, salt, iterations=1000).read(20)) } def bruteforce_old_pass(h): salt = h["salt"].data hash = h["hash"].data f = hashMethods.get(h["hashMethod"]) if f: print "Bruteforcing hash %s (4 digits)" % hash.encode("hex") for i in xrange(10000): p = "%04d" % (i % 10000) if f(p, salt) == hash: return p
def main(): # Get the arguments if len(sys.argv) != 3: print "Usage: backup_passwd_guess.py iOS_Backup_Dir Password_Dictionary" sys.exit(1) backup = sys.argv[1] pwddict = sys.argv[2] # Open the manifest plist manifest_loc = backup + "/Manifest.plist" if not os.path.exists(manifest_loc): print "Can't find Manifest.plist - bad backup?" sys.exit(1) manifest = readPlist(manifest_loc) # Open the dictionary if not os.path.exists(pwddict): print "Can't find dictionary" sys.exit(1) dictfile = open(pwddict) # Get the backup information info = readPlist(backup + "/Info.plist") print "Backup Details:" print " Device: %s" % (info['Product Name']) print " Serial: %s" % (info['Serial Number']) print " Firmware: %s" % (info['Product Version']) print "" # Make sure the backup is encrypted if not manifest["IsEncrypted"]: print "Backup is not encrypted" sys.exit(1) # Determine if we have the new format of the backup encryption iosFlag = False if 'ManifestKey' in manifest: print "***** Backup is encrypted using newer algorithm. Time per try is now minutes instead of seconds *****" print "" iosFlag = True # Get the keybag kb = Keybag(manifest["BackupKeyBag"].data) kb.deviceKey = None if kb.type != BACKUP_KEYBAG and kb.type != OTA_KEYBAG: print "Backup does not contain a backup keybag" sys.exit(1) salt = kb.attrs["SALT"] iter = kb.attrs["ITER"] if iosFlag: dpsl = kb.attrs["DPSL"] dpic = kb.attrs["DPIC"] # Loop through the passwords in the file while True: password = dictfile.readline() if password == "": break password = password[:-1] opassword = password print "Trying %s" % (opassword) # Check the password if iosFlag: password = PBKDF2(password, dpsl, iterations = dpic, digestmodule=SHA256).read(32) code = PBKDF2(password, salt, iterations=iter).read(32) success = 0 for classkey in kb.classKeys.values(): k = classkey["WPKY"] if classkey["WRAP"] & WRAP_PASSCODE: k = AESUnwrap(code, classkey["WPKY"]) if not k: success = 1 break if classkey["WRAP"] & WRAP_DEVICE: if not kb.deviceKey: continue k = AESdecryptCBC(k, kb.deviceKey) if success == 0: print "Password found - ",opassword break