// HackTheBox  ·  writeup

SalineBreeze-2

HackTheBox Easy Pythonobjdumpstringssha256sumbase64
Malware Analysis

Scenario

In this Sherlock, players will investigate the Demodex rootkit attributed to Salt Typhoon.

Executive Summary

The sample is a PowerShell dropper for the Demodex rootkit. The script holds an AES-encrypted, base64-encoded payload and decrypts it with a key passed on the command line. That key is a weak password, so it falls to a wordlist attack. The decrypted second stage writes an embedded DLL into the registry as binary data, registers a new service under a custom svchost group, and starts it. The DLL is a service DLL whose ServiceMain loops with a variable sleep and a fixed delay. Everything was recovered statically; nothing was executed.

Artifacts

Timestamp note: No timestamps are involved, so there is no Forensic Timeline for this case.

Execution

Q1 — What is the name of the malware family associated with the provided file?

The scenario names the rootkit and the actor: Demodex, attributed to Salt Typhoon. The family name is read from the brief, not from the sample, which carries no family string in the loader.

Click flag to reveal Demodex
Q2 — What .NET cryptographic class is used to perform decryption in the script?

Unzip the sample and open onedrived.ps1. The class name is not written in the clear: the script keeps it as a base64 string and decodes it at run time before instantiating it. Decoding that string gives the AES implementation class from System.Security.Cryptography.

unzip -P "$(cat DANGER.txt)" danger.zip -d work/x

Tip: The format mask has the shape of a dotted namespace followed by a class name, so look for a base64 string that decodes to that.

Click to reveal answer System.Security.Cryptography.AesManaged
Q3 — The key to decrypt the script must be entered on the command line when running the ps1. What variable holds the key?

The top of the script declares its parameter by reading the first argument: [string] $k=$args[0]. That variable is the decryption key supplied by the operator at launch, so the key is never stored in the file.

Click flag to reveal $k

Defense Evasion

Q4 — What is the key required to decrypt the base64 encoded data?

The key is not in the sample, but the algorithm is AES and the script’s plaintext has a predictable start, so a wordlist attack can be validated automatically. Run each rockyou.txt entry as the key and accept the one that yields a script beginning with $svchostdata. One candidate decrypts cleanly. This answer was found by brute force against a known plaintext prefix rather than read from an artifact.

python3 -I work/brute.py

The recovered key then decrypts the payload to the second-stage script:

python3 -I work/dec.py

Gotcha: The key length in the format mask is twelve characters, which fits a short human-chosen password. That is why the wordlist works.

Click to reveal answer password@123
Q5 — After decrypting the initial payload, a new PowerShell script assigns a value to the variable $cregvalue. What is that value?

From Q4 the stage-2 script is readable. Search it for $cregvalue: it is assigned a short string that is used as a registry value name for the stored DLL data.

Click flag to reveal midihelp
Q6 — The variable $cregdata is associated with binary registry data stored as a base64 blob. What is the SHA-256 hash of the binary data?

Copy the base64 blob assigned to $cregdata in stage 2, decode it to bytes, and hash the decoded bytes, not the base64 text. The decoded bytes are the DLL that later questions analyse.

base64 -d cregdata.b64 > work/msmp4dec.dll && sha256sum work/msmp4dec.dll

Gotcha: Hashing the base64 string gives a different value. The question asks for the hash of the binary data.

Click to reveal answer 3b1c251b0b37b57b755d4545a7dbbe4c29c15baeca4fc2841f82bc80ea877b66

Persistence

Q7 — What is the name of the malicious service?

Stage 2 stores the service name in $svcname and uses it for the service registration and the start call.

Click flag to reveal MsMp4Hw
Q8 — What is the full path of the malicious DLL?

$svcdllpath in stage 2 holds the location the DLL is written to and the service points at. It sits in System32 under a name that imitates a Microsoft media component.

Click to reveal answer C:\Windows\System32\msmp4dec.dll
Q9 — What registry path is used to associate the service group (msgroup) with the malicious service, so that it can be launched by svchost.exe?

Svchost groups are defined as values under the SvcHost key. Stage 2 calls New-ItemProperty with -Name $svcgroup on that key, which is what ties the custom group to the service so svchost loads the DLL.

