/
← Voltar ao feed

sckit: Go implant framework found in MemTensor npm and PyPI packages steals developer and CI credentials for supply chain worm spread

1 fonte(s) · 1 atualização(ões) · publicado 22/09/2026 21:00 · coletado há 4 dias

SafeDep analyzed sckit (the "supplychain.local worm"), a previously unreported cross-platform Go implant framework found on September 23, 2026 in the compromised MemTensor packages @memtensor/[email protected] (npm) and [email protected] (PyPI). It harvests credentials from developer machines and CI jobs, takes signed tasks from a C2 server, and carries templates to install itself in npm packages, Python packages and GitHub Actions workflows. Its code and infrastructure match no known malware family, including Shai-Hulud. The C2 parent domain skyleen[.]fr was re-registered on September 15, 2026, eight days before the attack. SafeDep expects the operator to reuse the framework, and notes the tooling may have been LLM-written, which it cannot prove.

Detalhes técnicos

  • Build: Go module supplychain.local/campaign, built with -trimpath and CGO_ENABLED=0. Each package ships six static binaries (linux, darwin and windows on amd64 and arm64), 6.8-7.7 MB each. Function names were recovered from .gopclntab (7,259 functions in the npm build, 7,303 in the PyPI build).
  • Capability labels: the analysis rates each capability as confirmed (code read), indicated (function names and strings) or unknown.
  • Modes: stage0 runs on developer machines. initial-ci-emit runs in CI and exists only in the PyPI build, which adds the internal/ciemit package and sckit.initial-ci.* schemas. The runtime refuses to start unless the profile is semi-nuclear.
  • Execution (confirmed): the loaders spawn the implant detached, with the full process environment. The OpenClaw loader also passes user prompt text in SCKIT_EVENT_TEXT, so the implant can read what users send to their AI agent.
  • Credential collection (indicated): targets .npmrc, .pypirc, .git-credentials, .netrc, SSH keys, .vault-token, and Azure and Google Cloud CLI token caches. Regexes match secret-like variable names and token formats for JWT, AWS, GitHub, GitLab, npm, PyPI, Hugging Face, Vault, Slack, Stripe and SendGrid.
  • CI token capture (confirmed): a bridge script abusing BASH_ENV runs before the real publish step, hands the publish token to the implant, then halts the publish.
  • Spreading (indicated): agent.findRepositories, PrepareRemoteRepository, recursivePublish and loader templates for Python, Node.js and a GitHub Actions workflow (runtime-update.yml, triggered on push). Whether spreading is automatic or operator-approved is unknown.
  • Profiling and filtering (indicated): collects hostname, IPs, interfaces, time zone, languages and input methods, and checks for admin rights. The geo_iso, deny_iso and ja4_deny fields point to geographic and analysis-tool filtering.
  • C2 protocol (indicated): CBOR messages with admission requests, signed leases (max_activations, max_offline_until) and module manifests with digest checks. Results are returned encrypted with X25519 and XChaCha20-Poly1305. Server signatures are verified, so a fake C2 cannot task the implant. Module functionality is unknown, and the C2 subdomains now resolve to 127.0.0.1.
  • Cleanup (indicated): self-delete, state removal and a tombstone marker.
  • Campaign config: schema sckit.runtime.v1, campaign memos-semi-nuclear, state dir $HOME/.memos/.cache/runtime, with inventory rooted at $HOME.
  • Hunting pointers: the process command line sckit stage0 --config64 <base64>, SCKIT_EVENT_TEXT in process environments, .sckit/<os>-<arch>/sckit directories in node_modules or site-packages, BASH_ENV= written to $GITHUB_ENV, an unexpected backend-path = ["."], the log markers SCKIT_CI_RESULT_V2 and SCKIT_CI_OBSERVATION_V2, and package versions published that you did not release.

Remediação

  • Hunt for the process, file, directory, workflow and log artifacts listed above in developer endpoints, CI runners and package contents.
  • Treat any host or CI job that ran the affected MemTensor package versions as compromised. Rotate npm, PyPI, GitHub, cloud and other tokens, and review recent package publications for unauthorized versions.
  • Audit GitHub Actions workflows for runtime-update.yml and for steps writing BASH_ENV, and inspect build backends loaded from the repository.
  • Block skyleen[.]fr and its subdomains.

