Step 244. Windows Forensics: Registry, Event Logs, Prefetch — Digging Through the Archive of Execution Traces

Step 244. Windows Forensics: Registry, Event Logs, Prefetch — Digging Through the Archive of Execution Traces

Level 3 — Real-World CTF & Advanced Offensive Skills | Difficulty ★★★☆☆ | Estimated time: 3–4 hours

Prerequisites: Step 11 (registry exploration) and Step 12 (event logs) complete. Revisit those two chapters’ commands, this time with an investigator’s eye.

⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.

  • What you need: a Windows PC, PowerShell (both a regular window and an admin window). Every exercise today is read-only.
  • Caution: the registry and logs contain a person’s usage history exactly as it happened. Running these queries on someone else’s PC is only possible with legitimate investigative authority. Today’s target is your own PC.

Suppose a report comes in: "last night a malicious exe ran on this PC." What does the investigator look at? Windows records user behavior all over the place — caches of executed programs (Prefetch), execution counts and last-run times (UserAssist), logons and service installations (event logs). Breach investigation is the work of weaving these traces — artifacts — into a reconstruction of "who ran what, when." Today you reopen the registry and event logs you learned in Steps 11 and 12, from a forensic perspective.


1. Learning Objectives

By the end of this chapter, you will be able to:

  • Explain three kinds of Windows execution traces (Prefetch, UserAssist, event logs) using the term artifact
  • Check Prefetch’s operating condition (EnablePrefetcher) and storage location, and name the alternatives when it’s off
  • Open the UserAssist key and decode ROT13-hidden execution records yourself
  • Explain the investigative value of 7045 (service installation), 4688 (process creation), and 4624/4625 (logon)
  • Weave several artifacts into a draft "execution timeline"

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment PowerShell 5.1 (regular window + admin window), reading the registry and event logs
Today’s commands Get-ChildItem C:WindowsPrefetch, Get-ItemProperty ...UserAssist...Count, a ROT13 decoding function, Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045}
Concepts needed Artifacts, Prefetch, UserAssist and ROT13, event IDs 7045/4688/4624/4625, UTC vs local time

2-1. Artifacts — Traces Left Behind by Actions

In forensics, an artifact is "a trace left on a system as a result of an action." Just as a fingerprint stays on a doorknob, running a program leaves marks on disk, in the registry, and in logs.

Two properties matter. First, artifacts are not something the user consciously created — the operating system recorded them automatically for its own needs (performance, convenience). So users forget to erase them, which paradoxically makes them trustworthy to an investigator. Second, one artifact is weak, but several pointing at the same event become strong. If Prefetch shows an execution trace, UserAssist is stamped at the same time, and the log holds a process-creation event — the conclusion "it ran" gets confirmed three layers deep.

2-2. Prefetch — The Cache of Executed Programs

Prefetch is a Windows performance feature. It records the files a program reads in its first 10 seconds into C:WindowsPrefetchPROGRAMNAME-HASH.pf, then pre-reads them on the next launch for a faster start.

Through an investigator’s eyes, this is "a roster of programs that have run on this PC." Inside each .pf file are also the execution count and last-run time (UTC). That’s why the Prefetch folder is the first place dug for the question "has this malicious exe ever run?"

One caution: Prefetch can be off depending on settings or SSD environments. Today’s first exercise checks whether it’s on. If it’s off, no need for despair — UserAssist and event logs remain. An artifact is not a single item but a portfolio.

2-3. UserAssist — Execution Records Lightly Veiled by ROT13

Under the registry key HKCUSoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist sit GUID-named keys, and inside their Count keys, records of programs the user ran accumulate. Execution counts, last-run times, and more are stored as binary.

The fun part: the entry names are encoded in ROT13. ROT13 is a substitution that shifts each letter by 13 — A↔N, B↔O, and so on; applying it twice returns the original. It’s less encryption than a curtain that keeps casual onlookers from reading at a glance. Today you’ll peel that curtain off yourself with a PowerShell function.

