North Korea’s Crypt: Hunting Ghosts
A new unnamed cross-platform malware component attributed to North Korean threat actors was delivered via a fake job interview coding challenge. The infection chain uses OS-specific stager scripts that create a hidden .vscode directory, download bootstrap scripts, and fetch a final payload (ghost.js/ghost.npl) that beacons to an unauthenticated C2 server at 141.94.148.39:1224. The C2 endpoint /api/checkStatus accepts victim registration without authentication, allowing mass fake-registration flooding for infrastructure takedown.
- filenameghost.jsFinal malware payload filename on Unix/macOS systems.
- filenameghost.nplFinal malware payload filename on Windows systems.
- filenamestager_mac.shInitial stager script for macOS systems.
- filenamestager_nix.shInitial stager script for Unix/Linux systems.
- filenamestager_win.ps1Initial stager script for Windows systems.
- filename.vscodeHidden directory created by the stager to camouflage downloaded binaries as Visual Studio Code components.
- filenamevscode-bootstrap.ps1Second-stage bootstrap script downloaded on Windows systems.
- filenamevscode-bootstrap.shSecond-stage bootstrap script downloaded on Unix/macOS systems.
- ip141[.]94[.]148[.]39C2 server receiving victim registration data and serving as the primary command-and-control endpoint for the ghost.js/ghost.npl payload.
- md52e3fdb5b8befdb9b48cb1a5468dfc164MD5 of stager_win.ps1.
- md538614d05a905eab3a0885b637bfbb8e8MD5 of stager_nix.sh.
- md54d7d3dfd3d99727f450ee0883e9f60e2MD5 of stager_mac.sh.
- md572c3eea054187471a5d00b8d7c721b42MD5 of deobfuscated ghost.js (deobf_ghost.js).
- md5b42652763f78183cf779811dc2cb13bbMD5 of vscode-bootstrap.ps1.
- md5d804d3b1114766fb48b3b369df9d2f47MD5 of ghost.js / ghost.npl final payload.
- md5d8cc49f56265ca137a73a275379704faMD5 of vscode-bootstrap.sh.
- md5ea31f66a5164a394ce3a7253db49dd79MD5 of package.json dropped by the malware.
- sha256338f34788c92489b4b9078d10a436df035fcae395f3ec2fd95d1e29d28e67efdSHA256 hash of the final payload (ghost.js on Unix / ghost.npl on Windows). 0 hits on VirusTotal at time of analysis.
- sha2565d036408ac731df4f2909385ca5c3a75766ab528bcd784668a4997cfa2acd947SHA256 of vscode-bootstrap.ps1, Windows second-stage bootstrap script.
- sha2566effad9fdee81589b37c60bbbae20483200bf53bee3e3c107b1aa47d2ac4ccb3SHA256 of package.json dropped by the malware.
- sha2566ffedf7ec3b9cea4c99ac7ff5b0e2fb8e68f0a6bfce7110ff6ab267bc485fbb3SHA256 of stager_mac.sh, macOS Bash stager.
- sha2569cb437ca697a7550163c4a66e8b766952d3ddf94f714bafac91132ad37e5ddfaSHA256 of vscode-bootstrap.sh, Unix second-stage bootstrap script.
- sha256db2b3c88d8ab1a55591b21d727812bc855da0e02e85e0bfe77d4335153090ac0SHA256 of stager_nix.sh, Unix Bash stager.
- sha256f63c498b9c42612447fdb757a59aa9a1bb2285e77f83af8224577f9478fd8f2dSHA256 hash of stager_win.ps1, the Windows PowerShell stager that initiates the infection chain.
- sha256fcbcaf9a00757fff176afed4b3b115227b02f11f0cca4a762b0b0f12723daa53SHA256 of deobfuscated ghost.js (deobf_ghost.js).
- urlhxxp://141[.]94[.]148[.]39:1224Base C2 URL on port 1224 hosting the victim registration API.
- urlhxxp://141[.]94[.]148[.]39:1224/api/checkStatusC2 API endpoint used by the malware to register newly infected victims by sending system information (hostname, IP, MAC address).
Detection / Hunteropenrouter
What Happened
A new piece of malware linked to North Korean hackers was discovered after a developer received a fake job offer with a coding challenge repository. The repository contained malicious scripts that disguised themselves as Visual Studio Code files. Once running, the malware collects information about the victim's computer (hostname, IP address, MAC address) and sends it to a control server. The control server had no authentication, meaning anyone could send fake data to it, which the researchers used to flood and effectively shut down the attacker's infrastructure. People applying for jobs, especially in tech, should be cautious of coding challenges from unfamiliar employers and verify the legitimacy of any repositories they are asked to review.
Key Takeaways
- New unnamed North Korean malware delivered via fake job interview coding challenge repositories, continuing the DPRK tradecraft pattern seen in InvisibleFerret, BeaverTail, and OtterCookie campaigns.
- Cross-platform infection chain uses OS-specific stagers (PowerShell on Windows, Bash on macOS/Unix) that create a hidden .vscode folder to camouflage downloaded payloads as Visual Studio Code components.
- Final payload (ghost.js on Unix, ghost.npl on Windows) uses a reused obfuscation technique from prior DPRK campaigns, making it trivially deobfustcatable.
- C2 server at 141.94.148.39:1224 accepts unauthenticated victim registration via /api/checkStatus, enabling mass fake-registration flooding as a takedown method.
- Malware collects hostname, OS release, platform, IP address, and MAC address and transmits them to the C2 using Base64-encoded configuration strings.
Affected Systems
- Windows workstations
- macOS systems
- Unix/Linux systems
- Node.js runtime environments
Vulnerabilities (CVEs)
None identified.
Attack Chain
- Initial Access: Attacker sends fake job offer with a coding challenge repository laced with malware to a target developer.
- Execution: OS-specific stager script (stager_win.ps1 / stager_mac.sh / stager_nix.sh) runs and creates a hidden .vscode directory.
- Staging: Stager downloads vscode-bootstrap script (.ps1 or .sh) into the fake .vscode folder; bootstrap surveys system info and checks/updates Node.js.
- Payload Delivery: Bootstrap downloads the final payload (ghost.js on Unix, ghost.npl on Windows) which is obfuscated with a reused DPRK obfuscation technique.
- Discovery & C2: Payload's getSystemInfo() collects hostname, OS release, platform, IP, and MAC address, then registers the victim via HTTP POST to C2 at 141.94.148.39:1224/api/checkStatus using a Base64-encoded key string.
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: No
- Other Detection Logic: No
No detection rules (YARA, Sigma, Snort/Suricata, KQL, SPL, EQL) are provided in the article. The article focuses on malware analysis and C2 infrastructure takedown methodology.
Detection Engineering Assessment
| Dimension | Rating | Rationale |
|---|---|---|
| EDR Visibility | Medium | The stager scripts and payload execution would generate process creation and file write events visible to EDR. However, the use of legitimate scripting languages (PowerShell, Bash, Node.js) and masquerading as VS Code components may blend with normal developer activity. |
| Network Visibility | High | C2 communication occurs over plain HTTP to a non-standard port (1224) with a specific endpoint path (/api/checkStatus). Network monitoring can detect this beaconing pattern and the IP-checking Vercel subdomain. |
| Detection Difficulty | Moderate | The C2 IP and endpoint are hardcoded and easily detectable via network signatures. The stager scripts have unique hashes with 0 VirusTotal hits. However, the .vscode folder masquerading and use of legitimate developer tooling (Node.js, PowerShell, Bash) may generate false positives in developer-heavy environments. |
Required Log Sources
- Process creation logs (Sysmon Event ID 1 / EDR equivalent)
- Network connection logs (Sysmon Event ID 3 / firewall logs)
- File creation logs (Sysmon Event ID 11)
- PowerShell script block logs (Event ID 4104)
- Bash command history / auditd logs on Linux/macOS
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Consider hunting for processes that create a hidden .vscode directory in unexpected locations (e.g., user home, temp directories) followed by file downloads into that directory, as this masquerading technique is used to camouflage malware payloads. | File creation events, process command-line logs | Execution / Staging | Medium — legitimate VS Code extensions or project scaffolding tools may create .vscode directories, but typically not in hidden form or outside project roots. |
| Consider hunting for outbound HTTP connections to port 1224 or to the specific C2 IP, especially from Node.js or scripting interpreter processes, as this indicates the payload beaconing to its C2 server. | Network connection logs, firewall logs, EDR network telemetry | Command and Control | Low — non-standard port 1224 and known malicious IP reduce false positive likelihood. |
| Consider hunting for Node.js processes (node.exe or node) executing JavaScript files with unexpected names like ghost.js or ghost.npl from non-standard directories, as these are the final payload filenames. | Process creation logs, file access logs | Execution | Low — the specific filenames are unusual for legitimate Node.js applications. |
| Consider hunting for script interpreters (PowerShell, Bash) that download files from external URLs and immediately execute them, particularly when the downloaded files are placed in hidden directories. | Process creation logs with command-line arguments, network connection logs correlated with process events | Initial Access / Execution | Medium — some legitimate CI/CD or development automation may exhibit similar patterns. |
Control Gaps
- Network-based IDS/IPS may not alert on HTTP traffic to non-standard ports if policy only inspects standard web ports (80/443).
- Application allow-listing controls would not block this malware since it uses legitimate scripting interpreters (PowerShell, Bash, Node.js) already present on developer machines.
- Email security gateways may not flag the initial lure if the coding challenge repository link is delivered via a legitimate platform (e.g., GitHub, email from a recruiter).
Key Behavioral Indicators
- Process ancestry: script interpreter (powershell.exe / bash) spawning Node.js to execute files from a hidden .vscode directory
- Network pattern: HTTP requests to port 1224 with path /api/checkStatus containing Base64-encoded system information
- File pattern: creation of ghost.js or ghost.npl in a hidden .vscode folder under user directories
- Behavioral pattern: stager script creating hidden directory, downloading bootstrap, then downloading payload in sequence
False Positive Assessment
Medium — the malware uses legitimate developer tooling (PowerShell, Bash, Node.js) and masquerades as Visual Studio Code components, which may generate false positives in developer-heavy environments. However, the specific C2 IP, non-standard port, and unique payload filenames reduce overall false positive risk.
Recommendations
Immediate Mitigation
- Verify against your organization's incident response runbook and team escalation paths before acting. Consider blocking IP 141.94.148.39 and the URL ip-checking-psi.vercel.app at your firewall, proxy, and DNS filtering layers if not already blocked.
- Consider searching endpoint telemetry for the listed SHA256 and MD5 hashes across your fleet to identify any compromised hosts.
- If your EDR supports it, consider creating file hash-based detections for the stager and payload files listed in the IOC section.
- Evaluate whether any developers in your organization have recently participated in job interviews involving coding challenge repositories, and if so, consider reviewing those repositories for malicious content.
Infrastructure Hardening
- Consider implementing egress filtering to restrict outbound connections to non-standard ports from developer workstations where feasible.
- Evaluate whether your network monitoring covers non-standard HTTP ports (e.g., 1224) and not just 80/443.
- If applicable, consider deploying DNS filtering or sinkholing for known malicious domains and subdomains associated with this campaign.
User Protection
- Consider deploying enhanced monitoring for developer workstations that frequently clone external repositories or participate in coding challenges.
- Evaluate whether your EDR can detect and alert on creation of hidden directories in user profiles followed by script execution from those directories.
- If supported by your tooling, consider application allow-listing or behavioral monitoring for Node.js processes executing scripts from non-standard paths.
Security Awareness
- Consider incorporating guidance into existing security awareness programs about the risk of malicious coding challenges in fake job interviews, particularly for developers and engineering staff.
- Consider advising staff to verify the legitimacy of recruiters and companies before engaging with coding challenges or cloning external repositories.
- If applicable, consider establishing a process for developers to submit suspicious repositories or coding challenges to the security team for review before execution.
MITRE ATT&CK Mapping
Initial Access
Execution
Command and Control
Additional IOCs
- Urls:
hxxp://141[.]94[.]148[.]39:1224- Base C2 URL on port 1224 hosting the victim registration API.
- File Hashes:
fcbcaf9a00757fff176afed4b3b115227b02f11f0cca4a762b0b0f12723daa53(SHA256) - SHA256 of deobfuscated ghost.js (deobf_ghost.js).6effad9fdee81589b37c60bbbae20483200bf53bee3e3c107b1aa47d2ac4ccb3(SHA256) - SHA256 of package.json dropped by the malware.6ffedf7ec3b9cea4c99ac7ff5b0e2fb8e68f0a6bfce7110ff6ab267bc485fbb3(SHA256) - SHA256 of stager_mac.sh, macOS Bash stager.db2b3c88d8ab1a55591b21d727812bc855da0e02e85e0bfe77d4335153090ac0(SHA256) - SHA256 of stager_nix.sh, Unix Bash stager.5d036408ac731df4f2909385ca5c3a75766ab528bcd784668a4997cfa2acd947(SHA256) - SHA256 of vscode-bootstrap.ps1, Windows second-stage bootstrap script.9cb437ca697a7550163c4a66e8b766952d3ddf94f714bafac91132ad37e5ddfa(SHA256) - SHA256 of vscode-bootstrap.sh, Unix second-stage bootstrap script.72c3eea054187471a5d00b8d7c721b42(MD5) - MD5 of deobfuscated ghost.js (deobf_ghost.js).d804d3b1114766fb48b3b369df9d2f47(MD5) - MD5 of ghost.js / ghost.npl final payload.ea31f66a5164a394ce3a7253db49dd79(MD5) - MD5 of package.json dropped by the malware.4d7d3dfd3d99727f450ee0883e9f60e2(MD5) - MD5 of stager_mac.sh.38614d05a905eab3a0885b637bfbb8e8(MD5) - MD5 of stager_nix.sh.2e3fdb5b8befdb9b48cb1a5468dfc164(MD5) - MD5 of stager_win.ps1.b42652763f78183cf779811dc2cb13bb(MD5) - MD5 of vscode-bootstrap.ps1.d8cc49f56265ca137a73a275379704fa(MD5) - MD5 of vscode-bootstrap.sh.
- File Paths:
.vscode- Hidden directory created by the stager to camouflage downloaded binaries as Visual Studio Code components.ghost.js- Final malware payload filename on Unix/macOS systems.ghost.npl- Final malware payload filename on Windows systems.vscode-bootstrap.ps1- Second-stage bootstrap script downloaded on Windows systems.vscode-bootstrap.sh- Second-stage bootstrap script downloaded on Unix/macOS systems.stager_win.ps1- Initial stager script for Windows systems.stager_mac.sh- Initial stager script for macOS systems.stager_nix.sh- Initial stager script for Unix/Linux systems.
- Command Lines:
- Purpose: Creates hidden .vscode directory and downloads vscode-bootstrap script | Tools:
PowerShell,Bash| Stage: Initial Access / Staging |mkdir .vscode && curl -o .vscode/vscode-bootstrap
- Purpose: Creates hidden .vscode directory and downloads vscode-bootstrap script | Tools: