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 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 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 getBackupKeyBag(backupfolder, passphrase): manifest = readPlist(backupfolder + "/Manifest.plist") kb = Keybag(manifest["BackupKeyBag"].data) if kb.unlockBackupKeybagWithPasscode(passphrase): print "BackupKeyBag unlock OK" return kb else: return None
def decrypt_backup3(backupfolder, outputfolder, passphrase): auth_key = None manifest = readPlist(backupfolder + "/Manifest.plist") if manifest["IsEncrypted"]: manifest_data = manifest["Data"].data authdata = manifest["AuthData"].data pkbdf_salt = authdata[:8] iv = authdata[8:24] key = PBKDF2(passphrase, pkbdf_salt, iterations=2000).read(32) data = AESdecryptCBC(authdata[24:], key, iv) auth_key = data[:32] if hashlib.sha1(auth_key).digest() != data[32:52]: print "wrong auth key (hash mismatch) => wrong passphrase" return print "Passphrase seems OK" for mdinfo_name in glob.glob(backupfolder + "/*.mdinfo"): mddata_name = mdinfo_name[:-7] + ".mddata" mdinfo = readPlist(mdinfo_name) metadata = mdinfo["Metadata"].data if mdinfo["IsEncrypted"]: metadata = decrypt_blob(metadata, auth_key) metadata = BPlistReader.plistWithString(metadata) print metadata["Path"] filedata = read_file(mddata_name) if mdinfo["IsEncrypted"]: filedata = decrypt_blob(filedata, auth_key) filename = re.sub(r'[:|*<>?"]', "_", metadata["Path"]) makedirs(outputfolder + "/" + os.path.dirname(filename)) write_file(outputfolder + "/" + filename, filedata)
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 decrypt_backup3(backupfolder, outputfolder, passphrase): auth_key = None manifest = readPlist(backupfolder + "/Manifest.plist") if manifest["IsEncrypted"]: manifest_data = manifest["Data"].data authdata = manifest["AuthData"].data pkbdf_salt = authdata[:8] iv = authdata[8:24] key = PBKDF2(passphrase, pkbdf_salt, iterations=2000).read(32) data = AESdecryptCBC(authdata[24:], key, iv) auth_key = data[:32] if hashlib.sha1(auth_key).digest() != data[32:52]: print ("wrong auth key (hash mismatch) => wrong passphrase") return print ("Passphrase seems OK") for mdinfo_name in glob.glob(backupfolder + "/*.mdinfo"): mddata_name = mdinfo_name[:-7] + ".mddata" mdinfo = readPlist(mdinfo_name) metadata = mdinfo["Metadata"].data if mdinfo["IsEncrypted"]: metadata = decrypt_blob(metadata, auth_key) metadata = BPlistReader.plistWithString(metadata) print metadata["Path"] filedata = read_file(mddata_name) if mdinfo["IsEncrypted"]: filedata = decrypt_blob(filedata, auth_key) filename = re.sub(r'[:|*<>?"]', "_", metadata["Path"]) makedirs(outputfolder + "/" + os.path.dirname(filename)) write_file(outputfolder + "/" + filename, filedata)
def do_plist(self, p): d = None data = self.volume.readFile(self.get_path(p), returnString=True) if data: d = parsePlist(data) pprint(d) else: try: d = readPlist(p) if d: pprint(d) except: pass if d and d.has_key("_MKBIV"): print "=>System keybag file" print "_MKBPAYLOAD: encrypted" print "_MKBIV: %s" % d["_MKBIV"].data.encode("hex") print "_MKBWIPEID: 0x%x (%s)" % (d["_MKBWIPEID"], ("%x"%(d["_MKBWIPEID"])).decode("hex"))
def __init__(self, filename): self.plist = readPlist(filename)
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 readInfo(backup_path): if not os.path.exists(backup_path + "/Info.plist"): #print "Manifest.plist not found" return None info = readPlist(backup_path + "/Info.plist") return info
def readManifest(backup_path): if not os.path.exists(backup_path + "/Manifest.plist"): return None manifest = readPlist(backup_path + "/Manifest.plist") return manifest
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
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 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(): key = "" keyfile = "" getkey = 0 opts,args = getopt.getopt(sys.argv[1:],"",["keyfile=","getkey"]); for o,a in opts: if o in ("--keyfile"): keyfile=a pass elif o in ("--getkey"): getkey=1 pass args.insert(0,sys.argv[0]) sys.argv=args if len(sys.argv)!=2: print "Usage: extract_encfiles.py (--keyfile keyfile) (--getkey) backupdir" sys.exit(0) backup_path = sys.argv[1] manifest = readPlist(backup_path + "/Manifest.plist") kb = Keybag(manifest["BackupKeyBag"].data) if not keyfile or getkey: password=getpass.getpass() else: password = '' if password: key=kb.getPasscodekeyFromPasscode(password,ios102=True) if getkey: if (len(key)==32): if keyfile: f=open(keyfile,"w") f.write(base64.b64encode(key)) f.close() else: print base64.b64encode(key) pass else: print "There was a problem extracting the key." pass sys.exit(0) pass f=open(keyfile,"r") key=base64.b64decode(f.read()) key=key[0:32]; kb.unlockWithPasscodeKey(key) manifest["password"] = password 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) manifest_db = ManifestDB(backup_path, key=manifest_key) manifest_db.keybag = kb for filename, mbfile in manifest_db.files.iteritems(): if (mbfile.domain=="HomeDomain"): if mbfile.relative_path in ("Library/SMS/sms.db","Library/AddressBook/AddressBook.sqlitedb"): mbfile.domain="." mbfile.relative_path=os.path.basename(mbfile.relative_path) if mbfile.relative_path=="sms.db": mbfile.relative_path="sms-1.db" pass if mbfile.relative_path=="AddressBook.sqlitedb": mbfile.relative_path="addresses.db" pass manifest_db._extract_file(filename,mbfile,"sms")