2-4. Expanding Event IDs — The Investigator’s Regular Numbers

Step 12 taught 4624 (logon success) and 4625 (failure). Today we add two:

Event ID Log Meaning Investigative value
7045 System A service was installed A staple persistence technique of malware — an unknown service installation is a red flag
4688 Security A process was created The precise record of "what ran" — but off by default (must be enabled via audit policy to be recorded)
4624 Security Logon success Step 12 review
4625 Security Logon failure A burst of failures followed by success = a brute-force suspect pattern

7045 lives in the System log, so you can read it even without admin rights — we’ll measure it live today. 4624/4625/4688 are in the Security log and require administrator privileges — the same lock you learned in Step 12.

2-5. The Time Trap — UTC and Local Timezones

Each artifact records time differently. The internal timestamps of Prefetch and UserAssist are often in UTC, while the event log’s TimeCreated displays converted to local time. Korea is UTC+9.

"Prefetch says 2 AM but the event log says 11 AM" means the same event (2 + 9 = 11). Miss this conversion and your timeline shifts by 9 hours, making related events look unrelated. When building a timeline, the iron rule is to fix one reference time and convert every source to it.


3. Follow Along

3-1. Is Prefetch On? — Check the Setting First

Before opening the Prefetch folder, check whether this PC is even configured to record prefetch data:

Get-ItemProperty "HKLM:SYSTEMCurrentControlSetControlSession ManagerMemory ManagementPrefetchParameters" |
  Select-Object EnablePrefetcher
EnablePrefetcher
----------------
               3

(Measured 2026-09-09.)

How to read the output: 3 means "prefetch both applications and boot" — fully enabled (0=off, 1=apps only, 2=boot only, 3=both). This PC is accumulating prefetch records. If your PC shows 0, Prefetch can’t be used as evidence, and you move on to UserAssist and logs — that, too, is an investigative result.

3-2. Opening the Prefetch Folder — Measuring the Permission Barrier

Now open the folder. Try it in a regular window first:

Get-ChildItem "C:WindowsPrefetch" -Filter *.pf
Get-ChildItem : Access to the path 'C:WindowsPrefetch' is denied.

(Measured 2026-09-09 in a regular-privilege window.)

Why it’s blocked: the Prefetch folder is readable only by administrators. It aggregates execution records for the entire system, so it’s a protected object — the same design that kept the Security log locked in Step 12.

Run it again from an admin window (right-click the Start button → "Terminal (Admin)") and the .pf files appear:

Mode    LastWriteTime          Name
----    -------------          ----
-a----  2026-09-09 6:12 PM     CHROME.EXE-7C4A9E1F.pf
-a----  2026-09-09 6:09 PM     NOTEPAD.EXE-D8414F97.pf
-a----  2026-09-09 5:47 PM     POWERSHELL.EXE-88B3C12A.pf
...

(Screen example — run it yourself in an admin window to see your own PC’s list. The 8 hex digits after the name are a hash computed from the path, distinguishing different programs that share a name.)

Why we do this: this list is the evidence roster of "programs that ran on this PC." The folder’s own modification time was also measured — the Prefetch folder on the measured PC had last been updated this very evening (2026-09-09). A living artifact, accumulating records at this very moment.

3-3. UserAssist — Execution Records Behind the Curtain

Here’s an artifact that works even in a regular window. First, see which GUID keys exist:

Get-ChildItem "HKCU:SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist" |
  Select-Object -ExpandProperty PSChildName
{9E04CAB2-CC14-11DF-BB8C-A2F1DED72085}
{A3D53349-6E61-4557-8FC7-0028EDCEEBF6}
{BCB48336-4DDD-48FF-BB0B-D3190DACB3E2}
{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}
{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}
{FA99DFC7-6AC2-453A-A5E2-5E2AFF4507BD}
...

(Measured 2026-09-09. Nine GUID keys confirmed.)

The main body of execution records is {CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}. Open its Count key and you can see the entry count:

$guid = "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}"
$path = "HKCU:SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist$guidCount"
$props = Get-ItemProperty $path
$names = $props.PSObject.Properties.Name | Where-Object { $_ -notlike 'PS*' }
$names.Count
261

(Measured 2026-09-09 — 261 execution records had accumulated on this PC.)

But print the entry names as-is and you get this:

$names | Select-Object -First 4
HRZR_PGYPHNPbhag:pgbe
HRZR_PGYFRFFVBA
Zvpebfbsg.JvaqbjfPnyphyngbe_8jrxlo3q8oojr!Ncc
Zvpebfbsg.Cnvag_8jrxlo3q8oojr!Ncc

(Measured 2026-09-09.) Zvpebfbsg.Cnvag — a string that almost reads like something is what ROT13-veiled text looks like.

3-4. A ROT13 Decoder — Peeling Off the Curtain

ROT13’s rule is simple enough to write as a PowerShell function yourself. Shift uppercase and lowercase letters by 13 each:

function Convert-Rot13([string]$s) {
  -join ($s.ToCharArray() | ForEach-Object {
    $c = [int]$_
    if ($c -ge 65 -and $c -le 90) { [char](($c - 65 + 13) % 26 + 65) }
    elseif ($c -ge 97 -and $c -le 122) { [char](($c - 97 + 13) % 26 + 97) }
    else { [char]$c }
  })
}
$names | Select-Object -First 4 | ForEach-Object { Convert-Rot13 $_ }
UEME_CTLCUACount:ctor
UEME_CTLSESSION
Microsoft.WindowsCalculator_8wekyb3d8bbwe!App
Microsoft.Paint_8wekyb3d8bbwe!App

(Measured 2026-09-09.)

How to read the output: Zvpebfbsg.Cnvag turned out to be Microsoft.Paint. Calculator, Paint — records of UWP apps run on this PC. Entries starting with UEME_ are Windows-internal session information and can be excluded from investigation.

Let’s select just the executables:

$names | ForEach-Object { Convert-Rot13 $_ } | Where-Object { $_ -match '.exe' } |
  Select-Object -First 6
{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}HNCOffice 2020HOffice110BinHwp.exe
{6D809377-6AF0-444B-8957-A3773F02200E}KakaoKakaoTalkKakaoTalk.exe
{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}PickerHost.exe
{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}SteamSteam.exe
{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}msiexec.exe
{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}WindowsPowerShellv1.0powershell.exe

(Measured 2026-09-09.)

How to read the output: the GUID before each path is a known folder ID used instead of a drive letter — {1AC14E77...} corresponds to C:WindowsSystem32, {7C5A40EF...} to Program Files. You can see Hangul Word Processor (Hwp.exe), KakaoTalk, Steam, and even the PowerShell we’re using right now. You’ve just seen with your own eyes an artifact where the execution happening right now immediately becomes evidence. Each entry’s data (the value’s contents) holds the execution count and last-run time as binary, and practitioners use dedicated tools to parse it (see the Summary).

3-5. 7045 — Viewing Service Installation Records

Moving on to the event logs. 7045 (service installation) is in the System log, so it works in a regular window:

Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045} -MaxEvents 1 | Format-List TimeCreated, Message
TimeCreated : 2026-09-03 4:39:40 PM
Message     : A service was installed in the system.

              Service Name:  nProtect Online Security(PFS)
              Service File Name:  "C:Program Files (x86)INCAInternetnProtect Online Securitynossvc.exe" /SVC
              Service Type:  user mode service
              Service Start Type:  auto start
              Service Account:  LocalSystem

(Measured 2026-09-09.)

How to read the output: a record that some program installed a service (a resident background process) and registered it for auto start. Here it’s an online security program, so its identity is clear. The measured PC’s System log held 16 events of 7045 in total.

