// HackTheBox  ·  writeup

Nuts

HackTheBox Medium MFTECmdPECmdEvtxECmdAmcacheParserVirusTotalPython
DFIR

Scenario

As the team was nearing the deadline for pushing their project to production, one of the engineers, Alex, took charge of the deployment process. Alex had been exploring ways to expedite the deployment process and had recently discovered a package that promised to streamline the process significantly. Excited about the prospect of saving time, Alex decided to utilise this package for the deployment. As Alex began the deployment process using the package, he noticed that the CPU usage on the deployment server started to spike unusually high. Concerned about this anomaly, he decided to ask for help. A Triage image has been acquired for your examination. Your primary objective is to ascertain the means by which this malware infiltrated our organisation, successfully evading our existing security measures.

Executive Summary

A deployment engineer installed a NuGet package whose name was one letter off a legitimate one. The package shipped an init.ps1 that NuGet runs on install, and that script switched off Defender real-time protection before the attacker’s payload landed. The payload was a Sliver implant, which beaconed to the attacker, ran whoami as its first enumeration step, and registered a scheduled task named to look like a Microsoft update job. A second binary was later dropped into ProgramData and renamed after it had run. Defender caught it anyway, because only real-time scanning had been disabled. The whole chain is recoverable from the PowerShell history, the MFT and USN journal, prefetch, the Defender logs and the scheduled task XML.

Artifacts

Timestamp note: Q4 wants YYYY-MM-DD HH:MM with no seconds, while Q11, Q12, Q15 and Q19 want seconds. Zimmerman CSVs are already UTC.

Initial Access

Q1 — What action did Alex take to integrate the purported time-saving package into the deployment process? (provide the full command)

Alex’s PowerShell console history is the first place to look for a “what did the user type” question. ConsoleHost_history.txt holds the nuget install line with the package name and the exact version pin.

cat ConsoleHost_history.txt
Click flag to reveal nuget install PublishIgnor -Version 1.0.11-beta
Q2 — Identify the URL from which the package was downloaded.

