Purpose & Scope — ios-backup-forensic
A library repository, so this is the lighter Purpose & Scope form rather than a full product PRD (ADR-0003, fleet doc-naming conventions).
The problem
iOS device backups are among the most common mobile-evidence artifacts an
examiner meets, and until now no fleet tool could open one. 4n6mount
auto-detects filesystems, EWF/VMDK/AFF4 containers, AD1 and AFF4-Logical,
archives and memory dumps — but not the Apple backup format.
The gap bites hardest exactly where the evidence matters most. When a full-file-system extraction is unavailable — an agent that caps below the device's iOS version, a device state that blocks it — an extended logical acquisition is the remaining route, and it produces an encrypted iTunes-style backup. Pointed at one of those, every tool in the fleet reports
Manifest.db: file is not a database
because in an encrypted backup the manifest is itself AES-encrypted. The evidence is intact and unreadable.
Who this is for
- An examiner mounting a backup to browse it as a file tree, via
4n6mount. - A fleet analyzer that wants a specific artifact out of a backup — a messaging database, a preferences plist — without knowing anything about the backup format.
issen, correlating backup contents with other evidence.
What it does
ios-backup-core
- Opens a backup directory:
Manifest.plist,Status.plist,Info.plist. - Reads the
Manifest.dbFilestable into a typed file tree — domain, path, kind, size, mode, inode, timestamps, protection class. - Decrypts, for an encrypted backup: keybag → password-derived key → class keys → per-file keys → AES-CBC, with the manifest decrypted in memory.
- Reads any file's bytes on demand, truncated to the manifest-recorded length.
- Projects the whole thing as a logical container (
logical::LogicalView) shaped to drop intodisk_forensic::logical.
ios-backup-forensic
- Encryption state and device provenance, recorded even when nothing is wrong.
- Manifest↔blob integrity, both directions: a row with no blob, a blob with no row.
fileIDverified againstSHA1(domain + "-" + relativePath).- Expected domains that are absent, reported unrated (ADR-0006).
- Backup completeness from
Status.plist.
What it deliberately does not do
- No interpretation of file contents. A backup's
sms.dbis a SQLite database; reading it issqlite-forensic's job, and the messages inside are a parser's. This crate hands over bytes. - No password recovery. No wordlists, no GPU, no cracking. It derives a key from a password an examiner supplies and reports whether it worked.
- No writing. Read-only, in every path.
- No conclusions. Findings are observations in consistent-with language.
Planned next: a broader anomaly-reporting layer
The analyzer currently reports backup integrity — manifest/blob agreement,
the fileID invariant, encryption-state contradiction, completeness — plus
unrated domain-absence leads.
The next piece of work is to widen that into a fuller anomaly-reporting layer. Two references worth mining rather than re-deriving:
- MVT's module set, whose domain coverage is far broader than
EXPECTED_DOMAINS, which today is reasoned rather than measured. - The contradiction pattern itself — declaration versus effective state —
which generalises past encryption.
Status.plistversus the manifest,Info.plist's device identity versusManifest.plist'sLockdown, and the backup date versus the newest file mtime are all the same shape.
Scope boundary to hold: this analyzer reports what is observable in the backup.
IOC matching and threat intelligence belong upstream in issen, not here.
Non-goals for now
- An
iosbackup4n6CLI. The consumer is4n6mount; a standalone triage binary can be added if it is wanted, and the reader/analyzer split means nothing has to move when it is. - iCloud backups. A different acquisition path and a different keybag kind.
- Writing or re-encrypting a backup.
Success criteria
4n6mountmounts an encrypted iOS backup given a password, with no format-specific branch in any consumer.- Byte-exact reads, verified against an independent implementation.
- Never panics on malformed or hostile input.
- A wrong password is always reported as a wrong password, never as an empty or corrupt backup.
Where each of these currently stands is in validation.md,
including the one that is not yet met.