TraderTraitor — FLATROOF / ROOFDECK macOS Backdoors via Weaponized Terraform Lock Files

DPRK Lazarus subgroup (aka UNC4899, PUKCHONG, Jade Sleet, Slow Pisces) · fake job-interview GitHub repositories deliver a weaponized .terraform.lock.hcl that pulls a malicious Terraform provider, dropping Rust-based macOS backdoors FLATROOF and ROOFDECK. ROOFDECK resolves its C2 via the decentralized Nostr protocol.
Threat
TraderTraitor / FLATROOF & ROOFDECK
Severity
ACTIVE · NATION-STATE
Type
Supply-chain / macOS backdoor / C2
Access
Falcon macOS sensor (ProcessRollup2, DnsRequest, NetworkConnectIP4)
Version
v0.1 (Draft) · 2026-09-21
Author
HuntPack
Confidence
High — vendor-attributed, 4-source corroborated
01

Executive Summary

TraderTraitor, the DPRK state-sponsored Lazarus subgroup also tracked as UNC4899, PUKCHONG, Jade Sleet, and Slow Pisces, continues its Contagious-Interview playbook of posing as recruiters and hiring managers on GitHub to get developers to run attacker-controlled code. The objective is not the developer's laptop for its own sake — it is what the laptop can reach: cloud credentials, source control, and CI/CD pipelines. SentinelOne's 2026-09-18 report shows the group has moved beyond direct cryptocurrency targets (the USD 292M KelpDAO/LayerZero theft in April 2026) to a small IT-services shop with no crypto exposure at all, confirming this is now a general-purpose developer-endpoint intrusion vector, not a crypto-only campaign.

The technique that matters most defensively is the weaponized .terraform.lock.hcl file: victims clone a fake "technical assessment" repository, run terraform init, and Terraform silently downloads and executes a malicious provider binary from an attacker-controlled registry (registry.hashicorp-aws[.]com and lookalikes). This is the earliest, highest-fidelity, and most preventable point in the entire chain — before either backdoor (FLATROOF or ROOFDECK) ever touches disk. Everything downstream (Gatekeeper bypass, LaunchAgent persistence, Telegram/Nostr C2, credential theft, cloud-key abuse) is harder to catch cleanly and easier for the attacker to vary between victims.

ROOFDECK's C2 resolution is architecturally novel: instead of a hardcoded C2 address, it queries public Nostr relays for an attacker-controlled profile and reads that profile's website field as its live C2 URL — a dead-drop resolver built entirely on decentralized, difficult-to-take-down infrastructure that a defender cannot simply sinkhole.

Defender priority: gate Terraform provider installation to approved registries (Query 1 / Playbook 1) before a single review or a single automated scan. Every other control in this pack is compensating; that one is preventive. Relationship to existing coverage: FLATROOF is also tracked as macOS.Gaslight, first analysed by SentinelLABS in June 2026 and already covered by the published macOS-Gaslight-Hunt.html pack. FLATROOF itself is therefore not new. What is new in this pack, and absent from that earlier one, is the second backdoor ROOFDECK, the weaponized .terraform.lock.hcl initial-access vector, and the Nostr dead-drop C2 resolution mechanism. The two packs share no hashes and no C2 infrastructure — this is a distinct September 2026 intrusion against a non-crypto IT-services victim. Run both: use the Gaslight pack for the June 2026 FLATROOF/BONZAI sample set and Telegram C2, and this one for the Terraform delivery chain, ROOFDECK, and the current infrastructure.
02

Source Review & Web Hunter Notes

TierSourceKey FindingCarry Forward
TIER 1 SentinelLABS — "Don't Call Us, We'll Call Your APIs" (2026-09-18) Primary technical report: full IOC set, infection timeline, FLATROOF/ROOFDECK internals, Nostr C2 mechanics, weaponized-repo list, TLS cert details. Authors: Albert Priego, Alex Delamotte, Matej Havranek. Yes — primary source for all sections
TIER 1 The Hacker News — "Jade Sleet Linked to Indian IT Provider Breach" (2026-09-21) Corroborates actor aliases, FLATROOF/ROOFDECK capability summary, infection timeline, and the Bybit/Safe{Wallet} 2025 history for the actor. Yes — corroboration + actor history
TIER 2 GBHackers — "Hackers Weaponize Terraform Lock Files" (2026-09-21) Corroborates 3 of 3 SHA1 hashes, 3 of 3 C2 domains, and the primary C2 IP; adds independent hardening guidance (registry allowlisting, LaunchAgent monitoring). Yes — IOC corroboration + hardening
TIER 2 CyberPress — "ROOFDECK Backdoor Uses Nostr Profiles" (2026-09-21) Independent confirmation of the Nostr dead-drop C2 mechanism and 2 of 3 SHA1 hashes. Partial — used for Nostr-mechanism confirmation only

Prompt-injection check: all four fetched sources were reviewed for embedded instructions directed at an automated reader. None were found — every match for imperative-sounding phrasing (e.g. "override") was legitimate technical prose describing the malware's own config-override behavior, not an attempt to redirect this pipeline. No content from any source was treated as an instruction.

Confidence assessment: Overall confidence is high — this is a vendor-named, three-researcher-credited report picked up by three outlets within 72 hours of publication. Those three outlets are derivative coverage of the same SentinelLABS analysis, not independent observation — so this campaign effectively rests on one first-party source, and no indicator in this pack clears the two-independent-source bar for a prevent action. Gaps: the ROOFDECK staging IP, two of three C2 IPs, the Nostr relay list, the TLS certificate details, and the exact on-disk binary/config paths appear in the SentinelOne report alone — those ship as hunt/enrich. Everything else ships as detect; nothing ships as prevent. Perishability: C2 IPs and domains for a publicly burned campaign are typically rotated within weeks of disclosure (this report published 2026-09-18); treat network IOCs as high-confidence for roughly 90 days from that date, not indefinitely.

03

Hunt Brief & Attack Chain

