Threats
T1195Supply Chain Attack
How attackers compromise software updates, dependencies, and trusted vendor relationships to bypass perimeter defenses -- and how analysts detect supply chain intrusions.
View on Graph
What Supply Chain Attacks Are and Why They Are the Hardest To Detect
- A supply chain attack compromises an organization by attacking a trusted third party — a software vendor, open-source dependency, hardware manufacturer, or managed service provider — rather than attacking the target directly.
- MITRE ATT&CK maps this to
T1195(Supply Chain Compromise) with sub-techniques:T1195.001(Compromise Software Dependencies and Development Tools),T1195.002(Compromise Software Supply Chain), andT1195.003(Compromise Hardware Supply Chain). - The 2020 SolarWinds SUNBURST attack is the canonical example: Russian SVR threat actors injected malicious code into SolarWinds Orion platform updates.
- Over 18,000 organizations installed the trojanized update, and roughly 100 were targeted for follow-on exploitation including multiple U.S. federal agencies.
- Other major examples: the 2021 Codecov breach (attacker modified the Bash Uploader script, exfiltrating environment variables from CI/CD pipelines) and the 2023 3CX compromise (a double supply-chain attack where North Korean actors compromised a 3CX dependency, then used that access to trojanize the 3CX desktop app).
Detection Workflow — Supply Chain Compromise Triage
Step 1: Understand the Attack Surface
Supply chain compromise can enter through multiple vectors. The detection approach differs by vector:
| Vector | Entry Point | Detection Window |
|---|---|---|
| Software update hijack | Compromised update server or signing key | Days to months — the malicious update is distributed to all customers; lateral movement often follows |
| Open-source dependency poisoning | Malicious package published to npm, PyPI, RubyGems, Maven | Hours to weeks — detection often triggered by community disclosure |
| CI/CD pipeline compromise | Compromised build server credentials or actions | Hours to days — after the compromised build is deployed |
| Hardware/firmware backdoor | Modified components at manufacturing | Months to years — discovered through behavioral anomalies or physical inspection |
| Managed service provider breach | Attacker pivots from MSP tools to customer environments | Days to months — detection requires MSP log monitoring |
Step 2: Collect Critical Log Sources
| Question | Which Source to Check |
|---|---|
| Are any of our software vendors reporting a breach? | CISA alerts, vendor security notifications, US-CERT, threat intel feeds |
| Were any of our SaaS/cloud providers compromised? | Provider status pages, CISA advisories, industry threat intel |
| Did a software update introduce new network connections? | EDR connection monitoring, Sysmon Event ID 3 (network connect), firewall outbound logs |
| Did a software update modify system binaries or create new scheduled tasks? | Sysmon Event ID 11 (file create), Windows Event ID 4698 (scheduled task), file integrity monitoring |
| Are our CI/CD pipelines downloading dependencies from unusual sources? | Build server logs, package manager audit logs (npm audit, pip audit, trivy) |
| Has there been a spike in outbound traffic from application servers? | NetFlow, firewall logs, cloud VPC flow logs |
| Are code-signing certificates valid and from the expected publisher? | Authenticode signature verification, certificate transparency logs |
SPL query — detect new outbound connections from recently updated software:
index=windows sourcetype="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
| search Image IN ("*orion*", "*3cx*", "*agent*", "*update*")
| eval time_bucket = strftime(_time, "%Y-%m-%d")
| lookup software_update_timeline_lookup Image OUTPUT last_update_date
| where _time > last_update_date - 86400
| stats values(DestinationIp) as Destinations, values(DestinationPort) as Ports by Image, time_bucket
| where mvcount(Destinations) > 5
| eval alert = "HIGH — recently updated software making multiple outbound connections"
SPL query — detect dependencies resolved from unexpected package registries:
index=build sourcetype=ci_pipeline
| search stage="install" OR stage="dependencies"
| rex field=command "npm install (?<package>.*)"
| lookup npm_registry_lookup package OUTPUT expected_registry
| where registry != expected_registry
| stats values(registry) as ActualRegistry, values(package) as Package by build_id, repository
SPL query — detect CI/CD credential exfiltration (mass env dump):
index=ci sourcetype=vcs_audit_log
| search action="pushed" AND ref="codecov*" OR ref=".env*" OR ref="credentials*"
| eval tldr = "SUSPICIOUS — CI/CD credential exposure pattern"
| table _time, user, repository, ref, tldr
Step 3: Analyze Compromise Indicators
After a software update or dependency change, check these specific behavioral signals:
- New network connections to unusual destinations. SolarWinds Orion servers connected to
api.solarwinds[.]com(normal) but also to C2 domains registered shortly before the attack and hosted on different infrastructure. Any software making connections to infrastructure not associated with its vendor is suspicious. - Modified file timestamps. The malware inserted into SolarWinds Orion was compiled to match the timestamp of the legitimate build — zero anomaly on that dimension. But if the build environment is compromised, expect mismatched timestamps between the binary metadata and the CI pipeline log.
- Code-signing validity. SolarWinds Orion binaries were signed with the legitimate SolarWinds certificate, stolen from the build environment. A valid signature does not mean clean code. But an invalid signature on a software update is an immediate critical finding.
- Command-line anomalies in legitimate binaries. SUNBURST used
svchost.exe -kpatterns that were slightly different from normal. 3CX’s phone app made outbound network calls that looked like beaconing. - Unusual process parent-child relationships. A monitoring tool spawning
powershell.exethat then connects to the internet is abnormal — a potential insider threat or external compromise signal. A build tool accessing the Windows Registry or reading environment variables beyond its scope is suspicious.
PowerShell — verify code-signing certificates on suspect binaries:
Get-AuthenticodeSignature -FilePath "C:\Program Files\Vendor\update.exe" | Format-List
# Check: Status, SignerCertificate.Subject, SignerCertificate.NotAfter
# If Status is "NotSigned" or "HashMismatch" on an update binary — escalate
Step 4: Check for Second-Order Compromise
Supply chain attacks can cascade. A single compromised dependency can lead to multiple infected products:
- Check if your software vendor was listed as a supplier to other vendors you use
- Review the vulnerability disclosure: was the initial compromise in a transitive dependency?
- If your CI/CD pipeline downloaded a malicious package, check which builds consumed that package
- If a SaaS provider was compromised, check whether your tenant was accessed during the compromise window
Step 5: Determine Disposition
| Severity | Criteria | Action |
|---|---|---|
| Critical | Confirmed malicious update installed in production — beaconing C2 traffic detected | Isolate affected systems immediately. Preserve forensic images. Remove trojanized software. Reset all secrets on affected systems (including cloud credentials). Begin formal IR. Notify legal, compliance, and affected customers. |
| High | Vendor breach disclosed — malicious update distribution confirmed by vendor | Preventative isolation of affected systems pending investigation. Review network logs for C2 traffic. Check for outbound connections matching vendor-reported IOCs. |
| Medium | Dependency with known CVE installed — patch available but not deployed | Prioritize patching. Validate SBOM to find all affected dependencies. Verify CI/CD pipeline health. |
| Low | Dependency confusion risk identified — package name overlaps with internal package names | Verify internal registry configuration. Ensure scoped packages (@org/package) are used. Block public registry packages that match internal names. |
Preventative Controls
| Control | What It Prevents | Implementation |
|---|---|---|
| Software Bill of Materials (SBOM) | Provides visibility into all dependencies — without it you cannot know what you have | Generate SBOM in CI/CD (CycloneDX or SPDX format). Store in a centralized SBOM registry. |
| Dependency pinning and lock files | Prevents automatic upgrades to malicious package versions | package-lock.json, yarn.lock, requirements.txt with exact versions. Review lock file changes in PRs. |
| Package registry verification | Blocks typosquatted or dependency confusion packages | Configure npm to use scoped packages only. Use npm config set @org:registry. Block public packages matching internal names. |
| Code signing verification | Ensures binary integrity | Verify Authenticode signatures before deploying updates. Maintain a list of expected signing certificates. Alert on unexpected publishers. |
| CI/CD pipeline hardening | Prevents build environment compromise | Use immutable build agents. Scan CI/CD configuration for hardcoded secrets. Enable GitHub Actions audit logging. Limit write permissions on build scripts. |
| Signed commits | Ensures code integrity in repositories | Require GPG-signed commits. Validate commit signatures in CI/CD gate. |
| SLSA framework | Provides build integrity levels | Implement SLSA Level 3+ for critical build pipelines. Use provenance attestation. |
| Vendor security assessment | Evaluates third-party security posture before procurement | Vendor risk questionnaire. Review vendor SOC 2 Type II reports. Require breach notification SLA. |
Related
- Kill Chain — covers the kill chain concepts
- API Attacks — OWASP API Top 10 — detection and response for T1190 techniques
- Container and Kubernetes Threats — detection and response for T1611, T1525, T1574.002 techniques
- MITRE ATT&CK for Triage — covers the mitre att&ck for triage concepts
