Skip to content

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.

Published on 6 min read

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, origin https://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)

TimeSourceEvent
10:07:12Recovered database row, five joined filesSafari downloads tools.zip from files.example
10:12:05Database row, attributeChrome downloads Zx81.txt from paste.example
not datedAttribute on the LaunchAgent copycom.example.updater.plist in ~/Library/LaunchAgents/
not datedWhereFroms, no quarantinesync-helper under ~/Library/Caches/.sync/
10:26:30Database rowSafari downloads sync-agent.dmg from transfer.example
10:27:05.LastGKRejectGatekeeper rejects SyncAgent.app, type 2
about 10:48Free-space recoveryfiles.example row deleted with sqlite3
not datedAppleDouble on EXFILQ3_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.

Related articles