Yaamlabs

Supply chain

A trojanized Terraform provider is robbing cloud engineers

ThreatLabz found a fake AWS Terraform provider that installs backdoors and steals browser, keychain and wallet data. How it runs, how to pin and hunt.

Zscaler ThreatLabz published research on October 8, 2026 about a trojanized Terraform provider, terraform-provider-awsbeta_v1.0.0, that poses as an AWS provider for HashiCorp Terraform. When Terraform starts it, the provider quietly downloads a loader that installs a Rust backdoor called FLATROOF, Python scripts that steal browser data, shell histories, keychains and crypto wallet extension data, and on some machines a second backdoor called ROOFDECK. It works on macOS, Linux and Windows, and the provider keeps doing its normal job, so nothing in the Terraform run looks wrong.

Anyone who runs Terraform on a workstation is in scope, and the targets look like cloud engineers and developers whose laptops hold cloud credentials and source control access. ThreatLabz first spotted the campaign in July and sees overlaps with TraderTraitor, a North Korean group that steals cryptocurrency, but says the evidence is not strong enough for a firm attribution. ThreatLabz could not determine how the provider reached its victims.

How a provider gets to run code

A Terraform provider is an ordinary executable. terraform init downloads it into .terraform/providers/<hostname>/<namespace>/<type>/, and commands that need it, such as plan, apply and validate, launch it as a child process and talk to it over gRPC. It runs with the full rights of the engineer's account: their files, browser profiles, ~/.aws and shell history. No sandbox sits in between.

The attacker added a sibling package named awsbeta to a Go provider and called it from main, so the payload runs as soon as Terraform starts the binary. It checks the temp directory ($TMPDIR, falling back to /tmp) for a marker file, session.lock. If the marker is missing, it downloads a script from diagnose.hashicorp-terraform[.]io, on a path dressed up as a plugin metrics endpoint, saves it as safari_updater, runs it detached through sh -c and writes the marker so it only fires once.

That Bash loader works out the operating system and CPU and picks a matching file named like a web font, for example HiraginoSans-Regular.woff for macOS on Apple Silicon. Each file holds decoy font data, a @@ENDFONT@@ marker and then an AES-256 encrypted executable, which the loader decrypts with whichever of Python, Node.js, Perl or OpenSSL is installed. It tries a dynamic DNS host first, then a GitHub repository, then a site on Vercel. On macOS it strips the quarantine attribute and applies an ad hoc signature, which gets the binary past Gatekeeper.

What the malware takes

FLATROOF installs itself at $HOME/Library/com.apple.iTunesCloud/SystemUpdate on macOS, $HOME/.config/git/update on Linux and %USERPROFILE%\AppData\Local\Microsoft\Edge\service.exe on Windows. It talks to its operators over the Telegram Bot API, GitHub API polling or an HTTP webhook, and can run commands, move files, fetch more payloads and remove itself. It also checks whether Palo Alto Cortex XDR or Traps is present.

The Python stealers copy Chromium and Firefox history, cookies, saved logins and autofill data, plus shell history, installed applications and running processes. The macOS version adds Safari data and login.keychain-db. The Linux version pulls the Chrome Safe Storage secret from the Secret Service. On Windows it takes Chrome, Edge and Brave data, Credential Manager entries, PowerShell and Command Prompt history, and the extension data of the MetaMask, Phantom, Trust Wallet and Rabby wallets.

ROOFDECK, seen as imagent on macOS and update.exe on Windows, gives a reverse shell, file access and clipboard read and write. To find its server it reads a local config file first, then a signed, encrypted address on Pastebin, then the website field of an attacker-controlled Nostr profile, so taking down one channel does not cut it off.

Who is behind it

TraderTraitor (also tracked as Jade Sleet, UNC4899, Pressure Chollima and Slow Pisces) targets crypto and Web3 developers with trojanized developer tools and fake job offers, which matches this campaign. The same two backdoors appeared in the investigation of the April 18 theft of about $292 million from KelpDAO's LayerZero bridge, which LayerZero attributes to TraderTraitor. ThreatLabz still found no unique code, shared infrastructure or cryptographic link, so treat the attribution as provisional.

SentinelLabs reported a related case on September 18. Fake take-home interview repositories carried a .terraform.lock.hcl pointing to lookalike registries (registry.hashicorp-aws[.]com, registry.hashicorp-aws[.]io and registry.hashicorp-terraform[.]io). The victim was a DevOps engineer at an India-based IT services company with no crypto business, whose Mac ran both implants from March until June 1.

What to do

1. Check the provider addresses before you run init

Every provider has a source address of the form hostname/namespace/type. The real AWS provider is registry.terraform.io/hashicorp/aws; there is no HashiCorp provider called awsbeta. A hostname other than registry.terraform.io or your own private registry, or a namespace that is one letter off a known publisher, is a reason to stop. Run terraform providers to list what a configuration asks for, and read the provider "..." lines in .terraform.lock.hcl before running terraform init on a repository you did not write.

2. Pin, and understand what pinning covers

.terraform.lock.hcl records each provider's address, exact version and package hashes (h1: and zh: lines), and Terraform refuses a download that does not match. Commit it, and use terraform init -lockfile=readonly in CI so a run fails instead of rewriting it. The lock file only protects an address you already trust. It cannot tell you the address itself is malicious, and the SentinelLabs lures shipped their own lock file.

3. Restrict where providers can come from

Set a provider_installation block in the Terraform CLI config (~/.terraformrc, or terraform.rc in %APPDATA% on Windows) on engineer machines and CI runners, with a direct block whose include is ["registry.terraform.io/hashicorp/*", ...] plus the namespaces you approve, or a network_mirror you control. Terraform will then refuse providers from any other host or namespace.

4. Hunt

  • List every provider on a machine: find ~ -path '*/.terraform/providers/*' -type f -name 'terraform-provider-*' and look for hostnames you do not use and for awsbeta.
  • Look for the install paths above, safari_updater in the temp directory, the Linux service snap-imagent, a macOS zlogout entry for imagent with a payload at ~/Library/Services/imagent, and the Windows Run value powershell-config-service.
  • Search DNS and proxy logs for hashicorp-terraform[.]io, hashicorp-aws[.]com, hashicorp-aws[.]io, supportaru.serveftp[.]com, arusupport-region1-webhook[.]online, delay.servehttp[.]com and pastebin[.]com/raw/3yptBDhL.
  • On EDR, flag unsigned binaries running from the home directory and Telegram or Pastebin traffic from non-browser processes on developer machines, as SentinelLabs recommends.

5. If you find it

Isolate and rebuild the machine. Then assume anything the engineer's account could read is gone: rotate AWS and other cloud access keys, Git and CI tokens, SSH keys and any secret that ever appeared in shell history, and sign the user out of every web session, since stolen cookies outlive a password change. Move any wallet funds to new keys created on a clean device.

The wider lesson

Infrastructure code gets reviewed as configuration, but terraform init on an unknown repository installs and runs third-party binaries with the engineer's privileges. Treat the provider list like a dependency manifest, and keep interview exercises and unknown repositories off machines that hold production cloud access.

Our cloud and Kubernetes security reviews cover how Terraform runs and where its providers come from, and security operations can hunt engineer workstations for these indicators. Open the chat and Yaali, our AI agent, will pass your question to an engineer.


Sources: Zscaler ThreatLabz, SentinelLabs, Cyber Press, CyberUpdates365, GBHackers, eSecurity Planet, Decrypt, Terraform dependency lock file, Terraform CLI provider installation.

Back to the blog, or read this post on the full site.