Linha do tempo

  1. safedep.io ↗ · pub. 22/09/2026 21:00 · coletado 19/10 18:03 primeiro registro

    sckit: Go implant framework found in MemTensor npm and PyPI packages steals developer and CI credentials for supply chain worm spread

    ler a análise desta fonte

    SafeDep analyzed sckit (the "supplychain.local worm"), a previously unreported cross-platform Go implant framework found on September 23, 2026 in the compromised MemTensor packages @memtensor/[email protected] (npm) and [email protected] (PyPI). It harvests credentials from developer machines and CI jobs, takes signed tasks from a C2 server, and carries templates to install itself in npm packages, Python packages and GitHub Actions workflows. Its code and infrastructure match no known malware family, including Shai-Hulud. The C2 parent domain skyleen[.]fr was re-registered on September 15, 2026, eight days before the attack. SafeDep expects the operator to reuse the framework, and notes the tooling may have been LLM-written, which it cannot prove.

    Technical Details

    • Build: Go module supplychain.local/campaign, built with -trimpath and CGO_ENABLED=0. Each package ships six static binaries (linux, darwin and windows on amd64 and arm64), 6.8-7.7 MB each. Function names were recovered from .gopclntab (7,259 functions in the npm build, 7,303 in the PyPI build).
    • Capability labels: the analysis rates each capability as confirmed (code read), indicated (function names and strings) or unknown.
    • Modes: stage0 runs on developer machines. initial-ci-emit runs in CI and exists only in the PyPI build, which adds the internal/ciemit package and sckit.initial-ci.* schemas. The runtime refuses to start unless the profile is semi-nuclear.
    • Execution (confirmed): the loaders spawn the implant detached, with the full process environment. The OpenClaw loader also passes user prompt text in SCKIT_EVENT_TEXT, so the implant can read what users send to their AI agent.
    • Credential collection (indicated): targets .npmrc, .pypirc, .git-credentials, .netrc, SSH keys, .vault-token, and Azure and Google Cloud CLI token caches. Regexes match secret-like variable names and token formats for JWT, AWS, GitHub, GitLab, npm, PyPI, Hugging Face, Vault, Slack, Stripe and SendGrid.
    • CI token capture (confirmed): a bridge script abusing BASH_ENV runs before the real publish step, hands the publish token to the implant, then halts the publish.
    • Spreading (indicated): agent.findRepositories, PrepareRemoteRepository, recursivePublish and loader templates for Python, Node.js and a GitHub Actions workflow (runtime-update.yml, triggered on push). Whether spreading is automatic or operator-approved is unknown.
    • Profiling and filtering (indicated): collects hostname, IPs, interfaces, time zone, languages and input methods, and checks for admin rights. The geo_iso, deny_iso and ja4_deny fields point to geographic and analysis-tool filtering.
    • C2 protocol (indicated): CBOR messages with admission requests, signed leases (max_activations, max_offline_until) and module manifests with digest checks. Results are returned encrypted with X25519 and XChaCha20-Poly1305. Server signatures are verified, so a fake C2 cannot task the implant. Module functionality is unknown, and the C2 subdomains now resolve to 127.0.0.1.
    • Cleanup (indicated): self-delete, state removal and a tombstone marker.
    • Campaign config: schema sckit.runtime.v1, campaign memos-semi-nuclear, state dir $HOME/.memos/.cache/runtime, with inventory rooted at $HOME.
    • Hunting pointers: the process command line sckit stage0 --config64 <base64>, SCKIT_EVENT_TEXT in process environments, .sckit/<os>-<arch>/sckit directories in node_modules or site-packages, BASH_ENV= written to $GITHUB_ENV, an unexpected backend-path = ["."], the log markers SCKIT_CI_RESULT_V2 and SCKIT_CI_OBSERVATION_V2, and package versions published that you did not release.

    Remediation

    • Hunt for the process, file, directory, workflow and log artifacts listed above in developer endpoints, CI runners and package contents.
    • Treat any host or CI job that ran the affected MemTensor package versions as compromised. Rotate npm, PyPI, GitHub, cloud and other tokens, and review recent package publications for unauthorized versions.
    • Audit GitHub Actions workflows for runtime-update.yml and for steps writing BASH_ENV, and inspect build backends loaded from the repository.
    • Block skyleen[.]fr and its subdomains.