Hunt Hypotheses (ordered by fidelity)

  1. H1 (high): Developer endpoints resolve DNS for attacker-registered Terraform provider registries before any backdoor lands — the earliest network-visible step. Covered by Q1.
  2. H2 (high): FLATROOF/ROOFDECK execute from non-standard, fake Apple framework-support paths that no legitimate process uses. Covered by Q2 / Q5.
  3. H3 (high): Persistence is installed as a LaunchAgent whose spawned process masquerades as a Chrome renderer (--type=renderer) but is parented directly by launchd, which a real browser renderer never is. Covered by Q3.
  4. H4 (high): Confirmed C2 infrastructure (IPs/domains) receives outbound connections from developer endpoints. Covered by Q4.
  5. H5 (high): A new executable is written to one of the three fake Apple support paths before first execution. Covered by Q5.
  6. H6 (high/medium FP): Gatekeeper's quarantine attribute is programmatically stripped via xattr immediately ahead of execution. Covered by Q6.
  7. H7 (medium): A host process resolves public Nostr relay infrastructure — ROOFDECK's dead-drop C2 lookup mechanism. Covered by Q7.
  8. H8 (medium, investigate-only): terraform init executes inside a workspace whose naming matches the interview/candidate-assessment lure pattern. Covered by Q8.

Attack Chain

StepTelemetryHunt Angle
1. Social-engineering contact via fake recruiter/interviewer outreach (GitHub/LinkedIn)None (pre-endpoint)GitHub org & recruiting-pipeline awareness — no EDR angle
2. Candidate clones a weaponized "technical assessment" repo containing a poisoned .terraform.lock.hclProcess (git/IDE clone)Native hunt: lock-file provenance review (§7)
3. Candidate runs terraform initProcessRollup2Q8
4. Terraform resolves the custom provider registry (attacker domain)DnsRequestQ1
5. Malicious provider module downloaded and executedProcessRollup2 / NewExecutableWrittenQ2, Q5
6. FLATROOF strips Gatekeeper quarantine + chmod +x on ROOFDECKProcessRollup2Q6
7. Both implants launched via IDE integrated terminal with nohup … --type=rendererProcessRollup2Q2, Q3
8. LaunchAgent persistence installed (Chrome-renderer masquerade, RunAtLoad=true)ProcessRollup2 (subsequent launchd-spawned runs)Q3
9. FLATROOF beacons via Telegram; ROOFDECK resolves C2 via Nostr dead-drop, then beacons directDnsRequest / NetworkConnectIP4Q4, Q7
10. Recon, browser/keychain credential theft, system & process enumerationPartial — no dedicated browser-data-theft eventGAP — native hunt (§7) + EDR file-read telemetry where licensed
11. Lateral escalation into cloud environment (AWS/OVH/OpenStack) using stolen API keysOutside Falcon endpoint telemetryGAP — requires cloud-native audit logs (CloudTrail etc.); see Hardening §12
04

Consolidated IOC Table

