Как стать автором
Обновить

Комментарии 11

В этой отличной статье главное, то что это верхушка айсберга экспертизы по доверенной загрузке. И комментировать и ругать и хвалить нас можно по всей теме целиком :)

НЛО прилетело и опубликовало эту надпись здесь

Первый вопрос легко гуглится, действительно есть такая книжка.

Издатльство: Apress

Авторы: Jiewen YaoVincent Zimmer
Building Secure Firmware: Armoring the Foundation of the Platform

От того же издательства есть ещё:
System Firmware: An Essential Guide to Open Source and Embedded Solutions
Firmware Development: A Guide to Specialized Systemic Knowledge

В основном C, немного C++ и ассемблера.

Продукт ViPNet SafeBoot отличный! Главное, чтобы ответственный за это средство защиты не был балбесом, или кто-то из промежуточных звеньев.
Реальная история. Москва закупила большую партию компьютеров в защищенном исполнении с Астрой и ViPNet SafeBoot и по регионам раздавать. Ну и как-бы это, пароли то вам зачем? И если Астру переставить можно было бы, но ViPNet SafeBoot не особо. Пришлось выискивать эту в Москве эту гениальную прокладку между монитором и клавиатурой.

файлов на диске (на разделах с ФС FAT*, NTFS, ext2/3/4);

реестра Windows (на уровне ключей/значений);

Предзагрузочный контроль целостности не работает.

У вас возникают проблемы как только вы уходите от схемы "текущий компонент проверяет целостность только тех компонентов (данных), которые сам сразу и запускает (использует)".

В качестве примера возьмем CVE-2021-27094 и CVE-2021-28447 — загрузчик ядра (winload) читает и хеширует (для измерения с помощью TPM) данные из некоторых значений у определенных ключей реестра, а затем (в рамках той же загрузки) ядро (ntoskrnl) читает и использует данные из этих же значений (у тех же ключей и из того же загруженного куста реестра), однако данные значений уже отличаются от ранее хешированных (описание на английском). То бишь загрузчик ядра "видит" одни данные, вполне ожидаемые ("доверенные", "эталонные"), а ядро "видит" в том же месте другие данные (которые могут нарушать действующую политику, отсюда и признание этой ситуации уязвимостью, ведь хешируются ожидаемые данные, а используются какие-то другие, контролируемые атакующим, т. е. атакующий, имеющий права администратора в операционной системе или возможность модифицировать содержимое накопителя пока компьютер выключен, может подготовить такой файл куста реестра, что загрузчик ядра "увидит" одни данные, а ядро "увидит" другие данные ровно в том же месте).

Почему так происходит? Потому что реализация поддержки реестра в загрузчике ядра и в ядре различается — всего два, казалось бы, незначительных различия в коде привели к двум уязвимостям. А все из-за того, что измерение данных инициируется компонентом, который является предыдущим по отношению к тому, который эти данные использует, — а надо было, если делать архитектуру грамотно, хешировать и измерять все в рамках ядра (одного компонента).

Вы не можете парсить файловую систему NTFS или реестр Windows именно так, как это делает сама Windows. Даже "импорт" функций парсинга из менеджера загрузки или загрузчика ядра (bootmgr и winload) не поможет, потому что они тоже отличаются от того, что происходит после передачи управления ядру.

В итоге: добро пожаловать в мир, где модуль доверенной загрузки "видит" конфигурационный файл средства защиты информации, имеющий "ожидаемое" содержимое, а после загрузки это будет уже пустой файл (такое можно сделать, если модуль доверенной загрузки использует драйвер ntfs-3g для работы с файловыми системами NTFS, ведь в нем тоже есть различия в парсинге, если сравнивать с драйвером ntfs.sys).

Отключаете режим "fast startup"? Поздравляю, его элемент — запись данных реестра только в журнал транзакций — можно активировать путем изменения одной переменной ядра.

Как разработчик парсеров реестра Windows, файловых систем NTFS, FAT12/16/32 и exFAT могу сказать, что таких частных случаев масса и все их учесть невозможно.

Вот еще один — https://github.com/dosfstools/dosfstools/issues/174 ("Windows cannot see files listed after such directory entry in all the subsequent clusters of the directory file... Linux does not stop scanning directory upon encountering such entry, the problem can only be seen when the media is accessed from the Windows machine"). Простыми словами: в файловой системе FAT12/16/32 можно создать такую директорию, которая будет иметь некоторые файлы, видимые в Linux, но невидимые в Windows. И привет всем модулям доверенной загрузки на базе Linux! Да, атакующему нужны права администратора, но это входит в модель угроз, от которых должен защищать модуль доверенной загрузки (иначе зачем это все встраивание в UEFI, можно ведь просто драйвером Windows реализовать тогда).

P. S. А можно еще вернуться во времена, когда ставился "бряк" на 0x0000:0x7C00, чтобы вместо загрузчика операционной системы подставить загрузчик того самого "Аккорд-АМДЗ". У них в старых моделях вообще парсинг всего сделан — достойно, но неэффективно.

Предзагрузочный контроль целостности не работает

По сути смысл всего этого объемного комментария в том, что разница в реализации может быть фатальной в определенных (краевых) случаях. Более того, даже следование какому бы то ни было “бумажному” стандарту не спасает ситуацию, т.к. фактически надо учитывать специфику реального стандарта, который может иметь отступления от “бумажного” стандарта или иметь проблемы реализации, которые сами по себе со временем могут становиться расширением стандарта.

