Supply Chain Security

What is a supply-chain attack?

HuntRule Team · · 11 min read

A single carton on a packing line being resealed by gloved hands, hundreds of identical sealed cartons receding into darkness behind it
On this page

SolarWinds.Orion.Core.BusinessLayer.dll carried a valid SolarWinds Authenticode signature. It also carried SUNBURST.

A supply-chain attack is an intrusion where the attacker does not compromise the target. They compromise something the target already installs, already trusts, and already lets run with high privilege. The malicious code then arrives through the front door, on schedule, signed by the vendor whose certificate the defender allowlisted.

The arithmetic

Phishing a thousand organisations means a thousand lures, a thousand chances for one recipient to report it, and a thousand separate footholds. Compromising one build server means one intrusion and one implant, and the vendor's release pipeline does the distribution.

SolarWinds signed trojanized Orion updates between March and May 2020 and posted them to its own download host, including SolarWinds-Core-v2019.4.5220-Hotfix5.msp. SolarWinds later told the SEC that fewer than 18,000 customers may have had an installation of an affected build, which is a weaker claim than the installed-count figure usually quoted from it. Mandiant tracked the intrusion as UNC2452, now publicly attributed to Russia's SVR.

The four supplier classes below are not variations on one theme. They fail differently and need different telemetry.

Software vendors and their build systems

The attacker gets into the vendor's build environment and modifies the artifact before it is signed. Signing is not bypassed. It is used.

The trojanized SUNBURST DLL was loaded by the legitimate SolarWinds.BusinessLayerHost.exe. It slept for up to two weeks, then resolved a subdomain of avsvmcloud[.]com generated by a DGA that encoded the victim's machine domain name, using hostnames of the form <encoded>.appsync-api.us-east-1.avsvmcloud[.]com. Its C2 traffic imitated the Orion Improvement Program protocol and it stored reconnaissance results in legitimate plugin configuration files. Mandiant's report describes it as blending in with legitimate SolarWinds activity, which is the point.

Defender visibility: a signed hotfix from the vendor's own domain, installed by the change process, followed by DNS lookups from the monitoring server to a domain that looks like a CDN.

3CX in March 2023 is the same class with a twist. 3CX DesktopApp 18.12.416 and earlier shipped a downloader Mandiant named SUDDENICON, which pulled its real C2 address out of encrypted icon files hosted on GitHub, then fetched ICONICSTEALER. Mandiant attributed it to UNC4736, a suspected North Korean cluster with links to AppleJeus. The initial vector into 3CX was itself a supply-chain compromise: a trojanized X_TRADER_r7.17.90p608.exe installer signed by Trading Technologies International, which deployed the VEILEDSIGNAL backdoor.

Defender visibility: a signed desktop app talking to raw.githubusercontent.com. Very few organisations block that.

Open-source dependencies

No build server needed. The attacker becomes a maintainer.

XZ Utils 5.6.0 and 5.6.1 shipped a backdoor tracked as CVE-2024-3094. The build hook lived only in the release tarballs, not in readable form in the git tree, and it checked its environment before injecting anything: x86-64, linux-gnu, gcc as the compiler, GNU ld as the linker, and a Debian or RPM package build in progress. Andres Freund's disclosure notes that last condition was likely aimed at making the issue harder to reproduce for investigators. Once liblzma was loaded into an sshd built with systemd support, the backdoor installed an audit hook into the dynamic linker and redirected RSA_public_decrypt in the PLT into its own code.

Freund found it because ssh logins on Debian sid were burning noticeably more CPU than they should and valgrind was complaining. That is the entire detection story. No signature, no beacon, no child process. A performance regression.

The lower-effort version is social. In 2018 the npm package event-stream gained a dependency on flatmap-stream after the original maintainer handed publish rights to a volunteer who asked for them. The payload activated only inside the Copay bitcoin wallet build.

Defender visibility: for XZ, effectively none in production. For a typical npm or PyPI compromise, the postinstall script runs on a developer laptop or a CI runner, which is often the least instrumented host in the estate.

Managed service providers

Here the attacker inherits privilege rather than planting code. An MSP or RMM vendor already holds SYSTEM-level agents inside every customer network. Compromise the console and you are inside all of them. PwC and BAE Systems documented APT10 reaching customer environments this way in 2017, as Operation Cloud Hopper.