TypeValueConfidenceActionContextExpiry
sha102df07a173ab03b82a4fb6a08973fff8b1467f28highdetectFLATROOF backdoor binary (SystemUpdate) — 3-source corroborated2027-03-21
sha1c491d477dbe0ae04e9aed9dbe237144c03f73ec4highdetectROOFDECK backdoor binary (iSync) — 3-source corroborated2027-03-21
sha15728b11d30586bbfc1d8bd12df1c722a06e767a2highdetectStripped ROOFDECK binary (loginwindow) — 2-source corroborated2027-03-21
domaintechnicais.sytes.nethighdetectFLATROOF C2 — 2-source corroborated2027-03-21
domainstorage.hubpage.cloudhighdetectROOFDECK C2 — 2-source corroborated2027-03-21
domaingrenight.comhighdetectROOFDECK stage-3 C2 — 2-source corroborated2027-03-21
ipv4176.97.114.232highdetectFLATROOF C2 IP for technicais.sytes.net — 2-source corroborated2027-03-21
ipv445.11.59.140mediumhuntROOFDECK C2 IP for storage.hubpage.cloud — single-sourced (SentinelOne only)2026-12-21
ipv485.137.56.245mediumhuntROOFDECK C2 IP for grenight.com — single-sourced2026-12-21
ipv485.137.56.10mediumhuntROOFDECK staging server — single-sourced2026-12-21
domainregistry.hashicorp-aws.comhighdetectWeaponized Terraform provider registry — 3-source corroborated2027-03-21
domainregistry.hashicorp-aws.iohighdetectWeaponized Terraform provider registry — 2-source corroborated2027-03-21
domainregistry.hashicorp-terraform.iohighdetectWeaponized Terraform provider registry — 2-source corroborated2027-03-21
filenameSystemUpdatemediumhuntFLATROOF binary at ~/Library/com.apple.iTunesCloud/SystemUpdate — single-sourced path2026-12-21
filenameiSyncmediumhuntROOFDECK binary at ~/Library/com.apple.internal.ck/iSync — single-sourced path2026-12-21
filenameloginwindowmediumhuntStripped ROOFDECK binary at ~/Library/com.apple.appleaccountd/loginwindow — single-sourced path2026-12-21
sha2564b2d3e8ccce8920a6d01e7d02b84236545a20e5f754b3eec253f8b416b731daalowenrichmkcert dev-CA TLS certificate used by ROOFDECK C2 — single-sourced2026-10-21
other1cd6d13ff15adbf7a42025d10ec99b4alowenrichSerial number of the above TLS certificate — single-sourced2026-10-21
domain (x9)see §10 Behavioral Signatures blockmediumpivotPublic Nostr relay set used for ROOFDECK C2 dead-drop lookup — legitimate shared infrastructure, do not block; hunt via Q72026-10-21
url (x6)see §10 Named Tooling blockmediumpivotWeaponized interview-lure GitHub repositories — single-sourced2026-12-21
behavioralLaunchAgent Chrome-renderer masqueradehighhunt~/Library/LaunchAgents/*.plist, Label prefix com., ProgramArguments contains --type=renderer, RunAtLoad=true2027-03-21
behavioralConfig/IPC/lock-file artifact setmediumhunt$HOME/.config/.repl_history, /private/tmp/.pipe-airway, $TMPDIR/tmp*.lock — single-sourced2026-12-21
05

Affected Surface & Telemetry Matrix

SurfaceTelemetryPriorityGap
macOS developer endpoints (Apple Silicon)ProcessRollup2, SyntheticProcessRollup2, DnsRequest, NetworkConnectIP4, NewExecutableWrittenCriticalNone — full Falcon macOS sensor coverage if Endpoint Security extension is enabled
GitHub organization / candidate-repository reviewNone (outside EDR)HighGAP — requires GitHub audit log + branch-protection controls, see Hardening §12
Terraform / IaC CI pipelineProcess/network telemetry only if the CI runner itself carries a Falcon sensorHighPartial — ephemeral CI runners are frequently unmonitored by EDR
Cloud control-plane (AWS / OVH / OpenStack) post-compromise API useCloudTrail / provider audit logs (outside Falcon scope)CriticalGAP — requires cloud-native logging; not covered by this pack's CQL
Browser & Keychain data (FLATROOF collection target)FileReadInfo (where licensed)MediumPartial — no dedicated "browser credential theft" event in the Falcon data model
06

ATT&CK Mapping

TacticTechnique IDTechnique NameObserved Behavior
ReconnaissanceT1593.003Search Open Websites/Domains: Code RepositoriesIdentifying GitHub profiles of DevOps/crypto-engineering job seekers to target
Resource DevelopmentT1583.001Acquire Infrastructure: DomainsRegistered typosquatted Terraform-registry and C2 domains
Resource DevelopmentT1608.001Stage Capabilities: Upload MalwareWeaponized .terraform.lock.hcl staged in fake interview repositories
Initial AccessT1195.001Supply Chain Compromise: Compromise Software Dependencies and Development ToolsMalicious Terraform provider delivered via poisoned lock file (Q1)
ExecutionT1204.002User Execution: Malicious FileCandidate runs terraform init against the lure repo (Q8)
ExecutionT1059.004Command and Scripting Interpreter: Unix Shellnohup-launched implants from the IDE integrated terminal
Defense EvasionT1553.001Subvert Trust Controls: Gatekeeper Bypassxattr -rd com.apple.quarantine + chmod +x (Q6)
Defense EvasionT1036.005Masquerading: Match Legitimate Name or LocationBinaries dropped under fake com.apple.* support paths (Q2, Q5)
Defense EvasionT1036.004Masquerading: Masquerade Task or Service--type=renderer flag to mimic a Chrome renderer process (Q3)
Defense EvasionT1027.005Obfuscated Files or Information: Indicator Removal from ToolsStage-3 loginwindow binary stripped of symbols/debug info — GAP, no EDR query
PersistenceT1543.001Create or Modify System Process: Launch Agent~/Library/LaunchAgents/*.plist, RunAtLoad=true (Q3)
Command and ControlT1071.001Application Layer Protocol: Web ProtocolsFLATROOF Telegram C2; ROOFDECK HTTPS /app_version tasking (Q4)
Command and ControlT1102.002Web Service: Bidirectional Communication (Dead Drop Resolver)ROOFDECK Nostr relay profile lookup for C2 URL (Q7)
Command and ControlT1573Encrypted ChannelCustom mkcert TLS certificate for C2 transport
Credential AccessT1555.001Credentials from Password Stores: Keychainlogin.keychain-db collection — GAP, no EDR query
DiscoveryT1217Browser Information DiscoveryChrome/Brave/Firefox/Safari profile enumeration — GAP
CollectionT1119Automated CollectionSystem hardware/software profile, running-process snapshot, Terminal history
Lateral Movement / ImpactT1078.004Valid Accounts: Cloud AccountsStolen AWS/OVH/OpenStack API keys used for cloud escalation — GAP, requires cloud-native logs
07

Native Audit-Log Hunts

These checks require no CQL and can be run directly on a suspect endpoint (via Falcon RTR) or against a repository / CI pipeline. They cover artifacts the CQL section either cannot reach (filesystem contents, repo diffs) or should be corroborated with before triage.

  1. ROOFDECK config file: ls -la "$HOME/.config/.repl_history" — inspect contents for Nostr public keys / relay URLs / C2 hints. This path has no legitimate shell-history purpose.
  2. ROOFDECK IPC pipe: ls -la /private/tmp/.pipe-airway — should not exist on a clean host; a named pipe here is a strong artifact.
  3. FLATROOF lock file: ls $TMPDIR/tmp*.lock — review any match for owning process and creation time correlated against Q2/Q5 hits.
  4. LaunchAgent renderer-masquerade sweep: for f in ~/Library/LaunchAgents/com.*.plist; do plutil -p "$f" 2>/dev/null | grep -q -- '--type=renderer' && echo "SUSPECT: $f"; done
  5. Gatekeeper/quarantine unified-log review: log show --predicate 'eventMessage contains "quarantine"' --last 30d — cross-reference removals against Q6 process hits.
  6. Fake Apple bundle-ID sweep: log show --predicate 'process contains "SystemUpdate" or process contains "iSync" or process contains "loginwindow"' --last 30d
  7. Terraform lock-file provenance review (pre-merge, in CI or local): grep -R "hashicorp-aws\|hashicorp-terraform" **/.terraform.lock.hcl — any hit outside registry.terraform.io is a blocker, not a warning.

None of these seven checks require a Falcon macOS sensor and all seven are safe to run against a suspected-clean host as a baseline before rolling detections to prevent mode.

08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.
Q1 · DNS to attacker-controlled Terraform provider registry
CONF HIGH FP LOW COST LOW

Looks for: A developer endpoint or CI runner resolving one of the three known weaponized Terraform provider-registry domains during a terraform init.