The package name from Q1 resolves to its nuget.org page. The local .nupkg.metadata and NuGet.Config confirm the default nuget.org source was used. The package has since been removed, but the page for the pinned version still shows its details (https://www.nuget.org/packages/PublishIgnor/1.0.11-beta).

cat NuGet.Config .nupkg.metadata

Gotcha: The format hint ends in a trailing slash and the answer is the package page, not the version-specific URL you see in your browser bar.

Click to reveal answer https://www.nuget.org/packages/PublishIgnor/
Q3 — Who is the threat actor responsible for publishing the malicious package? (the name of the package publisher)

The local package files do not name a publisher, so this one comes from the web. The nuget.org page for the pinned version lists its owner (https://www.nuget.org/packages/PublishIgnor/1.0.11-beta).

Click flag to reveal a1l4m
Q4 — When did the attacker initiate the download of the package? Provide the timestamp in UTC format (YYYY-MM-DD HH:MM).

The download lands in the NuGet cache as a .nupkg. Parse the $MFT and look at the created timestamp of publishignor.1.0.11-beta.nupkg: 18:41:54, so the answer truncates to the minute.

MFTECmd -f '$MFT' --csv work/mft
Click to reveal answer 2024-03-19 18:41
Q5 — Despite restrictions, the attacker successfully uploaded the malicious file to the official site by altering one key detail. What is the modified package ID of the malicious package?

The .nuspec inside the cached package carries the <id> the attacker registered. It is the name of the real package (PublishIgnore) with the final letter dropped, which is how the upload got past the name already being taken.

cat publishignor.nuspec

Gotcha: The format mask is 12 characters ending in r. Read the <id> from the nuspec rather than copying the legitimate package name.

Click flag to reveal PublishIgnor
Q6 — Which deceptive technique did the attacker employ during the initial access phase to manipulate user perception? (technique name)

A package ID one character away from a legitimate one, published to the same registry, is typosquatting. This answer was reasoned from the Q5 finding rather than read from an artifact.

Click to reveal answer typosquatting

Execution

Q7 — Determine the full path of the file within the package containing the malicious code.

NuGet runs tools\init.ps1 automatically when a package is installed into a project, so that is the file to read. It sits in the extracted package folder under the Administrator profile and holds the Defender tampering from Q8.

cat '.nuget/packages/publishignor/1.0.11-beta/tools/init.ps1'
Click flag to reveal C:\Users\Administrator\.nuget\packages\publishignor\1.0.11-beta\tools\init.ps1

Defense Evasion

Q8 — When tampering with the system's security settings, what command did the attacker employ?

The same init.ps1 from Q7 holds the command. The PowerShell and Defender events from EvtxECmd agree that real-time monitoring was switched off just before the payload arrived.

EvtxECmd -d winevt/logs --csv work/evtx
Click to reveal answer Set-MpPreference -DisableRealtimeMonitoring $true

Command and Control

Q9 — Following the security settings alteration, the attacker downloaded a malicious file to ensure continued access to the system. Provide the SHA1 hash of this file.

The file is uninstall.exe, created at 19:23:36 in the $J journal. Defender’s MPLog records the file’s hash in its cloud lookup (SDN query) lines, so search the support logs for the filename rather than hashing a sample.

grep -ri 'uninstall.exe' 'ProgramData/Microsoft/Windows Defender/Support/'
Click flag to reveal 57b7acf278968eaa53920603c62afd8b305f98bb
Q10 — Identify the framework utilised by the malicious file for command and control communication.

The Defender detection event (ID 1116) for the Q9 file names the threat as VirTool:Win32/Sliver.D!MTB, which gives the C2 framework.

grep -h ',1116,' work/evtx/*.csv
Click to reveal answer sliver
Q11 — At what precise moment was the malicious file executed?

Prefetch records the first run of UNINSTALL.EXE. PECmd over the prefetch folder shows 19:23:36, the same second the $J journal logs its creation.

PECmd -d Windows/prefetch --csv work/pf
Click flag to reveal 2024-03-19 19:23:36
Q12 — The attacker made a mistake and didn’t stop all the features of the security measures on the machine. When was the malicious file detected? Provide the timestamp in UTC.

Only real-time monitoring was disabled, so Defender’s other protection kept working. The Defender Operational log has a detection event (ID 1116) at 19:33:32, about ten minutes after execution.

grep -h ',1116,' work/evtx/*.csv
Click to reveal answer 2024-03-19 19:33:32

Discovery

Q13 — After establishing a connection with the C2 server, what was the first action taken by the attacker to enumerate the environment? Provide the name of the process.

Sort the prefetch output by last run time after the Q11 execution. The first new process is WHOAMI.EXE at 19:24:46, the classic first check of the current user and privileges.

PECmd -d Windows/prefetch --csv work/pf
Click flag to reveal whoami.exe

Persistence

Q14 — To ensure continued access to the compromised machine, the attacker created a scheduled task. What is the name of the created task?

The task definition is a UTF-16 XML file under Windows\System32\Tasks, so convert it before reading. The file name is the task name, styled after a Microsoft update job.

iconv -f UTF-16 -t UTF-8 Windows/System32/Tasks/MicrosoftSystemDailyUpdates

Hint: The format mask ends in s and is 26 characters. The name is styled after a Windows update job.

Click to reveal answer MicrosoftSystemDailyUpdates
Q15 — When was the scheduled task created? Provide the timestamp in UTC.

The task file’s $MFT creation time and the StartBoundary in its XML both give 19:24:05.

MFTECmd -f '$MFT' --csv work/mft
Click flag to reveal 2024-03-19 19:24:05

Defense Evasion (Second Payload)

Q16 — Upon concluding the intrusion, the attacker left behind a specific file on the compromised host. What is the name of this file?

Amcache and the USN journal show a second executable, file.exe, created in ProgramData well after the Sliver implant. Parse both and look for new executables in that folder.

AmcacheParser -f Amcache.hve --csv work/amcache
Click to reveal answer file.exe
Q19 — When was the file dropped onto the system? Provide the timestamp in UTC.

The $J journal has the FileCreate entry for file.exe in ProgramData at 19:30:04.

MFTECmd -f '$J' --csv work/j
Click flag to reveal 2024-03-19 19:30:04
Q17 — As an anti-forensics measure. The threat actor changed the file name after executing it. What is the new file name?

Following the same file through $J, a rename entry at 19:33:48 turns file.exe into a name that reads like a legitimate updater, 16 seconds after Defender’s detection in Q12.

MFTECmd -f '$J' --csv work/j
Click flag to reveal Updater.exe
Q18 — Identify the malware family associated with the file mentioned in the previous question (17).

Take the SHA1 of file.exe from Amcache and look it up on VirusTotal. The popular threat label reads impalastealer. The accepted family name is the short form. This was reasoned from the VirusTotal label rather than read from an artifact.

vt f58f3660...

Gotcha: Longer vendor labels (Paketer, Trojan.MSIL.PAKETER, Impala Stealer) were not accepted. The answer is one word.

Click to reveal answer Impala

Attack Summary

PhaseAction
Initial AccessTyposquatted NuGet package PublishIgnor published by a1l4m
Initial AccessAlex installs it with nuget install and the package lands in the cache
ExecutionNuGet runs tools\init.ps1 on install
Defense EvasionSet-MpPreference disables Defender real-time monitoring
Command and Controluninstall.exe, a Sliver implant, is dropped and run
Discoverywhoami.exe is the first enumeration command
PersistenceScheduled task MicrosoftSystemDailyUpdates created
Defense EvasionSecond binary file.exe dropped in ProgramData
Defense EvasionDefender detects it; the actor renames it to Updater.exe

Forensic Timeline

Timestamp (UTC)Event
2024-03-19 18:41:54publishignor.1.0.11-beta.nupkg created in the NuGet cache
2024-03-19 19:23:36uninstall.exe created and executed
2024-03-19 19:24:05Scheduled task MicrosoftSystemDailyUpdates created
2024-03-19 19:24:46whoami.exe runs
2024-03-19 19:30:04file.exe dropped in ProgramData
2024-03-19 19:33:32Defender detects the malicious file
2024-03-19 19:33:48file.exe renamed to Updater.exe

IOCs

TypeValue
NuGet packagePublishIgnor 1.0.11-beta
Publishera1l4m
URLhxxps[://]www[.]nuget[.]org/packages/PublishIgnor/
FileC:\Users\Administrator\.nuget\packages\publishignor\1.0.11-beta\tools\init.ps1
SHA1 (uninstall.exe, Sliver)57b7acf278968eaa53920603c62afd8b305f98bb
SHA1 (file.exe / Updater.exe)f58f3660...
Scheduled taskMicrosoftSystemDailyUpdates
FileUpdater.exe

MITRE ATT&CK

TechniqueIDDescription
Supply Chain Compromise: Compromise Software Dependencies and Development ToolsT1195.002Typosquatted NuGet package pulled in by the deployment engineer
Command and Scripting Interpreter: PowerShellT1059.001init.ps1 executes on package install
Impair Defenses: Disable or Modify ToolsT1562.001Set-MpPreference -DisableRealtimeMonitoring $true
Ingress Tool TransferT1105Sliver implant and the second binary brought onto the host
System Owner/User DiscoveryT1033whoami.exe as the first post-C2 command
Scheduled Task/Job: Scheduled TaskT1053.005MicrosoftSystemDailyUpdates
MasqueradingT1036Update-themed task name and the Updater.exe rename

Defender Takeaways

Package install scripts are code execution. NuGet runs init.ps1 the moment a package is installed, with no prompt. Pin and mirror approved packages on an internal feed, and block installs straight from the public registry on deployment servers.

Typosquatted names are cheap to catch. PublishIgnor is one character from a real package. Alert on package installs whose ID is a small edit distance from a known package, and review the publisher before first use.

Disabling real-time protection is a loud event. The Set-MpPreference call is visible in PowerShell logging and Defender’s configuration-change events. Turn on script block logging, enable Defender tamper protection, and alert on any change to DisableRealtimeMonitoring.

Partial tampering leaves detections behind. The actor only turned off real-time monitoring, and Defender still flagged the second binary about ten minutes later. Treat any detection that follows a Defender settings change as a live intrusion, not routine malware cleanup.

Look-alike task names hide persistence. MicrosoftSystemDailyUpdates is styled to pass as a Windows job. Baseline the task list and flag Microsoft-themed names that don’t match known tasks.

Conclusion

A one-letter typo in a package name gave the attacker code execution on a deployment server, and a single PowerShell line took out real-time protection long enough to run a Sliver implant. The attack failed to stay hidden only because Defender’s remaining features still fired, and the case shows how little stands between a mistyped nuget install and a foothold.