Когда-то давно, в начале 2014 года, я назвал состояние безопасности большинства реализаций UEFI "полумифическим". С тех пор минуло полтора года, дело осторожно двигается с мертвой точки, но до сих пор очень многие производители ПК для конечного пользователя не обращают на эту самую безопасность почти никакого внимания — «пипл хавает».
В этой статье речь пойдет о модели угроз и векторах атаки на UEFI, а также о защитах от перезаписи содержимого микросхемы BIOS — самой разрушительной по возможным последствиям атаки.
Если вам интересно, как устроена защита UEFI и какие именно уязвимости в ней так и остаются неисправленными на большинстве современных систем — добро пожаловать под кат.
Безопасностью UEFI-совместимых прошивок я интересуюсь довольно давно, и уже почти 2 года занимаюсь ей профессионально. Поводом к написанию этой статьи послужило практически полное отсутствие в русскоязычной части интернета какой-либо информации по безопасности UEFI, кроме переводов статей известных англоязычных исследователей, выполненных слабо знакомыми с предметом людьми. Пробел это надо понемногу восполнять, т.к. иначе он заполняется разного рода лозунгами вроде «SecureBoot против свободного ПО», «UEFI — порождение дьявола» и тому подобное. Прошу заранее прощения за язык — когда долго не говоришь и не пишешь на русском, перестаешь на нем думать, и потому конструкции могут получаться весьма странные.
Ни одна защита не может защитить от всего сразу. К примеру, защиту прошивки от поражающего действия ядерного взрыва или от сбоев при работе в открытом космосе, я в этой статье рассматривать не буду, хотя с удовольствием почитал бы подобную статью от специалистов в соответствующей области.
— атакующий первого уровня имеет физический доступ к системе, способен загружать любые ОС, изменять настройки UEFI, прошивать свой код UEFI вместо оригинального на программаторе, переставлять джамперы на мат. плате, замыкать выводы микросхем и т.п.
— атакующий второго уровня имеет физический доступ к системе, но программатора у него нет.
— атакующий третьего уровня имеет удаленный доступ к системе в режиме администратора.
Остальные случаи рассматривать не будем, т.к. от более могущественного атакующего, способного менять сидящие на шарах чипы, в UEFI защищаться практически нечем, а более слабых, без прав администратора, остановит ОС.
Последствия атаки варьируются от получения полного контроля над прошивкой, аппаратурой и ОС в лучшем случае, до DoS в худшем. Физический атакующий может устроить DoS в любом случае (с размаху отверткой в плату — вот тебе и DoS), поэтому подробнее на DoS для атакующих первого и второго уровней останавливаться не буду.
Последствия — в лучшем случае доступ к хранилищу прошивки, и далее смотри пункт 1, в худшем — обход механизмов защиты ОС и гипервизора (которые, впрочем, можно было обойти и на уровне ОС, но из SMM это может быть намного проще).
Последствия — в лучшем случае смотри пункт 1, в худшем — почти то же самое, только стартуем значительно позже, и потому некоторые вещи уже настроены и заблокированы.
Последствия — в лучшем случае можно поотключать все защиты и сразу перейти к пункту 1, в худшем — снова DoS (пишем мусор в NVRAM, перезагружаемся, смотрим, что получилось).
Последствия — в лучшем случае получается загрузить UEFI Shell и сразу оказаться в пункте 4, в худшем — заменить стандартный загрузчик ОС на модифицированный, закрепившись таким образом в ОС, пока бдительный пользователь не включит SecureBoot обратно.
Обратная сторона такой защиты — невозможность модификации прошивки даже легитимным пользователем системы, сложности ремонта материнской платы при отказе чипсета или SoC'а (и хорошо, если меняем на чистый, а не на использованный с другим хэшем, в первом случае можно попробовать удалить драйверы для Verified Boot из образа, а во втором не поможет уже ничего).
Поддерживаются эти технологии начиная с Intel Haswell и AMD Trinity, и работающих атак на них я пока не знаю, но сейчас они используются на двух с половиной моделях корпоративных ноутбуков и я бы предпочел, чтобы ситуация сильно не менялась, ведь именно возможность модификации прошивки и ОС отличает твое устройство от чужого.
О том, как проверить конкретную систему на наличие какой-либо вариации Verified Boot — напишу в следующий раз, после того, как получу от Intel и AMD разрешение на публикацию.
Атакующие первого уровня могут расслабиться и получать удовольствие — кроме аппаратной верификации им не может помешать никакая из последующих защит. Именно поэтому я говорил и буду говорить: программатор и SOIC-клипса — маст-хэв для любого серьезного исследователя прошивок.
Проблем у такой защиты несколько:
— два чипа чуть менее чем вдвое дороже одного и любой закупщик мечтает сэкономить на них миллион-другой долларов на массовом производстве, поэтому плату с двумя чипами днем с огнем не найти.
— для прошивки обязателен физический доступ, т.к. вывод #WP на GPIO губит всю безопасность на корню.
— испортить содержимое RW-микросхемы все равно можно даже не имея физического доступа.
К сожалению, реализаций подобной защиты на имеющихся на массовом рынке системах с UEFI я пока не видел. Раньше — были, а теперь остались только на Chromebook, но там прошивка основана на coreboot. Я не знаю, как именно там реализована аппаратная защита от прошивки при условии, что там тот же самый ME, что и везде…
Защита подобного рода тоже не обходится без проблем:
— ее нужно правильно реализовать, не забыв, что при перезагрузке значения регистров тоже сбрасываются, и их нужно восстанавливать.
— нужно не забыть установить (и восстановить после перезагрузки) lock на их конфигурацию, иначе вредоносный код их может банально сбросить.
— защита не может быть отключена, т.е. обновление прошивки из ОС без перезагрузки становится невозможным.
— и, конечно, NVRAM и другие RW-области защитить таким способом не получится.
В отличие от предыдущего пункта, систем с PR'ами на рынке море, и почти на всех защита реализована неграмотно или неполно.
Защита эта достаточно простая в реализации и потому есть практически на любом UEFI, но иногда она отключена по умолчанию. Большой плюс — независимость кода прошивальщика от архитектуры.
Есть и недостатки:
— кода в SMM много, и любая уязвимость в нем дает полный доступ к прошивке.
— от багов в реализации самого прошивальщика тоже никто не застрахован.
— если защита управляется переменной в NVRAM (очень много систем, где это так), то она практически бесполезна, ибо может быть просто отключена атакующим, способным загрузить UEFI Shell.
Посмотрев на вышеперечисленные недостатки, ребята из Intel решили исправить их, где-то примерно в Ivy Bridge придумали следующую защиту, а именно…
— отвратительно высокая сложность во всем. Скрипты на собственном DSL, подписи на каждый чих, раздельное обновление компонентов и прочий ад и Гондурас.
— образ для обновления невозможно прошить на программаторе, и для восстановления такой прошивки приходится буквально собирать ее из кусков, непрерывно матерясь.
— ну и vendor lock-in, конечно.
Некоторые отважные производители используют PFAT и у них он даже работает, но я попробовал и могу сказать — ни за какие коврижки, лучше я сделаю аудит кода SMM еще пару раз, чем это.
Про атаки на PFAT я ничего не знаю, но тут скорее всего работает правило неуловимого Джо.
В итоге вся защита построена на том, что BIOS добавит обработчик и SMI будет сгенерирован, поэтому для успешной атаки достаточно было забытого бита SmiLock, чтобы можно было отключить источник этого SMI и спокойно шить все, что угодно. Затем SmiLock перестали забывать и некоторые IBV даже были уверены, что защита надежная, пока на 31С3 Rafal Wojtczuk и Corey Kallenberg не показали, что на многоядерных процессорах механизм BLE/BIOS_WE уязвим к race condition, и толку от него практически ноль, т.к. атака занимает меньше 10 минут и успешна всегда.
Тем не менее, до сих пор попадаются системы, защищенные только и исключительно BLE. Это печально.
С защитами от прошивки более или менее разобрались, в следующей части поговорим об SMM и атаках на него.
Буду рад любым вопросам и комментариям. Спасибо за внимание.
В этой статье речь пойдет о модели угроз и векторах атаки на UEFI, а также о защитах от перезаписи содержимого микросхемы BIOS — самой разрушительной по возможным последствиям атаки.
Если вам интересно, как устроена защита UEFI и какие именно уязвимости в ней так и остаются неисправленными на большинстве современных систем — добро пожаловать под кат.
Часть нулевая. Введение
Безопасностью UEFI-совместимых прошивок я интересуюсь довольно давно, и уже почти 2 года занимаюсь ей профессионально. Поводом к написанию этой статьи послужило практически полное отсутствие в русскоязычной части интернета какой-либо информации по безопасности UEFI, кроме переводов статей известных англоязычных исследователей, выполненных слабо знакомыми с предметом людьми. Пробел это надо понемногу восполнять, т.к. иначе он заполняется разного рода лозунгами вроде «SecureBoot против свободного ПО», «UEFI — порождение дьявола» и тому подобное. Прошу заранее прощения за язык — когда долго не говоришь и не пишешь на русском, перестаешь на нем думать, и потому конструкции могут получаться весьма странные.
Модель угроз
Прежде чем говорить о защите и уязвимостях, поговорим немного о модели угроз.Ни одна защита не может защитить от всего сразу. К примеру, защиту прошивки от поражающего действия ядерного взрыва или от сбоев при работе в открытом космосе, я в этой статье рассматривать не буду, хотя с удовольствием почитал бы подобную статью от специалистов в соответствующей области.
Уровни доступа
Определим для атакующего несколько уровней доступа и посмотрим, что и насколько успешно «среднестатистическая» реализация UEFI может противопоставить ему:— атакующий первого уровня имеет физический доступ к системе, способен загружать любые ОС, изменять настройки UEFI, прошивать свой код UEFI вместо оригинального на программаторе, переставлять джамперы на мат. плате, замыкать выводы микросхем и т.п.
— атакующий второго уровня имеет физический доступ к системе, но программатора у него нет.
— атакующий третьего уровня имеет удаленный доступ к системе в режиме администратора.
Остальные случаи рассматривать не будем, т.к. от более могущественного атакующего, способного менять сидящие на шарах чипы, в UEFI защищаться практически нечем, а более слабых, без прав администратора, остановит ОС.
Векторы атаки
Теперь определим основные векторы и последствия успешно совершенной атаки, в порядке уменьшения опасности:1. Хранилище основной прошивки (в 95% современных систем — 1-2 микросхемы NOR-flash с интерфейсом SPI)
Суть атаки — вставляем свой код в прошивку, удаляем части имеющегося, воруем, убиваем, молчим про гусей.Последствия атаки варьируются от получения полного контроля над прошивкой, аппаратурой и ОС в лучшем случае, до DoS в худшем. Физический атакующий может устроить DoS в любом случае (с размаху отверткой в плату — вот тебе и DoS), поэтому подробнее на DoS для атакующих первого и второго уровней останавливаться не буду.
2. Код в SMM
Суть — получаем доступ к особо привилегированному режиму процессора, из которого нам доступна на чтение и запись вся физическая память и много другого вкусного.Последствия — в лучшем случае доступ к хранилищу прошивки, и далее смотри пункт 1, в худшем — обход механизмов защиты ОС и гипервизора (которые, впрочем, можно было обойти и на уровне ОС, но из SMM это может быть намного проще).
3. Хранилище прошивки PCI-устройств
Суть — вставляем свой код в прошивку какого-либо PCI-устройства (она же Option ROM), к примеру, сетевой карты или контролера Thunderbolt, UEFI выполняет этот код при инициализации устройства, ..., профит.Последствия — в лучшем случае смотри пункт 1, в худшем — почти то же самое, только стартуем значительно позже, и потому некоторые вещи уже настроены и заблокированы.
4. Переменные в NVRAM
Суть — получаем возможность изменять настройки UEFI, в том числе скрытые.Последствия — в лучшем случае можно поотключать все защиты и сразу перейти к пункту 1, в худшем — снова DoS (пишем мусор в NVRAM, перезагружаемся, смотрим, что получилось).
5. SecureBoot
Суть — получаем возможность загрузить любую нужную ОС, в том числе UEFI Shell.Последствия — в лучшем случае получается загрузить UEFI Shell и сразу оказаться в пункте 4, в худшем — заменить стандартный загрузчик ОС на модифицированный, закрепившись таким образом в ОС, пока бдительный пользователь не включит SecureBoot обратно.
Часть первая. Защиты от записи в хранилище основной прошивки
1. Аппаратная верификация прошивки или её части перед выполнением любого кода
Самые серьезные технологии в нашем списке, которые, будучи правильно реализованными, защищают прошивку от атакующих всех трех уровней — Intel BootGuard и AMD Hardware-Validated Boot. Существенно отличаясь в деталях, они выполняют одинаковую задачу: проверяют целостность небольшой части прошивки, которая подписана ЭЦП производителя материнской платы, а хэш ключа прошит в чипсет. Если проверка прошла успешно, прошивка стартует, если же нет — все зависит от настроек. Обе технологии предоставляют «аппаратный корень доверия» для последующих стадий загрузки, и прошивка может выстроить цепочку доверия, в которой чипсет проверяет bootstrap-код, этот код проверяет том PEI, тот в свою очередь — том DXE, а в DXE уже включается SecureBoot и проверяет подпись загрузчика ОС. Любое изменение защищенных таким образом частей прошивки приводит, чаще всего, к банальному DoS.Обратная сторона такой защиты — невозможность модификации прошивки даже легитимным пользователем системы, сложности ремонта материнской платы при отказе чипсета или SoC'а (и хорошо, если меняем на чистый, а не на использованный с другим хэшем, в первом случае можно попробовать удалить драйверы для Verified Boot из образа, а во втором не поможет уже ничего).
Поддерживаются эти технологии начиная с Intel Haswell и AMD Trinity, и работающих атак на них я пока не знаю, но сейчас они используются на двух с половиной моделях корпоративных ноутбуков и я бы предпочел, чтобы ситуация сильно не менялась, ведь именно возможность модификации прошивки и ОС отличает твое устройство от чужого.
О том, как проверить конкретную систему на наличие какой-либо вариации Verified Boot — напишу в следующий раз, после того, как получу от Intel и AMD разрешение на публикацию.
Атакующие первого уровня могут расслабиться и получать удовольствие — кроме аппаратной верификации им не может помешать никакая из последующих защит. Именно поэтому я говорил и буду говорить: программатор и SOIC-клипса — маст-хэв для любого серьезного исследователя прошивок.
2. Хранилище только для чтения с аппаратным переключателем
В стародавние до-UEFI-шные времена на многих материнских платах устанавливался джампер, защищающий микросхему с BIOS'ом от случайной или злонамеренной прошивки. Сложностей с реализацией такой защиты практически не возникало, т.к. все содержимое BIOS Setup хранилось в отдельно в CMOS SRAM и, кроме случаев обновления прошивки, ничего писать было просто не нужно. Затем кто-то в Intel принял решение, что в CMOS места мало, и потому нужно взять микросхему поёмче и побыстрее, и все настройки писать туда, чего месту зря пропадать. В результате этого «гениального» решения (и цепочки последующих, такого же уровня гениальности) в одной микросхеме оказалось все: собственно UEFI, часть прошивки встроенной сетевой карты (GbE), большая часть прошивки чипсета (ME), прошивка EC и черт знает что еще, и каждый из трех владельцев микросхемы (CPU, ME и GbE) получил право писать в нее не только при обновлении, а вообще в любой момент. Чтобы как-то упорядочить возникший бардак, Intel добавила в начало микросхемы Flash Descriptor, в котором явно прописаны права доступа трех владельцев к каждому региону (подробнее о дескрипторе и форматах я уже писал), но это не сильно помогло. Единственный официально поддерживаемый способ отделить мух от котлет и RW от RO — установка двух микросхем SPI, первая отдается под Descriptor, ME, GbE и NVRAM, а вторая — под оставшуюся часть UEFI, после чего нога #WP второго чипа садится джампером на землю, защищая его от записи аппаратно.Проблем у такой защиты несколько:
— два чипа чуть менее чем вдвое дороже одного и любой закупщик мечтает сэкономить на них миллион-другой долларов на массовом производстве, поэтому плату с двумя чипами днем с огнем не найти.
— для прошивки обязателен физический доступ, т.к. вывод #WP на GPIO губит всю безопасность на корню.
— испортить содержимое RW-микросхемы все равно можно даже не имея физического доступа.
К сожалению, реализаций подобной защиты на имеющихся на массовом рынке системах с UEFI я пока не видел. Раньше — были, а теперь остались только на Chromebook, но там прошивка основана на coreboot. Я не знаю, как именно там реализована аппаратная защита от прошивки при условии, что там тот же самый ME, что и везде…
3. PR-регистры чипсета
Если аппаратно микросхему SPI защитить от записи не получилось, можно защитить ее силами чипсета. Все современные чипсеты имеют как минимум 4 регистра PR, предназначенных для защиты от чтения и/или записи блока физической памяти, а т.к. микросхема SPI всегда отображается на «дно» первых 4 Гб физической памяти (т.е. последний байт микросхемы SPI всегда находится по физическому адресу 0xFFFFFFFF), но можно защитить всю прошивку или ее часть.Защита подобного рода тоже не обходится без проблем:
— ее нужно правильно реализовать, не забыв, что при перезагрузке значения регистров тоже сбрасываются, и их нужно восстанавливать.
— нужно не забыть установить (и восстановить после перезагрузки) lock на их конфигурацию, иначе вредоносный код их может банально сбросить.
— защита не может быть отключена, т.е. обновление прошивки из ОС без перезагрузки становится невозможным.
— и, конечно, NVRAM и другие RW-области защитить таким способом не получится.
В отличие от предыдущего пункта, систем с PR'ами на рынке море, и почти на всех защита реализована неграмотно или неполно.
4.1. SMM_BWP и SpiRomProtect
Вновь похожие друг на друга защиты от Intel и AMD соответственно, которые не позволяют запись в микросхему SPI из любого режима процессора, кроме SMM. Для обновления прошивки используется специальный SMI-обработчик, который должен выполнять проверку целостности и подписи новой прошивки, и только после успешной проверки выполнять прошивку.Защита эта достаточно простая в реализации и потому есть практически на любом UEFI, но иногда она отключена по умолчанию. Большой плюс — независимость кода прошивальщика от архитектуры.
Есть и недостатки:
— кода в SMM много, и любая уязвимость в нем дает полный доступ к прошивке.
— от багов в реализации самого прошивальщика тоже никто не застрахован.
— если защита управляется переменной в NVRAM (очень много систем, где это так), то она практически бесполезна, ибо может быть просто отключена атакующим, способным загрузить UEFI Shell.
Посмотрев на вышеперечисленные недостатки, ребята из Intel решили исправить их, где-то примерно в Ivy Bridge придумали следующую защиту, а именно…
4.2. Intel BIOS Guard, в девичестве PFAT
Справедливо рассудив, что кода в SMM слишком много, а IBV никак не могут написать свои прошивальщики так, чтобы в них не зияло дыр, Intel решили, что нужно идти глубже, и добавили еще один привилегированный режим исполнения, специальную область памяти ACRAM, недоступную из других режимов, в которую можно загрузить только подписанный Intel'овской ЭЦП прошивальщик, и только ему будет доступна запись в микросхему SPI. Все три проблемы из пункта 4.1 удалось успешно решить, но при этом, конечно, добавили новых:— отвратительно высокая сложность во всем. Скрипты на собственном DSL, подписи на каждый чих, раздельное обновление компонентов и прочий ад и Гондурас.
— образ для обновления невозможно прошить на программаторе, и для восстановления такой прошивки приходится буквально собирать ее из кусков, непрерывно матерясь.
— ну и vendor lock-in, конечно.
Некоторые отважные производители используют PFAT и у них он даже работает, но я попробовал и могу сказать — ни за какие коврижки, лучше я сделаю аудит кода SMM еще пару раз, чем это.
Про атаки на PFAT я ничего не знаю, но тут скорее всего работает правило неуловимого Джо.
5. BLE и BIOS_WE
Давным-давно, когда SMM_BWP еще не было, а у процессора было одно ядро, защита от записи в SPI-чип у Intel была организована так: есть бит BIOS_WE, который нужно уставить, чтобы чипсет позволил отправить команду на запись. Бит доступен любому коду, поэтому рядом с ним есть другой бит — BLE. Если он установлен, то установка BIOS_WE генерирует SMI, а BIOS регистрирует обработчик этого SMI, который это самый BIOS_WE сбрасывает. Софт видит, что бит сбросился и перестает пытаться писать — защита, все, нельзя. Если же прошивать из SMM, то при установке BIOS_WE прерывания не происходит (мы и так уже в SMM), и можно шить.В итоге вся защита построена на том, что BIOS добавит обработчик и SMI будет сгенерирован, поэтому для успешной атаки достаточно было забытого бита SmiLock, чтобы можно было отключить источник этого SMI и спокойно шить все, что угодно. Затем SmiLock перестали забывать и некоторые IBV даже были уверены, что защита надежная, пока на 31С3 Rafal Wojtczuk и Corey Kallenberg не показали, что на многоядерных процессорах механизм BLE/BIOS_WE уязвим к race condition, и толку от него практически ноль, т.к. атака занимает меньше 10 минут и успешна всегда.
Тем не менее, до сих пор попадаются системы, защищенные только и исключительно BLE. Это печально.
6. Отсутствующая
Хрестоматийный пример «пирожка без никто». Некоторые производители материнских плат для десктопов, не будем показывать пальцем, до сих пор не защищают прошивку от перезаписи вообще. Ваша система — вы и заморачивайтесь, никакой иллюзии безопасности мы вам не даем, только голый BIOS, только хардкор. Вести себя таким образом с каждым днем становится труднее, ведь с одной стороны давит Intel с рекомендациями, а с другой — Microsoft с HSTI, но пока справляются. Безумству храбрых, и все такое.Заключение
С защитами от прошивки более или менее разобрались, в следующей части поговорим об SMM и атаках на него.
Буду рад любым вопросам и комментариям. Спасибо за внимание.