Forensics Challenge 3 - Heap Hunter

Prompt

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.


Answers

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


Steps I Took

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.