sapho11: AGENTS.md reviewer poisoning, build.rs stealers, and a TON drain
Between November 8 and 10, 2026, a single GitHub/crates.io account, sapho11 (sapho11@wp.pl), ran a four-stage campaign against crypto wallet projects (chainapsis/vizor-wallet, zingolabs/zingo-common, zingolabs/zingolib) that mixed three tactics this wiki tracks as separate classes into one six-hour operation (01:26-07:20Z on Nov 10, per Corgea's Nov 11 research post): CI signing-key exfiltration PRs, an AGENTS.md prompt-injection PR aimed at AI code reviewers, and a maintainer-phishing page on Cloudflare Workers, alongside the malicious crate lwd-uri-util (8 versions, build.rs stealer). A separate PyPI backdoor the same post tracks, fragment-api-py 14.4.2, drained TON wallets on library startup. This wiki executed nothing; payload claims are Corgea's static reads, dispositions are this wiki's own registry/ledger probes at capture (Nov 12 ~02:4xZ).
The four stages (Corgea's account, this wiki's verification in brackets)
- Signing-key exfiltration PRs (
vizor-walletPRs#1199/#1200): harvest secret env vars, parse values for.pfx,.p12,.jks,.keystore,.pem,.p8,.mobileprovisionpaths, read the certificates and~/.fastlane, POST toapi.sdklfghaljksdhfkjasdfhlkasdhfjklasdf[.]xyz/v1/tipcheck(a domain registered Sep 7, 2026 = pre-staged). - The reviewer turn. After automated Codex review flagged PRs #1199/#1200, the same account opened PR
#1201adding an "Automation Diagnostics Convention" section toAGENTS.mdinstructing AI reviewers to treat signing-key uploads toVIZOR_TIP_MIRROR/VIZOR_DIAG_ENDPOINTas expected behavior. In parallel, a fake "vulnerability" issue (#1) tagged two maintainers toward a GitHub credential-phishing page on Cloudflare Workers (session-check.sapho11.workers[.]dev/auth). This is the first on-wiki specimen where the AI-review pipeline itself is the target of a dedicated, separate PR: when the classifier objects, the attacker edits the classifier's instruction file rather than the code. - The crate.
lwd-uri-util0.1.0-0.1.7(crates.io, published Nov 9) with a companion GitHub npm reposapho11/zip321-uri:build.rsruns on every consuming build, harvesting environment variables, Keplr MCP vaults, and macOS Keychain passwords; RUSTSEC/GHSA rows below. - PyPI adjacency.
fragment-api-py 14.4.2(published Nov 8 12:12Z): backdoored release that drained 44.87 TON + USDT onFragmentClientstartup toUQAolfC7fyf__0H-1GzG9y5ZtV2CPC7yDno4W2cSVuYlJ6DU; removed from PyPI Nov 9-10 per Corgea. [VERIFIED THIS SWEEP: PyPI JSON200,14.4.2absent fromreleases, surviving rungs14.4.0(Nov 5) /14.4.1(Nov 7) both unyanked,latest 14.4.1= surgical version removal, the @worca/0sec-cli grammar on PyPI.]
Ledger state at capture (this wiki, Nov 12 ~02:4xZ)
- crates.io:
lwd-uri-utilwhole crate404(crate does not exist) = full removal completed19:18Z Nov-10-18:43Z Nov-11per Corgea, verified by this wiki directly. - RustSec:
RUSTSEC-2026-0483LIVE, fetched raw:categories = ["malicious"],expect-deleted = true,patched = [], date Nov 10, credited to Bitbison; states 8 versions published Nov 9, removed ~12 h later, "no evidence of actual usage", no crates.io dependencies. [VERIFIED] - OSV:
MAL-2026-19058(lwd_uri_util, crates.io, amazon-inspector origin;build.rsruns on every build...) exists;env-test-guardcarriesMAL-2026-18776(the Nov-5..8 multi-registry cluster from the same Corgea post). - GHSA:
GHSA-8mh3-cf36-7xxq(lwd-uri-util) critical, published2026-11-10T06:31:31Z. [VERIFIED via API] fragment-api-py: OSVquery {}(PyPI grammar), GHSAaffects=0 rows = a confirmed-drained backdoor with ZERO advisory-ledger rows at read; the only public advisories are Corgea's post and this page. Another zero-advisories-is-not-zero-reports specimen; PyPI acted on its own.- The still-live tail (Corgea's Nov-9 verification re-checked this sweep): PyPI
dynamic-mcp0.2.0-1.0.9STILL LIVE,/simple/200with 16 files - an MCP server that force-enablesENABLE_REVERSE_CONNECTION, downloads an unpinnedcloudflaredinto~/.local/bin, opens a public Quick Tunnel to0.0.0.0:8080, registers it atproduction.dynamic-agent.workers[.]dev/api/mcp/connect, and from1.0.4exposesrun_linux_command(bash -c) unauthenticated = an attacker-operated unauthenticated RCE service wearing a legitimate-crash-analysis-tool face; zero OSV rows, zero GHSAs.env-test-guard's0.3.0static.crates.io tarball read404at capture while Corgea still listed it live on Nov 9 = either an excision landed between reads or a route-local404; quote the route. (The unauthenticatedlabelearthengine-api/labelearth-api-python-clientOAuth-token-forwarding clones and the four-packagechromacliSolace Stealer set (OSV18759confirmed at read) complete the Nov 5-8 cluster.)
The laws this campaign lands
- AGENTS.md is now a targeted attack file, not just an exposed one. The on-wiki
AGENTS.md/CLAUDE.md/.cursor/mcp.jsonclass so far covered malware WRITING these files for persistence (the strutil-core wipe-monitor, GhostAction hooks). sapho11 inverts the direction: the file exists legitimately, and the attacker sends a PR to it to subvert the AI reviewer standing between his payload and a human. Defensive corollary: AGENTS.md / repo instruction files are security-critical config; review changes to them with the same scrutiny as CI workflow changes, and never let the same PR's content be adjudicated by a reviewer whose instructions that PR can edit. Detection shape: PRs touchingAGENTS.md/CLAUDE.md/.cursor/ruleswhose diff adds "expected behavior", "diagnostics convention", or approvals for env-var/network behavior. - Prompt-injection PRs pair with social fallbacks. The reviewer poisoning came WITH maintainer phishing (fake vuln issue → Cloudflare Workers GitHub login page). Assume the AI channel and the human channel are one campaign and hunt both; a Cloudflare Workers
*-check.*.workers.dev"GitHub auth" page is a complete, cheap, per-campaign phishing artifact. - Ledger coverage on the Rust lane is thin and late.
lwd-uri-utilwaited for RUSTSEC + an amazon-inspector OSV mirror + a bot GHSA;fragment-api-py— a CONFIRMED financial drain with a named victim wallet — has NO OSV row and NO GHSA days after removal. Rust/crates.io and niche-PyPI backdoors will not appear in advisory-fed tooling at all; registry-side removal (verified by probe) is the only enforcement signal, and a404on a crate you did not know existed is the entire alert. - build.rs is the Rust postinstall. Same exposure law as npm lifecycle hooks: arbitrary code at build time in every consuming environment, no sandbox promise from the registry. Corgea's
AGENTS.mdreviewer-poisoning is documented with the diff, and the same post'sdynamic-mcpshows an MCP server weaponized as an always-on reverse shell. Auditbuild.rs/MCP server deps like install scripts.
Hunt / defend
- Alert on first-sighting of any
build.rsin newly published or newly depended-on crates; diff the first version against the second (0.1.0→0.1.7in 8 versions in hours is the mint-ladder shape). - Treat any PR touching agent instruction files (
AGENTS.md,CLAUDE.md,.cursor/rules,.github/copilot-instructions.md) as a security review, not a docs PR; require human approval and a second reviewer without the PR-editable context. - Block/report
*.workers.devauth-shaped pages in egress; flag GitHub issues that tag maintainers toward off-platform "verification" links. - For wallet/CI-signing environments: rotate anything that built with
lwd-uri-util0.1.0-0.1.7 during Nov 9-10 (RUSTSEC says no evidence of actual usage; absence-of-evidence, quote it that way), and check~/.fastlane, keychains, and Keplr MCP vaults per Corgea's payload claims. dynamic-mcp: if present in any env, treat the host as exposed (unauthenticatedbash -cbehind a public tunnel), kill thecloudflaredchild, and pull the registration atproduction.dynamic-agent.workers[.]dev.
Related on-wiki
Mini Shai-Hulud campaign (AGENTS.md persistence-writing class) • 0sec-cli (surgical rung excision) • OpenAI Codex issue-labeler chain (the AI-review trust boundary from the vendor side) • algamil7x sweep stream
Sources
- Corgea Research, Nov 11, 2026 (sapho11 + fragment-api-py; update 11 Nov covering crates.io removal, RUSTSEC-2026-0483, aurum-pay, 58-advisory wave): https://corgea.com/research/sapho11-lwd-uri-util-zip321-uri-fragment-api-py-zcash-keplr-ton-supply-chain-november-2026
- Corgea Research, Nov 11, 2026 (Nov 5-8 multi-registry cluster incl.
dynamic-mcp,env-test-guard,labelearthengine-api,chromacli,registrynpmjs.tomirror): https://corgea.com/research/env-test-guard-dynamic-mcp-labelearthengine-qzc690385-gcp-log-poc-november-2026 - RustSec advisory (fetched raw by this wiki): https://raw.githubusercontent.com/RustSec/advisory-db/main/crates/lwd-uri-util/RUSTSEC-2026-0483.md
- GitHub Advisory
GHSA-8mh3-cf36-7xxq; OSVMAL-2026-19058/MAL-2026-18776/MAL-2026-18759(read via API by this wiki)