FlawOpen

flawopen.com/Incidents/solarwinds-sunburst-build-compromise-december-2020

● SolarWinds · CWE-506 / CWE-829 · September 2019 – December 2020 · Kritis
Riset Keamanan · FlawOpen

SUNBURST: serangan pada rantai build

SUNSPOT mengubah kode sumber Orion saat build dan menyisipkan SUNBURST ke pembaruan bertanda tangan. Tanda tangan membuktikan asal, bukan integritas.

💡 Penjelasan Sederhana (ELI5)

Bayangkan tukang kunci tepercaya yang mengirim kit perawatan bersegel dan berstempel ke ribuan gedung. Seseorang menyusup ke pabrik tempat kit dirakit dan menambahkan satu komponen kecil ke setiap kit sebelum segel dan stempel dipasang. Setiap gedung menerima kit yang benar-benar dari tukang kunci itu dan memasangnya. Segelnya tidak pernah rusak, karena perusakan terjadi sebelum penyegelan.

Konsep Kunci & Istilah

SUNSPOT
Implan di server build yang dianalisis CrowdStrike. Implan ini mengawasi MSBuild.exe saat membangun Orion dan mengganti satu berkas sumber dengan versi berisi backdoor selama build berlangsung.
SUNBURST
Backdoor yang dikompilasi ke dalam SolarWinds.Orion.Core.BusinessLayer.dll. Ia diam hingga dua minggu, lalu menghubungi infrastruktur penyerang lewat HTTP.
Penandatanganan kode
Tanda tangan kriptografis yang menunjukkan bahwa sebuah biner berasal dari pemegang kunci. Tanda tangan itu tidak mengatakan apa pun tentang apakah build yang menghasilkannya dimanipulasi.
Build yang dapat direproduksi
Build yang menghasilkan keluaran identik bit demi bit dari sumber yang sama, sehingga builder independen dapat saling memeriksa hasil.
CWE-506
Kode berbahaya yang tertanam. Di sini kode itu disisipkan saat build milik vendor sendiri, bukan di repositori kode sumber.

Pemetaan kerangka kerja

Kronologi Insiden

2019-09-04

Penyerang mengakses lingkungan SolarWinds; pada 12 September mereka menyuntikkan kode uji ke build Orion untuk memastikan metodenya berhasil.

2020-02-20

SUNBURST dikompilasi ke dalam build Orion melalui SUNSPOT.

2020-03-26

SolarWinds mulai mengirim hotfix Orion yang tanpa disadari berisi SUNBURST; versi terdampak mencakup 2019.4 HF5 dan 2020.2.

2020-06-04

Penyerang menghapus SUNSPOT dari lingkungan build.

2020-12-13

FireEye menerbitkan analisis SUNBURST dan CISA mengeluarkan Emergency Directive 21-01 yang memerintahkan lembaga federal memutus Orion.

Alur Serangan Langkah demi Langkah

Langkah 1

Server build dibobol

Penyerang memperoleh akses ke lingkungan build SolarWinds dan memasang SUNSPOT di server yang mengompilasi Orion.

Langkah 2

Berkas sumber ditukar di tengah build

Saat SUNSPOT melihat MSBuild.exe membangun solusi Orion, ia mengganti InventoryManager.cs dengan versi berisi backdoor dan memulihkan aslinya setelah kompilasi.

Langkah 3

Kunci asli menandatangani hasilnya

SolarWinds.Orion.Core.BusinessLayer.dll hasil kompilasi melewati tahap penandatanganan biasa, sehingga DLL berisi backdoor itu membawa tanda tangan SolarWinds yang sah.

Langkah 4

Pelanggan memasang pembaruan tepercaya

Kurang dari 18.000 pelanggan memasang pembaruan terdampak. Penyerang lalu memilih kelompok korban yang jauh lebih kecil untuk penyusupan lanjutan.

Kode Sumber: Rentan vs Aman

C# ilustratif, bukan pipeline SolarWinds. Job yang rentan memercayai satu server build berumur panjang dan menandatangani apa pun yang dihasilkannya, tepat hal yang dimanfaatkan SUNSPOT. Gerbang yang diperkuat mewajibkan dua build dari commit yang sama dan sudah disetujui di builder yang baru disiapkan dan dikelola terpisah, membandingkan digest SHA-256 keduanya dalam waktu konstan, dan menolak menandatangani jika ada perbedaan sekecil apa pun. Implan di satu builder pun menghasilkan ketidakcocokan, bukan rilis bertanda tangan; perlindungan ini hanya gagal bila penyerang menguasai kedua builder, karena itu keduanya tidak boleh berbagi kredensial atau image.

IMPLEMENTASI RENTAN
using System;
using System.Diagnostics;

public static class ReleasePipeline
{
    // Build menggunakan salinan kerja bersama yang dapat ditulis di satu server build, lalu menandatangani
    // semua hasilnya. Perubahan pada pohon selama build juga ikut ditandatangani.
    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
    }
}
PERBAIKAN AMAN & KUAT
using System;
using System.IO;
using System.Security.Cryptography;

public static class ReleaseGate
{
    // Dua builder terisolasi mengompilasi commit yang sama dan dipatok dari checkout baru yang hanya dapat dibaca,
    // dengan /p:Deterministic=true. Gerbang hanya menandatangani keluaran yang identik.
    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
    }
}

Daftar Periksa Penguatan Sistem Rekayasa

Sumber