Tip: The format mask uses the PowerShell drive form with a colon after the hive, so answer with HKLM:\... rather than HKEY_LOCAL_MACHINE\....

Click flag to reveal HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost
Q10 — What is the line of code responsible for starting the malicious service after it has been installed?

It is the last line of stage 2, which starts the service by the name held in $svcname.

Gotcha: The format mask includes the trailing semicolon, so it belongs in the answer.

Click to reveal answer Start-Service -name $svcname;

Defense Evasion and Execution (DLL)

Q11 — Which Windows API does the DLL import to obtain the local computer name?

Extract the DLL from the Q6 blob and list its strings. The import names are readable, and the computer-name call is the ANSI variant.

strings -a work/msmp4dec.dll | grep -i computername
Click flag to reveal GetComputerNameA
Q12 — In service DLLs, which function is typically responsible for being called by the Service Control Manager to initiate the service?

A service DLL loaded by svchost exports ServiceMain, which the Service Control Manager calls on start. The Q8 DLL exports it. This is general Windows service behaviour, confirmed against the DLL’s export table.

Click to reveal answer ServiceMain
Q13 — Inside the previously named function, there are two calls to Sleep: one uses a variable argument and one uses a hard-coded delay. What is the value of the hard-coded delay (in milliseconds)?

Disassemble ServiceMain from Q12. Its control flow is flattened, so follow the calls to Sleep rather than reading top to bottom. One passes a register holding a variable, the other loads an immediate into ecx just before the call: mov ecx,0x2710 at 0x180001fad, which is 10000 in decimal.

objdump -d -M intel work/msmp4dec.dll | grep -B3 'call.*Sleep'

Gotcha: The immediate is hex. Convert 0x2710 to decimal before answering.

Click flag to reveal 10000

Attack Summary

PhaseAction
ExecutionPowerShell loader onedrived.ps1 run with the decryption key as its first argument
Defense EvasionAES-encrypted, base64-encoded second stage decrypted in memory
Defense EvasionClass name hidden as a base64 string inside the loader
PersistenceEmbedded DLL stored as base64 registry data and written to System32
PersistenceCustom svchost group registered under the SvcHost key
ExecutionService created and started with Start-Service
ExecutionServiceMain in the DLL loops with a variable and a fixed 10 second sleep

IOCs

TypeValue
File (loader)onedrived.ps1
File (DLL)C:\Windows\System32\msmp4dec.dll
SHA-256 (DLL)3b1c251b0b37b57b755d4545a7dbbe4c29c15baeca4fc2841f82bc80ea877b66
ServiceMsMp4Hw
Registry valuemidihelp
Registry keyHKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost
Decryption keypassword@123

MITRE ATT&CK

TechniqueIDDescription
Command and Scripting Interpreter: PowerShellT1059.001Loader and stage 2 are PowerShell
Obfuscated Files or Information: Encrypted/Encoded FileT1027.013AES-encrypted, base64-encoded payload and base64-hidden class name
Modify RegistryT1112DLL stored as binary registry data and a new svchost group value written
Create or Modify System Process: Windows ServiceT1543.003MsMp4Hw service installed to load the DLL through svchost
System Services: Service ExecutionT1569.002Service started with Start-Service

Defender Takeaways

A weak password protecting a payload is a weak lock. The loader’s key sat in a common wordlist and the plaintext had a known prefix, so the payload opened in seconds. Triage of encrypted droppers should try a wordlist against the known script header before reaching for heavier tooling.

New values under the SvcHost key are rare and worth alerting on. The persistence depends on adding a custom group under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost. Monitor writes to that key and flag service creation whose ServiceDll is a recently written file in System32.

Large binary registry values are a hiding place. The DLL travelled as base64 and was stored as registry data. Flag PowerShell that decodes a big base64 string and writes it as a binary registry value, and review PowerShell script block logs for New-ItemProperty against service-related keys.

Name-matching a Microsoft component is not trust. msmp4dec.dll and MsMp4Hw imitate media components. Check the signature and the file’s origin, not the name.

Conclusion

The Demodex dropper turned a PowerShell script into a svchost-hosted service with an embedded DLL, and its only secret was a password that sat in a wordlist. The loader’s protection was thin; detection value lies in the SvcHost registry write and the service start.