Все это верно, но делать после этого вывод о том, что предзагрузочный контроль целостности именно поэтому не работает – очень радикально. На краевых случаях – возможны проблемы, но они выявляются и решаются.

Отключаете режим "fast startup"? Поздравляю, его элемент — запись данных реестра только в журнал транзакций — можно активировать путем изменения одной переменной ядра.

Журнал транзакций той же NTFS в ViPNet SafeBoot контролируется на непустоту – скорее всего, приведенный сценарий не пройдет (хотя он описан очень поверхностно). Да и непонятно, с чем именно поздравляете :).

P. S. А можно еще вернуться во времена, когда ставился "бряк" на 0x0000:0x7C00, чтобы вместо загрузчика операционной системы подставить загрузчик того самого "Аккорд-АМДЗ". У них в старых моделях вообще парсинг всего сделан — достойно, но неэффективно.

А вот здесь противоречие всему написанному выше – “Все животные равны, но некоторые равнее других”? :)

Все это верно, но делать после этого вывод о том, что предзагрузочный контроль целостности именно поэтому не работает – очень радикально. На краевых случаях – возможны проблемы, но они выявляются и решаются.

Радикально? Нет. Эти граничные случаи — как раз то, на что может целиться атакующий. Если в повседневной жизни они не возникают, то тут возникнуть вполне могут.

А как решать эти проблемы? Писать парсеры файловых систем NTFS и FAT, реестра Windows, которые бы полностью соответствовали реализациям в Windows, включая все граничные случаи? Когда напишете подобное (скажем, потратив на это пять лет работы, ибо нужно досконально изучить в IDA Pro и WinDbg все эти драйверы и подсистемы ядра), "эталонная" реализация уже изменится (ту же реализацию реестра в ядре Windows регулярно перерабатывают, "подбрасывая" новые граничные случаи).

Масштаб проблемы серьезный, сама проблема носит принципиальный характер, поэтому и пишу, что "не работает".

Журнал транзакций той же NTFS в ViPNet SafeBoot контролируется на непустоту – скорее всего, приведенный сценарий не пройдет (хотя он описан очень поверхностно). Да и непонятно, с чем именно поздравляете :).

Журнал NTFS не может быть пустым при обычной работе операционной системы Windows. В нем всегда что-то есть. Контролировать можно незавершенность транзакций, но в данном случае речь шла про журналы реестра (файлы SYSTEM.LOG1, SYSTEM.LOG2 и т. д.).

Файлы реестра тоже можно контролировать на незавершенность транзакций, вот только умеет ли средство доверенной загрузки делать это корректно? Тут проблемы могут начаться и с реализации расчета контрольной суммы заголовка.

А вот здесь противоречие всему написанному выше – “Все животные равны, но некоторые равнее других”? :)

Здесь про "теплую ламповость" было.

Радикально? Нет. Эти граничные случаи — как раз то, на что может целиться атакующий. Если в повседневной жизни они не возникают, то тут возникнуть вполне могут.

...

Масштаб проблемы серьезный, сама проблема носит принципиальный характер, поэтому и пишу, что "не работает".

Основной задачей для процедуры КЦ модуля доверенной загрузки является проверка системных файлов ОС (на их неизменность) и проверка на неизменность системных каталогов ОС (ну и проведение симметричных операций для реестра Windows, если идет речь об этой ОС). Списки каталогов/файлов (ключей/значений реестра) составляются либо администратором, либо получаются автоматически по некоторой фиксированной логике, либо вообще приходят извне (от лабораторий/регуляторов). Сам процесс КЦ неплохо проверяется на многих версиях и сборках ОС, т.е. правильность функционирования КЦ подтверждается практикой. Ну просто невозможно согласиться с радикальным “не работает” и все.

Согласен с тем, что очень сложно поддержать все граничные случаи, но для большинства практических сценариев этого более чем достаточно.

Очень хорошо, что процесс хорошо воспроизводится на данных, на которых он и должен хорошо воспроизводиться. Особенно, когда речь идет об установленных экземплярах операционных систем, на которые не имитировалось воздействие злоумышленника. Или имитировалось, но не тем способом, а гораздо более простым. "Не работает" — это не значит, что у вас ошибка высвечивается, а значит, что сама концепция настолько ужасна, что ее уже и не исправить.

Ведь я говорю о ситуации, когда контроль целостности проходит успешно, но для данных (файлов или значений ключей реестра), не соответствующих "неизменному" ("доверенному", "эталонному") состоянию. Потому что модуль доверенной загрузки "увидел" ожидаемые данные (значение хеш-функции от них совпало с "эталоном"), а операционная система "увидела" другие данные, хотя исходный набор байтов на накопителе был тот же самый (и будет хуже, если "другие данные" — это контролируемые злоумышленником).

Если модификация структур файловых систем и кустов реестра на низком уровне вообще не рассматривается — это не значит, что проблемы нет. Выше уже была ссылка, где про драйвер FAT в Linux: если вы смонтируете специально подготовленный образ файловой системы в режиме "только чтение" (хотя и в режиме "чтение-запись" можно), то в Linux вы увидите директорию с какими-то файлами (и эти файлы могут иметь именно то содержимое, которое вы ожидаете увидеть), а в Windows это будет уже директория без части файлов (или даже без всех файлов). Цена вопроса — модификация одного байта в индексной записи (в Windows этот байт остановит цикл перечисления индексных записей в директории, в Linux — нет, листинг директории продолжится). Не используете Linux, "залатали" эту возможность? Есть еще десятки других.

Зарегистрируйтесь на Хабре , чтобы оставить комментарий