A workstation triggered an alert after suspicious file access activity. The SOC captured a process memory dump shortly before the machine was isolated. Initial triage suggests it was a legitimate application that may have been used to access sensitive documents. Analyze the process dump to find out what happened.
Q1 (10 pts) - What is the first DLL sideloaded by the executable from its working directory?
WindowsCodecs.dll
Q2 (10 pts) - What DLL was subsequently loaded by the first DLL?
stage2.dll
Q3 (10 pts) - From what directory were these DLLs loaded?
C:\Users\MadEye\Downloads\Report Feb 4 92203\
Q4 (10 pts) - How many files were enumerated in the compromised user’s Private folder?
6
Q5 (15 pts) - What is the base address of the DLL referred to in Q2 (in hexadecimal)?
0x00007ff95a100000
Q6 (15 pts) - Consider the DLL referred to in Q2. What is the hexadecimal ThreadID executing code within that DLL?
0x1418
Q7 (15 pts) - At what virtual address (in hexadecimal) does the full path containing VendorWireInstructions.docx begin?
0x20366177940
Q8 (15 pts) - What is the flag hidden in the dump?
N/A
This challenge focused on analyzing a process memory dump, calc.DMP, from a compromised Windows system. The goal was to identify DLL sideloading behavior, suspicious file access, memory-resident artifacts, and the hidden flag hidden in memory.
Q1 / Q2 / Q3 — I started by extracting strings from the dump and looking for DLL references:
strings -a calc.DMP | grep -i dll
From that output, I found that WindowsCodecs.dll was loaded from the working directory, which answered Q1. I also found that stage2.dll was loaded after it, which answered Q2. The path tied to those DLLs was:
C:\Users\MadEye\Downloads\Report Feb 4 92203\
That gave the answer to Q3.
This confirmed the sideloading chain:
calc.exe -> WindowsCodecs.dll -> stage2.dll
Q4 — Next, I looked for references to the user’s private files:
strings -a calc.DMP | grep -i Private
That revealed documents such as:
VendorWireInstructions.docx
Tax_Reconciliation_Draft.pdf
Q4_Budget_Final.xlsx
Payroll_Adjustments_2025.csv
There were 6 files total, which answered Q4. This suggested the malware was enumerating sensitive documents, likely as part of reconnaissance before exfiltration.
Q5 — To inspect the module list more carefully, I parsed the dump with the Python minidump library:
MinidumpFile.parse("calc.DMP")
From the module list, I found:
0x7ff95a100000 stage2.dll
That gave the answer to Q5.
Q6 — I then checked the thread contexts and examined t.ContextObject.Rip values. I needed to find which thread was executing inside the stage2.dll address range:
0x7ff95a100000 - 0x7ff95a10a000
The thread whose RIP fell inside that range gave the Q6 answer.
Q7 — To answer Q7, I searched for the document path directly:
strings -a -td calc.DMP | grep VendorWireInstructions
This returned:
1384044 C:\Users\MadEye\Documents\Private\VendorWireInstructions.docx
I then converted the file offset to a virtual address using the minidump segment mapping:
VA = segment_base + (offset - segment_file_offset)
That produced the virtual address used for Q7.
Q8 — To analyze the second-stage payload more directly and look for the flag, I reconstructed the in-memory DLL:
python carve_stage2.py
That produced:
stage2_mem.bin: PE32+ DLL
This was much more useful than looking at raw memory alone, because it allowed me to focus on the payload itself.
From there, I searched the reconstructed DLL for possible flag material, including plaintext strings, encoded strings, and runtime-decoded values:
strings stage2_mem.bin | grep -iE 'flag|ncl|ctf|SKY'
floss stage2_mem.bin
The important point here was that the flag appeared to be hidden in memory artifacts rather than on disk. This also explained why the workflow for this challenge had to be:
extract -> reconstruct -> analyze
Overall, this challenge showed a DLL sideloading attack delivered through a legitimate executable, followed by a second-stage DLL that enumerated sensitive financial documents. One important limitation was that this was a process dump rather than a full memory image, so Volatility kernel plugins were not useful here. I had to rely on minidump parsing, manual reconstruction, and targeted carving instead.