// HUNT: DNS resolution of attacker-controlled Terraform provider registries
// MITRE: T1195.001
// CONF: high  FP: low  COST: low
// REQUIRES: DnsRequest telemetry, any OS running Terraform
// FALSE POSITIVES: none expected -- these domains are not legitimate Terraform registries and have no benign use
// LOOKBACK: 30d
#event_simpleName=DnsRequest
| DomainName=/^registry\.hashicorp-aws\.(com|io)$/i or DomainName=/^registry\.hashicorp-terraform\.io$/i
| table([@timestamp, aid, ComputerName, UserName, DomainName, ContextProcessId_decimal])
Q2 · FLATROOF/ROOFDECK execution from fake Apple support paths
CONF HIGH FP LOW COST LOW

Looks for: SystemUpdate, iSync, or loginwindow executing from one of the three fabricated com.apple.* support directories.

// HUNT: Process execution from fake Apple framework-support directories (FLATROOF/ROOFDECK)
// MITRE: T1036.005, T1564.001
// CONF: high  FP: low  COST: low
// REQUIRES: ProcessRollup2, macOS
// FALSE POSITIVES: none expected -- these are not genuine Apple framework-support paths
// LOOKBACK: 30d
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| FileName=/^(SystemUpdate|iSync|loginwindow)$/i
| ImageFileName=*com.apple.iTunesCloud* or ImageFileName=*com.apple.internal.ck* or ImageFileName=*com.apple.appleaccountd*
| table([@timestamp, aid, ComputerName, UserName, ImageFileName, ParentBaseFileName, CommandLine, SHA256HashData])
Q3 · launchd-spawned Chrome-renderer masquerade
CONF HIGH FP LOW COST LOW

Looks for: A process carrying --type=renderer whose parent is launchd directly — real Chrome renderers are never launchd children.

// HUNT: launchd-spawned process masquerading as a Chrome renderer (LaunchAgent persistence trigger)
// MITRE: T1543.001, T1036.004
// CONF: high  FP: low  COST: low
// REQUIRES: ProcessRollup2, macOS
// FALSE POSITIVES: none expected -- legitimate browser renderer processes are spawned by the browser's own
// helper process, never directly by launchd
// LOOKBACK: 14d
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| ParentBaseFileName=/^launchd$/i
| CommandLine=*--type=renderer*
| table([@timestamp, aid, ComputerName, UserName, ImageFileName, FileName, CommandLine])
Q4 · Beacon to confirmed FLATROOF/ROOFDECK C2 infrastructure
CONF HIGH FP LOW COST LOW

Looks for: Outbound network/DNS activity to any of the seven confirmed C2 IPs/domains.

// HUNT: Network beacon to confirmed FLATROOF/ROOFDECK command-and-control infrastructure
// MITRE: T1071.001, T1105
// CONF: high  FP: low  COST: low
// REQUIRES: NetworkConnectIP4, DnsRequest, macOS
// FALSE POSITIVES: none expected -- attacker-registered infrastructure with no legitimate use
// NOTE: 45.11.59.140, 85.137.56.245 and 85.137.56.10 are single-sourced (SentinelOne only); treat hits on
// those three as high-confidence but corroborate with Q2/Q5/Q6 before declaring compromise
// LOOKBACK: 30d
#event_simpleName=/NetworkConnectIP4|DnsRequest/
| RemoteAddressIP4=/^(176\.97\.114\.232|45\.11\.59\.140|85\.137\.56\.245|85\.137\.56\.10)$/ or DomainName=/^(technicais\.sytes\.net|storage\.hubpage\.cloud|grenight\.com)$/i
| table([@timestamp, aid, ComputerName, UserName, RemoteAddressIP4, DomainName, RemotePort])
Q5 · Executable write to a fake Apple support path
CONF HIGH FP LOW COST LOW

Looks for: A new Mach-O executable staged at one of the three fabricated com.apple.* paths before first execution.

// HUNT: New executable written to a fake Apple framework-support path
// MITRE: T1036.005, T1105
// CONF: high  FP: low  COST: low
// REQUIRES: NewExecutableWritten, macOS
// NOTE: ⚠ validate in tenant -- confirm NewExecutableWritten coverage for Mach-O binaries on your sensor
// version; some tenants surface this only via ProcessRollup2 first-execution telemetry (see Q2)
// FALSE POSITIVES: none expected -- these are not legitimate Apple framework-support paths
// LOOKBACK: 30d
#event_simpleName=NewExecutableWritten
| TargetFileName=*com.apple.iTunesCloud* or TargetFileName=*com.apple.internal.ck* or TargetFileName=*com.apple.appleaccountd*
| table([@timestamp, aid, ComputerName, UserName, TargetFileName, SHA256HashData])
Q6 · Gatekeeper quarantine stripped via xattr
CONF HIGH FP MEDIUM COST LOW

Looks for: xattr removing com.apple.quarantine immediately ahead of executing an unsigned binary.

FP: developer tooling and package managers occasionally strip quarantine on unsigned local builds — see the in-query // TUNING: line.

// HUNT: Gatekeeper quarantine attribute stripped via xattr ahead of execution
// MITRE: T1553.001
// CONF: high  FP: medium  COST: low
// REQUIRES: ProcessRollup2, macOS
// FALSE POSITIVES: developer tooling and package managers occasionally strip quarantine on unsigned local builds
// TUNING: exclude ParentBaseFileName values for approved build/package tooling (e.g. brew, xcodebuild, your CI
// runner's helper process) once you have baselined 30 days of benign hits per Validation Gates (Section 11)
// LOOKBACK: 30d
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| FileName=/^xattr$/i
| CommandLine=*com.apple.quarantine*
| table([@timestamp, aid, ComputerName, UserName, ParentBaseFileName, ParentProcessId_decimal, CommandLine])
Q7 · Nostr relay resolution (ROOFDECK C2 dead-drop lookup)
CONF MEDIUM FP MEDIUM COST LOW

Looks for: A host process resolving one of the nine known public Nostr relay / discovery domains ROOFDECK uses to locate its operator's C2 profile.

FP: legitimate Nostr client software exists and this traffic alone does not indicate compromise — see the in-query // TUNING: line.

