Back to Intelligence

Nimbus Manticore Recruitment Lures: Detecting Cross-Platform Node.js RATs on Linux and macOS

SA
Security Arsenal Team
September 1, 2026
10 min read

Kaspersky has attributed two previously undocumented malware families to Nimbus Manticore, the Iranian state-aligned threat group also tracked as UNC1549 and Smoke Sandstorm. The operation is a textbook evolution of a proven playbook: operators impersonate recruiters from defense, aerospace, and technology firms, funnel targets through convincing fake career portals, and deliver malicious coding assessments that install cross-platform remote access trojans built on Node.js and JavaScript — giving the group reliable reach into Linux and Apple macOS environments for the first time in its observed history.

This matters for three reasons. First, JavaScript-based implants run anywhere the Node.js runtime exists, which collapses the traditional Windows-centric detection model most SOCs still operate under. Second, developer workstations are disproportionately privileged: they hold SSH keys, cloud credentials, source code, and CI/CD tokens. Third, the social engineering vector — a recruiter asking an engineer to run a coding test — is engineered to produce deliberate execution by the victim, which defeats most perimeter controls by design.

If your organization employs software engineers, DevOps staff, or cleared technical personnel, treat unsolicited recruitment contact involving downloadable coding challenges as an active intrusion vector.

Technical Analysis

Threat Actor and Campaign Profile

Nimbus Manticore has a documented history of targeting aerospace, defense, and telecommunications organizations across the Middle East and Europe using recruitment-themed spear-phishing. The group's tradecraft includes registering lookalike domains impersonating legitimate employers, building functional fake career portals, and engaging targets in multi-stage social engineering before payload delivery. The Kaspersky attribution extends this picture with two new malware families written in JavaScript and executed via Node.js — a deliberate architectural choice.

Why Node.js Changes the Defensive Equation

A Node.js RAT is not a compiled PE or Mach-O binary. It is a script — or a bundle of scripts plus dependencies — executed by the node interpreter. That has concrete implications for defenders:

  • Interpreter abuse: The malicious process shows up as node (or node.exe) — a legitimate, signed binary present on virtually every developer machine and CI runner. Application allowlisting that trusts signed interpreters will not stop it.
  • Cross-platform parity: The same JavaScript payload runs on Windows, Linux, and macOS. Kaspersky's reporting indicates Nimbus Manticore is explicitly exploiting this to expand beyond Windows into Linux servers and macOS endpoints — platforms where many organizations have weak or nonexistent EDR coverage.
  • Delivery disguised as developer workflow: The payload arrives as what looks like a normal coding project — a directory with package.json, index.js, or an install script. The victim is expected to run npm install, npm test, or node solution.js. The execution chain looks indistinguishable from normal engineering activity unless you know what to look for.

Attack Chain

  1. Lure: Target is contacted via LinkedIn, email, or messaging platforms by a persona posing as a recruiter from a recognizable employer, often referencing the victim's actual CV or open-source work to establish credibility.
  2. Staging: Target is directed to a professionally built fake career portal and asked to complete a coding assessment, which requires downloading a project archive (ZIP/tarball) from attacker-controlled or abused infrastructure.
  3. Execution: The project contains malicious JavaScript — typically obfuscated, and frequently wired into the preinstall/postinstall hooks in package.json, or embedded in the test harness itself — so that npm install or node execution triggers the implant. This is the same npm lifecycle-hook abuse pattern behind countless supply-chain incidents, now weaponized for targeted intrusion (MITRE ATT&CK T1204.002, T1059.007).
  4. Implant: The Node.js RAT establishes outbound C2 over standard web protocols (HTTPS/WebSocket, T1071.001), blends with developer network noise, and provides remote command execution, file access, and data staging. Because JavaScript has native modules for filesystem, network, and child process access, the implant needs no additional tooling to operate.
  5. Persistence: On macOS, expect LaunchAgents/LaunchDaemons plists; on Linux, systemd user services or cron; on Windows, Run keys or scheduled tasks invoking node.exe against a dropped script.

Exploitation Status

This is a confirmed, actively operating campaign — not a theoretical capability. Kaspersky's analysis is based on observed intrusions and recovered malware samples. No CVE is associated with this activity: there is no software vulnerability to patch. The exploited weakness is the trust relationship between technical staff and recruitment processes, combined with the universal presence of script interpreters. Remediation is therefore behavioral, architectural, and detective — not a version bump.

Detection & Response

The highest-fidelity signals are behavioral: Node.js execution in the context of recently downloaded archives, npm lifecycle-hook execution pulling obfuscated payloads, and node processes making outbound connections to infrastructure that isn't a known registry, repository, or corporate endpoint. Tune these to your developer population before deploying broadly.

