Threat reportSupply ChainTL-2026-2089

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

criticalACTIVE

Hackers poison arrayref Rust crate (0.3.10) via proc-macro1 (TL-2026-2089), also tracked as Rust crate supply chain August 2026, is a critical-severity supply-chain compromise, first published 2026-08-20. It is attributed to APT38 (North Korea) with high confidence, affects Rust arrayref crate, maps to 16 MITRE ATT&CK techniques (T1027, T1036, T1059), and is covered by 9 detection rules and 31 indicators of compromise.

Severity
CRITICALAssessed severity
CVEs
0None referenced
Techniques
16MITRE ATT&CK
Actors
1APT38
Detection rules
9SPL · KQL · Sigma
IOCs
31Indicators of compromise

Key facts for TL-2026-2089

Threat ID
TL-2026-2089
Also known as
Rust crate supply chain August 2026, proc-macro1 typosquat attack, arrayref poisoning
Severity
CRITICAL
Status
ACTIVE
Category
SUPPLY_CHAIN
First published
Last reviewed
Attribution
APT38
Attribution confidence
HIGH
Nation-state nexus
North Korea
Motivation
ESPIONAGE
Target sectors
technology, software-development, blockchain, cryptocurrency, financial-services, cloud-computing, it - security
Target regions
Global
Detection rules
9
Indicators of compromise
31

Malware and tooling in Hackers poison arrayref Rust crate (0.3.10) via proc-macro1

Malware and tooling: proc-macro-en, proc-macro1, rust-crate backdoor, systemd

How Hackers poison arrayref Rust crate (0.3.10) via proc-macro1 works

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.

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 techniques used in TL-2026-2089

Defense Evasion

T1027 Obfuscated Files or Information; T1036 Masquerading; T1564 Hide Artifacts

Execution

T1059 Command and Scripting Interpreter; T1204 User Execution

Command and Control

T1071 Application Layer Protocol; T1568 Dynamic Resolution; T1573 Encrypted Channel

Discovery

T1082 System Information Discovery; T1518 Software Discovery

Initial Access

T1195 Supply Chain Compromise

Persistence

T1543 Create or Modify System Process; T1547 Boot or Logon Autostart Execution

Credential Access

T1555 Credentials from Password Stores

Resource Development

T1585 Establish Accounts

defense-impairment

T1685 Disable or Modify Tools

Affected products and versions in Hackers poison arrayref Rust crate (0.3.10) via proc-macro1

  • Rust — arrayref crate
    Vulnerable versions: 0.3.10
    Fixed in: 0.3.9
  • Rust — internment crate
    Vulnerable versions: 0.8.7
    Fixed in: 0.8.6
  • Rust — append-only-vec crate
    Vulnerable versions: 0.1.9
    Fixed in: 0.1.8
  • Rust — proc-macro1 crate (typosquat)
    Vulnerable versions: 1.0.106; 1.0.107
  • Google — Chrome
    Vulnerable versions: All versions with saved credentials
  • Microsoft — Edge
    Vulnerable versions: All versions with saved credentials
  • Brave Software — Brave
    Vulnerable versions: All versions with saved credentials
  • Rust — blake3 crate
    Vulnerable versions: <1.8.7
    Fixed in: 1.8.7
  • Rust — tiny-skia crate
    Vulnerable versions: All versions depending on arrayref
  • Rust — winit crate
    Vulnerable versions: All versions depending on sctk-adwaita

Remediation for Hackers poison arrayref Rust crate (0.3.10) via proc-macro1

Immediate actions

  • Pin arrayref to 0.3.9, internment to 0.8.6, and append-only-vec to 0.1.8 in all Cargo.lock files
  • Block 23.254.164.0/23 (Hostwinds range) at network perimeter, including ports 443, 9089
  • Scan all build systems for /tmp/rust-setup, %TEMP%\rust-setup.ps1, and %TEMP%\rust-setup-launch.vbs
  • Check ~/.cargo/registry/cache for deleted crate files (proc-macro1, proc-macro-en, aovine, arone, aronenao, tinymember)
  • Search Cargo.lock files for proc-macro1 dependency across all repositories
  • Regenerate lockfiles from trusted crates.io metadata after pinning safe versions
  • Rotate ALL credentials, CI tokens, signing keys, and secrets exposed on any machine that ran cargo build during the 07:11-09:25 UTC window
  • Treat any host with confirmed execution as fully compromised

