MemTensor npm and PyPI Packages Compromised in Credential-Stealing Supply Chain Attack
Malicious versions of MemTensor's npm and PyPI packages drop a Go binary that steals developer credentials and exfiltrates them to skyleen.fr infrastructure. The compromised npm package @memtensor/memos-cloud-openclaw-plugin (0.1.21, 0.1.23, 0.1.25) and PyPI package MemoryOS (2.0.34) are currently latest on their registries. Both bundle a Go binary named sckit that searches $HOME for npm, PyPI, AWS, Vault, GitHub, GitLab, and SSH secrets. The binary exfiltrates findings to three C2 servers under skyleen.fr. Stolen registry tokens may enable republishing, indicating worm potential.
Detection / Hunteropenrouter
Immediate Actions
- Pin npm to 0.1.20 and PyPI to 2.0.33, or uninstall affected versions.
- Kill any running sckit process and delete cache directories.
- Block skyleen.fr and all subdomains at DNS and proxy.
- Rotate all secrets reachable from affected $HOME and environment.
Key Takeaways
- npm 0.1.20 and PyPI 2.0.33 are the last known-good releases; pin to these or uninstall.
- sckit runs detached, surviving parent exit. For npm, user prompt text is passed via SCKIT_EVENT_TEXT on every recall.
- PyPI payload triggers on module import via get_logger() hook; no explicit API call needed.
- Configuration expires October 22, 2026; campaign names are cloud-openclaw-semi-nuclear and memos-semi-nuclear.
- Malicious commits e0c1ca3 and b52958f were not referenced by any branch or tag in either repo.
Attack Chain
- Initial Access: Attacker publishes malicious versions of MemTensor npm and PyPI packages on September 23, 2026.
- Execution: sckit Go binary launches on package import or OpenClaw gateway start, detached from parent.
- Collection: Binary searches $HOME for credential files and environment variables containing secrets.
- Exfiltration: Collected credentials sent to three C2 servers under skyleen.fr over HTTPS.
- Impact: Stolen registry tokens may enable republishing packages, indicating worm behavior potential.
Affected Systems
- Systems with @memtensor/memos-cloud-openclaw-plugin 0.1.21, 0.1.23, or 0.1.25
- Systems with PyPI package MemoryOS version 2.0.34
- Linux x64 and arm64
- macOS x64 and arm64
- Windows x64 and arm64
- Developer machines, CI runners, and test containers
Detection Availability
No detection rules or queries are published in the source article.
Detection Engineering Assessment
Hypotheses are starting points derived from the article, not findings about your environment; validate against your own telemetry.
| Dimension | Rating | Rationale |
|---|---|---|
| EDR Visibility | Medium | Go binary spawned by node/python visible; detached execution and swallowed errors reduce visibility. |
| Network Visibility | High | C2 traffic to skyleen.fr subdomains over HTTPS detectable in DNS and proxy logs. |
| Detection Difficulty | Moderate | Known C2 domain and binary name simplify detection; supply chain vector hard to prevent. |
Hunting Hypotheses
| Hypothesis | Telemetry | Stage | FP Risk |
|---|---|---|---|
| Processes named sckit or spawned by node/python making HTTPS to skyleen.fr subdomains (T1071.001) | EDR process network connections, DNS | Command and Control | Low — sckit is an unusual binary name |
| npm or pip install followed by unexpected binary execution from .sckit directories (T1059) | Package manager logs, EDR process events | Execution | Low — post-install binary execution is suspicious |
| Processes scanning $HOME for credential files like .npmrc, .vault-token, id_ecdsa (T1552.001) | EDR file access telemetry | Credential Access | Medium — dev tools may read credential files |
Required Log Sources
- DNS query logs
- Proxy and egress firewall logs
- EDR process telemetry
- Package manager install logs
- Endpoint file creation events
- npm and PyPI registry logs
Key Behavioral Indicators
- sckit binary spawned by node or python processes
- Files created in ~/.openclaw/.cache/runtime or ~/.memos/.cache/runtime
- DNS queries to *.skyleen.fr subdomains
- PyPI wheel size 19MB vs 951KB in previous release
- npm package published without gitHead attribute
- Base64-encoded JSON passed to sckit via --config64 flag
Control Gaps
- Package registries cannot detect bundled native binaries
- EDR may miss detached processes surviving parent exit
- No egress restrictions on CI runners to block C2
- Registry publish token security insufficient against unauthorized publishes
- Lack of package signing on npm and PyPI
False Positive Assessment
Low — sckit is an unusual binary name, and skyleen.fr has no legitimate use.
Recommendations
Suggestions to evaluate against your own environment, tooling, and incident-response procedures — not directives.
Infrastructure Hardening
- Restrict CI runner egress to approved domains only.
- Implement package allowlisting in CI pipelines.
- Enable package signing and verification on registries.
- Monitor package sizes for anomalous growth on install.
User Protection
- Deploy EDR rules alerting on sckit binary execution.
- Scan lockfiles and SBOMs for affected package versions.
- Alert on post-install native binary execution from package directories.
- If EDR supports host isolation, isolate affected developer machines and CI runners.
Security Awareness
- Train developers to pin package versions, not use latest.
- Review npm and PyPI publish token scope and rotation policies.
MITRE ATT&CK Mapping
Initial Access
Execution
Defense Impairment
Credential Access
Discovery
Collection
Command and Control
Exfiltration
Plain-Language Summary
Attackers compromised two popular software packages from MemTensor, a company making memory tools for AI. The packages are on npm and PyPI (online libraries for JavaScript and Python). The compromised versions include a hidden program that steals passwords, access keys, and other secrets from developers' computers and sends them to attacker-controlled servers. Anyone who installed these packages since September 23, 2026 should remove them, change their passwords and keys, and check for unauthorized activity.
Additional IOCs
- Domains:
8a8acaf167b3[.]skyleen[.]fr- C2 subdomain for npm campaign0b48fafd6fbe[.]skyleen[.]fr- C2 subdomain for npm campaign266297c6df27[.]skyleen[.]fr- C2 subdomain for npm campaign
- Urls:
hxxps://8a8acaf167b3[.]skyleen[.]fr/6110ea0c63c61803b1232685/config- C2 config retrieval endpointhxxps://8a8acaf167b3[.]skyleen[.]fr/6110ea0c63c61803b1232685/status- C2 status reporting endpointhxxps://0b48fafd6fbe[.]skyleen[.]fr/68b93a6c00a233c93dfbf8d2/config- C2 config retrieval endpointhxxps://0b48fafd6fbe[.]skyleen[.]fr/68b93a6c00a233c93dfbf8d2/status- C2 status reporting endpointhxxps://266297c6df27[.]skyleen[.]fr/accc57f34d89299a4ae50b846/config- C2 config retrieval endpointhxxps://266297c6df27[.]skyleen[.]fr/accc57f34d89299a4ae50b846/status- C2 status reporting endpoint
- File Paths:
~/.openclaw/.cache/runtime- npm state/cache directory for sckit~/.memos/.cache/runtime- PyPI state/cache directory for sckitlib/sckit.js- npm launcher module that spawns sckit binarymemos/_stage0.py- PyPI launcher module that spawns sckit binarymemos/_sckit_config64- Base64-encoded JSON config for sckitmemos/_pypi_bridge.sh- Helper script targeting PyPI publish tokenmemos/_initial_ci_delivery.py- CI delivery helper for publish pipelinesckit_poetry_build.py- Modified Poetry build backend in sdist
- Command Lines:
- Purpose: Launch sckit binary detached on OpenClaw gateway start and memory recall | Tools:
node,sckit| Stage: Execution |sckit --config64 - Purpose: Launch sckit binary on memos module import via get_logger hook | Tools:
python3,sckit| Stage: Execution |sckit --config64
- Purpose: Launch sckit binary detached on OpenClaw gateway start and memory recall | Tools:
- Other:
e0c1ca3- Malicious commit in MemTensor plugin repositoryb52958f- Malicious commit in MemOS repository
- domain0b48fafd6fbe[.]skyleen[.]frC2 subdomain for npm campaign
- domain266297c6df27[.]skyleen[.]frC2 subdomain for npm campaign
- domain8a8acaf167b3[.]skyleen[.]frC2 subdomain for npm campaign
- domainskyleen[.]frRoot C2 domain for credential exfiltration
- filenamesckit_poetry_build.pyModified Poetry build backend in sdist
- file_pathlib/sckit.jsnpm launcher module that spawns sckit binary
- file_path~/.memos/.cache/runtimePyPI state/cache directory for sckit
- file_pathmemos/_initial_ci_delivery.pyCI delivery helper for publish pipeline
- file_pathmemos/_pypi_bridge.shHelper script targeting PyPI publish token
- file_pathmemos/_sckit_config64Base64-encoded JSON config for sckit
- file_pathmemos/_stage0.pyPyPI launcher module that spawns sckit binary
- file_path~/.openclaw/.cache/runtimenpm state/cache directory for sckit
- npm_package@memtensor/memos-cloud-openclaw-pluginCompromised package; versions 0.1.21, 0.1.23, 0.1.25 drop sckit
- pypi_packagememoryosCompromised package; version 2.0.34 drops sckit
- urlhxxps://0b48fafd6fbe[.]skyleen[.]fr/68b93a6c00a233c93dfbf8d2/batchC2 data exfiltration endpoint (npm campaign)
- urlhxxps://0b48fafd6fbe[.]skyleen[.]fr/68b93a6c00a233c93dfbf8d2/configC2 config retrieval endpoint
- urlhxxps://0b48fafd6fbe[.]skyleen[.]fr/68b93a6c00a233c93dfbf8d2/statusC2 status reporting endpoint
- urlhxxps://266297c6df27[.]skyleen[.]fr/accc57f34d89299a4ae50b846/batchC2 data exfiltration endpoint (npm campaign)
- urlhxxps://266297c6df27[.]skyleen[.]fr/accc57f34d89299a4ae50b846/configC2 config retrieval endpoint
- urlhxxps://266297c6df27[.]skyleen[.]fr/accc57f34d89299a4ae50b846/statusC2 status reporting endpoint
- urlhxxps://8a8acaf167b3[.]skyleen[.]fr/6110ea0c63c61803b1232685/batchC2 data exfiltration endpoint (npm campaign)
- urlhxxps://8a8acaf167b3[.]skyleen[.]fr/6110ea0c63c61803b1232685/configC2 config retrieval endpoint
- urlhxxps://8a8acaf167b3[.]skyleen[.]fr/6110ea0c63c61803b1232685/statusC2 status reporting endpoint