SCKit is a Windows malware toolkit used to establish persistent backdoor access and attempt worm-like propagation through ConnectWise ScreenConnect environments. An unattributed threat actor deployed it during a November 2026 campaign affecting at least 288 managed endpoints across 48 organizations, including managed service providers and their customers. Attackers abused ScreenConnect's legitimate Run Command functionality to execute deployment commands with SYSTEM privileges and install unauthorized ScreenConnect Access clients.
The toolkit combines PowerShell scripts, batch scripts, configuration data, and locally compiled C# components. Its encrypted delivery mechanism binds payload decryption to individual hosts. Persistence mechanisms include attacker-controlled remote-access clients, scheduled tasks, and an autorun entry. SCKit attempts to add Microsoft Defender exclusions and stops or reconfigures legitimate ScreenConnect services. Its RelayTrap component reuses legitimate ScreenConnect assemblies and connection parameters to impersonate an endpoint's Guest client, maintaining an apparently normal presence in the management console while intercepting incoming technician connections.
SCKit's intended propagation chain targets technicians who connect to infected endpoints. RelayTrap attempts unauthorized Guest-to-Host file transfer and execution associated with CVE-2026-84869. Following execution on a technician workstation, additional components search browser cookie stores and process memory for authenticated ScreenConnect sessions. The toolkit attempts to replay stolen session cookies, enumerate systems accessible through the technician's permissions, and distribute further payloads through legitimate management commands and Shared Toolbox functionality. Successful technician compromise and end-to-end propagation were not established in the investigated campaign; controlled testing confirmed that a patched ScreenConnect client blocked the attempted transfer and execution.
A cross-platform Go credential-stealing implant distributed through compromised MemTensor npm and PyPI packages has also been called sckit. A relationship between that implant and the ScreenConnect toolkit has not been established; their capabilities and platform coverage should not be conflated.
1 CVE Mallory has correlated with this family across public research and vendor advisories. Each card links to the full Mallory page for that vulnerability.
35 distinct techniques documented for this family, organized by ATT&CK tactic.
La liste de TTPs de l’analyse identifie T1608.003 — Stage Capabilities: Install Digital Certificate; ca-roots.pem figure parmi les fichiers listés.
Two hours later, a follow-up commit removed the capture code, and the next tag push uploaded the fully malicious wheel to PyPI using MemTensor's own legitimate credentials.
L’attaque de type supply chain ciblait les packages npm @memtensor/memos-cloud-openclaw-plugin et PyPI MemoryOS, publiés avec l’implant Go sckit.
The attacker poisoned the npm package `@memtensor/memos-cloud-openclaw-plugin` and the PyPI package `MemoryOS`, publishing malicious versions through MemTensor's legitimate CI release pipelines.
Les modifications CI ajoutent une entrée BASH_ENV pointant vers sckit-publish-bridge.sh ou _pypi_bridge.sh, exécutés avant la publication des packages.
import memos executes memos/__init__.py ... mem_cube.py contains logger = get_logger(__name__) at module level. That's a function call ... and the hooked get_logger fires trigger().
The malicious versions add lib/sckit.js ... export function launchStageZero(text = "") { ... spawn(binary, ["stage0", "--config64", CONFIG], { detached: true ... }).unref(); }
It contains templates to install itself in npm packages, Python packages, and GitHub Actions workflows, and can function like a worm by self-proliferating through GitHub and direct npm and PyPI package publishing.
Otherwise, it attempts to spawn that binary with stage0 --config64 and an embedded base64 configuration. The child uses detached: true and stdio: "ignore".
The malicious npm versions contain code that launches the payload when the agent gateway starts and whenever the plugin handles a memory-recall event. The PyPI package starts the statically-linked Go binary as soon as the 'memos' module is imported.
Two hours later, a follow-up commit removed the capture code, and the next tag push uploaded the fully malicious wheel to PyPI using MemTensor's own legitimate credentials.
La liste de TTPs de l’analyse identifie T1543 — Create or Modify System Process; l’implant conserve aussi des répertoires d’état sous $HOME/.openclaw/.cache/runtime et $HOME/.memos/.cache/runtime.
For the npm versions, the malicious binary executes when the OpenClaw gateway starts and then executes again every time a memory recall occurs when the user submits a prompt. The PyPI version launches as soon as the package is imported.
The attacker wrote a `BASH_ENV` entry into `$GITHUB_ENV`... Because Bash reads the file named in `BASH_ENV` before running any non-interactive script, this let the attacker's shell script execute silently before the real publish step.
Two hours later, a follow-up commit removed the capture code, and the next tag push uploaded the fully malicious wheel to PyPI using MemTensor's own legitimate credentials.
La liste de TTPs de l’analyse identifie T1543 — Create or Modify System Process; l’implant conserve aussi des répertoires d’état sous $HOME/.openclaw/.cache/runtime et $HOME/.memos/.cache/runtime.
For the npm versions, the malicious binary executes when the OpenClaw gateway starts and then executes again every time a memory recall occurs when the user submits a prompt. The PyPI version launches as soon as the package is imported.
The attacker wrote a `BASH_ENV` entry into `$GITHUB_ENV`... Because Bash reads the file named in `BASH_ENV` before running any non-interactive script, this let the attacker's shell script execute silently before the real publish step.
La liste de TTPs de l’analyse identifie T1027 — Obfuscated Files or Information.
La liste de TTPs de l’analyse identifie T1036 — Masquerading.
The CI bridge scripts delete themselves after execution, and implant functions include `scheduleSelfDelete` and `deleteExecutable`.
Two hours later, a follow-up commit removed the capture code, and the next tag push uploaded the fully malicious wheel to PyPI using MemTensor's own legitimate credentials.
Both droppers serve to execute a platform-specific sckit binary from a hidden .sckit directory in the package.
The npm plugin also exposed OpenClaw prompts to the attacker, and users should assume any secrets included in prompts while a malicious plugin was installed have been compromised.
That script called `collectStageZero()` from within the package itself, passed the `NPM_TOKEN` to the `sckit` binary... The bridge... captured `INPUT_PASSWORD` (the PyPI token).
The malware references environment variables related to package publishing credentials and contains a Go regular expression to search for Generic JWTs, AWS access key IDs, GitHub tokens, GitLab tokens, npm access tokens, PyPI API tokens, and other secrets.
Once running, `sckit` scans the entire home directory for credentials. Its target list... covers `.npmrc`, `.pypirc`, `.git-credentials`, `.netrc`, SSH private keys, HashiCorp Vault tokens, and Microsoft MSAL token caches.
Strings in the implant include `id_rsa`, `id_ecdsa`, and `id_ed25519`; affected users are instructed to treat SSH keys under their home directory as exposed.
Targets include AWS access keys, GitHub and GitLab tokens, npm and PyPI tokens, Hugging Face, HashiCorp Vault, Slack, Stripe and SendGrid keys, and JWTs.
La liste de TTPs de l’analyse identifie T1555 — Credentials from Password Stores.
Le comportement de sckit inclut le profilage de l’hôte : timezone, langue, géolocalisation ISO, filtrage deny_iso et empreinte TLS ja4_deny.
It first determines the victim’s operating system, with binaries supporting Linux, macOS and Windows on both x64 and arm64 architectures.
The configuration sets `inventory_roots` to `$HOME`, and implant functions include `credentialPaths` and `findRepositories`.
La liste de TTPs de l’analyse identifie T1526 — Cloud Service Discovery; sckit collecte également des tokens cloud.
The configuration and binary contain fields named `geo_iso`, `deny_iso`, and `ja4_deny`; the analysis states the operator can likely filter victims by country and TLS fingerprint.
It contains templates to install itself in npm packages, Python packages, and GitHub Actions workflows, and can function like a worm by self-proliferating through GitHub and direct npm and PyPI package publishing.
Because the npm launcher forwards recall prompt text in SCKIT_EVENT_TEXT, anything a developer asks the agent while an affected version is loaded should be treated as exposed.
The npm plugin also exposed OpenClaw prompts to the attacker, and users should assume any secrets included in prompts while a malicious plugin was installed have been compromised.
The implant configuration specifies HTTPS `base_url` values on skyleen[.]fr subdomains and `/config`, `/status`, and `/batch` C2 paths.
`_initial_ci_delivery.py` fetches a signed index from the skyleen[.]fr server, downloads an emitter binary, verifies it, and runs it; the implant supports server-delivered modules at runtime.
Collected data goes to subdomains of `skyleen[.]fr`... over encrypted channels using X25519 key exchange and XChaCha20-Poly1305.
L’implant exfiltre les données via HTTPS avec CBOR + X25519 + XChaCha20-Poly1305.
Collected data goes to subdomains of `skyleen[.]fr`, the campaign's control infrastructure, over encrypted channels using X25519 key exchange and XChaCha20-Poly1305.
73 indicators attributed across vendor reports, sandbox runs, and researcher write-ups. Values are masked here and available in full in Mallory.
36 sources tracked across advisories, community write-ups, and news. New activity surfaces here as Mallory finds it.