// HackTheBox  ·  writeup

Subatomic

HackTheBox Medium 7-ZippefileOpenSSLasarwebcrackNode.jsPython
Malware Analysis

Scenario

Subatomic is a medium difficulty Sherlock where you are tasked with analysing an electron focused malware sample on behalf of the Forela organisation due to the compromise of a Discord account. You will be tasked with answering questions directly relevant to the analysis of a sample currently found in the wild.

Warning:

This is a warning that this Sherlock includes software that is going to interact with your computer and files. This software has been intentionally included for educational purposes and is NOT intended to be executed or used otherwise. Always handle such files in isolated, controlled, and secure environments.

Once the Sherlock zip has been unzipped, you will find a DANGER.txt file. Please read this to proceed.

Executive Summary

The sample is an NSIS installer carrying a signed Electron application that poses as a Windows update tool. Inside the bundled app.asar sits a heavily obfuscated app.js whose real logic is an AES-encrypted stage decrypted at runtime. That stage fingerprints the host, bails out on known sandbox hostnames and VM processes, resolves the victim’s public IP, and registers with a hard-coded C2 API using a per-victim ID sent with every request. It then steals browser cookies, including Firefox’s, and rewrites a Discord desktop module so the client itself becomes the implant. A fallback routine pulls a replacement cmd.exe from the C2 into the user profile if the system one is missing. The whole chain was recovered statically; nothing was executed.

Artifacts

Timestamp note: No timestamps are needed in this case, every answer is a string read from the sample.

Execution

Q1 — What is the Imphash of this malware installer?

The installer is a PE, so the import hash comes straight from its import table. pefile computes it without loading anything.

python3 -I -c "import pefile,sys;print(pefile.PE(sys.argv[1]).get_imphash())" nsis-installer.exe
Click flag to reveal b34f154ec913d2d2c435cbd644e91687
Q2 — The malware contains a digital signature. What is the program name specified in the `SpcSpOpusInfo` Data Structure?

Pull the Authenticode blob out of the PE security directory and parse it as PKCS#7. The SpcSpOpusInfo attribute holds the program name as a BMPString, which strings misses because it is UTF-16, so decode it from the DER directly.

openssl pkcs7 -inform DER -in sig.der -print

Tip: Read the BMPString from the DER with a short script rather than eyeballing hex; the UTF-16 padding makes strings output look empty.

Click to reveal answer Windows Update Assistant
Q3 — The malware uses a unique GUID during installation, what is this GUID?

NSIS installers register an uninstall entry under Software\Microsoft\Windows\CurrentVersion\Uninstall\<GUID>, and that GUID is the installation identifier. The 7-Zip build used here (v26) did not emit the [NSIS].nsi script, so the compressed script header was inflated by hand (raw Deflate) and searched for GUIDs. The one sitting after the Uninstall key path is the answer.

python3 -I -c "import zlib,re,sys;d=zlib.decompressobj(-15).decompress(open(sys.argv[1],'rb').read());print(re.findall(rb'Uninstall\\\\[{]?([0-9a-fA-F-]{36})',d))" nsis_header_raw.bin

Gotcha: The header is not LZMA here. Trying LZMA first returns nothing; it is plain Deflate.

Click flag to reveal cfbc383d-9aa0-5771-9485-7b806e8442d5
Q4 — The malware contains a package.json file with metadata associated with it. What is the 'License' tied to this malware?

The installer unpacks to app-32.7z, which holds the Electron app.asar. Extracting the archive exposes package.json and the obfuscated app.js next to it. The license field is in the manifest.

7z x nsis-installer.exe -o ex && 7z x ex/app-32.7z -o app && npx asar extract app/resources/app.asar asar && grep license asar/package.json
Click to reveal answer ISC

Defense Evasion

Q9 — The malware checks for a number of hostnames upon execution, and if any are found it will terminate. What hostname is it looking for that begins with `arch`?

app.js is obfuscated with a string-table decoder, and webcrack only partly cleaned it. Rather than run the sample, only the decoder prelude was lifted into a standalone script to dump the string table, and that same prelude was then used to AES-decrypt the embedded stage (the key and IV parts come from the decoded strings). The decrypted payload.js is readable and contains the sandbox hostname blocklist.

node dec3.js asar/app.js > payload.js
grep -n -i 'arch' payload.js
Click flag to reveal archibaldpc
Q10 — The malware looks for a number of processes when checking if it is running in a VM; however, the malware author has mistakenly made it check for the same process twice. What is the name of this process?

The VM check is a list of process names in the decrypted stage. Dump the list and count duplicates; one VMware tools process appears twice.

grep -n -i 'vmware' payload.js
Click to reveal answer vmwaretray

Discovery

Q6 — The malware attempts to get the public IP address of an infected system. What is the full URL used to retrieve this information?

Search the decrypted stage for outbound HTTP calls. The victim’s public IP and geolocation are fetched from a third-party lookup service before the first C2 check-in.

grep -n -o -E "https?://[^'\" )]+" payload.js | sort -u
Click flag to reveal https://ipinfo.io/json

Command and Control

Q5 — The malware connects back to a C2 address during execution. What is the domain used for C2?

The stage holds an options object that carries the C2 configuration, including an api property. The host in that URL is the C2 domain.

grep -n -A6 'options' payload.js
Click flag to reveal illitmagnetic.site
Q7 — The malware is looking for a particular path to connect back on. What is the full URL used for C2 of this malware?