Kaseya on 2 July 2021 is the cleanest example. A REvil affiliate pushed a malicious update package from on-premises VSA servers to VSA agents. The agent monitor at C:\PROGRAM FILES (X86)\KASEYA\<ID>\AGENTMON.EXE wrote a base64-encoded payload to the agent working directory, by default C:\KWORKING\, then ran a shell command chain. Sophos analysed the sequence.

# from SophosLabs' analysis of the July 2021 REvil payload, abridged
C:\Windows\cert.exe -decode c:\kworking\agent.crt c:\kworking\agent.exe
del /q /f c:\kworking\agent.crt C:\Windows\cert.exe
c:\kworking\agent.exe

cert.exe is a copy of certutil.exe with a random five-digit number appended, which changes its hash and defeats signature-based certutil detections. agent.exe was Authenticode-signed with a certificate issued to "PB03 TRANSPORT LTD.". It dropped an expired but legitimate Microsoft binary, MsMpEng.exe version 4.5.218.0 signed in March 2014, alongside a malicious mpsvc.dll, then executed the Microsoft binary so it would side-load the DLL.

Defender visibility: close to zero, by design. Kaseya's own deployment documentation requires anti-malware exclusions on the Kaseya application and working folders. The vendor's supported configuration was the evasion.

A single master key held up to the light, dozens of identical closed doors receding out of focus behind it

Hardware and firmware

The lowest layer and the worst telemetry. On 18 December 2015 Juniper announced unauthorized code in ScreenOS, the operating system on NetScreen firewalls. Two separate issues shipped in official firmware: a VPN decryption weakness, and CVE-2015-7755, an authentication bypass in the SSH and Telnet daemons keyed on a hardcoded password.

The password was the string <<< %s(un='%s') = %u, which reads like a debug format string in a strings dump. Fox-IT recovered it within six hours of the advisory. Juniper listed 6.2.0r15 through 6.2.0r18 and 6.3.0r12 through 6.3.0r20 as affected, though Rapid7 could only confirm the authentication backdoor in 6.3.0r17 and 6.3.0r19. Rapid7 counted roughly 26,000 internet-facing NetScreen devices with SSH open at the time.

Juniper published what a successful intrusion looks like in the logs.

2015-12-17 09:00:00 system warn 00515 Admin user system has logged on via SSH from .....
2015-12-17 09:00:00 system warn 00528 SSH: Password authentication successful for admin user 'username2' at host ...

That is a successful administrator login, identical to a real one. Defender visibility was a log line indistinguishable from legitimate access, on a device most teams do not forward to a SIEM, that an attacker with admin could then delete. Fox-IT's Suricata signatures matched the password over Telnet, which is cleartext. Over SSH there was nothing on the wire to match.

What all four have in common

Four properties, and every one of them is a defence you already rely on:

  1. The code is signed, often by the correct vendor with a valid certificate.

  2. It is expected, because you asked for the update.

  3. It is scheduled, arriving in a patch window when noisy change is normal.

  4. It comes through a channel you have allowlisted, excluded from scanning, or given SYSTEM to.

Prevention means trusting fewer suppliers, which is not a plan you can execute. SBOMs tell you what you installed. They do not tell you whether the build that produced it was clean.

Detection: watch the updater, not the signature

Trust the update process. Verify the behaviour after it. Stop asking whether a binary is trusted and start asking whether a trusted binary is doing its job or somebody else's.

Updaters and RMM agents have narrow, boring behavioural envelopes. They fetch, they write to a known directory, they restart a service. When AgentMon.exe becomes the parent of cmd.exe which becomes the parent of a certutil copy, that is outside the envelope no matter who signed what.

title: Unexpected interpreter or LOLBin child process of an updater or RMM agent
id: 8f2c1a54-3d77-4e19-b0a2-6c9f5d3e1b47
status: experimental
description: >
  Detects script interpreters and commonly abused system binaries spawned by
  software update services and remote monitoring agents. Supply-chain payloads
  execute under the trusted parent and inherit its privileges and its
  anti-malware exclusions, so the signature and path of the child are not
  useful. The parent-child pair is.
references:
  - https://news.sophos.com/en-us/2021/07/04/independence-day-revil-uses-supply-chain-exploit-to-attack-hundreds-of-businesses/
  - https://attack.mitre.org/techniques/T1072/
