ExecutionUSB & devicesFile access
Mounted Disk Images on macOS: DMG, ISO and App Translocation
How to prove a DMG or ISO was downloaded, mounted and used on a Mac: quarantine, Unified Logs, FSEvents, App Translocation paths and Spotlight.
- Location
- /Volumes/<name>/ (mount point), plus logs and per-user caches
- Proves
- That a disk image was mounted, under which volume name, which apps were run from it and where it came from
- Timestamps
- Unified Log entries in UTC; FSEvents event IDs; file system times of the image and translocation folders
- Access
- root for logs and /private/var/folders; owning user for Downloads
- Retention
- Log events follow rotation; the image file, quarantine and FSEvents records persist longer
- Collection
- log collect, UAC, mac_apt, ditto
Tools
Compare all tools- Hash ExtractorIn browser
- hdiutilCLI · built into macOS
- logCLI · built into macOS
- FSEventsParserCLI · open source
- mac_aptCLI · open source
- xattrCLI · built into macOS
What it is
Disk images (.dmg, .sparseimage, .sparsebundle, .iso, .img) are the standard way to ship Mac software, and the most common delivery vehicle for Mac malware and stealers. When a user double-clicks one, DiskImageMounter (or hdiutil attach on the command line) attaches it as a virtual disk and mounts its volume under /Volumes/.
There is no single "mounted images" database on macOS. You prove a mount by joining several artifacts, much as on Windows with mounted ISO/VHD files.
Where it lives
| Evidence | Where | What it gives |
|---|---|---|
| The image file | ~/Downloads/, mail attachment folders, /tmp | Hash, content, com.apple.quarantine |
| Download record | QuarantineEventsV2 | Source URL and agent for the image |
| Attach events | Unified Logs, DiskImages processes (diskimagesiod, diskimages-helper on older releases) and diskarbitrationd | Image path, device node, mount time |
| Mount point activity | FSEvents on the boot volume (/Volumes/<name> created and removed) and in the image's own .fseventsd | Volume name, files touched |
| Apps run from the image | App Translocation: /private/var/folders/<xx>/<random>/T/AppTranslocation/<UUID>/d/<App>.app | Quarantined apps launched from read-only media |
| Execution | Gatekeeper / XProtect assessments, KnowledgeC app usage | Which binary ran |
| Recent items | Disk Utility and Finder preferences on some releases | Previously opened images |
What it proves
- Where the image came from (quarantine
LSQuarantineDataURLStringand agent) and when it was downloaded. - That it was attached: the image path and the
/dev/diskNnode in the Unified Logs, and the volume name created under/Volumes. - That an app was launched from it: an App Translocation path in logs, crash reports or process listings means the quarantined app ran straight from the image (or another read-only or quarantined location).
- What was on it, from FSEvents in the image's own
.fseventsd, Spotlight and QuickLook entries under/Volumes/<name>/.
Key fields
| Item | Meaning |
|---|---|
/Volumes/<name> | Volume name from the image; stealer campaigns reuse names that imitate the real app |
AppTranslocation/<UUID>/d/ | Randomised read-only mirror created by Gatekeeper path randomisation (10.12+) |
com.apple.quarantine on the .dmg | Flags, timestamp, agent name, event UUID linking to QuarantineEventsV2 |
hdiutil imageinfo | Format (UDZO, UDRO, ULFO, UDIF sparse), encryption, partition scheme |
| Code signature of the app inside | Team ID, notarisation (spctl -a -vv) |
Timestamps
Unified Log entries carry UTC instants. FSEvents records are ordered by event ID with no timestamp; bracket them with dated events such as log entries and the .fseventsd file times (see the FSEvents guide). The birth time of an AppTranslocation/<UUID> folder marks the first launch from the image in that session.
Retention
- Translocation folders live in the per-user temporary area and are cleaned at logout or reboot on most releases, so they are mostly a live-response artifact; their paths survive longer in logs and crash reports.
- Unified Log events follow rotation.
- The downloaded image and its quarantine record usually outlive everything else, unless the user deleted it; check the Trash.
Collection
# Live: what is attached right now
hdiutil info > ./case/hdiutil_info.txt
mount > ./case/mount.txt
# Images and their attributes
xattr -l ~/Downloads/*.dmg > ./case/dmg_xattr.txt
sudo log collect --output ./case/host.logarchive
Collect /private/var/folders on a live system if you need translocation folders. Image any still-mounted volume separately: it is evidence in its own right.
Parsing
# Image attach and mount activity
log show --archive host.logarchive --timezone UTC --style syslog \
--predicate 'process BEGINSWITH "diskimages" OR (process == "diskarbitrationd"
AND eventMessage CONTAINS "/Volumes/")'
# Apps launched from translocated paths
log show --archive host.logarchive --timezone UTC \
--predicate 'eventMessage CONTAINS "AppTranslocation"'
# Offline inspection of a recovered image
hdiutil imageinfo sample.dmg
hdiutil attach -readonly -nobrowse -noverify -mountpoint /tmp/evid sample.dmg
Process names and message wording for the DiskImages framework change between releases (the framework was rewritten around macOS 11); adapt predicates after a first broad search. For encrypted DMGs, the Hash Extractor produces a crackable hash when you are authorised to attempt recovery.
Investigator tips
- Only attach suspect images read-only, on an analysis machine, with
-nobrowseso Finder and Spotlight do not index them. - A volume named after a popular app, containing a single app plus an "open me" instruction image asking the user to right-click and Open, is a common stealer pattern designed to bypass Gatekeeper.
- Compare the
com.apple.quarantinevalue on the.dmgwith the one on the app copied to/Applications. Quarantine is usually carried over to files copied off a quarantined image, and matching agent names, timestamps or event UUIDs link the two; test the behaviour on the same release before relying on an exact match. - Hard-drive style images (
.sparsebundle,.img) created locally withhdiutil createcan be staging containers for exfiltration; look for them next to USB devices and cloud sync activity.