// HUNT: Outbound resolution of public Nostr relay infrastructure (ROOFDECK C2 dead-drop lookup)
// MITRE: T1102.002, T1568
// CONF: medium  FP: medium  COST: low
// REQUIRES: DnsRequest
// FALSE POSITIVES: legitimate Nostr desktop/web clients and crypto-curious end users running their own Nostr apps
// TUNING: exclude ParentBaseFileName values for approved/known Nostr client applications in your environment;
// treat a hit as a pivot into Q2/Q4/Q6 on the same aid, not as a standalone alert
// LOOKBACK: 14d
#event_simpleName=DnsRequest
| DomainName=/^(relay\.damus\.io|nos\.lol|nostr\.mom|relay\.snort\.social|offchain\.pub|relay\.nostr\.band|nostr\.oxtr\.dev|nostr\.wine|api\.nostr\.watch)$/i
| table([@timestamp, aid, ComputerName, UserName, DomainName, ContextProcessId_decimal])
Q8 · terraform init in a candidate/interview-styled workspace
CONF MEDIUM FP MEDIUM COST LOW

Looks for: Broad pivot query for terraform init executions; intended to be triaged jointly with Q1, not alerted on alone.

FP: this fires on ordinary DevOps work — see the in-query // TUNING: line.

// HUNT: terraform init executed against a candidate/interview-styled workspace
// MITRE: T1195.001, T1204.002
// CONF: medium  FP: medium  COST: low
// REQUIRES: ProcessRollup2
// FALSE POSITIVES: legitimate DevOps engineers routinely run terraform init; on its own this is a broad pivot,
// not an alert
// TUNING: correlate with Q1 (malicious registry DNS) on the same aid within the same session before triage;
// scope ImageFileName to known interview/candidate/assessment directory naming in your environment
// LOOKBACK: 14d
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| FileName=/^terraform$/i
| CommandLine=*init*
| table([@timestamp, aid, ComputerName, UserName, ImageFileName, ParentBaseFileName, CommandLine])
09

CrowdStrike Custom IOA Recommendations

Custom IOA Candidates

Queries Q1, Q2, Q3, Q4, Q5, and Q6 are high-confidence, low-to-medium-FP behaviors with no legitimate business use on a compromised host and are recommended for promotion to Falcon Custom IOA rules once the Validation Gates in Section 11 are satisfied. Q7 and Q8 remain investigate-only (medium confidence, broader legitimate-use surface).

IOA NamePatternExclusionsDeployment Path
Fake-Apple-Path ExecutionProcessRollup2 where FileName in {SystemUpdate, iSync, loginwindow} AND ImageFileName under a fabricated com.apple.* support directory (Q2)None identified Build as Custom IOA in Monitor mode for 14 days, then Detect, then Prevent per Section 11
Renderer-Masquerade PersistenceProcessRollup2 where ParentBaseFileName=launchd AND CommandLine contains --type=renderer (Q3)None identified — real browser renderers are never launchd childrenCustom IOA, Monitor → Prevent
Quarantine-Strip-Then-Exec Chainxattr removing com.apple.quarantine (Q6) followed within a short window by execution of the same TargetFileNameApproved build/package tooling (brew, xcodebuild, CI runner helper) — see Q6 // TUNING:Custom IOA, Monitor → Detect (hold at Detect given medium FP until baseline is clean)
Confirmed C2 BeaconNetworkConnectIP4/DnsRequest to any of the 7 confirmed FLATROOF/ROOFDECK indicators (Q4)None identifiedCustom IOC (not IOA) — import via the Falcon IOC Management CSV in Section 10, action per the two-source-corroboration policy in Section 4

Alert & Triage Quick-Reference

