# Sckit Supply Chain Worm Hits MemTensor npm & PyPi scopes

Malicious MemTensor npm/PyPI releases bundled a Go credential-harvesting worm launched from plugin lifecycle hooks, exfiltrating env secrets and prompts to skyleen.fr fronts.

- Payout: Real-world hack
- Severity: critical
- Program: MemTensor
- Analysis by: StepSecurity
- Disclosed: 2026-09-30
- Write-up quality: 8/10
- Original: https://www.stepsecurity.io/blog/sckit-supply-chain-worm-hits-memtensor-npm-pypi-scopes
- Library page: https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-sckit-supply-chain-worm-hits-memtensor-npm-pypi-scopes
- Tags: area:oss domain:oss impact:data-leak impact:mass-exploit kind:incident platform:threat-intel sev:critical tech:ci-cd tech:github-actions tech:nodejs tech:python technique:source-review vuln:dependency-confusion vuln:secrets-leak

**Target:** npm @memtensor/memos-cloud-openclaw-plugin and PyPI MemoryOS 2.0.34 packages
**Root cause:** Compromised publishing credentials let attackers push releases adding lib/sckit.js and memos/_stage0.py launchers that spawn a bundled Go binary with the host environment and prompt text; a Python logging hook triggers on normal import.
**Steps:**
1. Install @memtensor/memos-cloud-openclaw-plugin 0.1.21/0.1.23/0.1.25 or MemoryOS 2.0.34
2. npm: gateway startup calls `launchStageZero()`; memory recall calls `launchStageZero(userPrompt)` from lib/sckit.js
3. PyPI: `import memos` reaches `configure_logging()` in src/memos/log.py which calls `trigger()` from memos/_stage0.py
4. Launcher spawns `.sckit/<platform>-<arch>/sckit stage0 --config64 <CONFIG>` detached with `env: {...process.env, SCKIT_EVENT_TEXT: text}`
5. Binary scans `$HOME` per `inventory_roots`, matches credential regexes (AWS AKIA, gh[opusr]_, npm_, pypi-, hf_, hvs., xox, sk_live_, JWTs)
6. Exfiltrates to `https://<hash>.skyleen.fr/<id>/config|status|batch`; 0.1.25 adds `.sckit/ca-roots.pem` SSL_CERT_FILE fallback
7. Binary strings show `recursivePublish`, `prepareRemoteWorkflow` and a GitHub Actions template running `./%s/linux-amd64/sckit stage0 --config64 %q` on push
**How found:** Static analysis: diffed 0.1.20 baseline against 0.1.21+ (272KB→43.6MB), spotted new lib/sckit.js imported into index.js lifecycle hooks, decoded the base64 --config64 blob, extracted strings from the Go binaries, and traced the PyPI import chain from memos/__init__.py through log.py to _stage0.trigger().
**Exploitation:** Attacker with publishing access pushed alternating clean/malicious versions within minutes; on victim use the launcher spawns a detached stripped Go binary inheriting process.env (including NPM_TOKEN/NODE_AUTH_TOKEN) and prompt text, harvests credentials from $HOME, and beacons to rotating skyleen.fr fronts; binary contains recursivePublish/prepareRemoteWorkflow to propagate via npm/PyPI tokens and GitHub Actions workflows.
**Escalation:** Credential harvesting targets package-publishing tokens and source-control PATs to recursively publish further compromised packages and install push-triggered GitHub Actions workflows, turning a single package compromise into a supply-chain worm across ecosystems.
**Insight:** Diff package size and new files against a prior clean version; lifecycle hooks (gateway startup, memory recall, module-scope logger init) are execution triggers even without install scripts, so audit import-time code paths like configure_logging() and dotenv loads for spawn calls.
