# Hackers poison arrayref Rust crate (0.3.10) via proc-macro1 typosquat to push DPRK-linked cross-platform infostealer backdoor at compile time

> On August 20, 2026, attackers compromised the crates.io maintainer account droundy (David Roundy) and published malicious versions of three widely-used Rust crates — arrayref (245M+ lifetime downloads), internment, and append-only-vec — within a 23-minute window. The malicious versions added a single dependency on proc-macro1, a typosquat of the legitimate proc-macro2 crate, whose build.rs automatically downloaded and executed a feature-rich cross-platform backdoor at compile time. The second-stage payload steals browser credentials from Chrome, Brave, and Edge, establishes persistence via Registry Run keys, LaunchAgents, and systemd, and communicates over HTTPS with AES-128-GCM encrypted C2 channels. The Rust Security Response Team deleted the malicious versions within 86-107 minutes, but the attack exposed 264M+ cumulative downloads and affected 35%+ of all environments. Wiz Research identified significant infrastructure overlap with DPRK campaigns (Sapphire Sleet / UNC1069), including shared C2 endpoints and SSL certificate issuers with the prior Mastra and axios npm supply-chain attacks.

- **Published:** 2026-08-20T00:00:00Z
- **Last reviewed:** 2026-08-20T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-2089
- **ID:** TL-2026-2089
- **Severity:** CRITICAL
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Actor:** APT38 (North Korea)
- **Detections:** 9 · **IOCs:** 31 (full data via the Threadlinqs MCP server — Purple tier)

## Description

This sophisticated supply-chain attack targeted the Rust open-source ecosystem by compromising the crates.io maintainer account droundy (David Roundy, registered October 2009, user 2402). The attacker first created an impersonation account — dtolney (crates.io id 438608) — typosquatting prominent Rust developer David Tolnay (dtolnay), author of the ubiquitous proc-macro2 crate (154M+ downloads). At 01:55 UTC on August 20, the attacker published proc-macro1@1.0.106 as a clean decoy — a genuine renamed copy of proc-macro2 — to establish credibility. At 07:11 UTC, the weaponized proc-macro1@1.0.107 was published, containing a malicious build.rs script with build dependencies (ureq, rustls, base64) that acted as a download-and-execute dropper.

At 07:15 UTC, the compromised droundy account published arrayref@0.3.10, adding proc-macro1 as the crate's first-ever runtime dependency in its ten-year history. Critically, the attacker simultaneously yanked legitimate versions 0.3.5 through 0.3.9 in a scripted burst (each yank 2.6-5.6 seconds apart), leaving the malicious 0.3.10 as the only version Cargo would not warn about. Internment@0.8.7 followed at 07:34 UTC and append-only-vec@0.1.9 at 07:37 UTC. The library source code of all three crates was left completely unchanged — only the Cargo.toml dependency was added, making the infection invisible to casual inspection.

