Last Updated: 2026-08-20T17:22:10Z
What’s Happening
This morning (01:55:34 UTC, 2026-08-20), an attacker impersonating (dtolney) the developer account (dtolnay) for proc-macro2 published a typosquat package named proc-macro1. This malicious package was a clone of the original with a malicious build script later added. Simultaneously, the attacker published an update to arrayref with the compromised author account (droundy), referencing the typosquat proc-macro1package. When building, a payload is fetched that connects to a c2 address.
Update:
Two more crates owned by droundy have been compromised, internment 0.8.7, and append-only-vec 0.1.9, pushing the same build-time dropper. Additionally, a second dropper crate proc-macro-en was discovered, along with four other attacker-owned (dtolney) crates: aovine, arone, aronenao, tinymember which were subsequently removed from crates.io. Attacker accounts have been locked, and the maintainer of the three legitimate crates is not believed to be acting maliciously; the Rust Security Response Team assesses their machine or credentials as compromised and has locked the account as a precaution.
Actions
- check your cargo.lock for
arrayref 0.3.10,internment 0.8.7, andappend-only-vec 0.1.9as well as any hit forproc-macro1, proc-macro-en,aovine,arone,aronenao,tinymember.- the resolved lockfile version is what matters
- a quick check:
grep -rEn 'proc-macro1|proc-macro-en|aovine|arone|aronenao|tinymember|arrayref.*0\.3\.10|internment.*0\.8\.7|append-only-vec.*0\.1\.9' --include=Cargo.lock --include=Cargo.toml - check cargo cache directly, from the rust security team:
find ~/.cargo/registry/cache -type f \( -name 'arrayref-0.3.10.crate' -o -name 'internment-0.8.7.crate' -o -name 'append-only-vec-0.1.9.crate' -o -name 'proc-macro1-*.crate' -o -name 'proc-macro-en-*.crate' -o -name 'aovine-*.crate' -o -name 'arone-*.crate' -o -name 'aronenao-*.crate' -o -name 'tinymember-*.crate' \) -print
- a quick check:
- the resolved lockfile version is what matters
- audit build logs from 07:15–08:41 UTC on 2026-08-20 that created or updated lockfiles
- check egress logs for connections to
23.254.165[.]112,23.254.167[.]107,23.254.167[.]216 - review what each affected job could access
- check temp directories on developer machines for
rust-setup(unix),rust-setup.ps1andrust-setup-launch.vbs(windows)- additionally check for stage-2 persistence artifacts:
$HOME/.config/AzureKits,$HOME/.config/ServiceKit, as well as binaries namedMonoServiceorMonoXpc- check for any systemd service that restarts them.
- additionally check for stage-2 persistence artifacts:
- pin the clean release
- treat exposed machines as compromised
- purge caches and vendored copies
- rebuild artifacts produced during the window
- block outbound traffic to
23.254.165[.]112,23.254.167[.]107, 23.254.167[.]216on all ports (ideally the surrounding Hostwinds ranges) and alert historical connections - consider:
- only admitting crates older than N days, as these were live for only 86 minutes
- committing Cargo.lock for applications
- building with --locked in CI
- reviewing lockfile diffs in PRs
- using
cargo vetandcargo audit - alerting on “yanked” warnings
- using scoped, shorter-lived tokens
Indicators
| Value | Type | Description |
|---|---|---|
| 23.254.165[.]112:9089 | IPv4:Port | payload host, TLS with any certificate accepted |
| 23.254.165[.]112:443 | IPv4:Port | C2, passed to payload as argv[1] |
| 23.254.167[.]107 | IPv4 | Additional C2 |
| 23.254.167[.]216 | IPv4 | Stage-2 C2 |
| hwsrv-798836.hostwindsdns[.]com | Domain | Hostwinds VPS |
| /tmp/rust-setup | Filename | Unix |
| rust-setup.ps1 | Filename | Windows temp directory |
| rust-setup-launch.vbs | Filename | Windows temp directory |
| $HOME/.config/AzureKits | Filename | Stage-2 Persistence |
| $HOME/.config/ServiceKit | Filename | Stage-2 Persistence |
| MonoService | Filename | Stage-2 Persistence |
| MonoXpc | Filename | Stage-2 Persistence |
| rust-crate_0.1.0 | C2 Implant | Payload artifacts |
| rust-crate_0.2.0 | C2 Implant | Payload artifacts |
| rust-crate_0.3.0 | C2 Implant | Payload artifacts |
| rust-crate_0.4.0 | C2 Implant | Payload artifacts |
| arrayref 0.3.10 | Package version | Compromised Legitimate Crates |
| internment 0.8.7 | Package version | Compromised Legitimate Crates |
| append-only-vec 0.1.9 | Package version | Compromised Legitimate Crates |
| proc-macro1 1.0.106 | Package version | Attacker-Owned Crates |
| proc-macro1 1.0.107 | Package version | Attacker-Owned Crates |
| proc-macro-en | Package name | Attacker-Owned Crates |
| aovine | Package name | Attacker-Owned Crates |
| arone | Package name | Attacker-Owned Crates |
| aronenao | Package name | Attacker-Owned Crates |
| tinymember | Package name | Attacker-Owned Crates |
| dtolney | Account name | Accounts, impersonator of dtolnay |
| droundy | Account name | Accounts, legitimate owner, presumed compromised |
| rchaitm@gmail[.]com | Email, forged “David Tolnay” author metadata | |
| 25ad700976873c76af785cb99b33c48db7df8b81f21d1e9e06b3676b9a9373ae | SHA-256 | arrayref-0.3.10.crate file, registry-verified via index git history |
| 61198155da51b838772eecf5bfaac6cbc4dcc388dccc56658fc28a8e831b34d4 | SHA-256 | proc-macro1-1.0.107.crate file, registry-verified via index git history |
| b5c1b5b0763a8809a644a8f92224653f0aca623a98eecc714d27f74b80fbe436 | SHA-256 | proc-macro1-1.0.106.crate file, registry-verified via index git history |
Notes
arrayrefis one of the Rust ecosystem’s quiet load-bearing crates: a tiny array-conversion utility with roughly 245 million all-time downloads, sitting underneathtiny-skia,winit,blake3, and large parts of the Solana and Ethereum tooling stacks.
- 406 crate versions depend on
arrayrefdirectly- Rust build scripts run at compile time, simply building any project whose lockfile resolved
arrayref 0.3.10was enough to detonate the payload. The crate’s code never needs to be called.- the child handle is abandoned with
std::mem::forget(child), commented in-source as escaping Cargo’s job object, so the build does not wait on the malware and the compiler exits cleanly. The build succeeds. Nothing looks wrong.- Note that
Cargo.tomlpins do NOT protect you:arrayref = "0.3"matches 0.3.10. Only the resolved lockfile version matters.- Both
23.254.165[.]0/24and23.254.167[.]0/24are Hostwinds ranges; treat the ranges, not just the individual addresses, as the indicator- Checksums for
internment 0.8.7,append-only-vec 0.1.9and theproc-macro-enrelease are not recoverable: those versions were hard-deleted from crates.io, the sparse index and docs.rs before they could be archived. If you hold a cached.cratefile for any of them, the Rust security response team would like to hear from you.
