Skip to content

Rustbot, the macOS malware used in the latest Rust Supply Chain Attack

Cristian Molina Cristian Molina
Rustbot, the macOS malware used in the latest Rust Supply Chain Attack
  1. On August 20, 2026, attackers published malicious versions of three widely used Rust packages to crates.io, the official Rust package registry.
  2. On macOS, the payload is a remote access trojan (RAT) that collects cloud credentials, SSH keys, cryptocurrency wallet data, and browser profile information, then sends it to attacker-controlled infrastructure. It installs a launch agent to survive reboots and accepts follow-on commands from its operators.
  3. Once running, it decrypts its configuration, profiles the host, Reads the local browser stores, installs persistence via LaunchAgent, and beacons out.
  4. The packages were available for approximately two hours before removal. The attackers also withdrew the previous stable versions, which pushed automated dependency resolution toward the compromised releases. Any environment that compiled an affected project during that window should be treated as compromised.

This blog documents Iru's analysis of the native Apple Silicon ARM64 implant.

Four other research teams published on this campaign:

  • Wiz published the campaign on August 20, disclosing the AES-128-GCM configuration key, the four-command tasking surface, and the DGA fallback.
  • Socket's scanner independently flagged the malicious proc-macro1 crate, and their analysis of the recovered stage-2 payloads documented the backdoor's capabilities and the flaw in its command authentication.
  • StepSecurity reconstructed the publish, yank, and takedown timeline and dissected the build-time dropper.
  • The Rust Security Response Team's advisory covers the incident response and credits Nextron Systems with the initial report.

Our contribution is macOS-specific. From the arm64 sample we documented the on-disk characteristics of the Mach-O, the LaunchAgent persistence chain, and the collection target map, with observed and inferred paths distinguished.

Enrichment through Google Threat Intelligence surfaced additional indicators beyond those published, including the SHA-256 of the arm64 payload, which prior reporting published only the SHA-1.

The Sapphire Sleet association rests on two infrastructure links as reported by Wiz. The stage-2 C2 path /49890878was used in the Mastra campaign, which Microsoft attributed to Sapphire Sleet. The staging C2 hosts also present a self-signed TLS certificate with the issuer string WIN-A6QF8AHPQH1\Administrator@WIN-A6QF8AHPQH1, which appears on 23.254.167[.]13 in that same campaign.

Shared infrastructure has limits as evidence. DPRK clusters share hosting, builders, and deployment templates, so overlapping infrastructure may locate the tooling pipeline rather than the operator. The remaining indicators are weaker still: registry poisoning is common across DPRK clusters and is most associated with Contagious Interview, and asymmetric command authentication is a general operational security pattern.

We assess DPRK-nexus attribution at high confidence and Sapphire Sleet at low confidence.

Rustbot

Figure 1. Delivery chain on macOS. A cargo build resolves the poisoned crate, Cargo executes its build script, and the script fingerprints the host and fetches a matching ARM64 Mach-O from the delivery server. The payload is written to /tmp/rust-setup and executed with the C2 address as its launch argument. No user interaction beyond compiling the project is required

Implant Behavior

Rustbot functions as a remote access and information stealing tool. It decrypts an embedded configuration, screens for analysis environments, and communicates with C2 servers over an authenticated, encrypted channel featuring a domain-generation algorithm (DGA) fallback. Observed collection targets include host metadata, credential files (SSH, AWS, and Kubernetes), and browser data (login origins, usernames, and extension identifiers); dumping of stored browser passwords was not confirmed in the analyzed stage.

Build-time execution