YAML
---
title: Node.js Execution From User Download or Temp Directories
id: 3f8a1c94-7b2e-4d51-a9c6-8e5f2b7d1a34
status: experimental
description: Detects node/node.exe executing scripts from download caches, temp folders, or recently extracted archive paths — consistent with malicious coding-test payloads executed via node solution.js or npm test.
references:
  - https://thehackernews.com/2026/09/iranian-hackers-pose-as-recruiters-to.html
  - https://attack.mitre.org/techniques/T1059/007/
  - https://attack.mitre.org/techniques/T1204/002/
author: Security Arsenal
date: 2026/09/15
tags:
  - attack.execution
  - attack.t1059.007
  - attack.t1204.002
logsource:
  category: process_creation
  product: windows
detection:
  selection_img:
    Image|endswith:
      - '\node.exe'
      - '\npm.cmd'
  selection_path:
    CommandLine|contains:
      - '\Downloads\'
      - '\AppData\Local\Temp\'
      - '\AppData\Roaming\npm-cache\'
  filter_known:
    CommandLine|contains:
      - 'vscode'
      - 'npm-cli.js'
  condition: selection_img and selection_path and not filter_known
falsepositives:
  - Developers legitimately running downloaded sample projects — tune with known project paths
level: medium
---
title: NPM Lifecycle Hook Executing Shell or Interpreter Commands
id: 6c2d9e71-4a8f-4b36-9d25-1f7e3a8c5b92
status: experimental
description: Detects suspicious child processes spawned by npm during install/test phases — preinstall/postinstall hooks invoking curl, wget, bash, or base64-decoding commands is a hallmark of malicious packages and trojanized coding assessments.
references:
  - https://thehackernews.com/2026/09/iranian-hackers-pose-as-recruiters-to.html
  - https://attack.mitre.org/techniques/T1059/
  - https://attack.mitre.org/techniques/T1195/
author: Security Arsenal
date: 2026/09/15
tags:
  - attack.execution
  - attack.t1059.004
  - attack.t1195.002
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/npm'
      - '/node'
      - '/npm-cli.js'
  selection_child:
    Image|endswith:
      - '/bash'
      - '/sh'
      - '/curl'
      - '/wget'
      - '/base64'
      - '/python'
      - '/python3'
  condition: selection_parent and selection_child
falsepositives:
  - Legitimate packages with native build steps (node-gyp) — allowlist known package build hosts
level: high
---
title: LaunchAgent Persistence Executing Node.js Script
id: 9a4e6b18-2c7d-4f83-b1e5-7d3a9c4e8f61
status: experimental
description: Detects macOS LaunchAgent or LaunchDaemon persistence entries that invoke node against a script path — a likely persistence mechanism for cross-platform Node.js RATs on macOS endpoints.
references:
  - https://thehackernews.com/2026/09/iranian-hackers-pose-as-recruiters-to.html
  - https://attack.mitre.org/techniques/T1543/001/
author: Security Arsenal
date: 2026/09/15
tags:
  - attack.persistence
  - attack.t1543.001
  - attack.t1059.007
logsource:
  category: file_event
  product: macos
detection:
  selection_dir:
    TargetFilename|contains:
      - '/Library/LaunchAgents/'
      - '/Library/LaunchDaemons/'
  selection_ext:
    TargetFilename|endswith: '.plist'
  condition: selection_dir and selection_ext
falsepositives:
  - Legitimate developer tools installing background agents (Docker, nvm helpers) — correlate with plist contents referencing node
level: medium
KQL — Microsoft Sentinel / Defender
// Hunt: Node.js processes spawned shortly after archive/download activity, making outbound connections
// Relevant to Windows endpoints via MDE; adapt Syslog/CEF ingestion for Linux/macOS fleets
let lookback = 14d;
let suspiciousNode = DeviceProcessEvents
| where Timestamp > ago(lookback)
| where FileName in~ ("node.exe", "node", "npm.cmd", "npm")
| where ProcessCommandLine has_any ("Downloads", "Temp", "tmp/", "/var/tmp", "eval", "base64", "--input-type")
| project DeviceName, AccountName, ProcessCommandLine, ProcessCreationTime=Timestamp, DeviceId, ReportId;
DeviceNetworkEvents
| where Timestamp > ago(lookback)
| where InitiatingProcessFileName in~ ("node.exe", "node")
| where RemotePort !in (443, 80) or RemoteUrl !endswith ".npmjs.org"
| join kind=inner suspiciousNode on DeviceId
| project ProcessCreationTime, Timestamp, DeviceName, AccountName, ProcessCommandLine, RemoteIP, RemoteUrl, RemotePort
| order by Timestamp desc
VQL — Velociraptor
-- Hunt for active node processes with suspicious command lines, plus macOS persistence artifacts
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)node'
  AND CommandLine =~ '(?i)(Downloads|/tmp/|/var/tmp|AppData..Local..Temp|eval|base64|postinstall)'

