def extract_backup(backup_path, output_path, password=""): if not os.path.exists(backup_path + "/Manifest.plist"): print "Manifest.plist not found" return manifest = readPlist(backup_path + "/Manifest.plist") info = readPlist( backup_path + "/Info.plist") for i in showinfo: print i + " : " + unicode(info.get(i, "missing")) if manifest["IsEncrypted"] and password == "": password = getpass('Enter backup password : ') if not manifest.has_key("BackupKeyBag"): print "oops this is not encrypted" exit(1) else: mbdb = MBDB(backup_path) kb = Keybag.createWithBackupManifest(manifest, password) if not kb: return manifest["password"] = password mbdb.keybag = kb extract_sms_db(mbdb, output_path)
def extract_backup(backup_path, output_path, password=""): if not os.path.exists(backup_path + "/Manifest.plist"): print "Manifest.plist not found" return manifest = readPlist(backup_path + "/Manifest.plist") info = readPlist( backup_path + "/Info.plist") for i in showinfo: print i + " : " + unicode(info.get(i, "missing")) #jsc # print "Extract backup to %s ? (y/n)" % output_path # if raw_input() == "n": # return print "Backup is %sencrypted" % (int(not manifest["IsEncrypted"]) * "not ") #jsc # if manifest["IsEncrypted"] and password == "": # print "Enter backup password : "******"BackupKeyBag"): print "No BackupKeyBag in manifest, assuming iOS 3.x backup" decrypt_backup3(backup_path, output_path, password) else: mbdb = MBDB(backup_path) kb = Keybag.createWithBackupManifest(manifest, password) if not kb: return #jsc password = kb.bfPassword manifest["password"] = password makedirs(output_path) plistlib.writePlist(manifest, output_path + "/Manifest.plist") mbdb.keybag = kb mbdb.extract_backup(output_path) #jsc print "Bruteforce successful, backup password : %s" % password print "You can decrypt the keychain using the following command : " print "python keychain_tool.py -d \"%s\" \"%s\"" % (output_path + "/KeychainDomain/keychain-backup.plist", output_path + "/Manifest.plist")
def extract_backup(backup_path, output_path, password=""): if not os.path.exists(backup_path + "/Manifest.plist"): print "Manifest.plist not found" return manifest = readPlist(backup_path + "/Manifest.plist") info = readPlist(backup_path + "/Info.plist") for i in showinfo: print i + " : " + unicode(info.get(i, "missing")) print "Extract backup to %s ? (y/n)" % output_path if raw_input() == "n": return print "Backup is %sencrypted" % (int(not manifest["IsEncrypted"]) * "not ") if manifest["IsEncrypted"] and password == "": print "Enter backup password : "******"BackupKeyBag"): print "No BackupKeyBag in manifest, assuming iOS 3.x backup" decrypt_backup3(backup_path, output_path, password) else: mbdb = MBDB(backup_path) kb = Keybag.createWithBackupManifest(manifest, password) if not kb: return manifest["password"] = password makedirs(output_path) plistlib.writePlist(manifest, output_path + "/Manifest.plist") mbdb.keybag = kb mbdb.extract_backup(output_path) print "You can decrypt the keychain using the following command : " print "python keychain_tool.py -d %s %s" % ( output_path + "/keychain-backup.plist", output_path + "/Manifest.plist")
def main(): parser = OptionParser(usage="%prog keychain.db/keychain-backup.plist keyfile.plist/Manifest.plist") parser.add_option("-d", "--display", dest="display", action="store_true", default=False, help="Show keychain items on stdout") parser.add_option("-s", "--sanitize", dest="sanitize", action="store_true", default=False, help="Hide secrets on stdout with ***") parser.add_option("-p", "--passwords", dest="passwords", action="store_true", default=False, help="Save generic & internet passwords as CSV file") parser.add_option("-c", "--certs", dest="certs", action="store_true", default=False, help="Extract certificates and keys") parser.add_option("-o", "--old", dest="oldpass", action="store_true", default=False, help="Bruteforce old passcodes") (options, args) = parser.parse_args() if len(args) < 2: parser.print_help() return p = readPlist(args[1]) if p.has_key("BackupKeyBag"): deviceKey = None if p.has_key("key835"): deviceKey = p["key835"].decode("hex") else: if not p["IsEncrypted"]: print "This backup is not encrypted, without key 835 nothing in the keychain can be decrypted" print "If you have key835 for device %s enter it (in hex)" % p["Lockdown"]["UniqueDeviceID"] d = raw_input() if len(d) == 32: p["key835"] = d deviceKey = d.decode("hex") plistlib.writePlist(p, args[1]) kb = Keybag.createWithBackupManifest(p, p.get("password",""), deviceKey) if not kb: return k = Keychain4(args[0], kb) else: kb = Keybag.createWithPlist(p) k = keychain_load(args[0], kb, p["key835"].decode("hex")) if options.display: k.print_all(options.sanitize) if options.passwords: k.save_passwords() if options.certs: k.save_certs_keys() if options.oldpass: mc = k.get_managed_configuration() if not mc: print "Managed configuration not found" return print "Bruteforcing %d old passcodes" % len(mc.get("history",[])) for h in mc["history"]: p = bruteforce_old_pass(h) if p: print "Found : %s" % p else: print "Not Found"
def main(): parser = OptionParser( usage= "%prog keychain.db/keychain-backup.plist keyfile.plist/Manifest.plist") parser.add_option("-d", "--display", dest="display", action="store_true", default=False, help="Show keychain items on stdout") parser.add_option("-s", "--sanitize", dest="sanitize", action="store_true", default=False, help="Hide secrets on stdout with ***") parser.add_option("-p", "--passwords", dest="passwords", action="store_true", default=False, help="Save generic & internet passwords as CSV file") parser.add_option("-c", "--certs", dest="certs", action="store_true", default=False, help="Extract certificates and keys") parser.add_option("-o", "--old", dest="oldpass", action="store_true", default=False, help="Bruteforce old passcodes") (options, args) = parser.parse_args() if len(args) < 2: parser.print_help() return p = readPlist(args[1]) if p.has_key("BackupKeyBag"): deviceKey = None if p.has_key("key835"): deviceKey = p["key835"].decode("hex") else: if not p["IsEncrypted"]: print "This backup is not encrypted, without key 835 nothing in the keychain can be decrypted" print "If you have key835 for device %s enter it (in hex)" % p[ "Lockdown"]["UniqueDeviceID"] d = raw_input() if len(d) == 32: p["key835"] = d deviceKey = d.decode("hex") plistlib.writePlist(p, args[1]) kb = Keybag.createWithBackupManifest(p, p.get("password", ""), deviceKey) if not kb: return k = Keychain4(args[0], kb) else: kb = Keybag.createWithPlist(p) k = keychain_load(args[0], kb, p["key835"].decode("hex")) if options.display: k.print_all(options.sanitize) if options.passwords: k.save_passwords() if options.certs: k.save_certs_keys() if options.oldpass: mc = k.get_managed_configuration() if not mc: print "Managed configuration not found" return print "Bruteforcing %d old passcodes" % len(mc.get("history", [])) for h in mc["history"]: p = bruteforce_old_pass(h) if p: print "Found : %s" % p else: print "Not Found"
def extract_backup(backup_path, output_path, password="", app=None): ''' if not os.path.exists(backup_path + "/Manifest.plist"): print "Manifest.plist not found" return manifest = readPlist(backup_path + "/Manifest.plist") ''' manifest = readManifest(backup_path) if manifest is None: print("Manifest.plist not found") return # dict = manifest['Applications'] # for apps in dict.iteritems(): # print "App Name: " + apps[0] # for key, value in apps[1].iteritems(): # print key + " : " + value # print "####################################" showinfo = readInfo(backup_path) if showinfo is None: print("Info.plist not found") return for i in showinfo: value = unicode(showinfo.get(i, "missing")) if i == "Product Type": value = value + " (" + getIDeviceProductName(value) + ")" print(i + " : " + value + "...") # print "Extract backup to %s ? (y/n)" % output_path # if raw_input() == "n": # return print("Backup is %sencrypted" % (int(not manifest["IsEncrypted"]) * "not ")) if manifest["IsEncrypted"] and password == "": print ("Enter backup password : "******"BackupKeyBag"): print ("No BackupKeyBag in manifest, assuming iOS 3.x backup") decrypt_backup3(backup_path, output_path, password) else: mbdb = MBDB(backup_path) kb = Keybag.createWithBackupManifest(manifest, password) if not kb: return manifest["password"] = password makedirs(output_path) plistlib.writePlist(manifest, output_path + "/Manifest.plist") mbdb.keybag = kb database, cursor = iOSBackupDB() store2db(cursor, mbdb) database.commit() print_domains(cursor) cursor.execute("Select * from indice where mbapp_name= ?", (app,)) records = cursor.fetchall() for record in records: dbrecord = MBFileRecordFromDB(record) mbdb.extract_backup_from_db(dbrecord, output_path)
def extract_backup(backup_path, output_path, password=""): if not os.path.exists(backup_path + "/Manifest.plist"): print "Manifest.plist not found" return manifest = readPlist(backup_path + "/Manifest.plist") info = readPlist(backup_path + "/Info.plist") for i in showinfo: print i + " : " + unicode(info.get(i, "missing")) print "Extract backup to %s ? (y/n)" % output_path if raw_input() == "n": return print "Backup is %sencrypted" % (int(not manifest["IsEncrypted"]) * "not ") if manifest["IsEncrypted"] and password == "": print "Enter backup password : "******"BackupKeyBag"): print "No BackupKeyBag in manifest, assuming iOS 3.x backup" decrypt_backup3(backup_path, output_path, password) elif os.path.exists(backup_path + "/Manifest.mbdb"): mbdb = MBDB(backup_path) kb = Keybag.createWithBackupManifest(manifest, password) if not kb: return manifest["password"] = password makedirs(output_path) plistlib.writePlist(manifest, output_path + "/Manifest.plist") mbdb.keybag = kb mbdb.extract_backup(output_path) print "You can decrypt the keychain using the following command : " print "python keychain_tool.py -d \"%s\" \"%s\"" % ( output_path + "/KeychainDomain/keychain-backup.plist", output_path + "/Manifest.plist") elif os.path.exists(backup_path + "/Manifest.db"): if 'ManifestKey' in manifest: kb = Keybag.createWithBackupManifest(manifest, password, ios102=True) else: kb = Keybag.createWithBackupManifest(manifest, password) if not kb: return manifest["password"] = password makedirs(output_path) plistlib.writePlist(manifest, output_path + "/Manifest.plist") manifest_key = None if 'ManifestKey' in manifest: clas = struct.unpack('<L', manifest['ManifestKey'].data[:4])[0] wkey = manifest['ManifestKey'].data[4:] manifest_key = kb.unwrapKeyForClass(clas, wkey) manifset_db = ManifestDB(backup_path, key=manifest_key) manifset_db.keybag = kb manifset_db.extract_backup(output_path) print "You can decrypt the keychain using the following command: " print "python keychain_tool.py -d \"%s\" \"%s\"" % ( output_path + "/KeychainDomain/keychain-backup.plist", output_path + "/Manifest.plist") else: print "No Manifest database found, Is it a complete backup?"
def openBackup(self, path=None): if path is not None: self.backuppath = path self.manifest = readManifest(self.backuppath) if self.manifest is None: self.informationMessage("%s seems not to be a valid backup directory" % self.backuppath) self.ui.statusbar.showMessage("Stop...") return False else: # refresh gridLayoutManifest self.gridLayoutManifest_refresh(self.manifest) self.infoplist = readInfo(self.backuppath) if self.infoplist is None: self.informationMessage("Can't find Info.plist in directory %s. Not a valid backup directory?" % self.backuppath) self.ui.statusbar.showMessage("Stop...") return False else: # refresh gridLayoutInfo self.gridLayoutInfo_refresh(self.infoplist) if not self.manifest.has_key("BackupKeyBag"): self.informationMessage("Only iOSBackup >= Version 5 Supported") if self.manifest["IsEncrypted"]: self.passwd = self.passwordDialog() if self.passwd is None: self.informationMessage("Password not given! Will not be able to extract information...") progressBar = QtGui.QProgressBar() self.ui.statusbar.addWidget(progressBar) self.mbdb = MBDB(self.backuppath) if self.passwd is not None: kb = Keybag.createWithBackupManifest(self.manifest, self.passwd) if not kb: self.informationMessage( "Can not extract backup key.\nYou can only browse through the domains and apps...") # return False self.manifest["password"] = self.passwd self.mbdb.keybag = kb progressBar.setMaximum(self.mbdb.numoffiles) if TestMode is True: self.database, self.cursor = iOSBackupDB(TestDatabase) else: self.database, self.cursor = iOSBackupDB() store2db(self.cursor, self.mbdb) self.database.commit() self.ui.treeViewDomains.setHeaderLabel("Files/Domains/Apps") standardFiles = QtGui.QTreeWidgetItem(None) standardFiles.setText(0, "Standard files") self.ui.treeViewDomains.addTopLevelItem(standardFiles) for elementName in ['Manifest.plist', 'Info.plist', 'Status.plist']: newItem = QtGui.QTreeWidgetItem(standardFiles) newItem.setText(0, elementName) newItem.setText(1, "X") self.ui.treeViewDomains.addTopLevelItem(newItem) self.cursor.execute("SELECT DISTINCT(mbdomain_type) FROM indice") domain_types = self.cursor.fetchall() for domain_type_u in domain_types: domain_type = str(domain_type_u[0]) newDomainFamily = QtGui.QTreeWidgetItem(None) newDomainFamily.setText(0, domain_type) self.ui.treeViewDomains.addTopLevelItem(newDomainFamily) # show new domain family in main view QtGui.QApplication.processEvents() query = "SELECT DISTINCT(mbapp_name) FROM indice WHERE mbdomain_type = ? ORDER BY mbdomain_type" self.cursor.execute(query, (domain_type,)) domain_names = self.cursor.fetchall() for domain_name_u in domain_names: domain_name = str(domain_name_u[0]) if (len(domain_names) > 1): newDomain = QtGui.QTreeWidgetItem(newDomainFamily) newDomain.setText(0, domain_name) self.ui.treeViewDomains.addTopLevelItem(newDomain) rootNode = newDomain else: rootNode = newDomainFamily # query = "SELECT path, mbfile_path, mbfile_name, size, fileid, mbfile_type FROM indice WHERE mbdomain_type = ? AND mbapp_name = ? ORDER BY mbfile_path, mbfile_name" query = "SELECT mbfile_path, mbfile_name, size, id, mbfile_type FROM indice WHERE mbdomain_type = ? AND mbapp_name = ? ORDER BY mbfile_path, mbfile_name" self.cursor.execute(query, (domain_type, domain_name)) nodes = self.cursor.fetchall() pathToNode = {'': rootNode} for nodeData in nodes: path = str(nodeData[0]) # finding parent directory lookup = path missing = collections.deque() dirNode = None while dirNode is None: dirNode = pathToNode.get(lookup, None) if dirNode is None: lookup, sep, component = lookup.rpartition('/') missing.appendleft(component) # creating parent directory if neccesary for component in missing: newPath = QtGui.QTreeWidgetItem(dirNode) newPath.setText(0, component) newPath.setToolTip(0, component) self.ui.treeViewDomains.addTopLevelItem(newPath) dirNode = newPath #lookup = posixpath.join(lookup, component) lookup = path pathToNode[lookup] = newPath try: file_name = str(nodeData[1].encode("utf-8")) except: file_name = nodeData[1] if (nodeData[2]) < 1024: file_dim = str(nodeData[2]) + " b" else: file_dim = str(nodeData[2] / 1024) + " kb" file_id = int(nodeData[3]) file_type = str(nodeData[4]) if file_type == 'd': newFile = dirNode else: newFile = QtGui.QTreeWidgetItem(newPath) self.ui.treeViewDomains.addTopLevelItem(newFile) newFile.setText(0, file_name) newFile.setToolTip(0, file_name) newFile.setText(2, str(file_dim)) newFile.setText(1, file_type) newFile.setText(3, str(file_id)) newFile.setText(4, domain_type) newFile.setText(5, domain_name) rawFiles = QtGui.QTreeWidgetItem(None) rawFiles.setText(0, "Raw files") self.ui.treeViewDomains.addTopLevelItem(rawFiles) # query = "SELECT mbfile_path, mbfile_name, size, id, mbfile_type FROM indice ORDER BY mbfile_path, mbfile_name" query = "SELECT domain, path, size, id, mbfile_type FROM indice ORDER BY domain, path" self.cursor.execute(query) nodes = self.cursor.fetchall() for nodeData in nodes: domain_name = str(nodeData[0]).replace("-", "/", 1) + "/" + str(nodeData[1]) newFile = QtGui.QTreeWidgetItem(rawFiles) self.ui.treeViewDomains.addTopLevelItem(newFile) if (nodeData[2]) < 1024: file_dim = str(nodeData[2]) + " b" else: file_dim = str(nodeData[2] / 1024) + " kb" file_id = int(nodeData[3]) file_type = str(nodeData[4]) newFile.setText(0, domain_name) newFile.setToolTip(0, domain_name) newFile.setText(2, str(file_dim)) newFile.setText(1, file_type) newFile.setText(3, str(file_id)) self.ui.statusbar.removeWidget(progressBar) self.activateMenu(True) return True