During any cargo build, cargo check, or cargo test that resolved the poisoned dependency, the proc-macro1 build.rs would: (1) concatenate base64-encoded URL fragments at runtime to reconstruct the payload host (https://23.254.165.112:9089/) and C2 address (23.254.165.112:443); (2) install a custom AcceptAll TLS certificate verifier that unconditionally accepts self-signed or mismatched certificates; (3) select a platform-specific payload binary (rust-crate_0.1.0 through _0.4.0) for Linux x86-64, Windows x86-64, macOS x86-64, or macOS ARM64; (4) download the payload over HTTPS; (5) on Unix, write to /tmp/rust-setup, chmod +x, and spawn detached with no stdin/stdout/stderr via std::mem::forget(child) — a step explicitly commented in the source as escaping Cargo's job object; (6) on Windows, write a PowerShell script to %TEMP%\rust-setup.ps1, launch it hidden via a VBScript wrapper (rust-setup-launch.vbs) under wscript.exe with CREATE_NO_WINDOW, then abandon the child handle. The build then completed normally, producing no visible errors.

The second-stage payload is a feature-rich Rust-based backdoor supporting x86-64 Linux, x86-64 Windows, x86-64 macOS, and ARM64 macOS. It beacons to the C2 via HTTPS POST to endpoint /49890878, exfiltrating host info (hostname, OS type, OS version, architecture, platform version, installed applications) and stolen credentials as base64-encoded JSON. The payload targets Chromium-based browsers (Google Chrome, Brave, Microsoft Edge) by querying SQLite login databases for origin URLs and usernames, and also accesses Local Extension Settings where cryptocurrency wallet extensions store data. Configuration is encrypted with AES-128-GCM using the hardcoded null-padded key 'i am botking', with a secondary key 'test' for minicfg parameters. Commands are authenticated via an embedded RSA-2048 private key. The payload supports four commands: kill (terminate), minicfg (reconfigure C2 address and beacon interval), startup (install persistence), and runscript (download and execute arbitrary PowerShell or shell scripts, synchronously or in background). If primary C2 is unreachable, the backdoor generates 10 algorithmic .com domains every 5 days via a Domain Generation Algorithm (DGA). Persistence is established via Registry Run key (Windows), LaunchAgent at Library/LaunchAgents with a RunAtLoad /bin/zsh -c command (macOS), and a systemd user service (Linux). On Linux, the payload creates directories $HOME/.config/AzureKits and $HOME/.config/ServiceKit, dropping executables named MonoService and MonoXpc.

Researcher jhobern reported the attack to the Rust Security Response Team at 07:54 UTC. The team deleted proc-macro1 from crates.io at 08:03 UTC, removed arrayref@0.3.10 from the index at 08:41 UTC (86-minute exposure), deleted internment@0.8.7 at 09:04 UTC (90-minute exposure), and deleted append-only-vec@0.1.9 at 09:25 UTC (107-minute exposure). The droundy account was locked as a precaution, with the team assessing the author was compromised, not acting maliciously. All attacker-owned crates (proc-macro1, proc-macro-en, aovine, arone, aronenao, tinymember) were deleted. Pre-positioning crates arone and aronenao had been published as early as August 18 with malicious build scripts of their own.

Wiz Research (Rami McCarthy and Benjamin Read) identified significant overlap with DPRK campaigns: (1) the payload beacon endpoint /49890878 was shared with the Mastra npm supply-chain campaign (June 17, 2026), attributed by Microsoft to DPRK's Sapphire Sleet (BlueNoroff, UNC1069); (2) IP 23.254.165.112 shares an SSL certificate issuer (WIN-A6QF8AHPQH1\Administrator@WIN-A6QF8AHPQH1) with 23.254.167.13, also used in the Mastra campaign; (3) IP 23.254.167.216 — reported by a victim of this attack — appears in Google Cloud Threat Intelligence's analysis of UNC1069's axios npm attack (March 31, 2026), linked by Mandiant to North Korea; (4) all infrastructure uses the same 23.254.164.0/23 range via Hostwinds LLC.

Downstream impact is severe: arrayref is used in 35%+ of all environments and 75% of Rust environments. It is a transitive dependency of blake3 (cryptography), the winit → sctk-adwaita → tiny-skia → arrayref chain, and Rust GUI frameworks egui, eframe, and iced. It also sits beneath Ethereum and Solana blockchain tooling. Because the malicious versions were deleted — not merely yanked — from crates.io, cargo audit reports clean for projects that pinned a poisoned version, creating a persistent detection gap. No CVE has been assigned and no patched version exists. The Rust Security Response Team has a pull request for a global-min-publish-age setting (to block young dependencies) that entered its final comment period on August 18 but remained unmerged as of August 21.

## MITRE ATT&CK

- T1585 Establish Accounts
- T1195 Supply Chain Compromise
- T1204 User Execution
- T1059 Command and Scripting Interpreter
- T1547 Boot or Logon Autostart Execution
- T1543 Create or Modify System Process
- T1027 Obfuscated Files or Information
- T1036 Masquerading
- T1564 Hide Artifacts
- T1685 Disable or Modify Tools
- T1555 Credentials from Password Stores
- T1082 System Information Discovery
- T1518 Software Discovery
- T1071 Application Layer Protocol
- T1573 Encrypted Channel
- T1568 Dynamic Resolution

## Sources

- [Hackers poison arrayref Rust crate to push infostealer malware](https://www.bleepingcomputer.com/news/security/hackers-poison-arrayref-rust-crate-to-push-infostealer-malware/)
- [Rust Supply Chain Attack on arrayref: Significant Overlap with DPRK Campaigns](https://www.wiz.io/blog/rust-supply-chain-attack-on-arrayref-significant-overlap-with-dprk-campaigns)
- [JFrog Research: arrayref/proc-macro1 crates.io attack analysis](https://research.jfrog.com/post/arrayref-proc-macro1-crates-io/)
- [StepSecurity: arrayref, internment, and append-only-vec poisoned by supply chain attack](https://www.stepsecurity.io/blog/arrayref-rust-crate-supply-chain-attack)
- [Rust Security Response Team: Supply chain attack on arrayref](https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on-arrayref/)
- [Rust Supply Chain Attack Puts Build-Time Malware in Crates](https://thehackernews.com/2026/08/rust-supply-chain-attack-puts-build.html)
- [Two popular Rust crates compromised in supply chain attack](https://www.aikido.dev/blog/two-popular-rust-crates-arrayref-and-append-only-vec-compromised-in-supply-chain-attack)
- [Popular Rust Crates Compromised: arrayref, internment, append-only-vec](https://socket.dev/blog/popular-rust-crates-compromised)
- [RustSec advisory-db issue #3161](https://github.com/rustsec/advisory-db/issues/3161)
- [Microsoft: Postinstall payload inside Mastra npm supply chain compromise](https://www.microsoft.com/en-us/security/blog/2026/06/17/postinstall-payload-inside-mastra-npm-supply-chain-compromise/)
- [Microsoft links Mastra AI supply-chain attack to North Korean hackers](https://www.bleepingcomputer.com/news/security/microsoft-links-mastra-ai-supply-chain-attack-to-north-korean-hackers/)
- [Researchers tie the arrayref Rust crate hijack to North Korea](https://cryptonews.net/news/security/33326907/)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-2089
