No Fool's Errand: The Koalemos RAT Campaign
Alessandra
Rizzo
Jan 23, 2026

Introduction
Between January 14 and January 21, our NPM scanner identified several malicious npm packages, which we assess with moderate confidence may be part of a new campaign we have dubbed “Koalemos” by North Korean threat actors due to an overlap of tactics and techniques. Our analysis found that each package contains two obfuscated JavaScript files: a loader and a secondary-stage payload. The packages were published by accounts using Proton Mail addresses and names that matched the real identities of developers from a major US financial institution.
Some packages contained DNS gates targeting the financial institution's internal infrastructure, indicating a targeted supply chain attack. Other packages were published using the names of employees from the same institution, but would execute on any victim system. This leads us to believe there may be two parallel campaigns: one directly targeting the financial institution, and another leveraging stolen employee identities to target unknown victims through social engineering.
Both generic and targeted variants deploy Koalemos, a modular Remote Access Trojan (RAT) framework distributed as a secondary-stage payload. The initial loader performs DNS-based execution gating and engagement date validation before downloading and spawning the RAT module as a detached process. The RAT module implements a "Koalemos" class, from which we named this malware. Koalemos performs system fingerprinting, establishes encrypted command-and-control communications, and provides full remote access capabilities.
The malware bears strong similarities to known documented North Korean campaigns in obfuscation, malware distribution, and identity spoofing. This report documents the technical capabilities, infrastructure, and attribution of the Koalemos campaign based on analysis of multiple package variants.
Technical Analysis
Infection Chain
The infection begins when a victim installs one of the malicious npm packages. The package.json defines a postinstall hook that automatically executes the loader (index.js) after installation completes. The loader first performs a DNS resolution check against a configured gate domain. For targeted variants, this domain is internal to the victim organization and will only resolve within their network. For generic variants, the gate uses a dynamic DNS domain that attackers can enable or disable at will. If the DNS check fails, the loader exits silently without deploying the payload. If it succeeds and the configured engagement date has passed, the loader spawns the Koalemos RAT as a detached background process. The RAT then enters its main beacon loop: retrieving tasks from the C2 server, executing commands, encrypting responses, and sleeping with randomized jitter before repeating.

RAT Architecture Overview
Koalemos implements a two-stage architecture. Once the malicious package is installed, the first stage loader (usually index.js or index-o.js) handles execution gating, environment validation, and payload retrieval (usually koalemos.obfuscated.js). The second stage RAT, which contains the Koalemos class, implements encrypted C2 communications and a task-based command execution framework. Both components use obfuscator[.]io string array rotation for code protection. The RAT uses a class-based design with the Koalemos class containing all functionality, including system fingerprinting, encryption, and command handlers.