Why investigators look at 7045: service installation is a heavy act requiring administrator privileges, so it happens rarely in normal use. And malware’s staple technique for securing persistence is precisely "registering itself as a service." So "a service installation record I don’t recognize" becomes an immediate investigative subject. The question is the same as in Step 11 — "Do I know this? Do I remember installing it?"

3-6. The Security Log’s Trap — Same Lock, Different Reactions

4624/4625/4688 live in the Security log and need administrator privileges (Step 12). But you should measure for yourself that the failure looks different depending on how you query:

Get-WinEvent -LogName Security -MaxEvents 1
Get-WinEvent : Attempted to perform an unauthorized operation.

(Measured 2026-09-09 in a regular window — a clear permission error.)

But ask with FilterHashtable:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 3
Get-WinEvent : No events were found that match the specified selection criteria.

(Measured 2026-09-09 in a regular window — not a permission error, but a "nothing here" notice!)

Why this is a trap: you can’t read the log because you lack permission, yet the message says "no matching events" — and an investigator can misread that as "there are zero logon records." An empty result from an unauthorized query is not zero events. Before investigating the Security log, always confirm you’re in an admin window. In an admin window, the commands in this section return 4624/4625 records normally — the verification steps are the same as Step 12.

4688 (process creation) has one more layer: even when you can read it as admin, the record only exists at all if "Audit Process Creation" is enabled in audit policy. The default is off. That’s why incident-response teams make enabling this policy before an incident their standard — because "turning it on after the fact records nothing about the past."

3-7. Putting It Together — The "Malicious exe Ran Last Night" Scenario

Back to the report: "there’s a tip that a suspicious file named update_helper.exe ran on this PC last night." With today’s artifacts, the verification plan looks like this:

  1. Prefetch (admin window): is there a .pf file starting with UPDATE_HELPER? If so, is its LastWriteTime last night?
  2. UserAssist: does that name appear in the ROT13-decoded list? (If it ran under my account, it stays.)
  3. 7045: was any unknown service installed around last night?
  4. 4624/4625 (admin window): were there unknown logons last night?
  5. Run keys (Step 11): is a persistence registration still present right now?

If any one of them hits, sweep the other artifacts before and after that timestamp to widen the timeline. If all come back empty, the conclusion is "execution cannot be confirmed with this evidence" — an absence is also an investigative result, and then you move on to memory forensics (Step 242) or disk carving (Step 243).


4. Missions & Exercises

Mission — A Draft Execution Timeline of My PC

Use today’s artifacts to organize your PC’s recent execution records onto one page:

  1. Decode UserAssist and pull out 10 .exe entries (sections 3-3, 3-4)
  2. Organize the times and service names of the 5 most recent 7045 events — can you explain every one’s identity?
  3. In an admin window, pull the 10 most recent Prefetch .pf files with their LastWriteTime
  4. Find programs that overlap across the three lists — is the same program stamped in multiple artifacts at once?
  5. Save the result to timeline-draft.txt (format: one "time | artifact | content" line each)

Exercises

Problem 1. Explain why artifacts are trusted more in investigations than "records the user made consciously."

Problem 2. You’re investigating a PC whose EnablePrefetcher value is 0. Name two artifacts to check instead when prefetch evidence is unavailable, and where each lives.

Problem 3. What does the UserAssist entry name Zvpebfbsg.JvaqbjfAbgrcnq decode to under ROT13? (Do it by hand if you can — shift each letter by 13.)

Problem 4. In a regular-privilege window, Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} returned "No events were found that match the specified selection criteria." May the report say "zero logon failures"? Explain why.


5. Model Answers & Completion Criteria

Mission Model Answer

# 1. Decoding UserAssist
function Convert-Rot13([string]$s) {
  -join ($s.ToCharArray() | ForEach-Object {
    $c = [int]$_
    if ($c -ge 65 -and $c -le 90) { [char](($c - 65 + 13) % 26 + 65) }
    elseif ($c -ge 97 -and $c -le 122) { [char](($c - 97 + 13) % 26 + 97) }
    else { [char]$c }
  })
}
$guid = "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}"
$names = (Get-ItemProperty "HKCU:...UserAssist$guidCount").PSObject.Properties.Name |
  Where-Object { $_ -notlike 'PS*' }
$names | ForEach-Object { Convert-Rot13 $_ } | Where-Object { $_ -match '.exe' } |
  Select-Object -First 10 | Out-File timeline-draft.txt

# 2. 7045
Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045} -MaxEvents 5 |
  Select-Object TimeCreated, @{n='Service';e={($_.Message -split "`n")[2]}} |
  Out-File timeline-draft.txt -Append

# 3. Prefetch (in an admin window)
Get-ChildItem C:WindowsPrefetch -Filter *.pf |
  Sort-Object LastWriteTime -Descending | Select-Object -First 10 Name, LastWriteTime |
  Out-File timeline-draft.txt -Append

An organized example (in the form confirmed on the 2026-09-09 measured PC):

UserAssist: KakaoTalk.exe, Hwp.exe, powershell.exe, Steam.exe ...
7045: 2026-09-03 nProtect Online Security(PFS) — security program, I remember installing it
Prefetch: CHROME.EXE-..., NOTEPAD.EXE-... (confirmed in admin window)
Overlap: (compare the lists and underline the same programs)

How to verify: open it with notepad timeline-draft.txt and check that records from all three artifacts are present. It’s complete when each 7045 service carries a note like "I remember installing it / identity confirmed by search." If you found overlapping programs — that’s the real-world object of section 2-1’s principle that "multiple artifacts jointly prove one event."

Exercise Answers

Answer 1. Artifacts are recorded automatically by the operating system for performance and convenience, so users easily forget to manipulate or erase them. Intentional records (documents, memos) can be embellished by their author, but automatic records are "byproducts of action," making them hard to forge. They’re not perfect, though, so cross-confirmation across multiple artifacts is needed.

Answer 2. UserAssist (HKCU...ExplorerUserAssist{GUID}Count — requires ROT13 decoding) and the event logs (7045 in System; 4688 in Security with admin rights — though 4688 exists only if the audit policy is on). Persistence artifacts like Run keys also show circumstantial evidence of execution.

Answer 3. Microsoft.WindowsNotepad. Shift each letter by 13: Z→M, v→i, p→c, e→r, b→o, f→s, b→o, g→t, and so on.

Answer 4. No (measured and confirmed 2026-09-09). Without privileges you can’t read the Security log at all, yet the FilterHashtable method emits "no matching events" instead of a permission error. In other words, that message may mean "couldn’t read," not "zero events." Only after re-querying from an admin window and confirming the actual count may you write zero.

Completion Criteria Checklist

  • [ ] I can explain an artifact as "an automatic record left behind by an action"
  • [ ] I can query the EnablePrefetcher value and know what 0/1/2/3 mean
  • [ ] I know the Prefetch folder requires admin rights (the denial message measured in a regular window)
  • [ ] I opened the UserAssist {CEBFF5CD-ACE2-4F4F-9178-9926F41749EA} key and did the ROT13 decoding myself
  • [ ] I can explain what 7045 records and why it’s a staple of malware investigation
  • [ ] I know 4688 is recorded only when the audit policy is enabled
  • [ ] I don’t misread an unauthorized FilterHashtable query’s "none found" notice as zero events
  • [ ] Mission: completed timeline-draft.txt

6. Common Pitfalls & Fixes

Wall 1. Access denied on the Prefetch folder

Symptom: a red error appears (measured 2026-09-09):

Get-ChildItem : Access to the path 'C:WindowsPrefetch' is denied.

Cause: the Prefetch folder is readable only by administrators. The case where an empty list appears without an error is when -ErrorAction SilentlyContinue is attached — denied but looking like zero, which is more dangerous.
Fix: rerun in an admin window (right-click Start → Terminal (Admin)). And don’t casually use options that hide errors in investigation scripts — they make "denied" indistinguishable from "none."

