Threat Summary
A newly published AlienVault OTX pulse (TLP:WHITE, corroborated by Kaspersky Securelist research) documents a significant tactical evolution by Mirage Kitten, an APT group with a long operational history across the Middle East and Africa. The group has fielded two previously undocumented cross-platform remote access trojans — NodeRabbit (Node.js-based) and PollCat (JavaScript-based) — alongside supporting tooling tracked as Retrograde and MiniFast.
This marks the group's first departure from native-compiled malware toward runtime-dependent scripting languages, granting them Windows, Linux, and macOS reach from a single codebase. The campaign targets the finance (fintech) and aerospace/aviation sectors.
The attack chain is socially engineered at the front door: operators pose as recruiters on LinkedIn, approaching developers and technical staff with a trojanized coding challenge — a poisoned take-home project or assessment repository. When the victim runs the project (typically via node or npm), the RAT stages execute. C2 infrastructure is hosted on Microsoft Azure, blending malicious traffic with legitimate cloud egress and defeating simplistic domain-reputation filtering. The lure domains registered for the campaign (sahi-finance.com, optimumhealthcredit.com, visitfinancedentists.com, healthcomfsdpower.com) impersonate fintech and healthcare-credit brands, reinforcing the recruitment pretext.
Objective: persistent, cross-platform access into developer workstations at finance and aerospace organizations — a beachhead for source code theft, supply-chain positioning, and lateral movement into build infrastructure.
Threat Actor / Malware Profile
Mirage Kitten (APT)
- Historical focus: Middle East and Africa; espionage-motivated.
- Current pivot: scripting-language malware for cross-platform operator flexibility; Azure-hosted C2 for infrastructure legitimacy.
- Social engineering: LinkedIn recruitment personas delivering trojanized coding challenges to engineers — a technique that deliberately targets users with elevated developer privileges and repository access.
NodeRabbit (Node.js RAT)
- Distribution: bundled inside trojanized coding-challenge projects; executes when the victim runs
node app.js/npm startor installs malicious dependencies. - Payload behavior: cross-platform RAT providing remote command execution, file exfiltration, and reconnaissance; inherits host OS reach (Windows/Linux/macOS) via the Node runtime.
- C2: outbound HTTPS to Azure-hosted endpoints, including the resolved domain
msmanagementgrp.commasquerading as Microsoft management infrastructure. - Persistence: expected via startup-folder scripts, scheduled tasks (Windows), launchd/cron (macOS/Linux), or malicious
package.jsonlifecycle hooks (preinstall/postinstall) that re-execute on everynpm install. - Anti-analysis: JavaScript obfuscation, runtime dependency on Node (evades static binary analysis tooling), and cloud-hosted C2 that survives IP/domain age-based heuristics.
PollCat (JavaScript RAT)
- Companion JavaScript implant sharing the delivery vector; lighter footprint, likely used for initial beaconing and polling tasking (consistent with the name) before NodeRabbit full deployment.
Retrograde & MiniFast
- Supporting tooling in the same toolset; treat any unsigned Node/Electron-style binaries or script droppers co-located with the lure projects as suspect.
IOC Analysis
The pulse carries 37 indicators. Types present:
| Type | Examples | Operationalization |
|---|---|---|
| Domains | msmanagementgrp.com, sahi-finance.com, healthcomfsdpower.com, visitfinancedentists.com, optimumhealthcredit.com | Block at DNS sinkhole, secure web gateway, and egress proxy. Alert — do not just block — on historical DNS queries; a resolved query to msmanagementgrp.com is a near-certain compromise indicator given its Microsoft-mimic naming. |
| File hashes (MD5/SHA1/SHA256) | 0db36a04d304ad96f9e6f97b531934594cd95a5cea9ff2c9af249201089dc864, 810f8e3b88eb05f710c09552941d6f56 | Push SHA256 values into EDR blocklists (Defender, CrowdStrike, SentinelOne custom indicators). MD5/SHA1 retained for legacy tooling correlation only — prioritize SHA256. |
SOC guidance: Hashes identify known payloads; domains identify infrastructure. Because the malware is script-based and easily re-packed, hashes will age fast — domain and behavioral detections (below) are the durable layer. Retroactively sweep proxy, DNS, and EDR telemetry for the past 90 days against all 37 indicators; developer workstations and build agents are priority scope.
Tooling: AlienVault OTX DirectConnect/API for full indicator pull, MISP for internal sharing, and your EDR's custom-IOC engine for enforcement.
Detection Engineering
---
title: Mirage Kitten NodeRabbit - Suspicious Node.js Child Process Execution
id: 7c2a1e44-9f3b-4d2a-a1c5-mknoderabbit01
status: experimental
description: Detects Node.js runtime spawning shells, downloaders, or script interpreters consistent with NodeRabbit RAT staging from a trojanized coding challenge.
author: Security Arsenal Threat Intel
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npm.exe'
- '\npx.cmd'
selection_child:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
- '\cmd.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\curl.exe'
- '\certutil.exe'
- '\bitsadmin.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate build tooling and dev scripts invoking child processes
level: high
tags:
- attack.execution
- attack.t1059.007
- attack.t1204
date: 2026/09/01
---
title: Mirage Kitten C2 - Network Connection to Campaign Infrastructure
id: 8d3b2f55-1a4c-5e3b-b2d6-mkpollcat002
status: experimental
description: Detects DNS or network connections to Mirage Kitten NodeRabbit/PollCat C2 and lure domains, including Azure-hosted msmanagementgrp.com.
author: Security Arsenal Threat Intel
logsource:
category: dns
product: windows
detection:
selection:
query|contains:
- 'msmanagementgrp.com'
- 'sahi-finance.com'
- 'healthcomfsdpower.com'
- 'visitfinancedentists.com'
- 'optimumhealthcredit.com'
condition: selection
falsepositives:
- None expected; these are adversary-registered domains
level: critical
tags:
- attack.command_and_control
- attack.t1071.001
date: 2026/09/01
---
title: Malicious NPM Lifecycle Hook Execution - NodeRabbit Persistence
id: 9e4c3g66-2b5d-6f4c-c3e7-mknpmhook03
status: experimental
description: Detects execution of script interpreters triggered by npm install lifecycle hooks, a persistence and staging mechanism used by trojanized coding challenges.
author: Security Arsenal Threat Intel
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains:
- 'preinstall'
- 'postinstall'
- 'node-gyp rebuild'
selection_shell:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\node.exe'
condition: selection and selection_shell
falsepositives:
- Legitimate packages with native build steps (node-gyp)
level: medium
tags:
- attack.persistence
- attack.t1546
- attack.t1195.002
date: 2026/09/01
// Mirage Kitten NodeRabbit/PollCat hunt: campaign domains + suspicious Node.js chains
let MKDomains = dynamic(["msmanagementgrp.com","sahi-finance.com","healthcomfsdpower.com","visitfinancedentists.com","optimumhealthcredit.com"]);
let MKHashes = dynamic(["0db36a04d304ad96f9e6f97b531934594cd95a5cea9ff2c9af249201089dc864","810f8e3b88eb05f710c09552941d6f56"]);
union isfuzzy=true
(DeviceNetworkEvents
| where TimeGenerated > ago(90d)
| where RemoteUrl has_any (MKDomains)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP),
(DeviceProcessEvents
| where TimeGenerated > ago(90d)
| where FileName =~ "node.exe" or ProcessCommandLine has_any ("preinstall","postinstall")
| where ProcessCommandLine has_any ("powershell","cmd.exe","curl","certutil","http")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, SHA256),
(DeviceFileEvents
| where TimeGenerated > ago(90d)
| where SHA256 has_any (MKHashes) or MD5 has_any (MKHashes)
| project TimeGenerated, DeviceName, FileName, FolderPath, SHA256)
| sort by TimeGenerated desc
# Mirage Kitten NodeRabbit/PollCat endpoint hunt — run via EDR live response or RMM
$domains = @('msmanagementgrp.com','sahi-finance.com','healthcomfsdpower.com','visitfinancedentists.com','optimumhealthcredit.com')
$hashes = @('0db36a04d304ad96f9e6f97b531934594cd95a5cea9ff2c9af249201089dc864','810f8e3b88eb05f710c09552941d6f56')
Write-Host "[1/5] DNS cache check for campaign domains" -ForegroundColor Cyan
Get-DnsClientCache | Where-Object { $n=$_.Entry; $domains | Where-Object { $n -like "*$_*" } } | Format-Table Entry, Data
Write-Host "[2/5] Active/recent connections by node.exe" -ForegroundColor Cyan
Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue | ForEach-Object {
$p = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
if ($p.Name -match 'node|npm') { [PSCustomObject]@{Process=$p.Name; PID=$_.OwningProcess; Remote=$_.RemoteAddress; Port=$_.RemotePort} }
} | Format-Table
Write-Host "[3/5] Hash sweep of common dev/download locations" -ForegroundColor Cyan
$paths = @("$env:USERPROFILE\Downloads","$env:USERPROFILE\Desktop","$env:USERPROFILE\source","$env:USERPROFILE\repos","$env:TEMP")
foreach ($path in $paths) {
if (Test-Path $path) {
Get-ChildItem $path -Recurse -File -ErrorAction SilentlyContinue | ForEach-Object {
$h = (Get-FileHash $_.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
if ($hashes -contains $h.ToLower()) { Write-Host "HIT: $($_.FullName)" -ForegroundColor Red }
}
}
}
Write-Host "[4/5] Scheduled tasks launching node/npm (persistence)" -ForegroundColor Cyan
Get-ScheduledTask | Where-Object { $_.Actions.Arguments -match 'node|\.js$|npm' } | Format-Table TaskName, TaskPath, State
Write-Host "[5/5] Startup folder .js droppers" -ForegroundColor Cyan
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup" -ErrorAction SilentlyContinue |
Where-Object { $_.Extension -in '.js','.lnk','.cmd' } | Format-Table FullName, LastWriteTime
Response Priorities
Immediate (0–4h):
- Block all five campaign domains at DNS, proxy, and EDR network layers; push both hashes to EDR blocklists.
- Sweep 90 days of DNS/proxy/EDR telemetry for indicator hits — any resolution of
msmanagementgrp.com= treat as compromised host. - Hunt developer workstations and build agents for
node.exespawning shells or unexpected outbound HTTPS.
24 Hours:
- Interview staff in finance/aerospace engineering teams about recent LinkedIn recruiter contact or take-home coding challenges; collect any downloaded repositories for analysis.
- If execution is confirmed on any host, force credential rotation for that user's SSO, code-repository (GitHub/GitLab/Azure DevOps), and cloud console accounts — developer machines hold high-value tokens. Revoke active sessions and OAuth grants.
- Isolate affected endpoints; capture memory before reimage (RATs are script-resident and volatile).
1 Week:
- Harden the developer attack surface: enforce
npm install --ignore-scriptspolicy or proxy registries that strip lifecycle hooks; require package allowlisting for corporate builds. - Restrict Node.js runtime network egress from developer subnets to approved registries and repositories only.
- Publish an internal advisory on recruiter-lure social engineering; add trojanized coding challenges to security awareness training.
- Deploy the Sigma and KQL detections above to production monitoring.
Related Resources
Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.