Because Cargo runs build scripts automatically during cargo build, the payload fires the moment an affected project is compiled. StepSecurity's reconstruction of the dropper and its build-dependency toolkit, corroborating the original RustSec disclosure, is the primary external source for the behavior below. The deobfuscated behavior of proc-macro1's build.rs:

  1. Reconstructs a delivery URL from Base64 fragments, https://23.254.165[.]112:9089/
  2. Installs a custom TLS verifier that accepts any certificate, so the direct-to-IP fetch over HTTPS never fails validation.
  3. Fingerprints the host, operating system and CPU architecture (macOS Darwin, arm64 vs. x86_64), and requests the matching second stage.
  4. Writes the downloaded binary to a transient path, /tmp/rust-setup on Unix hosts, %TEMP%\rust-setup.ps1 on Windows.
  5. Executes it, passing the C2 beacon address as its first launch argument.

Runtime

The macOS payload is a Mach-O, arm64, roughly 3.07 MB. It’s self-signed with no valid Apple Developer Team ID. It imports only /usr/lib/libSystem.B.dylib and /usr/lib/libiconv.2.dylib. On the delivery server it is named rust-crate_0.4.0 / t_rust_arm64; on the victim it lands as /tmp/rust-setup.

Once running, it decrypts its configuration, profiles the host, reads the local browser stores, installs persistence via LaunchAgent, and beacons out.

Configuration decryption

The implant carries an encrypted configuration block, decrypted with AES-128-GCM. The key is not derived or fetched. The key, first published by Wiz, is the hardcoded ASCII string i am botking, 12 bytes null-padded to 16:

69 20 61 6d 20 62 6f 74 6b 69 6e 67 00 00 00 00

Decryption yielded the C2 endpoints, the beacon interval (1 min), and the implant's target list. Where the config named concrete filesystem paths, those are marked observed below; where it named applications or credential stores without paths, the standard macOS locations are given and marked inferred.

Host and browser profiling

The implant profiles the host and reads a targeted set of directories, weighted heavily toward non-human identities (tokens, keys) and local browser profiles. Socket's analysis of the recovered stage-2 payloads corroborates browser reconnaissance, noting that the analyzed stage inventories Chromium login origins, usernames, and extension IDs without decrypting stored passwords.

Collection targets, bucketed by asset value to the operator:

Cloud & infrastructure credentials (paths observed)

  • ~/.aws/, AWS CLI keys and config
  • ~/.ssh/, SSH private keys and known_hosts
  • ~/.kube/, Kubernetes cluster tokens and config

Cryptocurrency wallets (app names observed; paths are standard macOS locations, inferred)

  • Exodus, ~/Library/Application Support/Exodus/
  • Ledger Live, ~/Library/Application Support/Ledger Live/
  • MetaMask, browser extension; data lives inside the Chromium profiles below (extension ID nkbihfbeogaeaoehlefnkodbefgpgknn), not a standalone app dir
  • Coinbase Wallet, browser extension; likewise inside the browser profiles (extension ID hnfanknocfeofbddgcijnmhnfnkdnaad)

Developer tooling (paths inferred)

  • VS Code, ~/Library/Application Support/Code/, ~/.vscode/
  • IntelliJ IDEA, ~/Library/Application Support/JetBrains/
  • Subversion, ~/.subversion/
  • Docker, ~/.docker/ (note: config.json can hold registry auth tokens)

Messaging & collaboration (paths inferred)

  • Slack, ~/Library/Application Support/Slack/
  • Telegram, ~/Library/Application Support/Telegram Desktop/tdata/
  • Signal, ~/Library/Application Support/Signal/
  • Discord, ~/Library/Application Support/discord/ (session tokens in Local Storage/leveldb/)

Browser profiles (Chromium family) (paths observed)

  • Google Chrome, ~/Library/Application Support/Google/Chrome/
  • Brave, ~/Library/Application Support/BraveSoftware/Brave-Browser/
  • Microsoft Edge, ~/Library/Application Support/Microsoft Edge/

The analyzed stage-2 payloads inventory browser login origins, usernames, and extension IDs but do not decrypt stored passwords.

C2 communication

The implant establishes an encrypted channel and beacons over HTTPS with a POST to the path /49890878, sending host information and collected data as Base64-encoded JSON. Inbound tasking was designed to authenticate tasking against authenticated against an embedded RSA-2048 key. However, as detailed below, that authentication is fatally undermined by an implementation flaw:

The developers intended an authenticated tasking system using asymmetric RSA cryptography. As designed, the operator would hold a private key off-host and sign each C2 task; the implant, carrying only the corresponding public key, would verify the signature and execute only tasks signed by the real operator. Done correctly, this makes the tasking channel exclusive. Someone who finds an infected host, or stands up a look-alike C2, cannot issue accepted commands without the private key, and cannot recover that key from the implant, because only the public half is in the binary. Combined with the DGA fallback, a correct implementation would have let the operators retain control of infected hosts even after the primary C2 was seized or sinkholed.

However, because the private key ships inside the implant, the tasking channel provided no exclusive operator authentication and the integrity of the C2 channel was neutralized.

The tasking surface itself is small, four commands:

Command Behavior
kill Terminate the implant
minicfg Reconfigure C2 endpoints / beacon interval
startup Install persistence
runscript Download and run a shell script (macOS/Linux) or PowerShell (Windows)

runscript served a second-stage delivery channel.

If the primary C2 is unreachable, the implant falls back to a domain-generation algorithm producing algorithmic .comdomains, none were registered at the time of analysis.

Analysis

DPRK-nexus actors run supply chain and social engineering campaigns to fund the regime through cryptocurrency theft, and the collection targets here continue to fit that pattern.

The malicious releases were downloadable for about two hours before removal. Individual impact is unconfirmed, but the exposure surface is not small: arrayref appears in over a third of all environments and three-quarters of environments where Rust is present. The attackers also yanked the stable versions, which pushed resolvers toward the compromised ones. Any environment that compiled an affected project in that window should be treated as compromised.

Developer workstations and CI/CD runners carry the same credential-harvesting risk as production. They hold API keys, code-signing certificates, and cloud credentials, and those are what the implant's collection routines go after. The analyzed stage enumerates browser login stores without decrypting them, but runscript is an open channel for whatever the operator wants to run next, so the ceiling is set by the operator, not by the implant.

Expect more of this. Language-specific registries are an efficient conduit, as npm and PyPI have already shown, and registry maintenance actions like yanking are becoming part of the delivery method rather than incidental to it. The move toward network-delivered payloads over statically linked implants also continues, since it defeats static detection and complicates cluster-based analysis.

Indicators of compromise

Packages and accounts

Type Indicator Notes
Package arrayref@0.3.10, internment@0.8.7, append-only-vec@0.1.9 Hijacked releases (removed). Last-safe: 0.3.9 / 0.8.6 / 0.1.8
Package proc-macro1, proc-macro-en, aovine, arone, aronenao, tinymember Attacker-controlled dropper/typosquat crates
Account droundy Legitimate maintainer; account/credentials assessed compromised
Account dtolney Impersonation account that published proc-macro1
Email rchaitm@gmail[.]com Forged author metadata on the malicious dependency

Network

Type Indicator Notes
IP 23.254.165[.]112:9089 Stage-2 payload delivery host
IP 23.254.165[.]112:443 C2 passed to the payload as its launch argument
IP 23.254.167[.]107:443 Stage-2 C2
IP 23.254.167[.]216 Stage-2 C2 seen on an infected host (third-party report, RustSec thread; not independently confirmed by Iru)
Range 23.254.165.0/24, 23.254.167.0/24 Hostwinds ranges; treat both. A single 23.254.164.0/23 misses the .167 C2 addresses
Domain hwsrv-798836.hostwindsdns[.]com Attacker infrastructure hostname
Path POST /49890878 Stage-2 C2 path
Certificate WIN-A6QF8AHPQH1\Administrator@WIN-A6QF8AHPQH1 Self-Signed TLS on Staging C2 host.

Host artifacts