Shared triage checklist for any Q1–Q6 hit (alert subject pattern: [CRITICAL] Detection: TraderTraitor -- <behavior> for Q1/Q2/Q3/Q4/Q5, [HIGH] for Q6):

  1. Confirm the endpoint is macOS and record aid / ComputerName / UserName from the hit.
  2. Pull the live process tree via Falcon RTR (ps aux, launchctl list) for the flagged PID/plist entry.
  3. Run Q2, Q5, and Q6 scoped to the same aid to establish full compromise scope (see Pivot A below).
  4. Hash any binary found at the three fake Apple support paths and compare against the Section 4 IOC table.
  5. Enumerate ~/Library/LaunchAgents/*.plist for --type=renderer masquerade entries — preserve, do not delete, for forensics.
  6. If confirmed, network-contain the host via Falcon RTR and proceed to the Containment Runbook (Section 14).
  7. Rotate any AWS/OVH/OpenStack/GitHub credentials reachable from the endpoint.
  8. Escalate to IR lead with the Hunt Summary Ticket (Section 16) populated.

Pivot Queries

Pivot A — host-scoped timeline

// PIVOT (host-scoped): full process/network/DNS timeline for one endpoint after a Q1-Q8 hit
// MITRE: n/a -- investigation pivot
// CONF: n/a  FP: n/a  COST: medium
// REQUIRES: ProcessRollup2, DnsRequest, NetworkConnectIP4
// LOOKBACK: 30d -- narrow to the incident window once the timeline is confirmed
// NOTE: replace REPLACE_WITH_AID with the aid value from the triggering hit before running
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2|DnsRequest|NetworkConnectIP4/
| aid=REPLACE_WITH_AID
| table([@timestamp, #event_simpleName, ImageFileName, ParentBaseFileName, CommandLine, DomainName, RemoteAddressIP4])
| sort(@timestamp, order=asc)

Pivot B — environment-wide blast radius

// PIVOT (environment-wide): blast-radius count across all Q1/Q2/Q4/Q6 indicators, grouped by host
// MITRE: n/a -- investigation pivot
// CONF: n/a  FP: n/a  COST: medium
// REQUIRES: ProcessRollup2, DnsRequest, NetworkConnectIP4
// LOOKBACK: 30d
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2|DnsRequest|NetworkConnectIP4/
| (FileName=/^(SystemUpdate|iSync|loginwindow|xattr)$/i) or (RemoteAddressIP4=/^(176\.97\.114\.232|45\.11\.59\.140|85\.137\.56\.245|85\.137\.56\.10)$/) or (DomainName=/^(registry\.hashicorp-aws\.(com|io)|registry\.hashicorp-terraform\.io|technicais\.sytes\.net|storage\.hubpage\.cloud|grenight\.com)$/i)
| groupBy([ComputerName, aid], function=count(as=Hits), limit=1000)
| sort(Hits, order=desc, limit=200)
10

Machine-Readable IOC Appendix

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
sha1,02df07a173ab03b82a4fb6a08973fff8b1467f28,detect,critical,2027-03-21,FLATROOF backdoor binary (SystemUpdate) -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
sha1,c491d477dbe0ae04e9aed9dbe237144c03f73ec4,detect,critical,2027-03-21,ROOFDECK backdoor binary (iSync) -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
sha1,5728b11d30586bbfc1d8bd12df1c722a06e767a2,detect,critical,2027-03-21,Stripped ROOFDECK binary (loginwindow) -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
domain,technicais.sytes.net,detect,critical,2027-03-21,FLATROOF C2 domain -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
domain,storage.hubpage.cloud,detect,critical,2027-03-21,ROOFDECK C2 domain -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
domain,grenight.com,detect,critical,2027-03-21,ROOFDECK stage-3 C2 domain -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
ipv4,176.97.114.232,detect,critical,2027-03-21,FLATROOF C2 IP for technicais.sytes.net -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
domain,registry.hashicorp-aws.com,detect,critical,2027-03-21,Weaponized Terraform provider registry -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
domain,registry.hashicorp-aws.io,detect,critical,2027-03-21,Weaponized Terraform provider registry -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
domain,registry.hashicorp-terraform.io,detect,critical,2027-03-21,Weaponized Terraform provider registry -- SentinelLABS primary + derivative coverage,campaign:TraderTraitor
ipv4,45.11.59.140,detect,high,2026-12-21,ROOFDECK C2 IP -- single-sourced (SentinelOne only) -- see two-source policy in Section 4,campaign:TraderTraitor
ipv4,85.137.56.245,detect,high,2026-12-21,ROOFDECK C2 IP -- single-sourced -- see two-source policy in Section 4,campaign:TraderTraitor
ipv4,85.137.56.10,detect,high,2026-12-21,ROOFDECK staging server -- single-sourced -- see two-source policy in Section 4,campaign:TraderTraitor

Hash type is sha1 (only SHA1 values were published for these binaries) -- confirm your tenant's IOC Management accepts sha1 before bulk import, or pivot to Q2/Q5 for hash-agnostic behavioral coverage.

Every row ships at detect, never prevent, and this CSV matches §4 exactly. All four cited sources trace back to the single SentinelLABS report of 2026-09-18: The Hacker News, GBHackers and CyberPress are derivative coverage of that same analysis, not independent observation. "Corroborated" in §4 therefore means "the value is reproduced consistently across outlets", which is a transcription check, not independent confirmation. This pack's bar for a prevent-tier action is two genuinely independent sources, so nothing here meets it. Promote to prevent only after your own tenant telemetry or a second first-party report confirms the indicator.

Behavioral Signatureshunt reference
# FLATROOF / ROOFDECK behavioral signatures (macOS, ARM64, Rust)
Gatekeeper bypass chain : xattr -rd com.apple.quarantine <path> && chmod +x <path>
Renderer masquerade     : launchd-spawned process, CommandLine contains --type=renderer, ParentBaseFileName=launchd
Fake Apple support paths: ~/Library/com.apple.iTunesCloud/SystemUpdate
                          ~/Library/com.apple.internal.ck/iSync
                          ~/Library/com.apple.appleaccountd/loginwindow
LaunchAgent persistence : ~/Library/LaunchAgents/*.plist  (Label prefix "com.", ProgramArguments contains
                          --type=renderer, RunAtLoad=true)
ROOFDECK config file    : $HOME/.config/.repl_history
ROOFDECK IPC pipe       : /private/tmp/.pipe-airway
FLATROOF lock file      : $TMPDIR/tmp*.lock
Example lure workspace  : ~/DevOps-Automation/cloudshield  (name varies per victim -- illustrative, not durable)

Nostr relay set used for ROOFDECK C2 dead-drop lookup (do NOT block outright -- legitimate shared public
infrastructure; hunt via Q7 for anomalous ParentBaseFileName instead):
  relay.damus.io, nos.lol, nostr.mom, relay.snort.social, offchain.pub,
  relay.nostr.band, nostr.oxtr.dev, nostr.wine, api.nostr.watch
Named Malware / Toolingcontext
Malware family    : FLATROOF (aka macOS.Gaslight) -- Rust, ARM64 macOS backdoor, Telegram C2
Malware family    : ROOFDECK -- Rust, ARM64 macOS backdoor, Nostr decentralized C2 resolution
Actor             : TraderTraitor (DPRK Lazarus subgroup) aka UNC4899, PUKCHONG, Jade Sleet, Slow Pisces

Lure repositories (single-sourced -- pivot/investigation use only, not blocklist material):
  github.com/exubient0/terraform-candidate-repo
  github.com/radupopa369/gtn-candidate-repo
  github.com/chainstacker/Northwind-IAC
  github.com/RyanLRay/Technical-Assessments
  github.com/Steed-LHV/assessment
  github.com/derrix060/novacart_interview

Code-signing certificate (single-sourced, enrich only):
  mkcert development CA, serial 1cd6d13ff15adbf7a42025d10ec99b4a
  cert SHA-256 4b2d3e8ccce8920a6d01e7d02b84236545a20e5f754b3eec253f8b416b731daa
Endpoint / Repo Audit Checklistmanual verification
# Developer-endpoint / repo audit checklist
[ ] terraform -version && terraform providers            -- confirm no custom registry mirrors outside registry.terraform.io
[ ] grep -R "hashicorp-aws\|hashicorp-terraform" **/.terraform.lock.hcl   -- flag any hit
[ ] spctl --status                                        -- Gatekeeper must report "assessments enabled"
[ ] ls -la ~/Library/LaunchAgents/ | grep -i com.         -- review for --type=renderer masquerade entries
[ ] falconctl stats                                       -- confirm macOS sensor + Endpoint Security extension active
[ ] aws iam generate-credential-report                    -- rotate long-lived static keys on developer/candidate-facing accounts
[ ] gh api repos/:owner/:repo/branches/:branch/protection -- confirm required review on .terraform.lock.hcl changes
11

