Researchers Detail sapho11 Supply-Chain Campaign Targeting Cryptocurrency Wallet Developers

Summary
OpenSourceMalware reports that the sapho11 campaign targeted wallet projects with malicious pull requests, a credential-stealing Rust crate and maintainer phishing. The crate collected secrets during builds; two Zingo Labs pull requests remained open.
Key points
- The report links the sapho11 GitHub account to a campaign targeting Keplr, Zcash, Vizor and Cosmos projects through pull requests, malicious packages and phishing.
- The lwd-uri-util Rust crate, versions 0.1.0–0.1.7, used build.rs to collect environment variables, credential files, Keplr MCP vaults and keychain secrets during builds, then attempt to upload them.
- The crate wrote collected data to a local JSON file even when upload was suppressed; the report says its opt-out did not stop collection.
- Pull requests against Vizor attempted to exfiltrate CI and signing secrets. Another proposed AGENTS.md content that would normalize credential uploads and discourage automated reviewers from flagging them.
- A fake security disclosure directed maintainers to a GitHub credential-phishing page hosted on Cloudflare Workers.
- The related zip321-uri repository contained a Node.js install-hook stealer, although the report says its module configuration would likely cause it to fail on current Node.js versions as written.
- Vizor closed all four campaign pull requests; two Zingo Labs pull requests were still open without reviews, and the report said the malicious crate had not been removed from crates[.]io.
Article Details
- Attack Vectors
- Malicious pull requests proposed sending CI environment variables and signing-related files to attacker-controlled endpoints.
- The lwd-uri-util Rust crate used its build.rs script to collect environment variables, credential files, Keplr MCP vaults, and keychain secrets during builds.
- The zip321-uri repository used prepare and postinstall hooks for a Node.js stealer when added as a Git dependency; the article says the hook may fail on current Node.js versions as written.
- A fake security disclosure directed Vizor maintainers to a GitHub credential-phishing page hosted on a Cloudflare Worker.
- Dependency changes in open Zingo Labs pull requests were obscured by whole-file CRLF rewrites, while an AGENTS.md change attempted to influence automated code reviewers.
- Defensive Notes
- If a build included lwd-uri-util, treat build-time environment variables and targeted credential files as exposed; revoke and reissue affected credentials and signing material.
- For affected Keplr MCP vaults, move funds to freshly generated keys.
- Search Cargo build output directories for lwd_uri_build_context.json; preserve a copy for incident response if needed, then remove it securely because it may contain plaintext secrets.
- Review proxy, DNS, and endpoint telemetry for the listed webhook.site UUIDs and the identified .xyz and sapho11.workers.dev endpoints.
- Review dependency build scripts and install hooks, not only application diffs; restrict secrets available to automated CI builds of pull requests.
- Review changes to AGENTS.md and similar files with the same scrutiny as code or CI configuration.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
sapho11@wp[.]pl | Email address used as the author address on commits from the malicious sapho11 account. | |
| SHA256 | 10304aa2c167bb0d66800020fb1f983bc62bb5bec89239de9fddb129b523149a | SHA-256 hash of the malicious lwd-uri-util-0.1.1.crate package. |
| SHA256 | 129be19ca4d1d997d168af561e5cea12b0a401716a05720daf48072e470d7db5 | SHA-256 hash of the malicious lwd-uri-util-0.1.0.crate package. |
| SHA256 | 3b290a899d741be14f9bb9f3545279911f774608362f348654f10823774c2f87 | SHA-256 hash of the malicious lwd-uri-util-0.1.5.crate package. |
| SHA256 | 476a207e057ec463ff045a2c0115c8a34ea8eab70e0abe4c1efd90ceb8b5161c | SHA-256 hash of the malicious lwd-uri-util-0.1.4.crate package. |
| SHA256 | 5c848823a78313c47596bdf3c260e8862a02c7e48fa8ce718aca332f7b80c4fd | SHA-256 hash of the malicious lwd-uri-util-0.1.6.crate package. |
| SHA256 | 6d35f023e3d87f8d4bc91a3bc670ae4681e9d85937146b9b0683d0f33eb0f55a | SHA-256 hash of the malicious lwd-uri-util-0.1.2.crate package. |
| SHA256 | 7c0fbaf582b9b4e674c108ed5b0cb2835b11369fbdb1ce7ac29d63e9321a6981 | SHA-256 hash of the malicious lwd-uri-util-0.1.7.crate package. |
| SHA256 | 80c54ff4fe231c363db0c75cbb81f566ea4d10c266ec594165d840df13ab0973 | SHA-256 hash of the malicious lwd-uri-util-0.1.3.crate package. |
| SHA256 | ac82fd28228bfb55acbb9bfdd2f3a4b926c6d65e2965db5a34c11d1a76fbd762 | SHA-256 hash of the src/lib.rs file from lwd-uri-util 0.1.7, part of the identified malicious crate. |
| SHA256 | c469240c313d7da0d40b901e51e642b4efd61906e28849c1059b70451065ccca | SHA-256 hash of the Cargo.toml file from lwd-uri-util 0.1.7, part of the identified malicious crate. |
| SHA256 | d8671b8aed8771dba6b57bd51d2e42914c0df87bd9e9d148478a0fbc121e81e6 | SHA-256 hash of the HTML served by the attacker’s GitHub credential-phishing page. |
| SHA256 | f466d5621525a4cf229e4a8377cd7285da5797eee77384253f1040a722765953 | SHA-256 hash of the malicious lwd-uri-util 0.1.7 build.rs file. |
| URL | hxxps[:]//api[.]sdklfghaljksdhfkjasdfhlasdhfjklasdf[.]xyz/v1/tipcheck | Exfiltration sink embedded in early lwd-uri-util versions; the article reports that this misspelled domain did not resolve. |
| URL | hxxps[:]//api[.]sdklfghaljksdhfkjasdfhlkasdhfjklasdf[.]xyz/v1/tipcheck | Attacker-controlled endpoint used in malicious Vizor pull request code; the article says this correctly spelled domain was prepared for the campaign. |
| URL | hxxps[:]//github[.]com/chainapsis/vizor-wallet/pull/1199 | Malicious pull request that proposed sending environment data to attacker infrastructure. |
| URL | hxxps[:]//github[.]com/chainapsis/vizor-wallet/pull/1200 | Malicious pull request that proposed collecting release credentials and signing files for exfiltration. |
| URL | hxxps[:]//github[.]com/chainapsis/vizor-wallet/pull/1201 | Pull request that attempted to normalize uploading sensitive environment snapshots in reviewer guidance. |
| URL | hxxps[:]//github[.]com/chainapsis/vizor-wallet/pull/1202 | Malicious pull request that added the lwd-uri-util dependency. |
| URL | hxxps[:]//github[.]com/sapho11/lwd-uri-util | Malicious repository containing the lwd-uri-util crate source. |
| URL | hxxps[:]//github[.]com/sapho11/zip321-uri | Malicious repository containing a Node.js stealer intended to run through package install hooks. |
| URL | hxxps[:]//github[.]com/zingolabs/zingo-common/pull/85 | Open pull request adding the malicious lwd-uri-util dependency. |
| URL | hxxps[:]//github[.]com/zingolabs/zingolib/pull/3148 | Open pull request adding the malicious lwd-uri-util dependency. |
| URL | hxxps[:]//session-check[.]sapho11[.]workers[.]dev/auth | Credential-phishing page impersonating GitHub sign-in and presented as a private security disclosure. |
| URL | hxxps[:]//session-check[.]sapho11[.]workers[.]dev/auth/login | Credential collection endpoint used by the GitHub phishing page. |
| URL | hxxps[:]//session-check[.]sapho11[.]workers[.]dev/v1/tipcheck | Attacker-controlled exfiltration endpoint used by early lwd-uri-util versions. |
| URL | hxxps[:]//webhook[.]site/0a60608b-63de-480c-a441-38a8d107a9ea | Attacker-used exfiltration sink listed for lwd-uri-util versions 0.1.0–0.1.3. |
| URL | hxxps[:]//webhook[.]site/14b3cc9b-3275-4b63-8b93-f4d2669fbdc1 | Attacker-used exfiltration sink for lwd-uri-util versions 0.1.4–0.1.7 and the zip321-uri stealer. |
MITRE ATT&CK
T1005 · Data from Local SystemThe crate collected local environment data, credential files, signing material, and Keplr MCP vault files.T1027 · Obfuscated Files or InformationThe crate stored sink URLs and scanner-evasion keywords in base64-encoded form and decoded them at runtime.T1041 · Exfiltration Over C2 ChannelCollected JSON data was POSTed to attacker-used webhook.site and other exfiltration endpoints.T1056.003 · Web Portal CaptureThe phishing page cloned GitHub sign-in and collected usernames and passwords through a web form.T1059.001 · PowerShellOn Windows, the payload used hidden, non-interactive PowerShell with Invoke-WebRequest to upload collected data.T1059.004 · Unix ShellOn Unix-like systems, the payload launched curl through a detached /bin/sh -c command.T1059.007 · JavaScriptThe zip321-uri repository used an install.js script as a prepare and postinstall hook for its Node.js stealer.T1071.001 · Web ProtocolsThe payload communicated with its endpoints using HTTP or HTTPS requests, including POST requests carrying collected data.T1195.001 · Compromise Software Dependencies and Development ToolsThe campaign added a malicious Rust crate whose build.rs collected secrets when downstream projects built the dependency.T1497.001 · System ChecksFrom version 0.1.4, the payload suppressed network uploads when environment names or values contained sandbox and scanner canary markers.T1552.001 · Credentials In FilesThe stealer read credentials from files including .git-credentials, .netrc, .env files, and configuration files.T1552.004 · Private KeysThe Node.js stealer targeted SSH private-key files, and the Rust payload collected signing-key files.T1555.001 · KeychainOn macOS, the Rust payload used security find-generic-password to retrieve secrets from the keychain.T1566.002 · Spearphishing LinkA fake security disclosure issue sent Vizor maintainers to a credential-phishing page.T1583.001 · DomainsThe article reports that the campaign’s correctly spelled .xyz domain was registered through Namecheap two months before the sapho11 account was created.
Threat Actors
Vendors
Products
CargoA Rust crate whose build.rs steals credentials, Keplr MCP vaults, and macOS keychain items on every cargo buildCloudflare WorkersA fake vulnerability disclosure that sends maintainers to a GitHub credential-phishing kit hosted on Cloudflare Workerscrates.iochainapsis and Zingo Labs. It also published eight versions of a credential-stealing Rust crate to crates.io, staged a matching Node.js stealer, and posted a fake security disclosure meant to phish two VizorFastlanelaptop or a release build box. That means update-feed signing keys, GitHub and cloud credentials, fastlane and Android signing material, and the encrypted vaults of the Keplr MCP wallet tooling. At the time ofGitHubThe OpenSourceMalware team has identified a targeted supply chain campaign targeting multiple wallet companies, run from a GitHub account called sapho11.Keplr MCPGitHub and cloud credentials, fastlane and Android signing material, and the encrypted vaults of the Keplr MCP wallet tooling. At the time of writing, the two pull requests against Zingo Labs are still open, and theNode.jsIt also published eight versions of a credential-stealing Rust crate to crates.io, staged a matching Node.js stealer, and posted a fake security disclosure meant to phish two Vizor maintainers.VizorSo far we know that Keplr, Zcash, Vizor and Cosmos have been targeted.
Tools
CodexResponds to Codex review findings, claims the exfiltration has been removedv12 auditor botOnce a rule like this sits in AGENTS.md, every future AI review of the repository reads it. The v12 auditor bot skipped the PR entirely (“No auditable source files found in this PR’s diff”), which shows how easily