author: HuntRule
date: 2026/07/31
tags:
  - attack.execution
  - attack.t1072
  - attack.t1195.002
  - attack.t1059.001
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\AgentMon.exe'
      - '\SolarWinds.BusinessLayerHost.exe'
      - '\SolarWinds.BusinessLayerHostx64.exe'
      - '\ScreenConnect.ClientService.exe'
      - '\TeamViewer_Service.exe'
      - '\atera_agent.exe'
      - '\3CXDesktopApp.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\rundll32.exe'
      - '\regsvr32.exe'
      - '\certutil.exe'
      - '\bitsadmin.exe'
      - '\net.exe'
      - '\nltest.exe'
  condition: selection_parent and selection_child
falsepositives:
  - RMM platforms whose documented function is remote script execution
  - Vendor-supplied maintenance scripts and scripted Orion monitors
  - Patch scripts run by administrators through the agent console
level: medium

What the rule catches and misses

It catches the Kaseya chain. AgentMon.exe spawning cmd.exe fires on the parent alone, so the cert.exe rename never has to be recognised as certutil.

It misses three of the four cases in this post:

  • SUNBURST on most hosts. The implant slept for up to two weeks and then spoke DNS. Where it never reached a hands-on-keyboard stage, no child process was created. The query to avsvmcloud[.]com was the artifact, not a process tree.

  • XZ completely. The backdoor lives inside sshd, hooks a function in the PLT and waits for an attacker-signed payload in a public key. Nothing spawns.

  • Juniper entirely. Different log source, different question.

The false positives are the honest problem. On an RMM agent, remote script execution is the product, so against ScreenConnect or Atera this rule will page you hourly. Run it as a hunt instead: baseline the distinct child command lines per agent over 30 days, then surface only the ones that agent has never produced before. On SolarWinds.BusinessLayerHost.exe, where the expected child set is small, it is closer to alertable.

We have not tested the parent list against every RMM build. Vendors rename service binaries between major versions, so verify the process names in your own telemetry first.

Residual risk

No detection closes this class. An implant in a signed vendor binary that does nothing for two weeks, speaks a protocol its host already speaks, and only escalates on the handful of victims the operator wants leaves no behavioural signature on the other 17,900 installs. Freund found XZ with a stopwatch, not a SIEM, and has said publicly it took a lot of luck.

What reduces the blast radius is not detection. Egress control on monitoring and management servers, so a compromised Orion box cannot resolve arbitrary domains. Tiering RMM so one console does not hold SYSTEM in every customer estate. Knowing your patch schedule well enough that an update arriving outside it is itself an event. The defensive programme is covered in what is software supply chain security.

ATT&CK mapping

ID

Name

Where it shows up

T1195

Supply Chain Compromise

All four classes

T1195.001

Compromise Software Dependencies and Development Tools

XZ Utils, event-stream

T1195.002

Compromise Software Supply Chain

SolarWinds, 3CX

T1195.003

Compromise Hardware Supply Chain

Juniper ScreenOS

T1199

Trusted Relationship

MSP and RMM access

T1072

Software Deployment Tools

Kaseya VSA update push

T1553.002

Subvert Trust Controls: Code Signing

SUNBURST, 3CX, REvil dropper

T1574.001

Hijack Execution Flow: DLL

MsMpEng.exe side-loading mpsvc.dll

Summary

A supply-chain attack replaces a thousand intrusions with one and hands delivery to the victim's own update process. The four classes fail differently. Vendor build systems produce signed malicious artifacts. Open-source dependencies produce malicious code with no signature to check. MSPs hand over inherited privilege with no code change at all. Firmware produces valid logins no log can distinguish from real ones. The stance that holds across all four is behavioural: trust the update, then watch what the updated thing does. Accept that the best-run operators leave nothing to watch, and spend the rest of the budget on egress control and privilege tiering.

Telemetry to collect before you need it:

Sysmon Event ID 1   process creation with ParentImage and full CommandLine
Sysmon Event ID 3   network connection, source process name
Sysmon Event ID 7   image loaded, for side-loaded DLLs next to signed EXEs
Sysmon Event ID 22  DNS query, source process name
Windows 4688        process creation with command line auditing enabled
Windows 4624/4625   logon events forwarded from network appliances
Linux auditd        execve on package post-install and CI runner hosts

Detection content for these parent-child patterns lives in the catalog at /rules?domain=windows, and the supply-chain specific rules are under /rules?q=supply%20chain.

Related articles