SELECT FullPath, Mtime, read_file(file=FullPath) AS PlistContents
FROM glob(globs=['/Library/LaunchAgents/*.plist', '/Library/LaunchDaemons/*.plist', '~/Library/LaunchAgents/*.plist'])
WHERE PlistContents =~ '(?i)node'
ORDER BY Mtime DESC
Bash / Shell
#!/bin/bash
# Nimbus Manticore / Node.js RAT triage — run on Linux and macOS endpoints
# Audits interpreter execution, npm hook artifacts, and persistence mechanisms

echo "=== [1] Active node processes with suspicious origins ==="
ps -eo pid,user,etime,args | grep -E '[n]ode' | grep -Ei 'tmp|Downloads|eval|base64' || echo "none"

echo "=== [2] node processes with established outbound connections ==="
if command -v lsof >/dev/null; then
  lsof -i -nP | grep -i node | grep ESTABLISHED || echo "none"
fi

echo "=== [3] Recently modified npm projects in user home dirs (last 14 days) ==="
find /home /Users -maxdepth 4 -name 'package.json' -mtime -14 2>/dev/null -exec grep -lE 'preinstall|postinstall' {} \;

echo "=== [4] Persistence: systemd user services invoking node ==="
find /home -path '*/.config/systemd/user/*.service' 2>/dev/null -exec grep -l 'node' {} \;
systemctl list-units --type=service --state=running 2>/dev/null | grep -i node || true

echo "=== [5] Persistence: LaunchAgents/Daemons referencing node (macOS) ==="
if [ "$(uname)" = "Darwin" ]; then
  grep -rl 'node' /Library/LaunchAgents /Library/LaunchDaemons ~/Library/LaunchAgents 2>/dev/null || echo "none"
fi

echo "=== [6] Cron entries referencing node/npm ==="
crontab -l 2>/dev/null | grep -Ei 'node|npm' || echo "user crontab clean"
grep -rEi 'node|npm' /etc/cron* 2>/dev/null || echo "system cron clean"

echo "=== [7] Globally installed npm packages (review for typosquats/unknowns) ==="
npm ls -g --depth=0 2>/dev/null || echo "npm not present"

Remediation

There is no patch for a social-engineering campaign — remediation is a control problem. Prioritize the following:

Immediate (24–72 hours):

  • Communicate the lure to technical staff now. Engineering, DevOps, and security-cleared personnel are the target population. Issue a standing policy: no coding assessments from unverified recruiters are executed on corporate hardware, period. Require assessments to run inside IT-provisioned sandboxes or disposable cloud VMs with no credential material.
  • Hunt with the detections above. Pull 30 days of process-execution telemetry for node/npm spawned from download paths, and audit persistence locations (LaunchAgents, systemd user units, Run keys) for interpreter references. Any hit outside known developer tooling warrants host isolation and memory acquisition.
  • Audit npm lifecycle hooks. Scan repositories and recently onboarded third-party code for preinstall/postinstall scripts. Enforce npm install --ignore-scripts as the default in developer environments and CI where build requirements permit.

Short term (1–2 weeks):

  • Constrain interpreter network egress. Node.js has no legitimate reason to reach arbitrary internet hosts from most build contexts. Egress-filter developer VLANs to approved registries (npmjs, GitHub, artifact mirrors) and alert on node connections to anything else — this single control breaks most JavaScript RAT C2.
  • Extend EDR to macOS and Linux. This campaign exists precisely because defenders under-instrument non-Windows platforms. If your EDR coverage stops at Windows, that gap is your exposure.
  • Credential hygiene on developer machines: enforce short-lived, hardware-bound credentials; prohibit persistent cloud CLI tokens and unprotected SSH private keys on endpoints; rotate any credentials found on hosts touched by suspect projects.

Longer term:

  • Sandbox detonation for recruitment-linked downloads. Route attachments and archives associated with external HR/recruitment contact through detonation before delivery, and treat lookalike employer domains (monitor via DNSTwist-style permutation feeds and brand-abuse services) as phish infrastructure to preemptively block.
  • Tabletop this scenario. Run an IR exercise where a senior engineer executes a trojanized take-home test on a macOS laptop holding cloud admin credentials. If your playbooks only cover Windows ransomware, they will fail here.

Incident response triggers: If you confirm execution of a malicious coding assessment, assume credential compromise on that host — rotate all reachable secrets (SSH keys, cloud tokens, repo access, session cookies), acquire memory before reboot (JavaScript implants live in interpreter memory), and review outbound proxy/DNS logs for the full window the process was resident.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.