BusySnake Stealer — Armored Likho (Eagle Werewolf) APT
pnx.exe, pulls a Python 3.12 runtime + module.pyw payload from GitHub into %APPDATA%\WindowsHelper, and persists via a WindowsHelper scheduled task. BusySnake loots Chromium/Firefox credentials, cookies, Telegram tdata, crypto wallets and 2FA secrets, then opens a reverse SSH tunnel + RustDesk for hands-on access. Defensive hunt & harden pack — no offensive code.Executive Summary
Kaspersky's Securelist (published 3–4 July 2026) attributed a new Python-based infostealer, BusySnake Stealer, to the espionage actor Armored Likho (also tracked as Eagle Werewolf). The campaign targets government agencies and electric-power sector entities across Russia, Kazakhstan and Brazil, and marks a jump in the actor's technical maturity — Python source obfuscation with PyArmor Pro 9.2.0, rapid payload rotation via automated GitHub releases, and network mechanisms embedded directly into the malware to bypass security tooling.
The chain starts with a spear-phishing email carrying a RAR/ZIP archive with government/social-program lures. A first-stage NSIS self-extracting EXE (e.g. psihologicheskiy_test.exe) shows a decoy application, injects into a legitimately-named pnx.exe, and downloads follow-on archives from GitHub into %APPDATA%\WindowsHelper. A parallel LNK variant abuses the ZDI-CAN-25373 shortcut vulnerability to hide PowerShell parameters. The staging step fetches a portable Python 3.12 interpreter (python.zip), get-pip.py and data.zip containing the payload module.pyw. Persistence is a scheduled task named WindowsHelper (via run.vbs, later via the Schedule.Service COM object) that re-launches the stealer every 5 minutes; wh_selfdelete.vbs removes the loader.
BusySnake then harvests Chromium (DPAPI) and Firefox (NSS) passwords, cookies, screenshots, keystrokes, clipboard 2FA otpauth:// secrets, cryptocurrency wallet JSONs, and Telegram tdata, writing staged output (chromium_passwords.json, firefox_passwords.json, all_browser_data.json) under %APPDATA%\WindowsHelper before exfiltration to a Flask C2. For hands-on access it opens a reverse SSH tunnel (Go2Tunnel-style -R 0.0.0.0 arguments) and drives RustDesk.
python.exe/pythonw.exe running module.pyw out of %APPDATA%\WindowsHelper) and Q3 (the WindowsHelper scheduled task re-launching run.vbs/.pyw every 5 minutes). Escalate any hit on Q6 (reverse SSH -R 0.0.0.0) — that is hands-on-keyboard access, not automated theft.
Source Review & Web Hunter Notes
| Tier | Source | Key Finding | Carry |
|---|---|---|---|
| 1 · Vendor research | Kaspersky Securelist — "Armored Likho's new weapon: BusySnake Stealer" | Full chain: NSIS/LNK dropper → pnx.exe injection → GitHub Python payload → WindowsHelper task; PyArmor 9.2.0; C2 IPs/domains; file hashes; SSH-tunnel/RustDesk | yes |
| 1 · News | The Hacker News — "Armored Likho Targets Government Agencies, Power Sector with BusySnake Stealer" | Attribution (Eagle Werewolf); gov + energy targeting in RU/KZ/BR; AI-assisted first-stage loader; tool polymorphism | yes |
| 2 · News | TechTimes ("New APT Group Hits Power Grids in Three Countries with AI-Crafted Malware") · MalwareTips · CyberSecBrief | Corroborates three-country power-sector targeting and LLM-generated loader stylistic tells | partial |
Decisions: behavior-first — the payload is rotated through automated GitHub releases and obfuscated with PyArmor, so no single hash is durable. Anchor on (1) the portable-Python-runs-module.pyw-from-WindowsHelper execution, (2) the WindowsHelper scheduled-task persistence, (3) the staged stealer-output JSONs, and (4) the reverse-SSH/RustDesk egress. Atomic IOCs (four C2 IPs, ~10 C2 domains, MD5 hashes) are carried as a refreshable watchlist for Q7/Q8 and §9 — treat as perishable. All atomic indicators below trace to the Kaspersky Securelist report.
Hunt Brief & Attack Chain
Working hypothesis: A targeted user opens a spear-phishing RAR/ZIP; an NSIS EXE (or ZDI-CAN-25373 LNK) shows a decoy, injects pnx.exe, and stages a portable Python 3.12 + module.pyw under %APPDATA%\WindowsHelper; a WindowsHelper scheduled task re-launches the stealer every 5 minutes; BusySnake harvests browser/wallet/Telegram/2FA secrets and opens a reverse SSH tunnel + RustDesk for interactive access.
| Step | Behavior | Telemetry | Hunt Angle |
|---|---|---|---|
| 1 · Spear-phish | RAR/ZIP with gov/social-program lure; NSIS EXE or LNK | Mail gw; file; ProcessRollup2 | N1; N3 |
| 2 · Dropper / injection | NSIS decoy injects into pnx.exe in an nsn*.tmp dir | ProcessRollup2 | Q1 |
| 3 · Staging | GitHub pull of python.zip / data.zip / get-pip.py to WindowsHelper | NetworkConnectIP4; DNS; file | N2 |
| 4 · Execution | Portable python.exe runs module.pyw from WindowsHelper | ProcessRollup2 | Q2; N4 |
| 5 · Persistence | WindowsHelper scheduled task re-runs run.vbs/.pyw every 5 min | ScheduledTaskRegistered; ProcessRollup2 | Q3; N1 |
| 6 · Collection | Reads browser creds / cookies / wallet / Telegram tdata; writes staged JSON | file open/write | Q4; Q5 |
| 7 · Remote access | Reverse SSH tunnel (-R 0.0.0.0) + RustDesk | ProcessRollup2; net | Q6 |
| 8 · Exfil / C2 | Flask C2 over web; known IPs/domains | NetworkConnectIP4; DNS | Q7; Q8 |
Affected surface & telemetry
| Surface | Required Telemetry | Priority | Gap Risk |
|---|---|---|---|
| Government / OT-adjacent Windows workstations | Process lineage + command line | Critical | Low — core process telemetry |
| Browser / wallet / Telegram secret stores | File open/write attribution | High | Medium — needs file-read visibility |
| Persistence (Scheduled Tasks / WSH) | ScheduledTaskRegistered; script-host exec | High | Low |
| Egress | DNS / proxy / NetworkConnectIP4 | Medium | Medium — IPs/domains rotate |
Consolidated IOC Table
| Type | Value | Conf | Action | Context |
|---|---|---|---|---|
| Behavior | Portable python.exe/pythonw.exe running module.pyw from %APPDATA%\WindowsHelper | high | detect | Execution — flagship |
| Behavior | WindowsHelper scheduled task re-launching run.vbs / .pyw every 5 min | high | detect | Persistence |
| Behavior | Injected pnx.exe executing from an nsn*.tmp NSIS dir | high | detect | Dropper / injection |
| Behavior | ssh.exe with -R 0.0.0.0 reverse-tunnel args; RustDesk remote control | high | detect | Hands-on access |
| File | chromium_passwords.json / firefox_passwords.json / all_browser_data.json / inventory_state.db under WindowsHelper | high | detect | Exfil staging |
| IP (C2) | 159.198.41.140 · 159.198.75.219 · 159.198.32.222 · 69.67.173.153 | medium | hunt | Flask C2 / tunnel — perishable |
| Domain (C2) | winupdate.live/.ink · arvax.xyz · varenie.live · lvl99.store · onetoken.ink · grked.online · ndrt.ink · myboard.chickenkiller.com/.twilightparadox.com | medium | hunt | C2 / tunnel endpoints — perishable |
| Hash (MD5, dropper) | 1096268FA2B3D454C86CF851CB782319 · 894332174F536C2E1EFEDA05CBA79F8B · 393B498F2114CABC0B29D5FCD9DC6723 | medium | hunt | EXE / DLL / LNK — polymorphic |
| Hash (MD5, stealer) | C7622A1EFFA27BBFEE6D6E03D6474343 · 80B7700053E115D65365CE7330383320 | medium | hunt | module.pyw variants — polymorphic |
ATT&CK Mapping
| Tactic | Technique | Observed Behavior | Query / Control |
|---|---|---|---|
| Initial Access / Execution | T1566.001 / T1204.002 — Spear-phish attachment / user execution | RAR/ZIP lure → NSIS EXE or LNK run by user | N1, N3; Q1 |
| Execution | T1059.006 / T1059.005 — Python / VBScript | module.pyw run by portable Python; run.vbs | Q2, Q3 |
| Defense Evasion | T1055 / T1027.013 / T1218.011 — Injection / obfuscated payload / rundll32 | Inject pnx.exe; PyArmor; rundll32→powershell→python | Q1, N4 |
| Persistence | T1053.005 — Scheduled task | WindowsHelper task every 5 min (schtasks / Schedule.Service COM) | Q3, N1 |
| Command & Control | T1105 / T1102 — Ingress tool transfer / web service (GitHub) | Python runtime + payload pulled from GitHub | N2 |
| Credential Access | T1555.003 / T1539 / T1111 — Browser creds / cookies / 2FA | Chromium DPAPI + Firefox NSS; clipboard otpauth:// | Q4, Q5 |
| Collection | T1113 / T1115 / T1005 — Screenshots / clipboard / local data | Screenshots, keylog, wallet JSON, Telegram tdata | Q5 |
| Command & Control | T1572 / T1219 — Protocol tunneling / remote access tool | Reverse SSH -R 0.0.0.0; RustDesk | Q6 |
| Exfiltration | T1041 / T1071.001 — Exfil over C2 / web | Flask C2 at known IPs/domains | Q7, Q8 |
Native Audit-Log Hunts
| Hunt | Source | Logic | Response |
|---|---|---|---|
| N1 · WindowsHelper task | Security 4698 / Task Scheduler Op log | Scheduled task named WindowsHelper (or any task whose action launches wscript/python from %APPDATA%\WindowsHelper), trigger every 5 min | Disable task; isolate; triage |
| N2 · GitHub payload pull | Proxy / DNS / EDR net | Download of python.zip / data.zip / get-pip.py from a GitHub raw/release URL by a non-dev user, landing in WindowsHelper | Pull files; block repo |
| N3 · LNK / archive delivery | Mail gateway / EDR | RAR/ZIP attachment containing an EXE or a .lnk (ZDI-CAN-25373) that spawns PowerShell with a download cradle | Quarantine mail; hunt recipients |
| N4 · rundll32→powershell→python | EDR / process | A rundll32→powershell→python lineage, or PowerShell with -enc/download cradle spawning a portable Python | Isolate; capture tree |
| N5 · Firefox/Chromium secret read by non-browser | EDR file audit | A non-browser process opening Login Data / key4.db / logins.json / Telegram tdata | Treat as stealer; reset creds |
CrowdStrike LogScale CQL Hunt Queries
SyntheticProcessRollup2. Q2 (Python running module.pyw from WindowsHelper) and Q3 (the WindowsHelper task) are the durable anchors — payload hashes rotate. Baseline any legitimate portable-Python and RustDesk usage before promoting.Looks for: a process named pnx.exe executing from an NSIS extraction dir (\Temp\nsn*.tmp\ / \Temp\). Accomplishes: catches the first-stage decoy dropper / injection target. FP: low — pnx.exe in a temp NSIS path is not a common legit pattern.
// HUNT: BusySnake NSIS dropper — injected pnx.exe from an nsn*.tmp temp dir // MITRE: T1204.002, T1055 | CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 // FALSE POSITIVES: pnx.exe from an NSIS temp path is not a common legit binary #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^pnx\.exe$/i | ImageFileName=/\\(Local\\Temp|Temp)\\(nsn.+\.tmp\\)?pnx\.exe$/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine, SHA256HashData], limit=200)
Looks for: python.exe/pythonw.exe whose command line references module.pyw and/or the WindowsHelper working dir. Accomplishes: the flagship execution signature. FP: low — a portable Python running a .pyw out of %APPDATA%\WindowsHelper is not normal.
// HUNT: BusySnake stealer execution — module.pyw run from WindowsHelper // MITRE: T1059.006 | CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 // FALSE POSITIVES: baseline sanctioned portable-Python automation writing to AppData #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^(python|python3|pythonw)\.exe$/i | CommandLine=/(\\WindowsHelper\\.+\.pyw|module\.pyw)/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine, SHA256HashData], limit=200)
Looks for: wscript/cscript executing a .vbs/.pyw from a WindowsHelper path — the 5-minute re-launch task. Accomplishes: catches persistence firing. FP: low — WSH running from %APPDATA%\WindowsHelper is anomalous.
// HUNT: BusySnake persistence — WindowsHelper task re-launches run.vbs / module.pyw // MITRE: T1053.005, T1059.005 | CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 // FALSE POSITIVES: legit WSH rarely runs from %APPDATA%\WindowsHelper #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^(wscript|cscript)\.exe$/i | CommandLine=/\\WindowsHelper\\.+\.(vbs|pyw)/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
Looks for: creation of chromium_passwords.json / firefox_passwords.json / all_browser_data.json / inventory_state.db under a WindowsHelper directory. Accomplishes: a near-zero-FP tell that theft has run. FP: low — these exact staged filenames are BusySnake-specific.
// HUNT: BusySnake exfil staging — stealer output written under WindowsHelper // MITRE: T1074.001, T1555.003 | CONF: high FP: low COST: low | REQUIRES: FileCreate telemetry // FALSE POSITIVES: these exact staged filenames under WindowsHelper are malware-specific #event_simpleName=/NewExecutableWritten|PeFileWritten|FileCreateInfo/ | TargetFileName=/\\WindowsHelper\\.*(chromium_passwords|firefox_passwords|all_browser_data|inventory_state)\.(json|db)$/i | table([@timestamp, ComputerName, UserName, ContextBaseFileName, TargetFileName], limit=200)
Looks for: a non-browser image opening many browser credential / wallet / Telegram tdata files. Accomplishes: BusySnake's core looting. FP: medium — some backup/security tools read these; require a high distinct-file count and a non-browser image (correlate to Q2 lineage).
// HUNT: BusySnake credential harvest — mass read of browser/wallet/Telegram secrets // MITRE: T1555.003, T1539, T1005 | CONF: high FP: medium COST: med | REQUIRES: file-read telemetry // TUNING: require many distinct targets + non-browser image; baseline backup/security tools #event_simpleName=/FileOpenInfo/ | TargetFileName=/(\\User Data\\.+\\(Login Data|Cookies|Local State|Web Data)|key4\.db|logins\.json|\\Telegram Desktop\\tdata|wallet\.dat|\\MetaMask|keystore)/i | ContextBaseFileName=/^(python|python3|pythonw|pnx)\.exe$/i | groupBy([ComputerName, ContextBaseFileName], function=count(TargetFileName, distinct=true, as=files)) | files >= 4 | table([ComputerName, ContextBaseFileName, files], limit=200)
Looks for: ssh.exe invoked with a reverse-forward to 0.0.0.0 plus host-key checking disabled — the Armored Likho Go2Tunnel argument set. Accomplishes: flags hands-on-keyboard tunneling. FP: low-med — baseline any sanctioned ssh -R automation.
// HUNT: BusySnake reverse SSH tunnel — Go2Tunnel-style arguments // MITRE: T1572 | CONF: high FP: low-med COST: low | REQUIRES: ProcessRollup2 + CommandLine // TUNING: baseline sanctioned ssh -R jump-host automation before alerting #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^ssh\.exe$/i | CommandLine=/-R\s+0\.0\.0\.0:|ExitOnForwardFailure=yes|StrictHostKeyChecking=no/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
Looks for: DNS resolution of the reported C2 / tunnel domains. Accomplishes: a cheap watchlist hit. FP: low, but the domains are perishable — confirm they are still live before treating a miss as clean.
// HUNT: BusySnake C2 DNS — known Armored Likho domains (perishable) // MITRE: T1071.001 | CONF: medium FP: low COST: low | REQUIRES: DnsRequest // FALSE POSITIVES: domains rotate; refresh from current threat intel #event_simpleName=DnsRequest | DomainName=/(winupdate\.(live|ink)|arvax\.xyz|varenie\.live|lvl99\.store|onetoken\.ink|grked\.online|ndrt\.ink|myboard\.(chickenkiller\.com|twilightparadox\.com))$/i | table([@timestamp, ComputerName, ContextBaseFileName, DomainName], limit=200)
Looks for: outbound connections to the four reported C2 / tunnel IP addresses. Accomplishes: confirms exfil / tunnel egress. FP: low, but the IPs are perishable — treat as hunt, not a standalone block.
// HUNT: BusySnake C2 beacon — known Flask C2 / tunnel IPs (perishable) // MITRE: T1041, T1071.001 | CONF: medium FP: low COST: low | REQUIRES: NetworkConnectIP4 // FALSE POSITIVES: IPs rotate; confirm against current threat intel before blocking #event_simpleName=NetworkConnectIP4 | in(RemoteAddressIP4, values=["159.198.41.140","159.198.75.219","159.198.32.222","69.67.173.153"]) | table([@timestamp, ComputerName, ContextBaseFileName, RemoteAddressIP4, RemotePort], limit=200)
CrowdStrike Custom IOA Recommendations
| IOA Name | Field Patterns | Benign Exclusions | Deployment Path |
|---|---|---|---|
| BusySnake — Python module.pyw from WindowsHelper | Image python/pythonw.exe; CommandLine matches WindowsHelper\...\.pyw or module.pyw | Sanctioned portable-Python automation (allow-list by path/signer) | Endpoint Security → Custom IOA → Process Creation, Detect+Block |
| BusySnake — WindowsHelper WSH persistence | Parent/child wscript/cscript.exe; CommandLine matches WindowsHelper\...\.(vbs|pyw) | None expected in most enterprises | Custom IOA → Process Creation, Detect+Block |
| BusySnake — reverse SSH tunnel | ssh.exe with -R 0.0.0.0 + StrictHostKeyChecking=no | Sanctioned jump-host tunneling (allow-list source hosts/users) | Custom IOA → Process Creation, Detect |
WindowsHelper execution + persistence + staged-output triad is BusySnake-specific and near-zero-FP. Q6 (reverse SSH) generalizes to many tunneling actors and is worth promoting fleet-wide with a tuned allow-list. The C2 IPs/domains (Q7/Q8) are a refreshable network watchlist, not IOAs.Machine-Readable IOC Appendix
Grouped IOC Quick-Copy
One-click blocks for detection. Atomic indicators (IPs/domains/hashes) are perishable and trace to the Kaspersky Securelist report — behavior is the durable surface. Confirm atoms against current intel before blocking.
type,value,action,severity,expiration,description,tags ipv4,159.198.41.140,detect,high,2027-01-06,BusySnake Flask C2,campaign:ArmoredLikho ipv4,159.198.75.219,detect,high,2027-01-06,BusySnake C2/tunnel,campaign:ArmoredLikho ipv4,159.198.32.222,detect,high,2027-01-06,BusySnake C2/tunnel,campaign:ArmoredLikho ipv4,69.67.173.153,detect,high,2027-01-06,BusySnake C2/tunnel,campaign:ArmoredLikho domain,winupdate.live,detect,high,2026-10-06,BusySnake C2,campaign:ArmoredLikho domain,arvax.xyz,detect,high,2026-10-06,BusySnake C2,campaign:ArmoredLikho domain,varenie.live,detect,high,2026-10-06,BusySnake C2,campaign:ArmoredLikho domain,grked.online,detect,high,2026-10-06,BusySnake tunnel endpoint,campaign:ArmoredLikho md5,C7622A1EFFA27BBFEE6D6E03D6474343,detect,high,2027-01-06,BusySnake module.pyw,campaign:ArmoredLikho md5,1096268FA2B3D454C86CF851CB782319,detect,high,2027-01-06,BusySnake NSIS dropper,campaign:ArmoredLikho
Portable python.exe/pythonw.exe running module.pyw from %APPDATA%\WindowsHelper (Q2) wscript/cscript launching run.vbs or a .pyw from a WindowsHelper path, every 5 minutes (Q3) Scheduled task named "WindowsHelper" (schtasks or Schedule.Service COM) (N1) Injected pnx.exe executing from a \Temp\nsn*.tmp NSIS dir (Q1) Stealer output written under WindowsHelper: chromium_passwords.json / firefox_passwords.json / all_browser_data.json / inventory_state.db (Q4) Non-browser process mass-reading Login Data / key4.db / logins.json / Telegram tdata / wallet.dat (Q5) ssh.exe with -R 0.0.0.0 + StrictHostKeyChecking=no + ExitOnForwardFailure=yes (reverse tunnel) (Q6) RustDesk remote-control launched by a WindowsHelper-lineage process
# C2 / tunnel IPs 159.198.41.140 159.198.75.219 159.198.32.222 69.67.173.153 # C2 / tunnel domains winupdate.live winupdate.ink arvax.xyz varenie.live lvl99.store onetoken.ink grked.online ndrt.ink myboard.chickenkiller.com myboard.twilightparadox.com # Hashes (MD5) 1096268FA2B3D454C86CF851CB782319 # NSIS EXE dropper 894332174F536C2E1EFEDA05CBA79F8B # DLL loader 393B498F2114CABC0B29D5FCD9DC6723 # LNK (ZDI-CAN-25373) C7622A1EFFA27BBFEE6D6E03D6474343 # module.pyw (BusySnake) 80B7700053E115D65365CE7330383320 # module.pyw (new version) # All atoms per Kaspersky Securelist; rotate frequently -- refresh before relying on them.
Disable Windows Script Host (blocks run.vbs / wscript persistence) where WSH is not required ASR: block executable content from email client and webmail (NSIS/LNK delivery) App control (WDAC/AppLocker): deny execution from %APPDATA%\Roaming\WindowsHelper\ and \Temp\nsn*.tmp\ Block/monitor unsanctioned portable Python interpreters on user endpoints Block outbound SSH (22) from workstations; alert on ssh.exe -R reverse tunnels Block C2 IPs/domains at proxy/DNS; alert on RustDesk on non-IT hosts Force reset of browser-stored creds + revoke sessions on any hit; hardware 2FA
Hardening — Tiered & Deployable
Break the WSH/portable-Python execution path, constrain the persistence dir, and cut the reverse-tunnel egress.
- Block executable content from email client and webmail (ASR) — M1042. Cuts the NSIS EXE / LNK delivery. GUID
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550. - Disable Windows Script Host where not required — M1042 / M1038. Kills
run.vbspersistence and the WSH launcher. - Promote Q2 / Q3 / Q4 to Detect+Block — M1040. The
WindowsHelperexecution + persistence + staged-output triad is malware-specific. - Block C2 IPs/domains + RustDesk on non-IT hosts at proxy/DNS — M1037 / M1021. Feeds Q7/Q8.
Deployable — disable WSH (GPO/registry)
REM Disable Windows Script Host for the machine (and per-user) -- run elevated reg add "HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings" /v Enabled /t REG_DWORD /d 0 /f reg add "HKCU\SOFTWARE\Microsoft\Windows Script Host\Settings" /v Enabled /t REG_DWORD /d 0 /f REM Verify: reg query "HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings" /v Enabled
Deployable — enable the email-content ASR rule (PowerShell)
Add-MpPreference -AttackSurfaceReductionRules_Ids BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 -AttackSurfaceReductionRules_Actions Enabled # Verify: (Get-MpPreference).AttackSurfaceReductionRules_Ids
- WDAC/AppLocker: deny execution from
%APPDATA%\Roaming\WindowsHelper\and\Temp\nsn*.tmp\— M1038. Breaks Q1/Q2. - Inventory + constrain unsanctioned portable Python interpreters — M1045 / M1038. Removes the runtime BusySnake ships with itself.
- Egress control: block outbound SSH (22) from workstations; alert on
ssh.exe -R— M1037. Feeds Q6.
Deployable — AppLocker deny rule (path condition)
# Deny execution from the malware's working/staging dirs (deny beats allow in AppLocker). # Add EXE + Script rule collections denying these paths, then test in Audit mode first: %OSDRIVE%\Users\*\AppData\Roaming\WindowsHelper\* %OSDRIVE%\Users\*\AppData\Local\Temp\nsn*.tmp\* # Deploy via GPO: Computer Config > Windows Settings > Security Settings > Application Control Policies
- Application allowlisting fleet-wide; default-deny user-path execution — M1038.
- Phishing-resistant (hardware) MFA + session-token binding — M1032. Blunts stolen cookies / 2FA reuse.
- Egress allow-listing / broker for OT-adjacent and government segments — M1030 / M1037. Denies arbitrary C2 + reverse tunnels.
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain the host; preserve %APPDATA%\WindowsHelper (payload, staged JSON/DB, VBScripts), the NSIS dropper and the phishing mail | SOC L2 | Containment timestamp; Q2/Q3 events; samples |
| Triage | Map dropper → injection → Python execution → task persistence → secret reads → tunnel/exfil; enumerate which browsers/wallets/Telegram/2FA were touched; extract C2 IPs/domains from Q7/Q8 | IR | Process tree; file-access list; C2 list |
| Eradicate | Delete the WindowsHelper scheduled task + run.vbs/wh_selfdelete.vbs; remove WindowsHelper dir + portable Python; kill any ssh -R / RustDesk session; block C2 | IR | Task/file removal log; killed sessions |
| Recover | Assume credential + cookie + wallet + Telegram-session compromise: force-reset passwords, revoke browser sessions/tokens, re-enroll 2FA, invalidate Telegram sessions, rotate/move any wallet funds; reimage if injection/loader ran | IR + IT + user | Cred reset; token revoke; wallet moves |
| Harden | Disable WSH; ASR email-content rule; AppLocker deny on WindowsHelper/Temp; block SSH egress; promote Q2/Q3/Q4/Q6; brief targeted teams | Detection Eng | IOA enabled; ASR/GPO applied; egress blocks |
WindowsHelper task, and widen scope to credentials used from the host.Detection Coverage Map & Validation
| Technique | Behavior | CQL | IOA | Coverage |
|---|---|---|---|---|
| T1204.002 / T1055 | NSIS dropper / pnx.exe injection | Q1 | — | Good |
| T1059.006 | module.pyw execution from WindowsHelper | Q2 | IOA-1 | Good |
| T1053.005 / T1059.005 | WindowsHelper task / run.vbs persistence | Q3 | IOA-2 | Good + N1 |
| T1074.001 | Stealer output staged under WindowsHelper | Q4 | — | Good |
| T1555.003 / T1539 / T1005 | Browser/wallet/Telegram secret reads | Q5 | — | Partial needs file-read telemetry |
| T1572 | Reverse SSH tunnel | Q6 | IOA-3 | Good |
| T1105 / T1102 | GitHub payload pull | — | — | GAP proxy/DNS (N2) |
| T1219 | RustDesk remote control | — | — | Partial app inventory / net |
| T1041 / T1071.001 | C2 exfil (IPs/domains) | Q7, Q8 | — | Partial perishable atoms |
Validation gates: (1) confirm process + file open/write + DNS/network telemetry is flowing from the targeted (government / OT-adjacent) hosts; (2) baseline any sanctioned portable-Python automation, RustDesk deployments, and ssh -R jump-host use so Q2/Q6 stay clean; (3) lab-test — a benign portable-Python script must NOT fire Q2 unless it runs from WindowsHelper, and a benign browser-profile read must stay below the Q5 distinct-file threshold; (4) refresh the C2 IP/domain watchlist (Q7/Q8) before relying on a clean result — the atoms rotate. No durable payload hash — anchor on behavior.
Hunt Summary Ticket
TITLE: Hunt — BusySnake Stealer / Armored Likho (Eagle Werewolf) APT
SEVERITY: High (state-nexus espionage; credential/wallet/Telegram theft; interactive access)
SCOPE: Government + electric-power Windows workstations; browser/wallet/Telegram secret stores; egress
HYPOTHESIS: Spear-phish RAR/ZIP -> NSIS EXE (or ZDI-CAN-25373 LNK) injects pnx.exe -> stages portable
Python 3.12 + module.pyw in %APPDATA%\WindowsHelper -> WindowsHelper task re-runs every 5 min
-> BusySnake harvests browser/wallet/Telegram/2FA -> reverse SSH tunnel + RustDesk -> Flask C2.
QUERIES RUN: Q1 pnx.exe dropper | Q2 module.pyw exec (IOA) | Q3 WindowsHelper task (IOA) |
Q4 staged-output JSON | Q5 secret reads | Q6 reverse SSH (IOA) | Q7 C2 DNS | Q8 C2 IP beacon
+ Native N1-N5 (WindowsHelper task, GitHub pull, LNK/archive, rundll32->ps->python, secret read)
DO FIRST: Q2, Q3, Q4 -- then escalate any Q6 hit (reverse SSH = hands-on-keyboard access)
FINDINGS: <pending analyst execution>
GAPS: GitHub payload pull (proxy/DNS); RustDesk (app inventory); C2 atoms perishable
ACTIONS: Disable WSH; ASR email-content rule; AppLocker deny WindowsHelper/Temp; block SSH egress;
promote Q2/Q3/Q4/Q6; assume cred+cookie+wallet+Telegram compromise on any hit
OWNER: HuntPack
VERSION: v0.2 - 2026-07-06
Changelog
table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.References
| Tier | Source | Used For |
|---|---|---|
| 1 | Kaspersky Securelist — Armored Likho's new weapon: BusySnake Stealer | Full infection chain, persistence, stealer functions, C2 IPs/domains, MD5 hashes, SSH-tunnel/RustDesk, attribution |
| 1 | The Hacker News — Armored Likho Targets Government Agencies, Power Sector with BusySnake Stealer | Attribution (Eagle Werewolf); gov + energy targeting (RU/KZ/BR); AI-assisted first stage; tool polymorphism |
| 2 | TechTimes · MalwareTips | Corroboration — three-country power-sector targeting; LLM-generated loader tells |
HuntPack v0.1 · BusySnake Stealer / Armored Likho (Eagle Werewolf) · Generated 2026-07-06 · Defensive use only — no offensive code. The payload rotates via automated GitHub releases and is PyArmor-obfuscated, so anchor on the WindowsHelper execution + persistence lineage and the reverse-SSH/RustDesk egress, not a fixed hash. Atomic IOCs are perishable and trace to Kaspersky Securelist — validate field names and baseline sanctioned portable-Python / RustDesk / ssh -R usage before promoting any query.