Type Indicator Notes
File /tmp/rust-setup On-host stage-2 (macOS/Linux)
File %TEMP%\rust-setup.ps1, %TEMP%\rust-setup-launch.vbs On-host stage-2 (Windows)
String i am botking AES-128-GCM config key; highest-signal static string
Persistence ~/Library/LaunchAgents/*.plist created by a build-descended process Detection surface

Payload hashes (SHA-256)

Platform SHA-256
macOS arm64 74d3447e7cf99c99ea01a16332ec27432dfb0f491e10e67cd118065a60483306 (rust-crate_0.4.0)
macOS x86_64 c9561a3b00a0fa38b7772675d987f84bd429c55cd024fc08a98245c2d1632848 (rust-crate_0.3.0)
Linux x86_64 408ef22050ffc5a67e005802809026b29f297a8019f8fda91a2afa8e877ba434 (rust-crate_0.1.0)
Windows 492f2ab86f8d8911adc79c10ec1541704f5311d207d9d799b0d2a57fcc6a4391 (rust-crate_0.2.0)
Loader (build.rs) cb7778eb6dda91028abf087eb7c3553f981a67e756769507d348e8c201805568 (shared by proc-macro1@1.0.107 and proc-macro-en@1.0.10)

MITRE ATT&CK

Technique ID Notes
Supply Chain Compromise: Software Dependencies and Development Tools T1195.001 Poisoned crate + added malicious build-time dependency
Command and Scripting Interpreter T1059 runscript executes shell (macOS/Linux) or PowerShell (Windows)
Ingress Tool Transfer T1105 build.rs fetches the second stage; runscript fetches further payloads
Persistence: Launch Agent T1543.001 macOS LaunchAgent created by a build-descended process
System Information Discovery T1082 Host profiling in every beacon
Software Discovery T1518 Enumerates installed applications
Unsecured Credentials: Credentials In Files T1552.001 Reads ~/.aws, ~/.ssh, and ~/.kube for keys and tokens
Data from Local System T1005 Bulk collection from the targeted directories
Browser Information Discovery T1217 Enumerates browser login stores via SQLite (reconnaissance, not confirmed dump)
Application Layer Protocol: Web Protocols T1071.001 HTTPS POST beacon
Encrypted Channel T1573 AES-128-GCM config; RSA-authenticated tasking
Data Encoding: Standard Encoding T1132.001 Base64-encoded JSON beacon; Base64 URL fragments in the dropper
Dynamic Resolution: Domain Generation Algorithms T1568.002 .com DGA fallback when primary C2 is unreachable
Exfiltration Over C2 Channel T1041 Collected host/profile data returned over the C2 channel

Recent Articles

Featured image: Inside the screensharingd Bugs: How macOS Screen Sharing Went from Root File Access to Pre-Auth Compromise
Csaba Fitzl 6 min read

Inside the screensharingd Bugs: How macOS Screen Sharing Went from Root File Access to Pre-Auth Compromise

In late July 2026, a cluster of vulnerabilities in macOS Screen Sharing turned what initially looked like a fairly constrained privilege problem into one of the more interesting macOS remote-attack stories in years.

Threat Intelligence
Featured image: Apple is deprecating hdiutil in macOS 27 Golden Gate. Are your scripts ready?
Arek Dreyer 3 min read

Apple is deprecating hdiutil in macOS 27 Golden Gate. Are your scripts ready?

If you spent part of last weekend fielding Slack messages about hdiutil, you're not alone. Jeff Johnson's lapcatsoftware.com blog flagged that the man page for hdiutil in the macOS 27 Golden Gate beta now carries a deprecation notice:

Educational
Featured image: Apple beta testing and device management services: the perfect match
Mike Boylan 6 min read

Apple beta testing and device management services: the perfect match

Every fall, Apple’s newest operating systems arrive everywhere at once. That’s great for users, but it puts IT teams on the clock: they need to validate the release, find blockers, prepare their support teams, and decide when the business is ready to move.

Educational

See Iru in action

Discover why thousands of teams choose Iru

By submitting this form I agree to Iru’s Privacy Policy and consent to be contacted by Iru about its products and services.

Stay up to date

Iru's bi-weekly collection of articles, videos, and research to keep IT & Security teams ahead of the curve.