FlawOpen

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

● SolarWinds · CWE-506 / CWE-829 · September 2019 – December 2020 · अति गंभीर
सुरक्षा अनुसंधान · FlawOpen

SUNBURST: जब बिल्ड पाइपलाइन ही कमज़ोरी थी

SUNSPOT ने बिल्ड के दौरान Orion स्रोत बदला और हस्ताक्षरित अपडेट में SUNBURST जोड़ा। वैध हस्ताक्षर स्रोत साबित करता था, कोड की अखंडता नहीं।

💡 आसान भाषा में (ELI5)

एक भरोसेमंद ताले वाले की कल्पना करें जो हज़ारों इमारतों को सील और मुहर लगी रखरखाव किट भेजता है। कोई उस फ़ैक्टरी में घुस जाता है जहाँ किट बनती हैं, और सील व मुहर लगने से पहले हर किट में एक छोटा अतिरिक्त पुर्ज़ा डाल देता है। हर इमारत को सचमुच उसी ताले वाले की किट मिलती है और वह उसे लगा लेती है। सील कभी नहीं टूटी, क्योंकि छेड़छाड़ सील लगने से पहले हुई थी।

इस पेज के मुख्य शब्द

SUNSPOT
CrowdStrike द्वारा विश्लेषित बिल्ड सर्वर का इम्प्लांट। यह MSBuild.exe के Orion बनाने पर नज़र रखता था और बिल्ड के दौरान एक सोर्स फ़ाइल को बैकडोर वाले संस्करण से बदल देता था।
SUNBURST
SolarWinds.Orion.Core.BusinessLayer.dll में कंपाइल किया गया बैकडोर। यह दो हफ़्ते तक निष्क्रिय रहता और फिर HTTP से हमलावर के इन्फ्रास्ट्रक्चर से संपर्क करता था।
कोड साइनिंग
एक क्रिप्टोग्राफ़िक हस्ताक्षर जो दिखाता है कि बाइनरी कुंजी रखने वाले से आई है। यह इस बारे में कुछ नहीं बताता कि उसे बनाने वाले बिल्ड से छेड़छाड़ हुई या नहीं।
पुनरुत्पादनीय बिल्ड
ऐसा बिल्ड जो एक ही सोर्स से बिट-दर-बिट एक जैसा आउटपुट देता है, ताकि स्वतंत्र बिल्डर एक-दूसरे के नतीजे जाँच सकें।
CWE-506
अंतर्निहित दुर्भावनापूर्ण कोड। यहाँ यह सोर्स रिपॉज़िटरी में नहीं, बल्कि विक्रेता के अपने बिल्ड के दौरान डाला गया था।

फ्रेमवर्क मैपिंग

घटना का समयक्रम (Timeline)

2019-09-04

हमलावर SolarWinds के वातावरण में पहुँचते हैं; 12 सितंबर को वे तरीक़ा परखने के लिए Orion के एक बिल्ड में परीक्षण कोड डालते हैं।

2020-02-20

SUNSPOT के ज़रिए SUNBURST को Orion के बिल्ड में कंपाइल किया जाता है।

2020-03-26

SolarWinds अनजाने में SUNBURST वाले Orion हॉटफ़िक्स भेजना शुरू करता है; प्रभावित संस्करणों में 2019.4 HF5 और 2020.2 शामिल हैं।

2020-06-04

हमलावर बिल्ड वातावरण से SUNSPOT हटा देते हैं।

2020-12-13

FireEye अपना SUNBURST विश्लेषण प्रकाशित करता है और CISA Emergency Directive 21-01 जारी कर संघीय एजेंसियों को Orion डिस्कनेक्ट करने का आदेश देता है।

हमले का चरण-दर-चरण प्रवाह

चरण 1

बिल्ड सर्वर में सेंध

हमलावरों ने SolarWinds के बिल्ड वातावरण तक पहुँच बनाई और Orion कंपाइल करने वाले सर्वर पर SUNSPOT लगा दिया।

चरण 2

बिल्ड के बीच में सोर्स फ़ाइल बदली जाती है

जब SUNSPOT देखता कि MSBuild.exe Orion सॉल्यूशन बना रहा है, तो वह InventoryManager.cs को बैकडोर वाले संस्करण से बदल देता और कंपाइलेशन के बाद मूल फ़ाइल वापस रख देता।

चरण 3

असली कुंजी नतीजे पर हस्ताक्षर करती है

कंपाइल हुई SolarWinds.Orion.Core.BusinessLayer.dll सामान्य साइनिंग चरण से गुज़री, इसलिए बैकडोर वाली DLL पर SolarWinds का वैध हस्ताक्षर था।

चरण 4

ग्राहक भरोसेमंद अपडेट इंस्टॉल करते हैं

18,000 से कम ग्राहकों ने प्रभावित अपडेट इंस्टॉल किए। इसके बाद हमलावरों ने आगे की घुसपैठ के लिए कहीं छोटे समूह के शिकार चुने।

सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन

यह उदाहरण के लिए C# है, SolarWinds की पाइपलाइन नहीं। कमज़ोर जॉब एक ही लंबे समय तक चलने वाले बिल्ड सर्वर पर भरोसा करता है और वह जो कुछ बनाए उस पर हस्ताक्षर कर देता है, ठीक वही जिसका SUNSPOT ने फ़ायदा उठाया। मज़बूत गेट नए सिरे से तैयार, अलग-अलग प्रशासित दो बिल्डर पर एक ही स्वीकृत कमिट के दो बिल्ड माँगता है, उनके SHA-256 डाइजेस्ट की स्थिर-समय में तुलना करता है और ज़रा-सा भी अंतर होने पर हस्ताक्षर से इनकार करता है। तब एक बिल्डर पर मौजूद इम्प्लांट हस्ताक्षरित रिलीज़ के बजाय बेमेल नतीजा देता है; यह तभी विफल होता है जब हमलावर दोनों बिल्डर नियंत्रित करे, इसलिए उनमें क्रेडेंशियल या इमेज साझा नहीं होने चाहिए।

कमज़ोर कार्यान्वयन
using System;
using System.Diagnostics;

public static class ReleasePipeline
{
    // build एक सर्वर पर साझा, लिखने योग्य working copy से चलता है और
    // जो भी output बनता है उस पर हस्ताक्षर करता है। build के दौरान tree में बदलाव भी sign हो जाते हैं।
    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
{
    // दो अलग-अलग builders नए, read-only checkouts से उसी pinned commit को compile करते हैं,
    // /p:Deterministic=true के साथ। gate केवल समान outputs पर हस्ताक्षर करता है।
    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
    }
}

इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट

स्रोत