Stage 1 - Loader Overview
The loader performs three checks before executing the RAT payload. First, it resolves a DNS gate domain to verify it is running in the intended target environment. Second, it validates whether an engagement date has been reached. Then, it downloads and spawns the RAT in a detached background process and exits cleanly.
The DNS gate calls dns.resolve() on the configured domain and only proceeds if resolution succeeds. This limits execution to networks where the gate domain resolves, allowing attackers to control which environments execute the payload by modifying DNS records.
Stage 2 - Koalemos Overview
The RAT is implemented as a JavaScript class named Koalemos. On initialization, it collects system fingerprint data, including hostname, internal IP address, operating system, current username, domain membership, process ID, and architecture. This fingerprint is used to register the agent with the C2 server.
The agent configuration hardcodes the C2 server URL, beacon endpoints, a unique PayloadUUID, authentication headers including a Bearer token, sleep interval (60 seconds), jitter percentage, and a kill date, which may vary depending on the package. The kill date mechanism checks the current date against the configured KillDate on each beacon cycle, terminating the RAT if the date has passed. All C2 communications are encrypted using AES-256-CBC with HMAC-SHA256 authentication.
After initialization, the RAT performs a check-in request to register itself with the C2 server, receiving a UUID that identifies this specific implant. It then enters the main beacon loop: retrieve tasks from the GetURI endpoint, process each task by dispatching to the appropriate command handler, encrypt and post responses to the PostURI endpoint, then sleep with randomized jitter before repeating.
The RAT implements twelve commands:
filesystem operations (ls, cat, cd)
identity query (whoami)
file transfer (download, upload)
implant control (sleep, exit, get_config, set_chunk_size)
native module loading (load_dll_local)
arbitrary code execution (eval).
The download command supports chunked transfer for large file exfiltration. The eval command executes arbitrary JavaScript received from the C2, enabling operators to deploy additional capabilities without modifying the implant.
Techniques Observed
Obfuscation
Both loader and RAT employ obfuscation using the obfuscator[.]io transformation suite. Strings are stored in a shuffled array and accessed through a decoder function that applies base64 decoding followed by URI component restoration. A checksum loop rotates the array to a specific offset before execution, serving as an integrity check that prevents the script from running if modified by a researcher. Decoded strings are cached to reduce performance overhead. The script hides its interaction with sensitive Node.js modules using bracket notation with decoded strings rather than direct method calls:
This prevents static analysis tools from identifying the script's true capabilities because API calls do not exist in the source until runtime.
Network Bypass (https-proxy-agent)
The loader includes support for HTTP proxies using the https-proxy-agent npm package. This allows C2 traffic to be routed through corporate proxy infrastructure rather than making direct outbound connections. In enterprise environments where egress traffic is monitored or restricted, direct connections to unknown CloudFront distributions would likely be flagged or blocked. By tunneling through a configured proxy, the malware can bypass network monitoring tools that only inspect direct connections and blend in with legitimate HTTPS traffic flowing through the corporate proxy. The loader iterates through a list of configured proxies, falling back to direct connection only if all proxies fail:
Remote Code Execution
The RAT implements an eval command that executes arbitrary JavaScript received from the C2 server. This provides full code execution capability without requiring hardcoded functionality.
This design means credential harvesting, lateral movement, and data exfiltration are delivered through C2-provided code rather than built into the RAT itself.
Jitter
The malware has a sleep mechanism through a jitter to randomize beacon intervals and evade network detection. The jitter percentage modifies the base sleep interval by a random factor.
Variant Differences
Specific Organization Targeting
Some of the analyzed packages contain DNS gates targeting the internal infrastructure of a major US financial institution. The gate domain ensures the payload only executes within their network environment. This indicates a targeted supply chain attack against the financial services company. Upon discovery, we alerted said institution and shared our findings.
Generic Targeting
Another variant uses the generic DNS gate on the mywire[.]org dynamic DNS service. The npm accounts publishing these packages use Proton Mail addresses and names matching real developer identities from the aforementioned financial institution, suggesting the attackers created convincing impersonations to build trust with potential victims.
Command and Control Infrastructure
The loader sends check-in data to dpzl4bak52ewv.cloudfront[.]net before spawning the bundled RAT payload. The RAT then beacons to a separate CloudFront distribution, d3byjvkj50cpgf.cloudfront[.]net, using specific endpoints. The PostURI /usage-logging/v1/log/hublytics-multi receives task responses while GetURI /usage-logging/v1/analytics/crumb retrieves new tasks. Communications use AES-256-CBC encryption with HMAC-SHA256 authentication.
Attribution
Koalemos shares tactical and technical overlap with the Contagious Interview campaign attributed to North Korean threat actors, including Lazarus Group, Famous Chollima (UNC5267), and WageMole.
Obfuscation similarities include the use of obfuscator.io string array rotation, which matches techniques documented in BeaverTail and InvisibleFerret malware. Both Koalemos and BeaverTail target developers through npm package distribution.
The delivery method through malicious npm packages mirrors the Contagious Interview playbook documented by Recorded Future and SilentPush.
The use of developer identities and targeting of known financial institutions aligns with North Korean fake job recruitment campaigns. Threat actors create convincing personas using stolen or fabricated identities to approach targets through job platforms, eventually delivering malware through "coding tests" or "interview projects" distributed as npm packages.
Characteristic | Koalemos | BeaverTail / InvisibleFerret |
|---|---|---|
Distribution | Malicious npm packages | Malicious npm packages |
Target | Software developers | Software developers |
Obfuscation | obfuscator.io string array rotation | obfuscator.io string array rotation |
Initial Stage | Node.js | Node.js |
Social Engineering | Fake developer identities | Fake job interviews / coding tests |
Conclusion
Koalemos represents a sophisticated RAT framework designed for targeted access operations. Unlike credential stealers such as BeaverTail which hardcode specific theft capabilities, Koalemos functions as a flexible platform where functionality is delivered dynamically through C2. The DNS gating mechanism enables precise targeting of specific network environments. Detection should focus on behavioral patterns including CloudFront C2 communications, obfuscator.io signatures, and the Koalemos class structure rather than specific file hashes which vary across re-obfuscated variants.
Learn more about Panther's homegrown Supply Chain Scanner here.
MITRE ATT&CK Mapping
Technique ID | Name | Usage |
|---|---|---|
T1195.002 | Supply Chain Compromise: Compromise Software Supply Chain | Distribution through malicious npm packages |
T1059.007 | Command and Scripting Interpreter: JavaScript | RAT implemented in Node.js with eval() RCE |
T1071.001 | Application Layer Protocol: Web Protocols | HTTPS C2 via CloudFront |
T1573.001 | Encrypted Channel: Symmetric Cryptography | AES-256-CBC with HMAC-SHA256 |
T1082 | System Information Discovery | Hostname, IP, OS, username, architecture collection |
T1083 | File and Directory Discovery | ls command implementation |
T1005 | Data from Local System | cat and download commands |
T1105 | Ingress Tool Transfer | upload command for file delivery |
T1027 | Obfuscated Files or Information | obfuscator.io string array rotation |
T1568.002 | Dynamic Resolution: Domain Generation Algorithms | DNS gate using dynamic DNS |
T1029 | Scheduled Transfer | Jittered beacon interval |
Detection
YARA Rules
IoCs
Category | Indicator | Description |
|---|---|---|
Package | env-workflow-test | v2.1.7 to v2.1.23 |
Package | sra-test-test | v1.1.26, v1.1.28 |
Package | sra-testing-test | v3.0.7 |
Package | vg-medallia-digital | v2.0.4 |
Package | vg-ccc-client | v3.0.5 |
Package | vg-dev-env | v5.9.9 |
C2 Server | dpzl4bak52ewv.cloudfront[.]net | Loader C2 |
C2 Server | d3byjvkj50cpgf.cloudfront[.]net | RAT C2 |
DNS Gate | elp-44.mywire[.]org | Generic targeting |
C2 Endpoint | /usage-logging/v1/log/hublytics-multi | POST - task responses |
C2 Endpoint | /usage-logging/v1/analytics/crumb | GET - task retrieval |
Authentication | Bearer a6f517528ca844598e8135569150885b | C2 auth token |
Encryption | 6QseDx8TLaIklEEWmAJPYDuFLBenON9W9WJFGdiLRhQ= | AES-256 key (base64) |
Identifier | 71a8f503-ea54-4164-8f5f-6f6315753cb4 | PayloadUUID |
Recommended Resources
Ready for less noise
and more control?
See Panther in action. Book a demo today.