Wall 2. Misreading "No events were found" as zero events

Symptom: querying the Security log with FilterHashtable in a regular window says "none found" (measured 2026-09-09).
Cause: this method sometimes fails to surface insufficient permission as a clear error. Contrast it with asking directly via -LogName Security, which raises "Attempted to perform an unauthorized operation."
Fix: before investigating the Security log, check that the window title says "Administrator" first. When an empty result comes back, build the habit of always asking yourself "is this permissions, or genuinely zero?"

Wall 3. The ROT13 decode still looks wrong

Symptom: even after decoding, a GUID like {7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E} sits in front of the path.
Cause: it’s not a malfunction. Windows records frequently used folders (Program Files, System32, etc.) as known folder GUIDs instead of drive letters. The decode succeeded (measured 2026-09-09).
Fix: read {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7} as C:WindowsSystem32 and {7C5A40EF-...} as Program Files. The full GUID list can be found by searching "Known Folder ID."

Wall 4. A program that should clearly be in Prefetch isn’t there

Symptom: the .pf of a program you ran yesterday isn’t visible.
Cause: one of three: (1) EnablePrefetcher is set to 0 — check with section 3-1. (2) Windows limited prefetch itself, e.g., due to SSD optimization. (3) the program ran long ago and got pushed out by the 1024-file cap.
Fix: Prefetch is an artifact that’s "powerful when present, but absence is not innocence." Cross-check with UserAssist and event logs. In investigation, "absence of evidence" is not "evidence of absence."

Wall 5. Prefetch time and event-log time differ by exactly 9 hours

Symptom: two records of the same event differ by exactly 9 hours.
Cause: one side is UTC, the other local time (Korea is UTC+9). Prefetch and UserAssist internal timestamps are often UTC; the event log’s display time is local.
Fix: when building a timeline, fix one reference (usually local) and convert everything to it. A 9-hour gap isn’t a mistake — it’s the same event viewed under two standards.


7. Summary

Today’s Concepts

Concept One-line explanation
Artifact A trace automatically left on a system as the result of an action — forensics’ unit of evidence
Prefetch The execution cache in C:WindowsPrefetch — "a roster of programs that have run" (admin required)
UserAssist Per-user execution records in the registry — names veiled by ROT13
ROT13 A substitution shifting letters by 13 — twice returns the original; curtain-level encoding
7045 / 4688 Service installation (System) / process creation (Security, audit policy required)
UTC vs local Each artifact uses a different time base — conversion is mandatory before any timeline

Today’s Commands

Command What it does
Get-ItemProperty ...PrefetchParameters Check whether prefetch is enabled (EnablePrefetcher)
Get-ChildItem C:WindowsPrefetch (admin) List .pf files of executed programs
Get-ItemProperty ...UserAssist{GUID}Count Read execution-record entries (ROT13 names)
Convert-Rot13 (the function you wrote) Decode UserAssist entry names
Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045} Query service-installation records (works without admin)
Get-WinEvent ... Id=4624/4625 (admin) Query logon success/failure records

An Instinct More Important Than Commands

Three things are at today’s core. First, artifacts are a portfolio — no Prefetch, go UserAssist; no UserAssist, go logs. One absence isn’t an ending but a signpost to the next artifact. Second, distrust "none" results — whether it’s insufficient permissions, a disabled feature, or a genuine absence are entirely different conclusions. Third, the investigative question never changes — "Do I know this? Is it the same as usual?"

In practice, dedicated tools do the decoding you did by hand today — Eric Zimmerman’s PECmd (prefetch parser) and EvtxECmd (event-log parser) are used as near-standards, tabulating execution counts and times for you. The principles are all the same as what you did today. The more convenient the tools get, the more the person who knows "what’s happening inside" reads the results correctly — today you touched that foundation with your own hands.


Once every box is checked, Step 244 is complete.