Event-Viewing picoCTF 2025 Solution

Published: April 2, 2025

Description

A compromised Windows host keeps shutting down. You're given Security.evtx and must prove three events (install, registry change, shutdown) while extracting the Base64 flag pieces buried in the event data.

Confirm the file: file Security.evtx should report MS Windows Vista Event Log.

Install python-evtx (pip install python-evtx, or pip3 install python-evtx if pip isn't on PATH). If install fails, you're usually missing Python dev headers (apt install python3-dev) or need --user because of permissions.

Dump the log to XML so you can grep it. Filter for IDs 1033 (Windows installer), 4657 (registry value modified), and 1074 (forced shutdown). Google Windows event ID <number> for any unfamiliar one.

bash
file Security.evtx
bash
pip install python-evtx  # or pip3 install python-evtx
bash
evtx_dump.py Security.evtx > output.xml
bash
grep -E 'EventID>(1033|4657|1074)<' output.xml -B2 -A40

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
Base64 encoding shows up constantly in forensics; see the CTF Encodings cheat sheet for fast recognition (the trailing = padding here is the giveaway).
  1. Step 1
    Extract Event ID 1033
    Observation
    I noticed the challenge description explicitly mentioned a software install event as one of the three required artifacts, which pointed directly to Event ID 1033, the Windows Installer completion record, as the source to investigate for the first flag fragment.
    Event ID 1033 is the Windows installer completion record. Its Manufacturer field carries cGljb0NURntFdjNudF92aTN3djNyXw== - the trailing == and ASCII-only charset are Base64 giveaways. Decode it for the first third of the flag.
    bash
    grep -B2 -A25 'EventID>1033<' output.xml | grep -A1 Manufacturer
    bash
    # Sample raw field shows: <Data Name="Manufacturer">cGljb0NURntFdjNudF92aTN3djNyXw==</Data>
    echo 'cGljb0NURntFdjNudF92aTN3djNyXw==' | base64 -d
    # -> picoCTF{Ev3nt_vi3wv3r_

    Expected output

    picoCTF{Ev3nt_vi3wv3r_
    1s_a_pr3tty_us3ful_
    t00l_...}
    What didn't work first

    Tried: Grepping for the Event ID using plain text like 'EventID 1033' without the angle-bracket syntax

    The XML dump wraps IDs as 'EventID>1033<', so a plain-text grep for 'EventID 1033' returns zero results. The raw EVTX is binary and the dump produces XML, so the search pattern must match the XML tag format exactly.

    Tried: Looking for the Base64 data directly with 'grep -i base64 output.xml'

    The embedded Base64 is stored in a named Data field with no label indicating it is Base64 - it just looks like an opaque string. Searching for the word 'base64' returns nothing. You have to grep for the Manufacturer field by name and inspect its value, then recognize the '==' padding as a Base64 indicator.

    Learn more

    Windows Event Log (.evtx) files are binary logs that record system activity, security events, and application messages. The EVTX format replaced the older .evt format in Windows Vista and stores events in a structured binary format with XML-encoded content inside each record. Each event is identified by an Event ID number that describes the type of activity recorded.

    Event ID 1033 is generated by the Windows Installer (MSI) subsystem when a product installation completes. It records the product name, version, language, manufacturer, and installation result code. Attackers who install malicious software on a compromised host will generate Event ID 1033 entries, making it a useful forensic artifact for detecting unauthorized software installations.

    Tools for parsing EVTX files without Windows Event Viewer include python-evtx (pure Python EVTX parser), EvtxEcmd (Eric Zimmerman's command-line tool that exports to CSV/JSON/XML), and Chainsaw (a Rust-based tool designed for threat hunting in EVTX files). On Linux, python-evtx is the most accessible option.

  2. Step 2
    Review Event ID 4657
    Observation
    I noticed the challenge described a registry change as the second key event, which pointed to Event ID 4657 (registry value modified) in the Security log, and the new value field on that event type is the most attacker-controlled place to hide encoded data.
    The registry-value modification event records the new value Immediate Shutdown (MXNfYV9wcjN0dHlfdXMzZnVsXw==). Decode the parenthesised Base64 chunk to get the middle third of the flag.
    bash
    echo 'MXNfYV9wcjN0dHlfdXMzZnVsXw==' | base64 -d
    # -> 1s_a_pr3tty_us3ful_
    What didn't work first

    Tried: Searching the Security.evtx file with 'grep EventID 4657 Security.evtx' before running evtx_dump.py

    Security.evtx is a binary file, not plain text. Running grep on it directly produces garbage output or no matches at all. The evtx_dump.py step must happen first to produce the XML representation that grep can reliably parse.

    Tried: Decoding the entire parenthesised string 'Immediate Shutdown (MXNfYV9wcjN0dHlfdXMzZnVsXw==)' as Base64 instead of just the inner token

    Passing the full string with the surrounding words and parentheses to base64 -d produces an error or garbled output because the parentheses and spaces are not valid Base64 characters. Only the token between the parentheses - 'MXNfYV9wcjN0dHlfdXMzZnVsXw==' - is the Base64-encoded fragment.

    Learn more

    Event ID 4657 - "A registry value was modified" - is logged by the Security audit subsystem when a monitored registry key is changed. This event requires the Audit Registry policy to be enabled and the specific registry key to have SACL (System Access Control List) auditing configured. It records the key path, old value, new value, and the process that made the change.

    Registry modifications are a key indicator of compromise. Attackers use the registry for persistence (adding run keys like HKCU\Software\Microsoft\Windows\CurrentVersion\Run), for storing payloads, and for disabling security features. Event ID 4657 allows defenders to detect and timeline these changes, making it one of the most valuable Security log events for incident response.

    The Windows Registry is a hierarchical database storing configuration for the OS and applications. Understanding its structure - hives like HKLM (local machine), HKCU (current user), and HKCR (class root), along with key paths for persistence, services, and security settings - is foundational knowledge for both offensive and defensive Windows security work.

  3. Step 3
    Capture Event ID 1074
    Observation
    I noticed the challenge listed a forced shutdown as the third required event, which mapped to Event ID 1074, and the free-text Comment field on shutdown events is the natural place to look for an attacker-controlled payload after the first two fragments surfaced in similar free-text fields.
    The shutdown log's Comment field hides the final chunk dDAwbF84MWJhM2ZlOX0=. Decode it, concatenate all three pieces, and paste the full flag back into the picoCTF challenge form to verify it's accepted.
    bash
    grep -B2 -A20 'EventID>1074<' output.xml | grep -A1 Comment
    bash
    echo 'dDAwbF84MWJhM2ZlOX0=' | base64 -d
    # -> t00l_...}
    # Submit the concatenated flag to picoCTF to confirm.
    What didn't work first

    Tried: Submitting just the final decoded chunk 't00l_...}' as the flag without concatenating all three parts

    Each of the three events contributes one third of the flag. The final decoded chunk ends with '}' which looks like a complete flag suffix, but it has no 'picoCTF{' prefix and is missing the two middle segments. The full flag is only obtained by joining all three Base64-decoded strings in order.

    Tried: Grepping for Comment in the full output.xml without first filtering to EventID 1074 events

    The word 'Comment' appears in many event records across the log. Grepping the entire output.xml for 'Comment' without pre-filtering to EventID 1074 returns dozens of unrelated hits and buries the relevant entry. Piping through the EventID 1074 grep first narrows the results to the single event that holds the flag fragment.

    Learn more

    Event ID 1074 - "The process X has initiated the restart / shutdown of computer Y on behalf of user Z for the reason: reason" - is logged when a shutdown or restart is initiated programmatically. It records the initiating process, the reason code, and a free-text comment field. Unexpected shutdowns are often a sign of ransomware, destructive malware, or an attacker clearing tracks.

    The challenge hides flag segments in the Manufacturer and Comment fields of events - fields that are free-text and controlled by whoever generates the event. This mirrors a real attacker technique: embedding exfiltration data or command-and-control signals in log fields that are less likely to be scrutinized. Defenders should treat unexpected Base64 strings in event fields as suspicious.

    Assembling the flag from three separate events teaches the forensic skill of timeline correlation: linking events across different log sources and event types to reconstruct an attacker's actions. Tools like Plaso (log2timeline) and Timesketch automate this correlation across dozens of artifact types simultaneously, giving investigators a unified timeline of system activity.

Flag

Reveal flag

picoCTF{Ev3nt_vi3wv3r_1s_a_pr3tty_us3ful_t00l_...}

Any Base64 decoding method works; the challenge is recognizing which events hide the chunks.

Key takeaway

Windows Event Logs are structured audit trails that record every significant system action with a numeric Event ID, a timestamp, and free-text fields. Because those free-text fields (Manufacturer, Comment, Description) accept arbitrary strings, attackers and challenge designers alike can embed encoded payloads in logs that forensic analysts must learn to recognize. Reading EVTX files with tools like python-evtx or Chainsaw and correlating multiple Event IDs across time is a core digital forensics skill, applying equally to incident response, threat hunting, and CTF log challenges.

Related reading

Want more picoCTF 2025 writeups?

Useful tools for Forensics

What to try next