Detection Validation Gates

GateRequirementStatus
Telemetry readyFalcon macOS sensor deployed with Endpoint Security extension and Full Disk Access approved via MDM on the DevOps/engineering cohortVerify before deploy
Benign baselineRun Q1, Q6, and Q7 in Monitor/Investigate mode for 30 days against the DevOps fleet to characterize legitimate Terraform, package-manager, and Nostr-client usageRequired before Prevent
Positive testsValidate Q2/Q3/Q5 field logic against a non-malicious harness that writes to and executes from a decoy com.apple.test/ path with a --type=renderer flag — do not detonate real FLATROOF/ROOFDECK samplesRequired before Prevent
Promotion criteriaZero false positives across the 30-day baseline before flipping Q1, Q2, Q3, Q4, or Q5 from Custom IOA Monitor to Prevent; Q6 holds at Detect given medium FP; Q7/Q8 remain investigate-only Gate before Prevent

These four gates fold forward into the Detection Coverage Map (Section 15).

12

Hardening — Tiered

Immediate

Terraform provider allowlisting. Pin required_providers source + checksum in every repo; block any provider source outside registry.terraform.io or your internal mirror. MITRE M1038 (Execution Prevention). No formal CIS benchmark covers Terraform specifically; HashiCorp's own provider-installation documentation is the authoritative source — flagged ⚠ best-practice, no formal benchmark. Verify: grep -R "source" **/.terraform.lock.hcl | grep -v registry.terraform.io returns nothing.

Enforce Gatekeeper on all developer macOS endpoints. MITRE M1038; verify via spctl --status (must report "assessments enabled") and MDM configuration profile locking SystemPolicy settings so a local admin cannot disable it.

GitHub branch protection on assessment/candidate repositories. Require signed commits and mandatory review for any change to .terraform.lock.hcl or providers.tf. MITRE M1047 (Audit); verify via gh api repos/:owner/:repo/branches/:branch/protection.

Near term (1–4 weeks)

