Threats

T1195

Supply 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), and T1195.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:

VectorEntry PointDetection Window
Software update hijackCompromised update server or signing keyDays to months — the malicious update is distributed to all customers; lateral movement often follows
Open-source dependency poisoningMalicious package published to npm, PyPI, RubyGems, MavenHours to weeks — detection often triggered by community disclosure
CI/CD pipeline compromiseCompromised build server credentials or actionsHours to days — after the compromised build is deployed
Hardware/firmware backdoorModified components at manufacturingMonths to years — discovered through behavioral anomalies or physical inspection
Managed service provider breachAttacker pivots from MSP tools to customer environmentsDays to months — detection requires MSP log monitoring

Step 2: Collect Critical Log Sources

QuestionWhich 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 -k patterns 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.exe that 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

SeverityCriteriaAction
CriticalConfirmed malicious update installed in production — beaconing C2 traffic detectedIsolate 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.
HighVendor breach disclosed — malicious update distribution confirmed by vendorPreventative isolation of affected systems pending investigation. Review network logs for C2 traffic. Check for outbound connections matching vendor-reported IOCs.
MediumDependency with known CVE installed — patch available but not deployedPrioritize patching. Validate SBOM to find all affected dependencies. Verify CI/CD pipeline health.
LowDependency confusion risk identified — package name overlaps with internal package namesVerify internal registry configuration. Ensure scoped packages (@org/package) are used. Block public registry packages that match internal names.

Preventative Controls

ControlWhat It PreventsImplementation
Software Bill of Materials (SBOM)Provides visibility into all dependencies — without it you cannot know what you haveGenerate SBOM in CI/CD (CycloneDX or SPDX format). Store in a centralized SBOM registry.
Dependency pinning and lock filesPrevents automatic upgrades to malicious package versionspackage-lock.json, yarn.lock, requirements.txt with exact versions. Review lock file changes in PRs.
Package registry verificationBlocks typosquatted or dependency confusion packagesConfigure npm to use scoped packages only. Use npm config set @org:registry. Block public packages matching internal names.
Code signing verificationEnsures binary integrityVerify Authenticode signatures before deploying updates. Maintain a list of expected signing certificates. Alert on unexpected publishers.
CI/CD pipeline hardeningPrevents build environment compromiseUse immutable build agents. Scan CI/CD configuration for hardcoded secrets. Enable GitHub Actions audit logging. Limit write permissions on build scripts.
Signed commitsEnsures code integrity in repositoriesRequire GPG-signed commits. Validate commit signatures in CI/CD gate.
SLSA frameworkProvides build integrity levelsImplement SLSA Level 3+ for critical build pipelines. Use provenance attestation.
Vendor security assessmentEvaluates third-party security posture before procurementVendor risk questionnaire. Review vendor SOC 2 Type II reports. Require breach notification SLA.

Sources