Signed PuTTY Installer Hides a Node.js Malware Loader

· Original article ↗

Summary

Analysis found a signed PuTTY.msi that installs genuine PuTTY alongside a re-signed Node.js loader. After a five-minute delay, it fetches an encrypted in-memory stage from Cloudflare Workers; the stage's purpose remains unknown.

Key points

  • The MSI installs genuine PuTTY as a decoy and launches a re-signed Node.js 26.7.0 executable carrying a hidden script and the koffi library.
  • The loader waits 300 seconds, checks for security-product DLLs, and chooses between network-communication paths based on what it finds.
  • On one path, it patches ETW and AMSI; it also uses encrypted key exchange and avoids writing the downloaded stage to disk.
  • In a sandbox, the loader contacted machinegirl[.]carvelpolman[.]workers[.]dev, then downloaded an approximately 240 KB module that contacted subdomains of normanitavo[.]workers[.]dev.
  • The second-stage module remains unanalyzed. Loaded libraries could be relevant to credential theft, but the article says their presence alone does not establish that activity.
  • The installer does not create a Run key, shortcut, or scheduled task, but its Node.js files remain after uninstall; the article recommends checking C:\ProgramData\NodeJS\node.exe and hunting for related activity.

Article Details

Attack Vectors
  • A PuTTY.msi installer installs the genuine PuTTY client while launching a re-signed Node.js executable from C:\ProgramData\NodeJS\ in the background.
  • The embedded JavaScript waits 300 seconds, checks for security-product DLLs, and downloads a second stage from a Cloudflare Workers address.
  • The loader decrypts and executes the returned module in memory; the observed second-stage module established a separate command channel through additional Workers hostnames.
Defensive Notes
  • Download PuTTY only from its official page or through winget, and stop if the installer is signed by someone other than Simon Tatham.
  • If this installer was run, check for C:\ProgramData\NodeJS\node.exe; uninstalling PuTTY does not remove the Node.js files.
  • Hunt for node.exe outside normal installation paths, particularly when it is signed by someone other than the OpenJS Foundation, and for HKCU\Software\NodeJS\Agent.
  • Flag Node processes that load koffi.node and then create private executable memory or thread-pool work.
  • Block or alert on *.carvelpolman[.]workers[.]dev and *.normanitavo[.]workers[.]dev; look for direct DNS to public resolvers or DoH from non-browser processes.
  • Watch for MSI custom actions launching node.exe from ProgramData.

Indicators of compromise

TypeIndicatorContext
HOSTNAMEbluepeak[.]normanitavo[.]workers[.]devObserved second-stage command-channel hostname.
HOSTNAMEcedar-stone[.]normanitavo[.]workers[.]devObserved second-stage command-channel hostname.
SHA2562214430d1611a20f60cd656025b031d9476c5f2d9bdb421ec5d4e87551167453SHA-256 of decoy_launch.exe, the helper used to open the genuine PuTTY client.
SHA25673ab77da60d7196bce61405c615f8cd03a3157abffaf4a2447bd79fb8082da9fSHA-256 of the malicious PuTTY.msi installer.
SHA2567409a74bb808d35d03e4aac7e05991b3b2263a30bc225144d6f520ad264be636SHA-256 of the in-memory httpc module used by the loader.
SHA256823d9e0d1086a5894e126dbff272259731208bd17dc47a0753849ee98818339eSHA-256 of the Node.js single-executable loader carrying the hidden script.
SHA256f384e2419f200e4eb8b49657be41a0e4327b044e7d571303b68463d417a2d544SHA-256 of the re-signed koffi.node component bundled with the loader.
URLhxxps[:]//machinegirl[.]carvelpolman[.]workers[.]dev/Loader C2 URL that supplied the get_module_luna stage in the observed sandbox run.

MITRE ATT&CK

People

Vendors

Products

Tools

Related Articles