flawopen.com/Incidents/solarwinds-sunburst-build-compromise-december-2020
SUNBURST: el ataque a la cadena de compilación
SUNSPOT alteró el código de Orion durante el build e incluyó SUNBURST en actualizaciones firmadas. La firma probaba el origen, no la integridad.
Piensa en un cerrajero de confianza que envía kits de mantenimiento precintados y sellados a miles de edificios. Alguien entra en la fábrica donde se montan los kits y añade una pieza extra a cada uno antes de ponerles el precinto y el sello. Todos los edificios reciben un kit que de verdad viene del cerrajero y lo instalan. El precinto nunca se rompió, porque la manipulación ocurrió antes de precintar.
Conceptos Clave y Términos
SUNSPOT- El implante del servidor de compilación que analizó CrowdStrike. Vigilaba MSBuild.exe compilando Orion y sustituía un fichero fuente por la versión con puerta trasera mientras duraba la compilación.
SUNBURST- La puerta trasera compilada en SolarWinds.Orion.Core.BusinessLayer.dll. Permanecía inactiva hasta dos semanas y después contactaba por HTTP con la infraestructura del atacante.
Firma de código- Una firma criptográfica que demuestra que un binario procede de quien tiene la clave. No dice nada sobre si se manipuló la compilación que lo generó.
Compilación reproducible- Una compilación que genera una salida idéntica bit a bit a partir del mismo código fuente, para que compiladores independientes puedan comprobar los resultados de los demás.
CWE-506- Código malicioso incrustado. En este caso se insertó durante la propia compilación del proveedor, no en el repositorio de código fuente.
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-506 CWE-829
- D3-OTF Filtrado del tráfico saliente — La restricción de red saliente de esta guía limita los destinos a los que puede acceder el servicio o el host.
Cronología del Incidente
Los atacantes acceden al entorno de SolarWinds; el 12 de septiembre inyectan código de prueba en una compilación de Orion para comprobar que el método funciona.
SUNBURST se compila en las versiones de Orion a través de SUNSPOT.
SolarWinds empieza a distribuir hotfixes de Orion que, sin saberlo, contienen SUNBURST; entre las versiones afectadas están 2019.4 HF5 y 2020.2.
Los atacantes retiran SUNSPOT del entorno de compilación.
FireEye publica su análisis de SUNBURST y CISA emite la Emergency Directive 21-01, que ordena a las agencias federales desconectar Orion.
Flujo de Ataque Paso a Paso
Se compromete el servidor de compilación
Los atacantes lograron acceso al entorno de compilación de SolarWinds e instalaron SUNSPOT en el servidor que compilaba Orion.
Se cambia un fichero fuente en plena compilación
Cuando SUNSPOT veía que MSBuild.exe compilaba la solución de Orion, sustituía InventoryManager.cs por una versión con puerta trasera y restauraba el original al terminar.
La clave auténtica firma el resultado
El SolarWinds.Orion.Core.BusinessLayer.dll compilado pasaba por el paso de firma normal, así que la DLL con puerta trasera llevaba una firma válida de SolarWinds.
Los clientes instalan una actualización de confianza
Menos de 18.000 clientes instalaron actualizaciones afectadas. Después, los atacantes eligieron un grupo mucho más pequeño de víctimas para intrusiones posteriores.
Código Fuente: Vulnerable vs. Seguro
C# ilustrativo, no es el pipeline de SolarWinds. El trabajo vulnerable confía en un único servidor de compilación de larga vida y firma todo lo que produce, justo lo que explotó SUNSPOT. La puerta reforzada exige dos compilaciones del mismo commit aprobado en compiladores recién aprovisionados y administrados por separado, compara sus resúmenes SHA-256 en tiempo constante y se niega a firmar ante cualquier diferencia. Un implante en un compilador produce entonces una discrepancia en lugar de una versión firmada; solo falla si el atacante controla ambos compiladores, por eso no deben compartir credenciales ni imágenes.
using System;
using System.Diagnostics;
public static class ReleasePipeline
{
// Las compilaciones usan la copia de trabajo compartida y escribible de un servidor y firman
// cualquier resultado. También se firma lo que modifique el árbol durante la compilación.
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
{
// Dos compiladores aislados compilan el mismo commit fijado desde checkouts nuevos y de solo lectura,
// con /p:Deterministic=true. La etapa de control firma únicamente resultados idénticos.
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
}
}Lista de Verificación de Seguridad para Ingeniería
- ✓Protege los runners de CI como si fueran producción: guardan código fuente, secretos y claves de firma y producen lo que ejecutan los clientes, así que merecen el aislamiento, el control de acceso y los registros de auditoría de una base de datos de producción.
- ✓Compila cada versión dos veces, en compiladores recién aprovisionados y administrados por separado, con compilación determinista, y haz fallar la publicación si los resúmenes de los artefactos difieren.
- ✓No trates una firma válida como prueba de seguridad; demuestra la procedencia, y la procedencia solo es tan fiable como el entorno que guardaba la clave.
- ✓Restringe el tráfico saliente de los agentes privilegiados. SUNBURST necesitaba llegar a sus servidores de mando y control, así que las herramientas de monitorización que pueden hablar con cualquier host de internet deben ser una decisión explícita y revisada.
- ✓Dimensiona los privilegios de cada agente de proveedor según lo que ganaría un atacante si lo comprometiera por completo, no según lo cómodo que sea desplegarlo.
- ✓Mantén telemetría que el atacante no pueda editar: los registros fuera del host y de solo anexado son los que permiten reconstruir después una intrusión de meses.
Fuentes
- Mandiant (FireEye) — un atacante muy evasivo aprovecha la cadena de suministro de SolarWinds para comprometer a varias víctimas en todo el mundo con la puerta trasera SUNBURST
- CrowdStrike — SUNSPOT: un implante en el proceso de compilación
- CISA — Emergency Directive 21-01: mitigar el compromiso del código de SolarWinds Orion
- La puerta trasera de XZ Utils: el ataque a la cadena de suministro que duró tres años
- Shai-Hulud: el gusano de npm que se publicaba a sí mismo