In this Sherlock players will investigate KAPE output to see the Windows management instrumentation artifacts and persistence left by a Threat actor using the machine to pivot to an internal workstation.
An attacker authenticated over the network with the account Werni and drove the host through Impacket’s WMI remote shell, so every command ran as a child of the WMI provider host and wrote its output to a file on the ADMIN$ share. After some reconnaissance they mapped a hostname to their own server in the hosts file, then created a scheduled task that runs a PowerShell script from the user’s profile every two minutes as SYSTEM. The script creates a randomly named local administrator with a timestamp-based password, enables RDP and posts the new credentials to the mapped hostname. The attacker then switched off the firewall and added a netsh port proxy that exposes an SSH service on an internal workstation through the compromised host. Process-creation auditing with command lines, enabled earlier by the administrator, is what made all of it readable.
winevt/logs folder → parse with EvtxECmd, then filter the CSV. Security 4688 (with command lines), 4624 and 4720 carry the storyC/Users/Werni/AppData/Local/JM.ps1 → read as text. The persistence payloadConsoleHost_history.txt under the Administrator profile → read as textregipy, used only for the time zoneTimestamp note:
EvtxECmdprints UTC. The host itself runs on Pacific Daylight Time (UTC-7), and that offset matters for Q9 because the script builds its password from local time.
Start here, because it explains why the rest of the case is readable at all. 4688 events only carry a command line when the ProcessCreationIncludeCmdLine_Enabled policy value is set. The Administrator’s PowerShell history file holds the reg add that set it, run before the intrusion window.
grep -ri "ProcessCreationIncludeCmdLine" evidence/C/Users/Administrator/AppData/Roaming/Microsoft/Windows/PowerShell/PSReadLine/ConsoleHost_history.txt
Parse every log with EvtxECmd, then pull Security 4688 process creations out of the CSV. The unfiltered list is mostly service noise, so filter on the parent process (see Q2). The earliest attacker child is a cmd.exe /Q /c wrapper whose real payload is systeminfo, redirected to a file on \\127.0.0.1\ADMIN$. Earlier lines in the session are cd calls, which the question excludes.
EvtxECmd -d evidence/C/Windows/System32/winevt/logs --csv work/evtx
grep "WmiPrvSE.exe" work/p4688.txt | head
Gotcha: The first full dump of 4688 events is far too noisy to read. Filter on the parent process rather than scrolling.
Every attacker cmd.exe in the 4688 data has the same parent: the WMI provider host. Legitimate WMI use rarely produces interactive-looking cmd.exe children, so a long run of them is the signal.
grep "cmd.exe /Q /c" work/p4688.txt | cut -d'|' -f1 | sort | uniq -c
The command shape gives it away: cmd.exe /Q /c <command> 1> \\127.0.0.1\ADMIN$\__<epoch> 2>&1. That quiet-mode wrapper, the output redirected to a timestamp-named file on ADMIN$, and the WMI parent together match Impacket’s WMI shell. This is reasoned from the command pattern, not from a tool artifact on disk.
grep -o '1> \\\\127.0.0.1\\ADMIN\$\\__[0-9.]*' work/p4688.txt | sort -u
The 4688 events do not carry a source address, so pivot to 4624 logons around the first command. The Werni account shows type 3 network logons using NTLM from one address, matching the remote WMI activity.
grep "4624" work/evtx/*.csv | grep -i "Werni" | grep -i "NTLM"
Search the WMI-spawned commands for schtasks. The earliest persistence is a scheduled task created at 23:03:50 UTC, set to run every two minutes as SYSTEM, and named to look like a routine update job.
grep "schtasks" work/p4688.txt
From Q5, the /tr argument of the same schtasks /create line is a hidden, execution-policy-bypassing PowerShell launch of a script in the Werni profile.
grep "schtasks" work/p4688.txt | grep -o '\-File [^ ]*'
Note: The task line spells the path
Appdata; the file on disk is underAppData\Local. Windows paths are case-insensitive.
JM.ps1 picks a name at random from a list of five update-service lookalikes, so the script alone cannot tell you which one ran. Security 4720 (user account created) settles it, at 23:05:09 UTC, about a minute after the task was registered.
cat evidence/C/Users/Werni/AppData/Local/JM.ps1
grep ",4720," work/evtx/*.csv
The script builds the password as Watson_ plus (Get-Date).ToString("yyyyMMddHHmmss"), so the answer is the creation time in the host’s local clock. No log held the literal password, so this one is reasoned rather than read from an artifact. The 4720 event for the account is at 23:05:09 UTC. The SYSTEM hive reports the time zone as Pacific Daylight Time, UTC-7, which makes the local timestamp 16:05:09 on 2025-08-24. The seconds value is the only inferred part, and HTB accepted it.
python3 -I -c "from regipy.registry import RegistryHive; print(RegistryHive('SYSTEM').get_key('ControlSet001\\\\Control\\\\TimeZoneInformation').get_values(as_json=True))"
Gotcha: Using the UTC time from the event log produces a password that is seven hours off. The script formats local time.
The last line of JM.ps1 sends the new user|password pair, base64 encoded, to a hostname with Invoke-WebRequest. That name does not resolve publicly, and the attacker made it work by appending it to the hosts file through WMI at 23:00:15 UTC, pointing it at their own address from Q4.
grep -ri "NapoleonsBlackPearl" evidence/ work/p4688.txt
After the firewall was disabled with netsh advfirewall, the attacker ran netsh interface portproxy add v4tov4 at 23:10:05 UTC. The connectaddress is the internal target.
grep "portproxy" work/p4688.txt
Same command as Q10. listenport is the port opened on the victim, bound to 0.0.0.0, and connectport=22 shows it relays to SSH on the internal host.
grep "portproxy" work/p4688.txt | grep -o "listenport=[0-9]*"
Reference knowledge: the iphlpsvc port proxy rules persist in the SYSTEM hive under the PortProxy service key, with one subkey per protocol pairing. It is the place to confirm a port proxy offline and to find rules that survive a reboot.
A port proxy on a compromised host that relays traffic to another internal host is Proxy: Internal Proxy, a sub-technique of T1090.
| Phase | Action |
|---|---|
| Lateral Movement | Network logons as Werni from the attacker host, then Impacket WMI shell |
| Execution | systeminfo and file reads through cmd.exe /Q /c under WmiPrvSE.exe |
| Command and Control | Hosts file entry maps the exfil hostname to the attacker address |
| Persistence | SYSTEM scheduled task SysHelper Update runs JM.ps1 every two minutes |
| Persistence | JM.ps1 creates a random local admin and enables RDP |
| Exfiltration | Credentials posted to the mapped hostname over HTTP |
| Defense Evasion | Windows Firewall disabled for all profiles |
| Command and Control | netsh port proxy forwards a local port to SSH on an internal workstation |
| Timestamp (UTC) | Event |
|---|---|
| 2025-08-24 22:51:09 | First attacker command, systeminfo, via WMI |
| 2025-08-24 22:55:10 | type known_hosts run through the WMI shell |
| 2025-08-24 23:00:15 | Hosts file entry added for the exfil hostname |
| 2025-08-24 23:03:50 | Scheduled task SysHelper Update created |
| 2025-08-24 23:05:09 | Local account svc_netupd created (4720) |
| 2025-08-24 23:05:46 | Firewall disabled, retried at 23:06:08 |
| 2025-08-24 23:10:05 | Port proxy added to the internal host |
| Type | Value |
|---|---|
| IP (attacker) | 10.129.242[.]110 |
| IP (pivot target) | 192.168.1[.]101 |
| Domain (exfil) | NapoleonsBlackPearl[.]htb |
| Scheduled task | SysHelper Update |
| File | C:\Users\Werni\AppData\Local\JM.ps1 |
| Account | svc_netupd |
| Password | Watson_20250824160509 |
| Port proxy | 0.0.0.0:9999 to 192.168.1.101:22 |
| Registry | HKLM\SYSTEM\CurrentControlSet\Services\PortProxy\v4tov4\tcp |
| Technique | ID | Description |
|---|---|---|
| Windows Management Instrumentation | T1047 | Impacket WMI shell, commands spawned by WmiPrvSE.exe |
| Remote Services: SMB/Windows Admin Shares | T1021.002 | Command output written to ADMIN$ |
| Scheduled Task/Job: Scheduled Task | T1053.005 | SysHelper Update runs JM.ps1 as SYSTEM every two minutes |
| Create Account: Local Account | T1136.001 | svc_netupd added to Administrators and Remote Desktop Users |
| Exfiltration Over Alternative Protocol | T1048 | New credentials posted over HTTP to the mapped hostname |
| Impair Defenses: Disable or Modify System Firewall | T1562.004 | netsh advfirewall set allprofiles state off |
| Proxy: Internal Proxy | T1090.001 | netsh interface portproxy relay to an internal SSH host |
Command-line auditing is what made this case solvable. The administrator had set ProcessCreationIncludeCmdLine_Enabled before the intrusion, so every 4688 carried the full command. Without it the WMI activity would have been a list of bare cmd.exe launches. Enable it on every host, and add PowerShell script block logging.
WmiPrvSE.exe spawning cmd.exe /Q /c with output to ADMIN$ is a ready-made detection. The pattern is stable across Impacket versions. Alert on cmd.exe children of WmiPrvSE.exe, and treat the \\127.0.0.1\ADMIN$\__<epoch> redirect as a high-confidence match.
A SYSTEM scheduled task launching a script from a user profile is out of place. powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File against AppData\Local on a two-minute interval should fire on 4698 task-creation events. Scripts that run as SYSTEM should live in locations that standard users cannot write to.
Watch for portproxy rules and firewall changes. A netsh interface portproxy add followed by a firewall disable is a pivot setup. Monitor the PortProxy registry key and netsh advfirewall commands, and check the key during triage on any host that sits between network segments.
Script-generated passwords built from the clock are guessable. Watson_ plus a timestamp is recoverable from the account creation time alone, so even without the exfil traffic the credential could be rebuilt. Rotate any account like this, and alert on new local administrators created outside change windows.
The attacker used one valid account and a WMI shell to plant a SYSTEM task, a backdoor administrator and a port proxy toward an internal SSH host, all with built-in Windows tooling. The whole chain showed up in process-creation events because command-line auditing was on, which is the control that separated a readable incident from an invisible one.