Package: iOSbackup
iOSbackupA Python 3 class that reads and extracts files from apassword-encrypted iOS backupcreated by iTunes on Mac and Windows.
Initial support for unencrypted backups has been aded since version 0.9.923.
Tested compatibility since iOS 10 up to current iOS 15.You will need your backup password to decrypt the backup files, this is the password iTunes asks when it is configured to do encrypted backups. This password can be found on macOS’ Keychain Access app, underloginkeychain, entryiOS Backup(update: newer macOS apparently doesn’t store it in KayChain anymore).You should always prefer encrypted backups because they are more secure and include more files from your device. Non-encrypted backups do not backup files as Health app database and other preciosities.DonationThis software is essential for advanced device forensic activities or to anyone in need to dominate and extract full data from an iOS device.Please consider donation of any amount in Bitcoin or Ethereum:Bitcoin donation: bc1qerzyzwdnsmpfdkl3lcjgm3rhvvy7svy0p89ndjEthereum donation: 0x098dADeDDf14382F19d4F5d989fD8734376B0224Thank you in advanceInstallationpip3installiOSbackup--userOn macOS, get native Python 3 from Apple with commandxcode-select --install. Read myguide to install Apple official Python 3 distributionfor more details.iOSbackuprequires other two packages:biplistandpycryptodomethat will beinstalled automatically bypip.pycryptodomehas an API compatible with olderpycrypto, which should also work withiOSbackup. Butpycryptodomeis more well maintained and easier to install on Windows and macOS.UsageGet list of backups available on your computer>>>fromiOSbackupimportiOSbackup>>>iOSbackup.getDeviceList()[{'udid':'00456030-000E4412342802E','name':'mobileavi','ios':'13.2.3','serial':'DNPPQRS0N4RW','type':'iPhone12,3','encrypted':True},{'udid':'00654030-01234412342802E','name':'ipad','ios':'13.1.3','serial':'DABCRS0N4RW','type':'iPad10,1','encrypted':True}]Open a device backupWith your password (a slow and compute-intensive task):>>>b=iOSbackup(udid="00456030-000E4412342802E",cleartextpassword="mypassword")Instead of a clear text password, use a derived key that can be seen into the instantiated object:>>>b=iOSbackup(udid="00456030-000E4412342802E",cleartextpassword="mypassword")>>>print(b)…decryptionKey:dd6b6123494c5dbdff7804321fe43ffe1babcdb6074014afedc7cb47f351524…From now on use your derived key instead of your clear text password to not expose it and because it is much faster:>>>b=iOSbackup(udid="00456030-000E4412342802E",derivedkey="dd6b6123494c5dbdff7804321fe43ffe1babcdb6074014afedc7cb47f351524")Linux virtual machine accessing iOS backup on a macOS hostForcing a backup folder, useful when reading backups on Linux, where there is no standard for backup folders:>>>b=iOSbackup(udid="00456030-000E4412342802E",cleartextpassword="mypassword",backuproot='/media/sf_username/Library/Application Support/MobileSync/Backup')For this to work on a Linux virtual machine accessing a VirtualBox-shared folder, you'll have to grant full disk access to your hypervisor (VirtualBox etc).
On macOS, go toSystem Preferences➔Security & Privacy➔Privacy➔Full Disk Accessand enable access to your hypervisor (VirtualBox etc).
The hypervisor and VM will have to be restarted for the new setting to be effective.You can also copy your device's backup folder, from a Windows or macOS computer, to a Linux computer, and then use this class on Linux to decrypt and read it.iTunes default backup folders on Windows and macOSFiles app (formerly iTunes) on macOS stores backups of associated devices under~/Library/Application Support/MobileSync/Backup.
iTunes on Windows stores backups of associated devices under%HOME%\Apple Computer\MobileSync\BackupGet some info about device on the backupInformation about device, model, serial number, its SIMs, iOS version etc can be inspected in
multiple places from backup basic catalog files (plist files), even before diving into its
vast amount of databases and other encrypted files.b=iOSbackup(...)# Device infoinfoKeys=[# This is a non-exaustive list of interesting info, but there are more...'Build Version','Device Name','Display Name','GUID','ICCID','ICCID 2','IMEI','IMEI 2','Last Backup Date','MEID','Phone Number','Phone Number 2','Product Name','Product Type','Product Version','Serial Number','Target Identifier','Target Type','Unique Identifier','macOS Build Version','macOS Version']foriininfoKeys:print(f'{i}:{b.info[i]}')# Other ways to get device infob.manifest['Lockdown']['DeviceName']# device name or hostnameb.manifest['Lockdown']['ProductVersion']# iOS version as 14.0.1, see Version column of https://en.wikipedia.org/wiki/IOS_version_history#Version_historyb.manifest['Lockdown']['BuildVersion']# iOS version as 18A393, see Build column of https://en.wikipedia.org/wiki/IOS_version_history#Version_historyb.manifest['Lockdown']['SerialNumber']# device serial numberb.manifest['Lockdown']['ProductType']# device type as iPhone12,3, see columns Identifier of https://www.theiphonewiki.com/wiki/Modelsb.udid# UDID of the deviceb.uuid.hex()# UUID of device# Backup infob.backupRoot# backup root folderb.date# UTC date and time of this backupb.getDecryptionKey()# password-derived key of backupb.manifest['IsEncrypted']# is it an encrypted backup?b.manifest['WasPasscodeSet']# backup has a passcode?b.status# Basic list of installed apps, probably used by iTunes to easily display things to usersb.info['Applications'].keys()# Apps iconspng_data=b.info['Applications']['com.burbn.instagram']['PlaceholderIcon']# Dive into device contentb.manifest['ManifestKey'].hex()# manifest DB decryption keyb.manifest['Applications']# list of installed appsb.manifestDB# decrypted copy of Manifest.db SQLite databaseGet a list of backed-up files:Info available in theManifest.dbwhich relates backup file hash to semi-full path of file into the device, plus file backup domain, plus some file metadata.>>>b.getBackupFilesList()[{'name':'','backupFile':'abfbc8747bfbb373e2b08ce67b1255ffda4e1b91','domain':'AppDomain-4GU63N96WE.com.p5sys.jumpdesktop','relativePath':'','flags':2,'file':b'bplist00\xd4...'},{'name':'Documents','backupFile':'ec0c1b379560bb5ccc81ee783538fd51cfd97461','domain':'AppDomain-4GU63N96WE.com.p5sys.jumpdesktop','relativePath':'Documents','flags':2,'file':b'bplist00\xd4...'},{'name':'Documents/Servers','backupFile':'a735380eade71b48f0fe27d38a283aacd8ed8372','domain':'AppDomain-4GU63N96WE.com.p5sys.jumpdesktop'},{'name':'Documents/extensions','backupFile':'c08f725cc39ec819ab7ced3b056f4e0630ead09f','domain':'AppDomain-4GU63N96WE.com.p5sys.jumpdesktop'},{'name':'Library','backupFile':'e60a6345697594c735e5a6ed86c0d57dad6a2176','domain':'AppDomain-4GU63N96WE.com.p5sys.jumpdesktop'},...]backupFileis the file name on your computer. Basically SHA1([Domain]/[FilePath]).nameis the original semi-complete path of file name in the device.domainis the file group this file is member, see bellow list of domains.fileis binary plist content with some file metadata.Or put it directly into a Pandas DataFrame for easier manipulation and searching:>>>importpandasaspd>>>backupfiles=pd.DataFrame(b.getBackupFilesList(),columns=['backupFile','domain','name'])With Pandas, display only list of files inHomeDomaingroup:>>>backupfiles[backupfiles['domain']=='HomeDomain']Get a decrypted copy of the call history SQLite database:ThegetFileDecryptedCopy()method creates a decrypted copy of requested file ontargetFolder/targetName.
IftargetFolderandtargetNamearen't given, a temporary file will be created.
The name of decrypted file (temporary or not) can be found in thedecryptedFilePathitem of returned dict, as seen below.>>>file=b.getFileDecryptedCopy(relativePath="Library/CallHistoryDB/CallHistory.storedata")>>>file{'decryptedFilePath':'HomeDomain~Library--CallHistoryDB--CallHistory.storedata','domain':'HomeDomain','originalFilePath':'Library/CallHistoryDB/CallHistory.storedata','backupFile':'5a4935c78a5255723f707230a451d79c540d2741','size':1228800}Fetch call records from the decrypted copy of call history database, using a SQL query.>>>calls=sqlite3.connect(file['decryptedFilePath'])>>>calls.row_factory=sqlite3.Row>>>calllog=calls.cursor().execute(f"SELECT * FROM ZCALLRECORD ORDER BY ZDATE DESC").fetchall()Restore Entire Folder ContainingPhotosand their MetadataThis content is located in theMediafolder ofCameraRollDomaindomain.
This example will exclude videos from restoration.>>>b.getFolderDecryptedCopy('Media',targetFolder='restored-photos',includeDomains='CameraRollDomain',excludeFiles='%.MOV')Restore an entire domainHere we restore all files ofWirelessDomainin a hierarchy starting at local directory:>>>b.getFolderDecryptedCopy(includeDomains='WirelessDomain',)Here we restore all files ofHomeDomainin a hierarchy starting at foldermy-folder:>>>b.getFolderDecryptedCopy(includeDomains='HomeDomain',targetFolder='my-folder',)To restore all backed up data files of an app, search for its domain name (see below) and use this technique.Get List of All Installed Apps>>>apps=list(b.manifest['Applications'].keys())>>>apps['group.com.apple.Maps','group.net.whatsapp.family','it.joethefox.XBMC-Remote','com.google.GoogleMobile.NotificationContentExtension','group.com.dendrocom.uniconsole',...]Get List of All Apps, Groups and Plugins with “whatsapp” In Their Name>>>[sforsinlist(b.manifest['Applications'].keys())if"whatsapp"ins]['group.net.whatsapp.WhatsApp.shared','net.whatsapp.WhatsApp.ShareExtension','group.net.whatsapp.WhatsAppSMB.shared','net.whatsapp.WhatsApp.NotificationExtension','net.whatsapp.WhatsApp.Intents','net.whatsapp.WhatsApp.TodayExtension','net.whatsapp.WhatsApp.IntentsUI','group.net.whatsapp.WhatsApp.private','net.whatsapp.WhatsApp.ServiceExtension','net.whatsapp.WhatsApp']Restore All Files of Apps, Groups and Plugins Matching “whatsapp”I had to use previous method to find the list of app IDs and see that “whatsapp” is a good word to match them.
Each app component has its own backup domain prefixed byAppDomain,AppDomainGrouporAppDomainPlugin.
So we'll iterate over all possibilities of fabricated domain names withgetFolderDecryptedCopy().foridin[sforsinlist(b.manifest['Applications'].keys())if"whatsapp"ins]:forprefixin["AppDomain","AppDomainGroup","AppDomainPlugin"]:b.getFolderDecryptedCopy(includeDomains=prefix+'-'+id)Other apps might have a less intuitive name. For example, Telegram can be matched by “telegra” (without ‘m’):foridin[sforsinlist(b.manifest['Applications'].keys())if"telegra"ins]:forprefixin["AppDomain","AppDomainGroup","AppDomainPlugin"]:b.getFolderDecryptedCopy(includeDomains=prefix+'-'+id)Apple-native Python 3 Installation on MacsFollow my guide athttps://avi.alkalay.net/2019/12/macos-jupyter-data-science-no-anaconda.htmlBasically use commandxcode-select --installto get Python 3 installed and updated by Apple on your Mac.List of DomainsDomainContainsAppDomain-...Backup of each installed app's filesAppDomainGroup-...Backup of each installed app's filesAppDomainPlugin-...Backup of each installed app's filesCameraRollDomainPhotosDatabaseDomainHealthDomainHealth app databasesHomeDomainMany interesting databases, such as contacts and call historyHomeKitDomainInstallDomainKeyboardDomainKeychainDomainManagedPreferencesDomainMediaDomainMobileDeviceDomainRootDomainSysContainerDomain-com.apple.Preferences.SettingsSpotlightIndexExtensionSysContainerDomain-com.apple.Preferences.indexSettingsManifestsSysContainerDomain-com.apple.accessibility.AccessibilityUIServerSysContainerDomain-com.apple.adidSysContainerDomain-com.apple.akdSysContainerDomain-com.apple.appstoredSysContainerDomain-com.apple.apsdSysContainerDomain-com.apple.backboarddSysContainerDomain-com.apple.fairplayd.H2SysContainerDomain-com.apple.geodSysContainerDomain-com.apple.icloud.findmydevicedSysContainerDomain-com.apple.icloud.ifccdSysContainerDomain-com.apple.icloud.searchpartydSysContainerDomain-com.apple.lsdSysContainerDomain-com.apple.lskddSysContainerDomain-com.apple.metrickitdSysContainerDomain-com.apple.mobilesafariBookmarks and cookies ?SysContainerDomain-com.apple.springboardSysSharedContainerDomain-systemgroup.com.apple.AssetCacheServices.diskCacheSysSharedContainerDomain-systemgroup.com.apple.DiagnosticsKitSysSharedContainerDomain-systemgroup.com.apple.ReportMemoryExceptionSysSharedContainerDomain-systemgroup.com.apple.VideoSubscriberAccountSysSharedContainerDomain-systemgroup.com.apple.WiFiAssistSysSharedContainerDomain-systemgroup.com.apple.bluetoothSysSharedContainerDomain-systemgroup.com.apple.cfpreferences.managedSysSharedContainerDomain-systemgroup.com.apple.configurationprofilesSysSharedContainerDomain-systemgroup.com.apple.coreanalyticsSysSharedContainerDomain-systemgroup.com.apple.icloud.findmydevice.managedSysSharedContainerDomain-systemgroup.com.apple.icloud.fmipcore.MockingContainerSysSharedContainerDomain-systemgroup.com.apple.icloud.ifccdSysSharedContainerDomain-systemgroup.com.apple.icloud.searchpartyd.sharedsettingsSysSharedContainerDomain-systemgroup.com.apple.itunesu.sharedSysSharedContainerDomain-systemgroup.com.apple.lsdSysSharedContainerDomain-systemgroup.com.apple.lsd.iconscacheSysSharedContainerDomain-systemgroup.com.apple.lskdrlSysSharedContainerDomain-systemgroup.com.apple.media.books.managedSysSharedContainerDomain-systemgroup.com.apple.media.shared.booksSysSharedContainerDomain-systemgroup.com.apple.mobile.installationhelperlogsSysSharedContainerDomain-systemgroup.com.apple.mobilegestaltcacheSysSharedContainerDomain-systemgroup.com.apple.nsurlstoragedresourcesSysSharedContainerDomain-systemgroup.com.apple.ondemandresourcesSysSharedContainerDomain-systemgroup.com.apple.osanalyticsSysSharedContainerDomain-systemgroup.com.apple.sharedpcloggingSystemPreferencesDomainTonesDomainWirelessDomainInteresting FilesBackup fileDomainFile nameContainsed1f8fb5a948b40504c19580a458c384659a605eWirelessDomainLibrary/Databases/CellularUsage.dbTablesubscriber_infoapparently contains all SIM phone numbers ever inserted in the phone since about iOS 11 or 12. Data here is related toLibrary/Preferences/com.apple.commcenter.plist.0d609c54856a9bb2d56729df1d68f2958a88426bWirelessDomainLibrary/Databases/DataUsage.sqliteA rich database that apparently contains app WWAN usage through time. Chack tablesZPROCESSandZLIVEUSAGE.1570a95f5dc7f4cd6b54bc17c427eda95288b8faHomeDomainLibrary/SpringBoard/LockVideo.movVideo used as background on lock screen.HomeDomainLibrary/Passes/Cards/*Wallet passes and items8d0167b67f664a3816b4c00115c2dfa6a8f81388WirelessDomainLibrary/Preferences/com.apple.AppleBasebandManager.Statistics.plistApparently contains times of last boot and restores.dafec408e48be2700704dd3e763014c39f6de6b3WirelessDomainLibrary/Preferences/com.apple.AppleBasebandManager.plist9329979c8298f9cd3fb110fa387570a8b957e912WirelessDomainLibrary/Preferences/com.apple.CommCenter.counts.plistHasCellularBytesRecvedandCellularBytesSent3dec38ca46c9e37ffebacf2611463eb47a65eb09WirelessDomainLibrary/Preferences/com.apple.commcenter.audio.plist7e5f642f6da5e2345c0893bdf944da9c53902756WirelessDomainLibrary/Preferences/com.apple.commcenter.callservices.plistbfecaa9c467e3acb085a5b312bd27bdd5cd7579aWirelessDomainLibrary/Preferences/com.apple.commcenter.plistCellular network informations and configurations, including all ever inserted SIM and eSIM cards, their phone numbers and nicknames as configured under Settings➔Celular. Data here is related toLibrary/Databases/CellularUsage.db160600e9c2e408c69e4193d325813a2a885bce2aWirelessDomainLibrary/Preferences/com.apple.ipTelephony.plist12b144c0bd44f2b3dffd9186d3f9c05b917cee25CameraRollDomainMedia/PhotoData/Photos.sqlitePhoto library data, albums, tagged faces, moments, places, geolocations, date and times, formats etc..CameraRollDomainMedia/DCIM/*APPLEOriginal master photos/videos taken by your camera or imported through AirDrop etc.CameraRollDomainMedia/PhotoData/Mutations/DCIM/*APPLEEdited version of photos/videos.HomeDomainLibrary/Mobile Documents/iCloud~...Apps documents on iCloud.HomeDomainLibrary/Mobile Documents/com~apple~CloudDocs/...Documents folder on iCloud5a4935c78a5255723f707230a451d79c540d2741HomeDomainLibrary/CallHistoryDB/CallHistory.storedataCall History database with only the last 600 calls31bb7ba8914766d4ba40d6dfb6113c8b614be442HomeDomainLibrary/AddressBook/AddressBook.sqlitedbUser contacts and address book. TableABPersonis the central one with facts about contact creation and modification, whileABMultiValue*tables contain contact details.cd6702cea29fe89cf280a76794405adb17f9a0eeHomeDomainLibrary/AddressBook/AddressBookImages.sqlitedbContact photos9db3e5a6f1672cc306cd785809811e79cc43a2f8HomeDomainLibrary/AddressBook/backup/AddressBook.sqlitedb2a87d5bcdb9753f1462dd1e929b17e6a971c5b01HomeDomainLibrary/AddressBook/backup/AddressBookImages.sqlitedb1a0e7afc19d307da602ccdcece51af33afe92c53HomeDomainLibrary/Safari/History.db.MediaDomainLibrary/SMS/Attachments/*.MediaDomainLibrary/SMS/StickerCache/*..Library/Caches/locationd/consolidated.dbApparently list of known iBeacons