A typosquatting campaign published a malicious npm package, @typescript_eslinter/eslint, that mimicked @typescript-eslint/eslint-plugin to compromise developer environments and install a live secondary payload (@typescript_eslinter/prettier). The malware monitored clipboard and keyboard input, established persistence via a startup .bat, and connected to a WebSocket C2 at 135.181.226.254 for real-time command execution and data exfiltration. #typescript_eslinter_eslint #typescript_eslinter_prettier
Keypoints
- The attacker published a typosquatted package, @typescript_eslinter/eslint, that closely mimicked @typescript-eslint/eslint-plugin and released 43 versions in two weeks to evade detection.
- The malicious package performed clipboard monitoring and global keyboard logging to capture sensitive information like API keys and credentials.
- A secondary malicious package, @typescript_eslinter/prettier, remained live on npm and acted as an additional payload to spread or enhance functionality.
- The malware established persistence on Windows by copying prettier.bat into the user’s Startup folder.
- It used obfuscation (string reversal and Base64) and a WebSocket connection to a C2 server (ws://135.181.226.254:5051) hosted in Finland for real-time command execution and exfiltration.
- The package attempted to disable legitimate tooling (e.g., removing or replacing ESLint processes) to avoid interference and maintain control.
MITRE Techniques
- [T1195] Supply Chain Compromise – Attackers used typosquatting to publish a malicious npm package impersonating a popular library (‘The malicious package @typescript_eslinter/eslint mimicked the legitimate @typescript-eslint/eslint-plugin’).
- [T1056.001] Input Capture: Keylogging – The package used a global keyboard listener to capture keystrokes (‘const { GlobalKeyboardListener } = require(“node-global-key-listener”); … pendingData.fuzzer += “,” + e.name;’).
- [T1056.003] Input Capture: Clipboard – It monitored clipboard changes to harvest copied secrets (‘const minimizerListener = require(“clipboard-event”); minimizerListener.startListening(); minimizerListener.on(“change” … pendingData.minimizer += “,” + change;’).
- [T1547.001] Boot or Logon Autostart Execution: Startup Folder – The malware copies prettier.bat into the Windows Startup folder for persistence (‘fs.copyFileSync(sourceFile, destinationFile);’ to Startup path).
- [T1027] Obfuscated Files or Information – Strings (C2 addresses) were reversed and Base64 encoded to hide the server address until runtime (‘the string is first reversed, encoded in Base64, and then dynamically decoded at runtime’).
- [T1071.004] Application Layer Protocol: Web Protocols – The package established a WebSocket connection to a remote C2 server for commands and exfiltration (‘const socket = io(SERVER_URL … );’ and ‘ws://135.181.226.254:5051’).
- [T1041] Exfiltration Over Command and Control Channel – Collected clipboard, environment variables, and credentials were sent to the C2 via the WebSocket connection (‘Exfiltrates sensitive data, such as clipboard contents, environment variables, and credentials’).
- [T1059.003] Command and Scripting Interpreter: Windows Command Shell – Attackers executed arbitrary shell commands remotely via the WebSocket C2 to further exploit systems (‘executes commands dynamically on compromised systems’).
- [T1562.001] Impair Defenses: Disable or Modify Tools – The package attempted to remove or disable legitimate tooling like ESLint to prevent interference (‘pm2 delete eslinter’ function to delete Eslinter).
Indicators of Compromise
- [Malicious npm packages] Typosquatted packages used to compromise developers – @typescript_eslinter/eslint (removed), @typescript_eslinter/prettier (still live)
- [IP / C2] Command-and-control server – 135.181.226.254 (ws://135[.]181[.]226[.]254:5051) hosted in Finland by Hetzner Online GmbH
- [File / Artifact] Persistence artifact – prettier.bat copied into the Windows Startup folder
- [Packages / Libraries] Packages used for spying – clipboard-event (clipboard monitoring), node-global-key-listener (global key logging)
Read more: https://socket.dev/blog/malicious-npm-package-typosquats-popular-typescript-eslint-plugin