The same options.api value from Q5 is the full URL, path included. The trailing slash is part of it.

grep -n 'api' payload.js
Click to reveal answer https://illitmagnetic.site/api/
Q8 — The malware has a configured `user_id` which is sent to the C2 in the headers or body on every request. What is the key or variable name sent which contains the user_id value?

Follow the C2 request helper in payload.js. Every request builds its headers with the configured user_id under a fixed key name.

grep -n 'user_id' payload.js
Click flag to reveal duvet_user
Q11 — The malware has a special function which checks to see if `C:\Windows\system32\cmd.exe` exists. If it doesn't it will write a file from the C2 server to an unusual location on disk using the environment variable `USERPROFILE`. What is the location it will be written to?

checkCmdInstallation tests for the system cmd.exe. If it is missing, the function downloads a file from the C2 and calls writeFileSync to a path built from USERPROFILE.

grep -n -A12 'checkCmdInstallation' payload.js
Click flag to reveal %USERPROFILE%\Documents\cmd.exe

Credential Access

Q12 — The malware appears to be targeting browsers as much as Discord. What command is run to locate Firefox cookies on the system?

getFirefoxCookies shells out with execSync to find the profile’s cookie database, since Firefox profile folders have random names.

grep -n -B2 -A6 'getFirefoxCookies' payload.js
Click to reveal answer where /r . cookies.sqlite

Persistence

Q13 — To finally eradicate the malware, Forela needs you to find out what Discord module has been modified by the malware so they can clean it up. What is the Discord module infected by this malware, and what's the name of the infected file?

The injection routine overwrites a file inside the Discord desktop install under modules\. The module folder name carries a numeric suffix, which is what the answer needs, and the file it replaces is index.js.

grep -n -i 'discord_desktop_core' payload.js

Gotcha: The module is discord_desktop_core-1, not discord_desktop_core. Submitting the bare name from memory of the common Discord injector fails; copy the folder name as written in the sample.

Click flag to reveal discord_desktop_core-1, index.js

Attack Summary

PhaseAction
ExecutionSigned NSIS installer, presenting as a Windows update tool, drops an Electron app
Defense EvasionObfuscated app.js decrypts an AES-encrypted stage at runtime
Defense EvasionExits on known sandbox hostnames and VM processes
DiscoveryResolves the victim’s public IP through a lookup service
Command and ControlRegisters with the C2 API, sending a per-victim ID in the headers of every request
Command and ControlPulls a replacement cmd.exe from the C2 if the system one is missing
Credential AccessLocates and reads Firefox cookies alongside other browser data
PersistenceOverwrites index.js in the Discord desktop core module

IOCs

TypeValue
Imphashb34f154ec913d2d2c435cbd644e91687
Install GUIDcfbc383d-9aa0-5771-9485-7b806e8442d5
Domain (C2)illitmagnetic[.]site
URL (C2 API)hxxps[://]illitmagnetic[.]site/api/
URL (IP lookup)hxxps[://]ipinfo[.]io/json
Request headerduvet_user
File%USERPROFILE%\Documents\cmd.exe
File (tampered)modules\discord_desktop_core-1\index.js

MITRE ATT&CK

TechniqueIDDescription
Obfuscated Files or InformationT1027String-table obfuscation and an AES-encrypted stage inside app.js
Virtualization/Sandbox Evasion: System ChecksT1497.001Hostname blocklist and VM process list that terminate execution
System Network Configuration DiscoveryT1016Public IP lookup through ipinfo.io
Application Layer Protocol: Web ProtocolsT1071.001HTTPS check-ins to the C2 API with a per-victim header
Ingress Tool TransferT1105Replacement cmd.exe fetched from the C2 into the user profile
Steal Web Session CookieT1539Browser cookie theft, including Firefox via cookies.sqlite
Credentials from Password Stores: Credentials from Web BrowsersT1555.003Browser data targeted alongside Discord
Compromise Host Software BinaryT1554index.js in the Discord desktop core module overwritten

Defender Takeaways

A valid signature says who signed the installer, not what is in it. The installer carried an Authenticode signature with a plausible program name. Treat the signer, the SpcSpOpusInfo name and the actual product as three things to compare, and alert when a “Windows Update” style name comes from an NSIS installer.

Electron apps hide their logic in app.asar. Scanning the installer finds nothing useful; the manifest, the obfuscated script and the encrypted stage are one layer down. Unpack app.asar in triage and review package.json and the entry script before trusting the app.

Hard-coded C2 values make cheap blocks. The C2 domain, the API path and the distinctive per-victim header key are all constants in the decrypted stage. Hunt for the header key in proxy logs and block the domain.

Discord client tampering is a persistence signal. Modifying index.js under modules\discord_desktop_core-* makes the legitimate client run attacker code on every launch. File integrity monitoring on the Discord install directory catches it, and cleanup means reinstalling the client and rotating the account’s tokens.

Dropping cmd.exe into the Documents folder is an easy detection. Any cmd.exe outside System32 and SysWOW64, especially one written by a user-mode Electron process, should alert.

Conclusion

An Electron-wrapped stealer reached the Discord account by living inside a signed installer, an obfuscated script and a runtime-decrypted stage, and persisted by rewriting the Discord client itself. None of it needed execution to read; the sharpest lesson is that the C2, the victim identifier and the cleanup target were all plain constants once the layers were peeled.