Fleet-wide Falcon macOS sensor with Endpoint Security extension for the DevOps/engineering cohort specifically (this and the prior LayerZero/KelpDAO victim were both targeted via a single DevOps engineer's laptop). MITRE M1047; verify via falconctl stats.

Short-lived cloud credentials. Replace static AWS/OVH/OpenStack keys on developer endpoints with STS AssumeRole sessions requiring MFA and capped session duration. MITRE M1026 (Privileged Account Management); verify via aws iam generate-credential-report — zero long-lived keys on developer-tagged principals.

Egress filtering for decentralized dead-drop protocols. Block or alert on outbound to the public Nostr relay set (Section 10) from developer endpoints unless a documented business need exists. MITRE M1037 (Filter Network Traffic); verify via firewall/EDR network-rule audit.

Strategic (1–3 months)

Sandboxed "clean room" for take-home / technical-assessment code. Ephemeral VM or container with no mounted cloud credentials and no access to production source control for any code received from an unverified recruiter or interviewer. MITRE M1048 (Application Isolation and Sandboxing).

IaC supply-chain scanning in CI. Gate merges on tfsec/checkov (or equivalent) provider-source review before any Terraform plan/apply runs. MITRE M1051 (Update Software) / M1038.

DPRK Contagious-Interview awareness training for the engineering hiring pipeline, tied to CISA/FBI joint advisories on fake recruiter/interview lures. MITRE M1017 (User Training).

13

Deployable Playbooks

Playbook 1 — Terraform provider registry allowlist

# Playbook 1 -- Terraform provider registry allowlist (local + CI)
# Prerequisites: Terraform >=1.7 CLI; write access to the repo's versions.tf / .terraformrc
# Reboot required: no
# Rollback: remove the provider_installation block from .terraformrc / CLI config; re-run `terraform init` to
#           restore default registry resolution (no state is modified by this control)

cat >> ~/.terraformrc <<'EOF'
provider_installation {
  network_mirror {
    url = "https://registry.terraform.io/"
    include = ["*/*"]
  }
  direct {
    exclude = ["registry.hashicorp-aws.com/*", "registry.hashicorp-aws.io/*", "registry.hashicorp-terraform.io/*"]
  }
}
EOF

# CI gate (example, add to your pipeline before `terraform init`):
grep -R "registry.hashicorp-aws\|registry.hashicorp-terraform" **/.terraform.lock.hcl && exit 1 || true

Playbook 2 — Enforce Gatekeeper via MDM

# Playbook 2 -- Enforce Gatekeeper via MDM configuration profile (macOS)
# Prerequisites: MDM enrollment (Jamf/Kandji/Mosyle/etc.) with custom payload push capability
# Reboot required: no (profile applies on install; a logout is recommended but not required)
# Rollback: remove the configuration profile via MDM; spctl --master-enable restores interactive Gatekeeper
#           control to the local admin if the profile is withdrawn

# Verify current state before pushing the profile:
spctl --status
# expected: "assessments enabled"

# MDM custom payload (com.apple.systempolicy.control), key fields:
#   AllowIdentifiedDevelopers : false
#   EnableAssessment          : true
# Push via your MDM's custom payload / profile mechanism -- syntax is MDM-vendor specific.

# Post-deploy verification on the endpoint:
spctl --status && echo "Gatekeeper: OK" || echo "Gatekeeper: NEEDS REMEDIATION"

Playbook 3 — GitHub branch protection for lock-file changes

# Playbook 3 -- GitHub branch protection for Terraform lock-file changes
# Prerequisites: gh CLI authenticated with repo admin scope
# Reboot required: no
# Rollback: gh api -X DELETE repos/:owner/:repo/branches/:branch/protection

gh api -X PUT repos/:owner/:repo/branches/main/protection \
  -F required_pull_request_reviews.required_approving_review_count=1 \
  -F required_status_checks.strict=true \
  -F enforce_admins=true \
  -F required_linear_history=true

# Confirm:
gh api repos/:owner/:repo/branches/main/protection

Playbook 4 — Rotate static cloud credentials

# Playbook 4 -- Rotate static cloud credentials for a compromised/at-risk developer principal
# Prerequisites: IAM admin access; inventory of the affected principal's access keys
# Reboot required: no
# Rollback: none required -- credential rotation is one-directional by design; if the NEW key breaks an
#           automation, issue a fresh key rather than reinstating the rotated-out one

aws iam list-access-keys --user-name REPLACE_WITH_USERNAME
aws iam update-access-key --access-key-id REPLACE_WITH_KEY_ID --status Inactive --user-name REPLACE_WITH_USERNAME
aws iam create-access-key --user-name REPLACE_WITH_USERNAME
# Validate the new key works, then after a burn-in window:
aws iam delete-access-key --access-key-id REPLACE_WITH_KEY_ID --user-name REPLACE_WITH_USERNAME
14

Containment Runbook

PhaseActionsOwnerEvidence
Isolate Falcon RTR network-contain the endpoint; disable/rotate any GitHub session tokens the account holds; revoke AWS/OVH/OpenStack credentials reachable from the host IR / SOC on-callRTR containment ticket, IAM revocation log
Eradicate Kill and remove SystemUpdate/iSync/loginwindow from the three fake Apple paths; remove the masquerading LaunchAgent plist; delete .repl_history, .pipe-airway, and $TMPDIR/tmp*.lock artifacts; re-image if persistence depth or scope is uncertain Endpoint engineeringRTR command output, before/after file listing
Recover Rotate every credential/API key/SSH key resident on or reachable from the host; force re-authentication of all cloud sessions; audit CI/CD pipeline runs triggered from the host for unauthorized changes; validate a clean baseline before returning the endpoint to service Cloud/Platform team + IRCredential-rotation log, CI audit report, clean-scan attestation
15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1195.001Weaponized Terraform lock file / malicious provider registryQ1, Q8N (IOC-based)Good
T1204.002User executes terraform init in a lure workspaceQ8N (investigate-only)Partial
T1036.005Backdoor masquerades under fake Apple support pathQ2, Q5Y (candidate)Good
T1036.004Renderer-flag masquerade on a launchd-spawned processQ3Y (candidate)Good
T1553.001Gatekeeper quarantine attribute stripped via xattrQ6Y (candidate, holds at Detect)Good
T1543.001LaunchAgent persistenceQ3Y (candidate)Good
T1071.001 / T1105C2 beacon to confirmed FLATROOF/ROOFDECK infrastructureQ4N (IOC-based)Good
T1102.002Nostr relay dead-drop C2 resolutionQ7N (investigate-only)Partial
T1027.005Symbol/debug stripping on the stage-3 loginwindow binary——GAP — not observable via process/network telemetry
T1555.001Keychain credential theft (login.keychain-db)——GAP — no dedicated Falcon event for keychain-file access
T1217 / T1119Browser data & system-profile collection——GAP — no dedicated browser-data-theft event in the Falcon model
T1078.004Stolen cloud API keys used for lateral escalation——GAP — requires cloud-native audit logs (CloudTrail/OVH/OpenStack), outside this pack's CQL scope

Validation gates (Section 11) apply to every row marked as an IOA candidate above: none of them move to Prevent until the 30-day benign baseline and positive-test gates are satisfied.

16

Hunt Summary Ticket

TITLE:      TraderTraitor -- FLATROOF/ROOFDECK macOS backdoors via weaponized Terraform lock files
SEVERITY:   CRITICAL (nation-state, active as of 2026-09-18 disclosure)
SCOPE:      macOS developer endpoints (Apple Silicon) running Terraform against fake job-interview repos
HYPOTHESIS: A developer cloned a fake technical-assessment repo, ran `terraform init` against a weaponized
            .terraform.lock.hcl, and the resulting malicious provider dropped FLATROOF and/or ROOFDECK with
            LaunchAgent persistence and Telegram/Nostr C2.
QUERIES:    Q1-Q8 (Section 8); Custom IOA candidates Q1-Q6 (Section 9)
DO FIRST:   Run Q1 (malicious registry DNS) and Q4 (confirmed C2 beacon) across the full macOS fleet --
            these are the two lowest-noise, IOC-grounded starting points.
FINDINGS:   REPLACE_WITH_HUNT_FINDINGS
GAPS:       Keychain/browser credential theft, binary stripping, and cloud-key lateral movement have no
            Falcon-native query coverage (Section 15) -- corroborate via native audit hunts (Section 7) and
            cloud-native logs.
ACTIONS:    See Containment Runbook (Section 14) and Hardening Playbooks 1-4 (Section 13).
OWNER:      REPLACE_WITH_OWNER
VERSION:    v0.1 -- 2026-09-21
17

Changelog

v0.12026-09-21 Initial pack: 8 hunt queries (Q1-Q8) + 2 pivot queries, 6 Custom IOA/IOC recommendations, hardening (Immediate/Near-term/Strategic) with 4 deployable playbooks, containment runbook, and full IOC provenance across 4 corroborating sources.
18

References

TierSourceUsed ForAccess Date
1SentinelLABS -- "Don't Call Us, We'll Call Your APIs" (Priego, Delamotte, Havranek; 2026-09-18)Primary technical report, full IOC set, execution chain, Nostr mechanics2026-09-21
1The Hacker News -- "Jade Sleet Linked to Indian IT Provider Breach" (2026-09-21)Actor-alias and capability corroboration2026-09-21
2GBHackers -- "Hackers Weaponize Terraform Lock Files" (2026-09-21)IOC corroboration (3 hashes, 3 domains, 1 IP) + hardening guidance2026-09-21
2CyberPress -- "ROOFDECK Backdoor Uses Nostr Profiles" (2026-09-21)Independent Nostr-mechanism confirmation2026-09-21
RefMITRE ATT&CKTechnique IDs (Section 6)2026-09-21

Generated 2026-09-21 · HuntPack v0.1 · TraderTraitor / FLATROOF & ROOFDECK