def crack(manifest, passwords, notify=None): manifest = readPlist(manifest) if not manifest["IsEncrypted"]: print "Backup is not encrypted" return iosFlag = 'ManifestKey' in manifest 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" return salt = kb.attrs["SALT"] iter = kb.attrs["ITER"] print 'iter', iter dpsl = None dpic = None if iosFlag: dpsl = kb.attrs["DPSL"] dpic = kb.attrs["DPIC"] print 'dpic', dpic res = None for password in passwords: password = password.strip() if not password: continue print "[%s]: Trying Crack" % (password) stime = time() res = try_password(password, iosFlag, dpsl, dpic, salt, iter, kb) etime = time() print "[%s]: Take time %s" % (password, etime - stime) if res: print 'Find Password: ', password return password
def download(self, backupUDID): mbsbackup = self.getBackup(backupUDID) print "Downloading backup %s" % backupUDID.encode("hex") self.outputFolder = os.path.join(self.outputFolder, backupUDID.encode("hex")) makedirs(self.outputFolder) print backup_summary(mbsbackup) #print mbsbackup.Snapshot.Attributes.KeybagUUID.encode("hex") keys = self.getKeys(backupUDID) if not keys or not len(keys.Key): print "getKeys FAILED!" return print "Got OTA Keybag" self.kb = Keybag(keys.Key[1].KeyData) if not self.kb.unlockBackupKeybagWithPasscode(keys.Key[0].KeyData): print "Unable to unlock OTA keybag !" return for snapshot in xrange(1, mbsbackup.Snapshot.SnapshotID + 1): files = self.listFiles(backupUDID, snapshot) print "%d files" % len(files) files2 = [] for f in files: if f.Attributes.EncryptionKey: files2.append(f) print f if len(files2): authTokens = self.getFiles(backupUDID, snapshot, files) self.authorizeGet(authTokens)
def getBackupKeyBag(backupfolder, passphrase): manifest = BPlistReader.plistWithFile(backupfolder + "/Manifest.plist") kb = Keybag(manifest["BackupKeyBag"].data) if kb.unlockBackupKeybagWithPasscode(passphrase): print "BackupKeyBag unlock OK" return kb else: return None
def download(self, backupUDID, fast): mbsbackup = self.getBackup(backupUDID) print "Downloading backup %s" % backupUDID.encode("hex") self.outputFolder = os.path.join(self.outputFolder, backupUDID.encode("hex")) makedirs(self.outputFolder) #print backup_summary(mbsbackup) #print mbsbackup.Snapshot.Attributes.KeybagUUID.encode("hex") keys = self.getKeys(backupUDID) if not keys or not len(keys.Key): print "getKeys FAILED!" return print "Got OTA Keybag" self.kb = Keybag(keys.Key[1].KeyData) if not self.kb.unlockBackupKeybagWithPasscode(keys.Key[0].KeyData): print "Unable to unlock OTA keybag !" return print "Available Snapshots: ", mbsbackup.Snapshot.SnapshotID for snapshot in xrange(1, mbsbackup.Snapshot.SnapshotID + 1): print "Listing snapshot..." files = self.listFiles(backupUDID, snapshot) print "Files in snapshot %s : %s" % (snapshot, len(files)) files2 = [] if fast == 'y': for f in files: if 'AddressBook.sqlitedb' in f.RelativePath or 'Calendar.sqlitedb' in f.RelativePath or 'sms.db' in f.RelativePath or 'call_history.db' in f.RelativePath or '.JPG' in f.RelativePath: files2.append(f) files = files2 if len(files): authTokens = self.getFiles(backupUDID, snapshot, files) #print authTokens self.authorizeGet(authTokens, snapshot) if fast == 'n': if len(files): authTokens = self.getFiles(backupUDID, snapshot, files) #print authTokens self.authorizeGet(authTokens, snapshot)
def download(self, backupUDID, item_types): mbsbackup = self.get_backup(backupUDID) self.output_folder = os.path.join(self.output_folder, backupUDID.encode("hex")) print "Downloading backup {} to {}".format(backupUDID.encode("hex"), self.output_folder) try: mkdir_p(self.output_folder) except OSError: print "Directory \"{}\" already exists.".format(self.output_folder) return keys = self.get_keys(backupUDID) if not keys or not len(keys.Key): print "get_keys FAILED!" return print "Got OTA Keybag" self.kb = Keybag(keys.Key[-1].KeyData) if not self.kb.unlockBackupKeybagWithPasscode(keys.Key[0].KeyData): print "Unable to unlock OTA keybag !" return print "Available Snapshots: %d" % (mbsbackup.Snapshot.SnapshotID) if self.chosen_snapshot_id == None: snapshot_list = [ 1, mbsbackup.Snapshot.SnapshotID - 1, mbsbackup.Snapshot.SnapshotID ] elif self.chosen_snapshot_id < 0: snapshot_list = [ mbsbackup.Snapshot.SnapshotID + self.chosen_snapshot_id + 1 ] # Remember chosen_snapshot_id is negative else: snapshot_list = [self.chosen_snapshot_id] for snapshot in snapshot_list: print "Listing snapshot %d..." % (snapshot) files = self.list_files(backupUDID, snapshot) print "Files in snapshot %d" % (len(files)) def matches_allowed_domain(a_file): return self.domain_filter in a_file.Domain def matches_allowed_item_types(a_file): return any(ITEM_TYPES_TO_FILE_NAMES[item_type] in a_file.RelativePath.lower() \ for item_type in item_types) if self.domain_filter: files = filter(matches_allowed_domain, files) if len(item_types) > 0: files = filter(matches_allowed_item_types, files) print "Downloading %d files due to filter" % (len(files)) if len(files): authTokens = self.get_files(backupUDID, snapshot, files) if len(authTokens.tokens) > 0: self.authorize_get(authTokens, snapshot) if self.itunes_style: self.write_info_plist(mbsbackup, snapshot) self.write_manifest_mbdb(snapshot) else: print "Unable to download snapshot. This snapshot may not have finished uploading yet." # Clean up self.files if not self.combined: self.downloaded_files = []
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