User Activity Forensics: ShellBags, LNK Files and Jump Lists
Prove which files and folders a Windows user opened, and when: ShellBags, LNK files, Jump Lists, MRU keys, Office Trust Records and Timeline, correlated.
This guide shows you how to prove that a specific Windows user opened a given file or browsed a given folder, and when. You will learn what each user activity artifact records, which timestamps you can actually trust, and how to combine ShellBags, LNK files, Jump Lists and the registry MRU keys into a defensible "who opened what, when" narrative.
Why user activity needs several artifacts
Execution artifacts answer "did this program run?" (see evidence of execution). User activity artifacts answer a different question: did this person interact with this data? No single source answers it fully. Some artifacts record folders, some record files, some record the application used, and most only keep the first and last occurrence. The skill is knowing what each one proves, then stacking them until the gaps close.
A quick map before the details:
| Artifact | Location | Proves | Key time |
|---|---|---|---|
| ShellBags | UsrClass.dat, NTUSER.DAT | Folder browsed (local, USB, network, ZIP, phone) | Key LastWrite for the most recent child only |
| LNK files | %APPDATA%\Microsoft\Windows\Recent\ | File or folder opened through the shell | LNK created / modified (first / last open of that name) |
| Jump Lists | Recent\AutomaticDestinations\, CustomDestinations\ | File opened with a specific application | DestList last access per entry |
| RecentDocs | NTUSER.DAT\...\Explorer\RecentDocs | File names opened, in MRU order | Key LastWrite = most recent item |
| OpenSave / LastVisited MRU | NTUSER.DAT\...\Explorer\ComDlg32 | File selected in an open/save dialog, by which program | Key LastWrite = most recent item |
| TypedPaths / WordWheelQuery | NTUSER.DAT\...\Explorer | Paths typed and terms searched in Explorer | Key LastWrite = most recent item |
| Office MRU and Trust Records | NTUSER.DAT\Software\Microsoft\Office\<ver> | Document opened in Office; editing or macros enabled | Per-entry FILETIME |
| Windows Timeline | ActivitiesCache.db | App focus, files and URLs opened (Windows 10) | Per-activity start / end |
| Thumbcache | %LOCALAPPDATA%\Microsoft\Windows\Explorer\ | A file was rendered as a thumbnail | None reliable per entry |
ShellBags: proof of folder navigation
Explorer stores view preferences for every folder a user opens, and to do so it records the folder path as a tree of shell items. On Vista and later most entries live in UsrClass.dat under Local Settings\Software\Microsoft\Windows\Shell\BagMRU and \Bags, with a smaller set in NTUSER.DAT under Software\Microsoft\Windows\Shell. On XP they sit in NTUSER.DAT under Software\Microsoft\Windows\ShellNoRoam and Shell.
What makes ShellBags valuable is that they survive the folder. Entries remain for:
- deleted directories, including ones the suspect created and wiped;
- removable drives that are no longer attached, recorded by drive letter and folder names;
- network shares (
\\server\share\path), including admin shares; - ZIP archives opened as folders, MTP phones and cameras, and Control Panel pages.
What they do not give you is a reliable access time for each folder. The BagMRU key LastWrite time applies to the child listed first in MRUListEx, so it dates the most recently accessed subfolder at that level, not every sibling. File entry shell items also embed the folder's own created, modified and accessed times in DOS format with 2-second resolution, but those describe the folder at the moment the item was built, not the user's visit.
Always parse the hive together with its .LOG1 and .LOG2 transaction logs: recent navigation is often only in the logs when the hive was collected from a live or recently used system.
# Parse every UsrClass.dat / NTUSER.DAT found under a collected Users folder
SBECmd.exe -d E:\case\C\Users --csv E:\out\shellbags --dedupe
# Live system, current user only
SBECmd.exe -l --csv E:\out\shellbags
ShellBags Explorer gives the same data as an interactive tree, which is useful for reading the path hierarchy. If you only have a single hive to look at, the ShellBags Parser decodes it in the browser.
LNK files: proof a file was opened
Every time a user opens a file through the shell, Explorer writes or updates a shortcut in C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Recent\, named after the target (budget.xlsx.lnk). On recent Windows versions the parent folder gets its own LNK as well.
Each LNK is a snapshot of the target at the time it was written:
- Target MAC times in the header: the target's own created, accessed and modified FILETIME values, copied in. They describe the file, not the user.
- LinkInfo: local path, drive type (fixed, removable, network, CD-ROM), volume serial number and volume label, or the UNC share name for network targets.
- LinkTargetIDList: shell items for the path, with MFT references on NTFS.
- TrackerDataBlock: the NetBIOS name of the machine where the target lived, plus object identifiers whose version-1 UUID node field often holds a MAC address.
The shortcut's own NTFS timestamps are the user activity times: creation approximates the first time a file with that name was opened, and modification the last time. Because the name is the key, opening a different budget.xlsx from another folder updates the same shortcut. Read the embedded path before assuming both events concern the same file.
# Parse all Recent shortcuts of every profile
LECmd.exe -d E:\case\C\Users --csv E:\out\lnk
# A single file, full detail on screen
LECmd.exe -f "E:\case\C\Users\jdoe\AppData\Roaming\Microsoft\Windows\Recent\budget.xlsx.lnk"
The volume serial number and drive type are what make LNK files the bridge to removable media: a LNK pointing to E:\Q3\budget.xlsx on a removable drive with serial A4F2-19C0 can be matched to a specific USB device (see USB device forensics). For one-off checks, the LNK Parser runs client-side.
Jump Lists: which application opened the file
Jump Lists, introduced in Windows 7, add the piece LNK files lack: the application. Each application gets its own file, named after its AppID, a hash derived from the application path or its AppUserModelID.
- AutomaticDestinations (
Recent\AutomaticDestinations\<AppID>.automaticDestinations-ms) are OLE compound files (CFB). Each numbered stream is an LNK, and theDestListstream holds per-entry metadata: last access time, the MRU position, pin status, the hostname, and on Windows 10 and later an access count. - CustomDestinations (
Recent\CustomDestinations\<AppID>.customDestinations-ms) are written by the application itself: tasks, pinned items and custom categories stored as concatenated LNK records. Browsers and chat apps put interesting data here.
Because entries are LNK records, you get the same volume serial, drive type and target times as a standalone shortcut, even when the standalone LNK was deleted. The DestList time is often the best "last opened in this app" timestamp you will find for a document.
# All Jump Lists in all profiles, with full LNK detail for each entry
JLECmd.exe -d E:\case\C\Users --csv E:\out\jumplists --ld
# One file
JLECmd.exe -f "E:\case\...\AutomaticDestinations\<AppID>.automaticDestinations-ms"
JLECmd resolves many known AppIDs to application names. When an AppID is unknown, compute it from the suspected application path or look for the same AppID on a reference system rather than guessing. The Jump List Parser handles single files in the browser.
Registry MRU keys in NTUSER.DAT
These keys are small, fast to review and all attributable to the profile owner. Their weakness is time: most keep an MRUListEx ordering and a single key LastWrite, so only the most recent entry of each key is dated.
RecentDocs
Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs lists recently opened items by name, with a subkey per extension (.docx, .zip, .ps1) and a Folder subkey. It stores names, not full paths; recover the path from the matching LNK or Jump List entry. The per-extension subkeys are a quick way to spot archives, scripts and disk images handled by the user.
OpenSavePidlMRU and LastVisitedPidlMRU
Under Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32, OpenSavePidlMRU records files selected in common open and save dialogs (per extension, plus *), and LastVisitedPidlMRU records the executable that used the dialog together with the last folder it browsed. An entry like chrome.exe pointing to E:\Export is a strong lead for a browser upload or a download to removable media. On XP the equivalents are OpenSaveMRU and LastVisitedMRU in plain text.
TypedPaths and WordWheelQuery
TypedPaths holds paths typed in the Explorer address bar (url1 is the most recent), which is where UNC paths to other hosts and hidden shares show up. WordWheelQuery holds search terms typed in the Explorer search box, in UTF-16 with an MRUListEx. Terms searched from the Windows 10/11 taskbar or Start menu are not stored there.
# Dump the user activity keys of one NTUSER.DAT with a RECmd batch file
RECmd.exe -f E:\case\C\Users\jdoe\NTUSER.DAT --bn .\BatchExamples\RECmd_Batch_MC.reb --csv E:\out\registry
Office MRU and Trust Records
Office keeps its own lists under NTUSER.DAT\Software\Microsoft\Office\<version>\<App>\, where <version> is 16.0 for Office 2016 through Microsoft 365. File MRU and Place MRU (or the same lists under User MRU\<account id>\ when a Microsoft 365 account is signed in) record full paths with a per-entry timestamp embedded in the value, in the form [F00000000][T01DB...][O00000000]*C:\path\file.docx, where the T field is a hexadecimal FILETIME of the last open.
Security\Trusted Documents\TrustRecords is even more telling: a value appears when the user clicks "Enable Editing" or "Enable Content" on a document. The value data begins with a FILETIME, and data ending in FF FF FF 7F is widely reported to indicate that macros were enabled. In phishing investigations this is often the cleanest proof that the user, not just the mail client, acted on the attachment.
Windows Timeline and thumbcache
Windows Timeline (C:\Users\<user>\AppData\Local\ConnectedDevicesPlatform\<account>\ActivitiesCache.db, Windows 10 1803 and later) records app launches, focus duration and many opened documents and URLs, per activity. It is a SQLite database: always collect the -wal file, since recent rows often live only in the write-ahead log. Timeline was removed from Windows 11 and activity history cloud sync was retired, so treat it as a Windows 10 source.
WxTCmd.exe -f "E:\case\...\ConnectedDevicesPlatform\L.jdoe\ActivitiesCache.db" --csv E:\out\timeline
Thumbcache (thumbcache_*.db in %LOCALAPPDATA%\Microsoft\Windows\Explorer\) holds thumbnails of pictures, videos and some documents that Explorer rendered for this user. It proves a file existed on a location the user viewed, including removed USB drives and shares, and it shows the content. It does not prove the file was opened, and file names come only from mapping the cache ID to the Windows Search index. The Thumbcache Parser extracts images in the browser.
Attributing activity to a user
All of the artifacts above are per-profile, which is what makes them so useful for attribution. Tie the profile to an account explicitly:
- Map the profile folder to a SID with
SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<SID>\ProfileImagePath. - Resolve the SID to a local account in the SAM or to a domain account.
- Confirm the account had an interactive session at the relevant times using logon events (4624 with logon types 2, 10 or 11, and 4634/4647 logoffs).
Attribution to the account is not attribution to a person. Shared credentials, unlocked sessions and remote access tools all need to be ruled out with other evidence.
# SID to profile path mapping on a live system
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' |
Select-Object PSChildName, ProfileImagePath
Building the "who opened what, when" narrative
Work from the question outward. Suppose you need to show that jdoe accessed payroll data on a file server and moved it to a USB drive.
- Search intent: WordWheelQuery holds
payroll; TypedPaths holds\\fs01\hr$. The user looked for the data and typed a hidden share path by hand. - Folder navigation: ShellBags contain
\\fs01\hr$\Payroll\2026, then laterE:\Q3. The BagMRU LastWrite on the2026parent dates the most recent visit. - File opening:
payroll_2026.xlsx.lnkin Recent points to\\fs01\hr$\Payroll\2026\payroll_2026.xlsx; the Excel Jump List contains the same target with a DestList last access time; ExcelFile MRUholds the path with itsTtimestamp. - Copy to removable media: a second LNK or Jump List entry points to
E:\Q3\payroll_2026.xlsxwith drive type removable and a volume serial number. OpenSavePidlMRU shows.xlsxsaved toE:\Q3. - Device identification: match the volume serial to a USB device and its connection window.
- Account: the profile maps to jdoe's SID, and a 4624 interactive logon covers the period.
Put every timestamp on a single timeline in UTC, labelled with its exact meaning ("LNK modified", "DestList last access", "BagMRU LastWrite"). A super timeline with Plaso does this at scale, but for a focused question a spreadsheet of the tool CSVs is often clearer.
Common mistakes
- Treating target times as access times. LNK header times and shell item times describe the file or folder, not the user action.
- Extending a key LastWrite to every entry. For BagMRU, RecentDocs, ComDlg32 and TypedPaths it dates only the most recent item.
- Ignoring transaction logs and the SQLite WAL. Recent activity is frequently only there.
- Assuming one LNK means one file. Recent shortcuts are keyed on file name.
- Reading absence as proof. Users, cleaners and Windows limits all remove entries. Check volume shadow copies before concluding nothing happened.
- Forgetting time zones. Registry and LNK times are UTC; some tool outputs and application logs are local time.
Workflow checklist
- Collect each profile's
NTUSER.DAT,UsrClass.datand their logs, theRecentfolder includingAutomaticDestinationsandCustomDestinations,ActivitiesCache.db*, the thumbcache folder and theSOFTWAREhive. The triage guide covers KAPE targets for this. - Map profiles to SIDs and accounts.
- Run SBECmd, LECmd, JLECmd, WxTCmd and a RECmd batch against the collected data.
- Filter on the paths, file names, shares and volume serials that matter to the case.
- Correlate folder (ShellBags), file (LNK, RecentDocs, ComDlg32) and application (Jump Lists, Office MRU) evidence for each item.
- Pivot volume serials to USB devices and UNC paths to the servers involved.
- Build the timeline in UTC with the meaning of each timestamp written next to it, and note every gap.
For the registry side of this work in more depth, continue with Windows registry forensics.
Area 06
User Activity
The artifact cheat sheets behind this guide: location by Windows version, what each one proves and the tools to parse it.