TrapDoor — Cross-Ecosystem Supply-Chain Credential Stealer
Executive Summary
TrapDoor is a coordinated cross-ecosystem software supply-chain campaign that simultaneously weaponizes npm, PyPI, and Crates.io — at least 34 malicious packages across 384+ versions — to deliver credential-stealing malware to developers in the crypto, DeFi, Solana, and AI tooling communities. Earliest publication was recorded 2026-05-22 20:20 UTC, pushed in rapid waves from a small cluster of throwaway registry accounts.
The campaign is notable for three things: (1) per-runtime execution paths — npm postinstall hooks run a shared trap-core.js payload, PyPI packages auto-execute on import and fetch attacker JavaScript that runs via node -e, and Rust crates execute through build.rs at compile time; (2) secret theft and lateral movement — it scans for crypto wallets/keystores, validates AWS and GitHub tokens, harvests SSH keys and browser data, and attempts SSH-based pivoting; and (3) AI coding-assistant poisoning — it plants hidden instructions inside .cursorrules and CLAUDE.md project files using zero-width Unicode characters, tricking AI agents into re-running credential-discovery "security scans." Exfiltration rides legitimate GitHub infrastructure (GitHub Pages payload host, GitHub Gists for Rust exfil), and persistence is planted via cron, systemd, Git hooks, shell hooks, and SSH config.
Defender priority: The highest-value, lowest-FP detection is a package-manager process (npm/pnpm/yarn, pip/python, cargo) spawning node -e or reaching out to *.github.io / gist.github.com during install/build. Pair that with file-write monitoring on .cursorrules, CLAUDE.md, and ~/.ssh/ on developer and build endpoints. Treat any hit as a credential-compromise event: rotate the dev's wallet keys, SSH keys, and cloud/GitHub tokens immediately.
Source Review & Web Hunter Notes
| Tier | Source | Key Finding | Carry Fwd |
|---|---|---|---|
| 1 | Socket Threat Research — "TrapDoor Crypto Stealer" | Full package list (21 npm / 7 PyPI / 6 crates), shared trap-core.js payload (48,485 bytes), GitHub account ddjidd564, XOR key cargo-build-helper-2026, attacker docs (AUDIT-MATRIX/BYPASS/PAYLOAD/SWARM.md) | yes |
| 1 | The Hacker News — "TrapDoor Supply Chain Attack Spreads Credential-Stealing Malware" | Timeline (2026-05-22), 34+ packages / 384+ versions, GitHub Pages C2 ddjidd564.github.io, malicious PRs vs. browser-use / langchain / langflow, AI-assistant poisoning via .cursorrules / CLAUDE.md | yes |
| 2 | Phoenix Security — TrapDoor cross-ecosystem writeup | Corroborates per-runtime execution (postinstall / import-time / build.rs) and AI-assistant config poisoning angle | partial |
Web-hunter note: Atomic file hashes for trap-core.js were not published at time of writing (only the byte count / line count). The IOC appendix therefore leads with the named registry packages, accounts, and infrastructure (all source-attributed) and uses REPLACE_WITH_SHA256 placeholders for binary hashes — confirm against your registry mirror / artifact store before promoting to prevent.
Hunt Brief & Attack Chain
Hunt hypotheses (ordered by fidelity)
- H1 (high): A package manager (npm/pnpm/yarn) triggers a
postinstallscript that launchesnoderunningtrap-core.js, scanning for credentials. → Q1 - H2 (high): A Python process imports a malicious package and spawns
node -ewith inline JavaScript fetched from an external host. → Q2 - H3 (high): A dev/build process (node/python/cargo) makes outbound connections to
*.github.ioorgist.github.comduring install/build — payload pull or Gist exfil. → Q4 - H4 (medium):
cargo buildspawns abuild.rs-driven child that reads keystores and reaches network during compile. → Q3 - H5 (medium): A new or modified
.cursorrules/CLAUDE.mdfile appears on a developer endpoint shortly after a package install. → Q5 - H6 (medium): A package-manager-descended process writes to
~/.ssh/authorized_keys, installs a systemd unit, or registers a cron job (persistence). → Q6 - H7 (medium):
nodeexecutes with an-eone-liner containingeval/fetch/child_processtokens (generic loader behavior). → Q7
Attack chain
| Step | Behavior | Telemetry | Hunt Angle |
|---|---|---|---|
| 1 · Initial access | Dev installs/imports a typo-themed "security/wallet/AI" package from npm/PyPI/Crates.io | ProcessRollup2 (pkg mgr), DnsRequest (registry) | Q1, baseline package installs |
| 2 · Execution | postinstall → trap-core.js; import-time → node -e; build.rs at compile | ProcessRollup2, parent/child lineage | Q1, Q2, Q3, Q7 |
| 3 · Payload pull | Python package fetches JS from ddjidd564.github.io | DnsRequest, NetworkConnectIP4 | Q4 |
| 4 · Collection | Scan wallets/keystores, browser data, env vars; validate AWS/GitHub tokens | ProcessRollup2, FileCreateInfo | Q5, Q6 |
| 5 · Persistence | cron, systemd, Git hooks, shell hooks, SSH authorized_keys | ScheduledTaskRegistered (Win), FileCreateInfo, ProcessRollup2 | Q6 |
| 6 · AI poisoning | Write hidden zero-width-Unicode prompts into .cursorrules / CLAUDE.md | FileCreateInfo, TargetFileName | Q5 |
| 7 · Exfiltration | Secrets to GitHub Gists (Rust) / GitHub Pages-tied infra; lateral SSH | NetworkConnectIP4, DnsRequest | Q4 |
Consolidated IOC Table
All values below are source-attributed (Socket / The Hacker News). Defang restored on copy. Registry package names are the primary atomic IOCs; binary hashes were not published and are placeholdered in the appendix.
| Type | Value | Conf | Action | Context |
|---|---|---|---|---|
| domain | ddjidd564.github.io | high | detect | GitHub Pages payload host (PyPI import-time JS, marker /defi-security-best-practices/) |
| account | github.com/ddjidd564 | high | hunt | Threat-actor GitHub account hosting payloads & PRs |
| account | npm user: asdxzxc | high | hunt | npm publisher of malicious packages |
| account | PyPI users: asdmini67, dae5411 | high | hunt | PyPI publishers of malicious packages |
| marker | P-2024-001 | medium | pivot | Campaign marker string embedded in payloads |
| artifact | trap-core.js (48,485 bytes, 1,149 lines) | high | hunt | Shared npm payload run at postinstall |
| artifact | .cursorrules / CLAUDE.md (zero-width Unicode) | high | hunt | AI-assistant poisoning persistence files |
| artifact | AUDIT-MATRIX.md / BYPASS.md / PAYLOAD.md / SWARM.md | medium | pivot | Attacker tooling/docs in repos |
| string | XOR key: cargo-build-helper-2026 | medium | pivot | Rust crate exfil encryption key |
| package | npm: crypto-credential-scanner, eth-wallet-sentinel, web3-secrets-detector, wallet-security-checker, solidity-deploy-guard, llm-context-compressor, prompt-engineering-toolkit (+14) | high | detect | 21 malicious npm packages (see appendix for full list) |
| package | PyPI: cryptowallet-safety, eth-security-auditor, defi-risk-scanner, solidity-build-guard, env-loader-cli, git-config-sync, data-pipeline-check | high | detect | 7 malicious PyPI packages |
| package | Crates.io: move-analyzer-build, move-compiler-tools, move-project-builder, sui-framework-helpers, sui-move-build-helper, sui-sdk-build-utils | high | detect | 6 malicious Rust crates |
Affected Surface & Telemetry Matrix
| Surface | Required Telemetry | Priority | Gap Risk |
|---|---|---|---|
| Developer workstations (Linux/macOS/Windows) | ProcessRollup2 / SyntheticProcessRollup2, FileCreateInfo, DnsRequest | Critical | Falcon on dev laptops often patchy — confirm coverage |
| CI/CD build agents | ProcessRollup2, NetworkConnectIP4, DnsRequest | Critical | Ephemeral runners may not be sensored |
| Source repos / GitHub org | GitHub audit log, Dependabot/SCA, PR review logs | High | Not Falcon — native GitHub audit hunts (s7) |
| Cloud identity (AWS/GitHub tokens) | CloudTrail, GitHub token usage, Falcon ITP | High | Token validation may look benign |
| AI coding assistants | File telemetry on .cursorrules / CLAUDE.md | Medium | Novel surface — no signature coverage yet |
ATT&CK Mapping
| Tactic | Technique | Observed Behavior | Query / Control |
|---|---|---|---|
| Initial Access | T1195.002 — Compromise Software Supply Chain | Malicious packages on npm/PyPI/Crates.io | Q1 · SCA / lockfile pinning |
| Execution | T1059.007 — JavaScript | node -e inline payload; trap-core.js | Q1, Q2, Q7 |
| Execution | T1059.006 — Python | Import-time auto-execution | Q2 |
| Execution | T1059.004 — Unix Shell | build.rs / install scripts spawning shells | Q3 |
| Credential Access | T1552.001 — Credentials in Files | Wallet/keystore/env-var harvesting; AWS/GitHub token validation | Q5, Q6 |
| Credential Access | T1552.004 — Private Keys | SSH key theft from ~/.ssh | Q6 |
| Credential Access | T1555.003 — Credentials from Web Browsers | Browser data exfil | Q5 |
| Persistence | T1543.002 — Systemd Service | systemd unit install | Q6 |
| Persistence | T1053.003 — Cron | cron job install | Q6 |
| Persistence | T1098.004 — SSH Authorized Keys | Append attacker key to authorized_keys | Q6 |
| Persistence | T1546.004 — Unix Shell Config | shell hook / rc-file modification | Q6 |
| Defense Evasion | T1027 — Obfuscated Files/Information | Zero-width Unicode prompts in AI config files | Q5 |
| Command & Control | T1071.001 — Web Protocols | GitHub Pages payload host | Q4 |
| Exfiltration | T1567.001 — Exfil to Code Repository | GitHub Gists (Rust XOR-encrypted) | Q4 |
Native Audit-Log Hunts (non-CQL)
- GitHub org audit: Review PRs opened by
ddjidd564(or any new external contributor) against AI/agent repos (browser-use/browser-use,langchain-ai/langchain,langflow-ai/langflowwere targeted). Flag dependency-adding PRs from low-reputation accounts. - Registry / artifact proxy logs: Search Artifactory/Nexus/registry-proxy access logs for the 34 named packages (full list in s10). Any download = potential exposure.
- SCA / Dependabot: Run an org-wide dependency scan for the named packages and any version published after 2026-05-22.
- Cloud token usage: In CloudTrail/GitHub, hunt for AWS STS calls or GitHub token use from developer hosts immediately following a package install window.
- Repo grep: Search developer repos for
.cursorrules/CLAUDE.mdcontaining zero-width Unicode (U+200B/U+200C/U+200D/U+FEFF) or unexpected "run a security scan" directives.
CrowdStrike LogScale CQL Hunt Queries
Looks for: npm/pnpm/yarn directly spawning node running a script during install (postinstall hook executing trap-core.js). FP: Legitimate packages also run postinstall scripts — scope to install windows and pair with Q4/Q5 hits; exclude known-good internal build tooling.
// HUNT: npm/pnpm/yarn postinstall spawning node // CONF: high FP: medium COST: low | REQUIRES: ProcessRollup2 (Linux/macOS/Win) // FALSE POSITIVES: legit postinstall build steps; scope by install window + correlate #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | in(field="ParentBaseFileName", values=["npm", "npm-cli.js", "pnpm", "yarn", "node"]) | ImageFileName=/(\\|\/)node$|(\\|\/)node\.exe$/i | CommandLine=/postinstall|trap-core\.js|--scripts/i | table([ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine, SHA256HashData], limit=200)
Looks for: a python process spawning node with an -e inline-eval flag — the PyPI import-time → node -e execution path. A Python interpreter launching Node to eval inline JS is highly anomalous.
// HUNT: python parent spawning node -e (PyPI import-time payload) // CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ParentBaseFileName=/^python(3(\.\d+)?)?$|^python\.exe$/i | ImageFileName=/(\\|\/)node$|(\\|\/)node\.exe$/i | CommandLine=/\s-e\s|--eval/i | table([ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine], limit=200)
Looks for: cargo / a build-script-build binary spawning a shell, curl/wget, or ssh during compile. FP: Some legitimate crates use build.rs to invoke shells — exclude your known-good crate build steps and focus on hosts also matching Q4/Q6.
// HUNT: cargo / build.rs spawning shell or network tooling at compile // CONF: medium FP: medium COST: low | REQUIRES: ProcessRollup2 // TUNING: exclude known-good crates: | !in(field="GrandparentBaseFileName", values=["your-ci-runner"]) #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ParentBaseFileName=/^cargo$|build-script-build|build_script_build/i | ImageFileName=/(\\|\/)(sh|bash|zsh|curl|wget|ssh|node)$/i | table([ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine], limit=200)
Looks for: DNS lookups for the known payload host and GitHub Gist/Pages exfil infra from package-manager-related processes. FP: github.io and gist.github.com are widely used — the named host ddjidd564.github.io is high-fidelity; treat the broad github.io arm as hunt-only and correlate with Q1–Q3.
// HUNT: payload-host / Gist exfil DNS from dev tooling // CONF: high FP: medium COST: low | REQUIRES: DnsRequest // TUNING: ddjidd564.github.io = confirmed; broaden to *.github.io only as hunt #event_simpleName=DnsRequest | DomainName=/ddjidd564\.github\.io|gist\.github\.com/i | table([ComputerName, ContextBaseFileName, DomainName, aid], limit=200)
Looks for: creation/modification of .cursorrules or CLAUDE.md by a non-editor process (node/python/cargo/shell), the AI-poisoning persistence step. FP: Developers legitimately edit these — scope the writing process to package-manager/runtime binaries, not editors/IDEs.
// HUNT: .cursorrules / CLAUDE.md written by a runtime/pkg-mgr process // CONF: high FP: medium COST: low | REQUIRES: FileCreateInfo / PeFileWritten // TUNING: exclude editors: | !in(field="ImageFileName", values=["Code.exe","cursor","vim","nvim"]) #event_simpleName=/FileOpenInfo/ | TargetFileName=/(\\|\/)\.cursorrules$|(\\|\/)CLAUDE\.md$/i | ImageFileName=/(\\|\/)(node|python(3)?|cargo|sh|bash|zsh)$|node\.exe$/i | table([ComputerName, UserName, ImageFileName, TargetFileName], limit=200)
Looks for: a node/python/cargo-descended process writing ~/.ssh/authorized_keys, a systemd unit, or a crontab. FP: Config-management tooling (Ansible/Chef) also writes these — exclude your management agents and scope to developer endpoints.
// HUNT: persistence file write from dev-runtime lineage // CONF: medium FP: medium COST: low | REQUIRES: FileCreateInfo // TUNING: exclude config-mgmt: | !in(field="ParentBaseFileName", values=["ansible","chef-client","puppet"]) #event_simpleName=/PeFileWritten/ | TargetFileName=/authorized_keys$|\/etc\/systemd\/system\/|\/etc\/cron|\/var\/spool\/cron/i | ParentBaseFileName=/^node$|^python(3)?$|^cargo$|^npm$|^pnpm$|^yarn$/i | table([ComputerName, UserName, ParentBaseFileName, ImageFileName, TargetFileName], limit=200)
Looks for: node -e command lines containing fetch/eval/child_process/require('https') — generic remote-loader behavior. FP: High — developers and tooling use node -e routinely. Run as a broad hunt, rank by host also hitting Q1–Q6, and exclude your CI's known one-liners.
// HUNT: node -e inline eval with network/exec tokens // CONF: medium FP: high COST: low | REQUIRES: ProcessRollup2 // TUNING: stack-rank by hosts also matching Q1-Q6; exclude known CI one-liners #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ImageFileName=/(\\|\/)node$|node\.exe$/i | CommandLine=/\s-e\s.*(fetch|eval|child_process|require\(.https.\))/i | table([ComputerName, UserName, ParentBaseFileName, CommandLine], limit=200)
CrowdStrike Custom IOA Recommendations
| IOA Name | Pattern | Exclusions | Deployment |
|---|---|---|---|
| SUPPLYCHAIN — Python spawns node -e | Parent python* → Child node with -e/--eval | None typical — rare lineage | Promote Q2 → Custom IOA (Detect, High) |
| SUPPLYCHAIN — Dev tooling → known C2 | node/python/cargo network to ddjidd564.github.io | n/a (named host) | Promote Q4 narrow arm → IOA + Custom IOC domain block |
| SUPPLYCHAIN — AI config write by runtime | node/python/cargo writes .cursorrules/CLAUDE.md | Editors/IDEs | Promote Q5 → IOA (Detect, Medium) after baseline |
Q1, Q3, Q6, Q7 stay Investigate-only hunts until baselined — postinstall, build.rs, and node -e have legitimate developer uses.
Machine-Readable IOC Appendix
type,value,action,severity,expiration,description,tags domain,ddjidd564.github.io,detect,critical,2026-12-22,TrapDoor GitHub Pages payload host,campaign:TrapDoor sha256,REPLACE_WITH_TRAP_CORE_JS_SHA256,detect,high,2026-12-22,TrapDoor trap-core.js payload,campaign:TrapDoor domain,gist.github.com,enrich,low,2026-07-22,TrapDoor Rust Gist exfil (broad - enrich only),campaign:TrapDoor
async-pipeline-builder build-scripts-utils chain-key-validator crypto-credential-scanner defi-env-auditor defi-threat-scanner deployment-key-auditor dev-env-bootstrapper eth-wallet-sentinel llm-context-compressor mnemonic-safety-check model-switch-router node-setup-helpers project-init-tools prompt-engineering-toolkit solidity-deploy-guard token-usage-tracker wallet-backup-verifier wallet-security-checker web3-secrets-detector workspace-config-loader
# PyPI (7) cryptowallet-safety data-pipeline-check defi-risk-scanner env-loader-cli eth-security-auditor git-config-sync solidity-build-guard # Crates.io (6) move-analyzer-build move-compiler-tools move-project-builder sui-framework-helpers sui-move-build-helper sui-sdk-build-utils
# Accounts github:ddjidd564 npm:asdxzxc pypi:asdmini67 pypi:dae5411 # Artifacts trap-core.js (48485 bytes / 1149 lines) .cursorrules / CLAUDE.md (zero-width Unicode U+200B/U+200C/U+200D/U+FEFF) AUDIT-MATRIX.md BYPASS.md PAYLOAD.md SWARM.md # Strings / markers campaign marker: P-2024-001 rust XOR key: cargo-build-helper-2026 # Behavior python* spawns node with -e/--eval npm/pnpm/yarn postinstall -> node trap-core.js cargo build.rs -> shell/curl/ssh + keystore read write authorized_keys / systemd unit / cron from dev runtime
Detection Validation Gates
- Telemetry ready: Confirm Falcon Linux/macOS sensors are deployed on developer laptops and CI runners (Windows-only coverage misses most of this campaign).
- Benign baseline: Run Q1/Q3/Q7 for 7 days in your environment, catalog legitimate postinstall/build.rs/
node -eusage, build exclusion lists before promoting any to Detect. - Positive tests: In a sandbox, simulate
python -c "import os; os.system('node -e \"console.log(1)\"')"to confirm Q2 fires; create a.cursorrulesvia a script to confirm Q5. - Promotion: Promote Q2 and Q4 (named host) to Custom IOA first; hold Q1/Q3/Q6/Q7 as scheduled hunts until baselined.
Hardening — Tiered & Deployable
- Block known IOCs (M1031): add
ddjidd564.github.ioto DNS/proxy denylist; block the 34 named packages in your SCA/registry proxy. - Disable install scripts (M1042): set
npm config set ignore-scripts trueorg-wide / in CI; usepip install --no-build-isolationreview gates; vetbuild.rscrates. - Rotate exposed secrets (M1027): for any host hitting s8 queries, rotate wallet keys, SSH keys, AWS/GitHub tokens immediately.
- Internal registry proxy (M1051): force all npm/PyPI/cargo installs through a vetting proxy (Artifactory/Nexus) with allowlists and publish-date quarantine (block packages newer than N days).
- Lockfile pinning + integrity (M1051): enforce
--frozen-lockfile/ hash-pinned installs in CI; fail builds on unpinned transitive deps. - Egress control on CI (M1037): restrict build-runner egress to an allowlist (registry + your infra) so payload-pull/Gist-exfil fails.
- Developer-endpoint EDR parity (M1049): ensure Falcon coverage on all dev laptops/CI to close the gap flagged in s5.
- AI-assistant config governance (⚠ best-practice, no formal benchmark): treat
.cursorrules/CLAUDE.mdas code — require review, scan for zero-width Unicode in CI, and store in version control with protected-branch rules. - Secretless dev (M1027): move to short-lived OIDC tokens / hardware-backed wallet keys so a stolen file yields nothing reusable.
Deployable Playbooks
1 · Org-wide npm install-script lockdown (.npmrc)
# /etc/npmrc or repo .npmrc — neutralize postinstall execution ignore-scripts=true # enforce integrity + frozen lockfile in CI audit=true fund=false
2 · CI guard — fail on the named TrapDoor packages (bash)
#!/usr/bin/env bash set -euo pipefail BAD="crypto-credential-scanner|eth-wallet-sentinel|web3-secrets-detector|wallet-security-checker|solidity-deploy-guard|cryptowallet-safety|eth-security-auditor|defi-risk-scanner|solidity-build-guard|move-analyzer-build|sui-move-build-helper" if grep -E -q "\"($BAD)\"" package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null; then echo "TrapDoor package detected in lockfile - failing build"; exit 1 fi echo "lockfile clean of known TrapDoor packages"
3 · Sweep for AI-config poisoning (zero-width Unicode)
# flag .cursorrules / CLAUDE.md containing zero-width chars
grep -rlP "[\x{200B}\x{200C}\x{200D}\x{FEFF}]" \
--include=".cursorrules" --include="CLAUDE.md" /home /Users 2>/dev/null
4 · Block payload host at the proxy (Squid example)
# /etc/squid/trapdoor.acl acl trapdoor_c2 dstdomain ddjidd564.github.io http_access deny trapdoor_c2
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain any host matching s8 queries; freeze affected CI runners; revoke the dev's active GitHub/cloud sessions | SOC / IR | Falcon detections, host list |
| Eradicate | Remove the 34 packages + lockfile entries; delete trap-core.js, planted persistence (cron/systemd/SSH keys), and poisoned .cursorrules/CLAUDE.md | IR / Dev | Removed artifacts, clean rebuild |
| Rotate | Rotate ALL secrets touchable from the host: wallet/seed phrases, SSH keys, AWS keys, GitHub PATs/OAuth, npm/PyPI/cargo tokens | IR / IAM | Rotation tickets, token revocation logs |
| Recover | Rebuild dev/CI from clean images; reinstall deps via vetting proxy with pinned lockfiles; restore from known-good commit | Dev / Platform | Rebuild records |
| Report | Notify SCA vendor / registries of any unreported packages; document blast radius (which repos pulled the deps) | IR Lead | Incident report |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | Coverage |
|---|---|---|---|---|
| T1195.002 | Malicious package install | Q1, s7 SCA | — | Partial |
| T1059.007 / .006 | node -e / postinstall / import-time | Q1, Q2, Q7 | Q2 | Good |
| T1059.004 | build.rs shell/network | Q3 | — | Partial |
| T1071.001 / T1567.001 | GitHub Pages / Gist C2 & exfil | Q4 | Q4 (named host) | Good |
| T1552 / T1555 / T1539 | Wallet/SSH/browser secret theft | Q5, Q6 | — | Partial |
| T1543.002 / T1053.003 / T1098.004 | systemd / cron / SSH persistence | Q6 | — | Partial |
| T1027 | AI-config zero-width poisoning | Q5, s7 grep | Q5 | Partial |
| — | In-memory token validation (no disk/process artifact) | — | — | GAP |
Validation: Coverage is strongest on the execution and C2 steps (Q2/Q4 promotable to IOA). The main gap is silent in-memory secret validation, which leaves no local artifact — close it with egress control (s12) and cloud-side token-use monitoring (s7) rather than endpoint detection.
Hunt Summary Ticket
TITLE: TrapDoor cross-ecosystem supply-chain stealer (npm/PyPI/Crates.io)
SEVERITY: High — active campaign, developer/CI credential theft
SCOPE: Developer workstations + CI runners (Linux/macOS/Windows), GitHub org
HYPOTHESIS: Devs pulled typo-themed crypto/AI packages; postinstall/import-time/
build.rs payloads stole wallets, SSH keys, cloud/GitHub tokens and
poisoned .cursorrules/CLAUDE.md
QUERIES: Q1 postinstall->node | Q2 python->node -e | Q3 build.rs | Q4 C2 DNS |
Q5 AI-config write | Q6 persistence | Q7 node -e loader
DO FIRST: Run Q4 (named host) + Q2; SCA-scan org for the 34 packages (s10)
FINDINGS: <fill on triage>
GAPS: In-memory token validation leaves no local artifact (cover via egress + cloud logs)
ACTIONS: Block IOCs, ignore-scripts, registry proxy, rotate all dev secrets on any hit
OWNER: <analyst>
VERSION: v0.1 · 2026-06-22
Changelog
table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.References
| Tier | Source | Used For | Access Date |
|---|---|---|---|
| 1 | Socket — TrapDoor Crypto Stealer (npm/PyPI/Crates) | Package list, payload artifacts, accounts, XOR key | 2026-06-22 |
| 1 | The Hacker News — TrapDoor Supply Chain Attack | Timeline, scope, GitHub Pages C2, AI-assistant poisoning, targeted repos | 2026-06-22 |
| 2 | Phoenix Security — TrapDoor cross-ecosystem & AI poisoning | Per-runtime execution corroboration | 2026-06-22 |
| Ref | MITRE ATT&CK T1195.002 | Technique mapping | 2026-06-22 |