LWA-2026-13509 confirmed malware

@ifasn/mmdd-doc-mcp@1.1.8

Malicious code in @ifasn/mmdd-doc-mcp (npm)

T1195.002 · Compromise Software Supply ChainT1059.007 · JavaScriptT1082 · System Information DiscoveryT1552.005 · Cloud Instance Metadata APIT1552.001 · Credentials In FilesT1071.001 · Web ProtocolsT1071.004 · DNST1041 · Exfiltration Over C2 ChannelT1070.004 · File Deletion

Analysis

This package is billed as a Markdown MCP server (md_toc / md_stats / md_table) but its entry point index.js runs an unsolicited cloud-infrastructure reconnaissance routine on startup, before any MCP request is served. The routine (v2Probe) issues requests to the Alibaba Cloud instance metadata service at hxxp://100[.]100[.]100[.]200 — a PUT to /latest/api/token with the X-aliyun-ecs-metadata-token-ttl-seconds header, a GET to /latest/meta-data/ram/security-credentials/ (the RAM role credential path), and a GET to /latest/meta-data/ — and reports only the HTTP status of each to the endpoint hxxp://121[.]199[.]24[.]94[.]nip[.]io/beacon (IP fallback hxxp://121[.]199[.]24[.]94/beacon) with query parameters stage=v2probe, src=mmdd-doc-mcp and res=<status list>. Results are also written to output/meta_field_dump.txt in the working directory. The same package ships in-tree generator scripts (build115.js, build116.js, rewrite111.js, patch1xx.js) whose source shows the fuller payload this routine was reduced from: a metaFieldDump function that enumerates ~35 instance metadata fields (instance-id, hostname, mac, vpc-id, vswitch-id, serial-number, zone-id, owner-account-id, ^user-data, ram/security-credentials/role-name, network/interfaces/), reads /proc/self/status CapEff to test for CAP_SYS_ADMIN, parses /proc/self/mountinfo for docker.sock, containerd.sock, kubelet and hostPath mounts, probes block devices /dev/vdb, /dev/vda, /dev/sda, /dev/nvme0n1, counts processes under /proc, and reads host paths including /var/run/secrets/kubernetes[.]io/serviceaccount/token, /etc/shadow, /etc/passwd, /root/.ssh/id_rsa, /var/www/html/.env and /var/www/html/config.php. Each generator script rewrites index.js and the package's own package.json version in place before publishing, so a post-install inspection of the extracted tree does not reflect what an earlier version executed.

analyzed by
Leitwacht
first seen
Oct 31, 2026, 02:56 PM
analyzed
Oct 31, 2026, 03:05 PM
weekly installs
1,993

Related advisories

browse all confirmed advisories →

Independently detected by the Leitwacht supply-chain probe. IOCs are defanged. Published CC0. Think this is a mistake? See the dispute policy.