flawopen.com/Incidents/solarwinds-sunburst-build-compromise-december-2020
SUNBURST: Als die Build-Pipeline die Schwachstelle war
SUNSPOT änderte Orion-Quellcode beim Build und brachte SUNBURST in signierte Updates. Eine Signatur belegte die Herkunft, nicht die Code-Integrität.
Stellen Sie sich einen vertrauenswürdigen Schlüsseldienst vor, der versiegelte, gestempelte Wartungskits an Tausende Gebäude schickt. Jemand bricht in die Fabrik ein, in der die Kits zusammengestellt werden, und legt in jedes ein kleines Zusatzteil, bevor Siegel und Stempel aufgebracht werden. Jedes Gebäude erhält ein Kit, das wirklich vom Schlüsseldienst stammt, und baut es ein. Das Siegel wurde nie gebrochen, weil die Manipulation vor dem Versiegeln geschah.
Kernkonzepte & Begriffe
SUNSPOT- Das von CrowdStrike analysierte Implantat auf dem Build-Server. Es wartete, bis MSBuild.exe Orion baute, und ersetzte für die Dauer des Builds eine Quelldatei durch die präparierte Version.
SUNBURST- Die in SolarWinds.Orion.Core.BusinessLayer.dll kompilierte Hintertür. Sie blieb bis zu zwei Wochen inaktiv und kontaktierte dann per HTTP die Infrastruktur der Angreifer.
Code-Signatur- Eine kryptografische Signatur, die zeigt, dass ein Binary vom Schlüsselinhaber stammt. Über eine Manipulation des erzeugenden Builds sagt sie nichts aus.
Reproduzierbarer Build- Ein Build, der aus demselben Quellcode bitgleiche Ausgaben erzeugt, sodass unabhängige Builder ihre Ergebnisse gegenseitig prüfen können.
CWE-506- Eingebetteter Schadcode. Hier wurde er während des Builds beim Hersteller selbst eingefügt, nicht im Quellcode-Repository.
Framework-Zuordnungen
- CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-506 CWE-829
- D3-OTF Filterung des ausgehenden Datenverkehrs — Die in diesem Leitfaden beschriebene Beschränkung des ausgehenden Netzwerkverkehrs begrenzt die für den Dienst oder Host erreichbaren Ziele.
Vorfall-Zeitstrahl
Die Angreifer verschaffen sich Zugang zur Umgebung von SolarWinds; am 12. September schleusen sie Testcode in einen Orion-Build ein, um die Methode zu erproben.
SUNBURST wird über SUNSPOT in Orion-Builds kompiliert.
SolarWinds beginnt, Orion-Hotfixes auszuliefern, die unbemerkt SUNBURST enthalten; betroffen sind unter anderem 2019.4 HF5 und 2020.2.
Die Angreifer entfernen SUNSPOT aus der Build-Umgebung.
FireEye veröffentlicht seine SUNBURST-Analyse, und die CISA erlässt die Emergency Directive 21-01, die Bundesbehörden anweist, Orion vom Netz zu nehmen.
Schritt-für-Schritt Angriffsablauf
Der Build-Server wird kompromittiert
Die Angreifer verschafften sich Zugang zur Build-Umgebung von SolarWinds und installierten SUNSPOT auf dem Server, der Orion kompilierte.
Eine Quelldatei wird mitten im Build getauscht
Sah SUNSPOT MSBuild.exe die Orion-Solution bauen, ersetzte es InventoryManager.cs durch eine präparierte Version und stellte nach der Kompilierung das Original wieder her.
Der echte Schlüssel signiert das Ergebnis
Die kompilierte SolarWinds.Orion.Core.BusinessLayer.dll durchlief den normalen Signaturschritt, sodass die präparierte DLL eine gültige SolarWinds-Signatur trug.
Kunden installieren ein vertrauenswürdiges Update
Weniger als 18.000 Kunden installierten betroffene Updates. Danach wählten die Angreifer eine viel kleinere Gruppe von Opfern für weitere Eindringversuche aus.
Quellcode: Verwundbar vs. Sicher
Illustratives C#, nicht die Pipeline von SolarWinds. Der verwundbare Job vertraut einem einzigen, langlebigen Build-Server und signiert alles, was er erzeugt – genau das nutzte SUNSPOT aus. Das gehärtete Gate verlangt zwei Builds desselben freigegebenen Commits auf frisch bereitgestellten, getrennt administrierten Buildern, vergleicht ihre SHA-256-Digests in konstanter Zeit und verweigert bei jeder Abweichung die Signatur. Ein Implantat auf einem Builder führt dann zu einer Abweichung statt zu einem signierten Release; das schlägt nur fehl, wenn der Angreifer beide Builder kontrolliert, weshalb sie keine Zugangsdaten oder Images teilen dürfen.
using System;
using System.Diagnostics;
public static class ReleasePipeline
{
// Builds verwenden die gemeinsame, beschreibbare Arbeitskopie eines Buildservers und signieren
// jedes Ergebnis. Auch Änderungen am Quellbaum während des Builds werden signiert.
public static void BuildAndSign(string project, string outputDll)
{
using var build = Process.Start("msbuild.exe", $"\"{project}\" /p:Configuration=Release");
build!.WaitForExit();
if (build.ExitCode != 0)
throw new InvalidOperationException("build failed");
Signer.Sign(outputDll); // HSM-backed signing service client
}
}using System;
using System.IO;
using System.Security.Cryptography;
public static class ReleaseGate
{
// Zwei isolierte Builder kompilieren denselben fixierten Commit aus frischen, schreibgeschützten Checkouts,
// mit /p:Deterministic=true. Die Prüfung signiert nur identische Ergebnisse.
public static void VerifyAndSign(string builderAOutput, string builderBOutput,
string builtCommit, string approvedCommit)
{
if (!string.Equals(builtCommit, approvedCommit, StringComparison.Ordinal))
throw new InvalidOperationException("build is not from the approved commit");
byte[] a = SHA256.HashData(File.ReadAllBytes(builderAOutput));
byte[] b = SHA256.HashData(File.ReadAllBytes(builderBOutput));
if (!CryptographicOperations.FixedTimeEquals(a, b))
throw new InvalidOperationException("independent builds differ; refusing to sign");
Signer.Sign(builderAOutput, Convert.ToHexString(a)); // digest is logged with the signature
}
}Checkliste für Engineering & Systemsicherheit
- ✓Schützen Sie CI-Runner wie Produktion: Sie enthalten Quellcode, Geheimnisse und Signaturschlüssel und erzeugen, was Kunden ausführen, und verdienen daher die Isolation, Zugriffskontrolle und Audit-Protokollierung einer Produktionsdatenbank.
- ✓Bauen Sie Releases zweimal auf frisch bereitgestellten, getrennt administrierten Buildern mit deterministischer Kompilierung und lassen Sie das Release scheitern, wenn die Artefakt-Digests abweichen.
- ✓Halten Sie eine gültige Signatur nicht für einen Sicherheitsnachweis; sie belegt die Herkunft, und die ist nur so vertrauenswürdig wie die Umgebung, die den Schlüssel hielt.
- ✓Beschränken Sie ausgehenden Verkehr privilegierter Agenten. SUNBURST musste seine Command-and-Control-Server erreichen; Überwachungswerkzeuge, die mit beliebigen Internet-Hosts sprechen dürfen, sollten eine bewusste, geprüfte Entscheidung sein.
- ✓Bemessen Sie die Rechte jedes Hersteller-Agenten danach, was ein Angreifer bei vollständiger Kompromittierung gewänne, nicht danach, was sich bequem ausrollen lässt.
- ✓Bewahren Sie Telemetrie auf, die der Angreifer nicht ändern kann: Nur Logs außerhalb des Hosts, die nur angehängt werden können, erlauben es, einen monatelangen Einbruch nachträglich zu rekonstruieren.
Quellen
- Mandiant (FireEye) — hoch ausweichender Angreifer nutzt die SolarWinds-Lieferkette, um mit der Hintertür SUNBURST zahlreiche Opfer weltweit zu kompromittieren
- CrowdStrike — SUNSPOT: ein Implantat im Build-Prozess
- CISA — Emergency Directive 21-01: Kompromittierung des SolarWinds-Orion-Codes eindämmen
- Die XZ-Utils-Hintertür: der Lieferkettenangriff, der drei Jahre dauerte
- Shai-Hulud: der npm-Wurm, der sich selbst veröffentlichte