macOS Download Forensics: An Investigation Walkthrough
A synthetic macOS intrusion worked through with Quarantine Parser: timeline, a recovered deleted row, a Gatekeeper rejection and an AppleDouble on USB.
TL;DR. This walkthrough uses the site's synthetic sample: macOS laptop FIN-MBP-03, user dana.whitlock, 14 September 2026. In a few minutes, quarantine data shows a tool archive from a file-sharing host whose database row was deleted and recovered, a paste download, a fake LaunchAgent carrying the archive's quarantine value, a helper with its quarantine stripped, a disk image whose app Gatekeeper rejected, and a finance spreadsheet that reached a USB volume. It also shows where quarantine data stops.
Everything below is fictional: hosts, people and files do not exist, and every domain ends in .example.
The scenario
The case continues the fictional FIN-WKS-07 / svc_backup intrusion. An attacker holding a stolen session is active on dana.whitlock's finance laptop between about 10:05 and 10:50 UTC. The question: what was downloaded, what was staged, and did anything leave?
1. Load the sample
Open the home page at /en and choose Try a sample. Parsing runs in your browser; nothing is uploaded. The Sources view lists what was loaded and how each file was parsed. The baseline covers 18 August to 15 September: intranet and document-server reports saved with Safari, MeetClient-5.2.pkg and MeetClient-5.3.pkg from downloads.meet.example with Chrome (5.3 approved by the user, flags 00c3), Mail attachments from ap@vendor.example and priya.raman@fin.example, Messages attachments and one AirDrop received through sharingd.
2. Set the incident window
Set the time range to 10:00–10:55 UTC on 2026-09-14, by typing it or by dragging on the density strip. The range applies to every view and export and is kept in the URL hash, so the link reproduces your view. The baseline drops away and the Findings view lists leads for this window only.
3. Read the timeline
The Timeline shows three downloads in the window:
- 10:07:12, Safari,
https://files.example/s/8f3k2/tools.zip, originhttps://files.example/s/8f3k2; - 10:12:05, Chrome,
https://paste.example/raw/Zx81; - 10:26:30, Safari,
https://transfer.example/d/Qm7/sync-agent.dmg.
The Domains view shows none of these hosts in the baseline. The findings flag them as file-sharing, paste and transfer hosts, and flag archives and disk images from rarely seen domains. These are leads, not verdicts: finance staff do use transfer services.
4. The recovered files.example row
The tools.zip row is marked as recovered. In the scenario, the row was deleted from the database with sqlite3 at about 10:48. The tool's own SQLite reader found the record in free space in the table page and rebuilt it. The finding says "possible deletion or clearing". The recovery article explains the carving.
The recovered QuarantineEventsV2 row still joins by UUID: the Files view shows five files carrying its identifier, among them the three files Archive Utility extracted (tools/README.txt, tools/updater.sh, tools/com.example.updater.plist) with the same quarantine value. Deleting the row did not remove the attributes, and the attributes put the row back in context.
5. The paste.example text
The Chrome download lands as ~/Downloads/Zx81.txt. A raw paste fetched during an intrusion can be a script or a list of commands, but the quarantine data only proves the download. Collect and read the file itself.
6. The LaunchAgent copy
A copy of com.example.updater.plist sits in ~/Library/LaunchAgents/. It still carries the tools.zip quarantine value, UUID included, so it is one of the five joined files. The finding "downloaded file in an autostart folder" points at it. The quarantine value tells you where the plist came from, not when it was copied into LaunchAgents; date that step with other artifacts.
7. The stripped sync-helper
~/Library/Caches/.sync/sync-helper has a WhereFroms pointing at files.example, but no quarantine attribute. The tool raises "WhereFroms but no quarantine attribute (possible xattr -d)". In the scenario, the attribute was stripped. In a real case, weigh the alternatives discussed in kMDItemWhereFroms vs quarantine before calling it anti-forensics.
8. The transfer.example disk image and the Gatekeeper rejection
Thirty-five seconds after the disk image download, a .LastGKReject record shows that Gatekeeper refused /Volumes/Sync Agent/SyncAgent.app at 10:27:05, with XProtectMalwareType 2 (reported as unsigned app/program; the mapping is not documented by Apple). The volume name matches the image; the link is by name and time. See .LastGKReject as evidence for the chain.
9. Q3_forecast.xlsx on the EXFIL volume
Widen the range to the whole dataset for this step. Q3_forecast.xlsx was a Mail attachment received on 28 August. The sample includes its AppleDouble file ._Q3_forecast.xlsx from the exFAT USB volume EXFIL. That file still holds the Mail quarantine value and the WhereFroms, which ties the copy on the stick to the original attachment.
Timeline (UTC, 2026-09-14)
| Time | Source | Event |
|---|---|---|
| 10:07:12 | Recovered database row, five joined files | Safari downloads tools.zip from files.example |
| 10:12:05 | Database row, attribute | Chrome downloads Zx81.txt from paste.example |
| not dated | Attribute on the LaunchAgent copy | com.example.updater.plist in ~/Library/LaunchAgents/ |
| not dated | WhereFroms, no quarantine | sync-helper under ~/Library/Caches/.sync/ |
| 10:26:30 | Database row | Safari downloads sync-agent.dmg from transfer.example |
| 10:27:05 | .LastGKReject | Gatekeeper rejects SyncAgent.app, type 2 |
| about 10:48 | Free-space recovery | files.example row deleted with sqlite3 |
| not dated | AppleDouble on EXFIL | Q3_forecast.xlsx present on the USB volume |
Export the timeline and files as CSV, JSON or a Timesketch-ready CSV; exports follow the selected range.
What quarantine data cannot show
Three steps of this scenario leave no quarantine trace:
- The Terminal launch used to run commands;
- the TCC Full Disk Access grant;
- the USB copy itself.
Pivot to other artifacts: unified logs for process and policy activity, TCC.db for privacy permissions, and FSEvents for file-system changes such as the write to the EXFIL volume. Also collect the files themselves: Zx81.txt, updater.sh, the LaunchAgent plist and sync-helper.
For collection commands, see collecting quarantine events, and for a condensed reference, the quarantine events cheat sheet on our sister site.
Frequently asked questions
Is the FIN-MBP-03 case real?
No. Host, user, domains and files are fictional and the data is synthetic. All domains use the reserved .example suffix. The sample exists to show how the artifacts fit together.
Can quarantine data show that a file was copied to USB?
Not directly. It shows where a file came from. In the sample, the AppleDouble file on the EXFIL volume shows that Q3_forecast.xlsx reached that volume with its attributes, but the copy itself has to be dated with other artifacts such as FSEvents.
Why was the files.example row missing from the live database?
In the scenario it was deleted with sqlite3 at about 10:48 UTC. Quarantine Parser recovered it by carving free space in the table page. Recovery depends on SQLite settings and later writes, so a missing recovery would not have proven anything.