ShellBags forensics: the messy artifact that closes cases
8 min read
ShellBags are the artifact analysts complain about and then rely on anyway. The format is awkward, the parsing is contested, the documentation is incomplete, and the data closes cases that nothing else can close. Every serious DFIR practitioner ends up making peace with them.
Here is what they actually contain, where the parsing traps are, and how to use them without being fooled.
What Explorer is recording
Explorer needs to remember per-folder display settings: sort order, column widths, view mode, icon positions. Storing that data is the surface purpose of ShellBags. The side effect we care about is that storing it requires recording every folder the user has ever opened, including folders on removable media and network shares.
The data lives in two parallel structures: BagMRU (a tree mirroring the folder hierarchy the user has navigated, each node carrying a MRUListEx and a numeric ID), and Bags (a flat array of bag records indexed by those IDs, holding the actual view settings plus timestamps).
On modern Windows (7 and later), the meaningful copies live in UsrClass.dat under Local Settings\Software\Microsoft\Windows\Shell\BagMRU and \Bags. NTUSER.DAT also has a Software\Microsoft\Windows\Shell\BagMRU, but on modern Windows that one is nearly empty. UsrClass is where the action is.
ItemIDs: the embedded shell items
The interesting bit is what each BagMRU node contains. The value names are integers (0, 1, 2, ...), and the data is a serialized SHITEMID structure. Same format as the SHITEMID stuffed inside an LNK file. Same format as the items in jump lists. Once you can parse one, you can parse the others.
The SHITEMID is tagged with a type byte that tells you what kind of shell item this is:
0x1F: root folder (My Computer, Recycle Bin, Control Panel).0x2F: drive letter (with the volume identifier).0x31,0x32: file system folder entries, with a short or long name, FAT/NTFS timestamps, and the entry size.0x3A: file system entry, less common variant.0x41,0x42: network locations (UNC paths, mapped shares).0x71: Control Panel.
For folders on local NTFS volumes, you get the folder name, the modified timestamp, the access timestamp, the created timestamp, and (on newer Windows) the MFT entry number plus sequence. That last part is the link to the MFT: you can resolve a ShellBag entry directly to an MFT record without ever touching the file system.
For folders on removable media, you get the same data plus the volume serial number. This is how you reconstruct USB usage even after the stick has been thrown in the river. The Bag still has the timestamps and the name.
The lazy-write problem
Explorer does not write to BagMRU on every navigation. It writes when the view settings change, when the folder is closed, or when Explorer's process exits cleanly. This produces three failure modes that bite analysts:
Folders the user opened do not appear. If the user opened a folder, looked at the default view, and closed Explorer with the X button, the bag may never be written. There is no log that this happened.
Timestamps do not reflect navigation. The Bag's modification time reflects the last write, not the last visit. If the user revisited a folder but did not change any view settings, no write occurred, and the timestamp is stale.
Subkey LastWrite values are not user-activity timestamps. The LastWrite on a BagMRU subkey only updates when its children change. People misread this all the time.
What you can rely on: a ShellBag's existence means the user navigated there at some point, and the folder name, MFT reference, and volume serial are correct. What you cannot rely on: the Bag's modification time as a precise navigation event. Cross-check against LNK, jump lists, and the USN journal for actual access events.
Removable media reconstruction
This is where ShellBags become irreplaceable. The chain goes:
- ShellBag has a
0x2Fnode with the volume's drive letter and serial number. - Under that node, the BagMRU tree records every folder the user opened on the device.
- The SYSTEM hive's
MountedDeviceskey maps drive letters to volume IDs at the time of the ShellBag's writes. - The USB device history under
SYSTEM\ControlSet001\Enum\USBSTORgives the device's vendor, product, and serial number.
Tie those four together and you can say: "On host X, user Y plugged in a Kingston DataTraveler with serial Z, and navigated through these folders." The USB stick is long gone; the registry remembers.
The reconstruction is the same on network shares. The ShellBag records the UNC path, the share name, and the folder hierarchy navigated. If the share no longer exists, the bag still has the path.
Survival after folder deletion
ShellBags persist after the underlying folder is deleted. Sometimes for years. I have pulled bags referencing folders that were deleted three Windows upgrades ago. For the question "did this user open this folder", where the folder has been deleted in an attempt to clean up, ShellBags answer yes if the answer is yes. If the user deletes their entire profile, the UsrClass.dat goes with it. If only the folder is deleted, the bag remains.
Tools that get it right, and tools that get it wrong
ShellBag parsing is one of the artifacts where tool quality matters most. The format has changed across Windows versions, the SHITEMID structures are not exhaustively documented, and small parsing bugs lead to silent data loss.
Tools that handle ShellBags correctly:
- Eric Zimmerman's ShellBagsExplorer. The reference implementation as far as I am concerned. Handles all known SHITEMID variants, displays the full hierarchy, and surfaces volume serial numbers and MFT references where present.
- RegRipper's
shellbagsplugin (and its companionshellbags_xp). Solid for command-line workflows. The plugin is well-commented and worth reading to understand what it is extracting.
Tools to be cautious of:
- Most ad-hoc Python implementations on GitHub. The half that handle
0x31correctly often miss0x42network items or the modernProperty Storageextension blocks. Test against a hive with known content before trusting one. - Generic registry browsers that show you the BagMRU tree but do not decode the embedded SHITEMID. You see the binary value and that is all.
If a tool gives you ShellBag output and you cannot tell from the output whether it parsed all the SHITEMID variants, assume it did not. Run a second tool and compare.
Edge cases that catch people
Per-user, not per-host. ShellBags are in UsrClass and NTUSER. If you parse only the admin's profile, you see the admin's history, not the suspect user's.
Roaming profiles. On a domain with roaming profiles, ShellBags from one machine may show up on another via profile sync. The bag does not know which machine it was written on. Cross-correlate with Prefetch and EVTX on the suspected host.
Multiple sessions can overwrite. With multiple Explorer windows open, the MRU ordering reflects whichever window updated last, not chronological access. Treat MRU position as approximate.
Special folders use known GUIDs. Desktop, Documents, Downloads are represented as GUIDs rather than paths. A tool that does not resolve {B4BFCC3A-DB2C-424C-B029-7FE99A87C641} to "Desktop" will leave you scratching your head.
The Property Storage extension. Newer ShellBag items carry extension blocks with serialized property store data (MFT entry, sequence, file size, additional timestamps). Older parsers do not see them.
A workflow that closes cases
For a "did this user open this file from this device" question:
- Pull UsrClass.dat for the user. Also NTUSER for the legacy bags.
- Parse with ShellBagsExplorer. Note the BagMRU paths and timestamps.
- Cross-reference USB device history from SYSTEM
Enum\USBSTOR. Match volume serials. - Pivot to LNK files in
Recent\for any matching folder. The LNK adds precise access timestamps. - Pivot to jump lists for the applications that opened files in those folders.
- If the file is on the host, the MFT gives you the timestamps. If it has been deleted, the USN journal may have the deletion event.
That sequence has answered "did this exfil happen via USB" for me more times than I can count. The ShellBag is the anchor; the other artifacts are the corroboration.
Further reading
- Willi Ballenthin's ShellBag analysis paper: the most rigorous public write-up of the format and its quirks.
- Joachim Metz, libfwsi: the C library for parsing the SHITEMID structures embedded in ShellBags and LNK files.
- Eric Zimmerman's ShellBagsExplorer: the practical tool.
- The RegRipper
shellbagsplugin source: read it for a working implementation in well-commented Perl.
ShellBags are messy. They are also one of the few artifacts that recover user activity after folder deletion, after device removal, and across system upgrades. Make peace with the format. The data is worth the friction.