Workarounds

  • Use cargo build --offline for CI/CD pipelines
  • Pin crate versions in Cargo.lock and audit all dependency additions
  • Implement a global-min-publish-age policy for CI systems to reject dependencies younger than 24 hours
  • Use sandboxed build environments with egress filtering

Longer-term hardening

  • Implement build-time dependency integrity verification (cargo vet, cargo crev)
  • Deploy runtime monitoring for anomalous build-script network connections (e.g., StepSecurity Harden-Runner)
  • Use cargo build --offline for CI/CD pipelines to prevent dynamic dependency resolution
  • Audit all Rust projects for dependency drift and lockfile consistency
  • Consider sandboxed/containerized build environments with restricted network access
  • Monitor for DGA domain registrations in the .com TLD matching the algorithmic pattern

Weaknesses (CWE) in Hackers poison arrayref Rust crate (0.3.10) via proc-macro1

CWE-494, CWE-1104, CWE-912

Timeline of Hackers poison arrayref Rust crate (0.3.10) via proc-macro1

  • Attacker-owned crates arone and aronenao first published with malicious build scripts, pre-positioning typosquat infrastructure before the main attack.
  • Wiz Research publishes analysis identifying significant infrastructure overlap with DPRK campaigns (Sapphire Sleet/UNC1069), including shared C2 endpoint /49890878 with the Mastra npm attack and shared SSL certificate issuer with Mastra infrastructure.
  • Rust Security Response Team locks the compromised droundy account as a precaution. All attacker-owned crates (proc-macro1, proc-macro-en, aovine, arone, aronenao, tinymember) deleted. Legitimate versions of arrayref (0.3.5-0.3.9) that were improperly yanked are restored.
  • append-only-vec@0.1.9 deleted at 09:25 UTC (107-minute exposure window — longest-lived malicious version).
  • internment@0.8.7 deleted at 09:04 UTC (90-minute exposure window). StepSecurity Harden-Runner detects anomalous connection to 23.254.165.112:9089 at 09:07 UTC.
  • arrayref@0.3.10 removed from crates.io index at 08:41 UTC (86-minute exposure window). blake3 drops arrayref dependency starting in version 1.8.7 at 09:09 UTC.
  • proc-macro1 deleted from crates.io at 08:03 UTC (52 minutes after weaponized release).
  • Attack reported to Rust Security Response Team at 07:54 UTC by researcher jhobern via RustSec advisory-db issue #3161.
  • internment@0.8.7 published at 07:34 UTC and append-only-vec@0.1.9 published at 07:37 UTC, poisoning all three droundy-maintained crates within a 23-minute window.
  • arrayref@0.3.10 published at 07:15 UTC via compromised droundy account. Legitimate versions 0.3.5-0.3.9 script-yanked in a 16-second burst (07:15:24-07:15:40) to force Cargo to suggest the malicious version.
  • proc-macro1@1.0.107 published at 07:11 UTC containing the weaponized build.rs with base64-encoded C2 URL fragments, TLS bypass, and download-and-execute dropper logic.
  • proc-macro1@1.0.106 published at 01:55 UTC as a clean decoy — a genuine renamed copy of proc-macro2 with no malicious code, to establish credibility.
  • GitHub account dtolney created at 01:17 UTC impersonating prominent Rust developer David Tolnay (dtolnay), followed by crates.io account dtolney (id 438608) at 01:25 UTC.

Sources cited for Hackers poison arrayref Rust crate (0.3.10) via proc-macro1

Detection coverage for TL-2026-2089

As of 2026-08-20, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-2089 across Splunk SPL, Microsoft KQL and Sigma, covering 31 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

9 detection rules (Splunk SPL, Microsoft KQL, Sigma) · Blue and above. Compare plans
31 indicators of compromise · Red and above. Compare plans

Community OSINT corroboration for TL-2026-2089

10 of this threat's indicators have also been reported by the open-source security community, which observed at least one of them before this report was published. Community sightings are unverified and are kept separate from Threadlinqs' curated indicators. Indicator values, reporters and campaign linkage are available to authenticated Red-tier users.

Further reading

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level
Fig. 01 · Threat weatherIndexing the archive…
1 square = 1 threat · click to open

Latest Threats