О безопасности UEFI, часть пятая

    После небольшого перерыва продолжаем разговор о безопасности UEFI. В этот раз речь пойдет о технологии SecureBoot, ее преимуществах и недостатках, об атаках на нее и защите от них.

    Впервые о SecureBoot речь зашла в стандарте UEFI 2.2 в 2011 году, но окончательно все аспекты были реализованы в версии 2.3.1C в начале 2012 года. Основным разработчиком технологии была Microsoft, которая сразу же заявила, что для получения сертификата Windows 8 Ready для своей еще не выпущенной новой ОС требуется реализация и включение SecureBoot по умолчанию на всех новых ПК. Это заявление вызвало волну резкой критики со стороны сторонников свободного ПО, которая успешно докатилась и до Хабра.
    Если вам интересно, чем именно закончилось противостояние MS и сообщества, как SecureBoot выглядит после почти 4 лет взросления, и какие атаки на него все еще возможны — добро пожаловать под кат.

    Стоп, чуть не забыл: по доброй традиции, набор ссылок на предыдущие части, для тех, кто умудрился их пропустить.

    Часть пятая. SecureBoot

    Это что вообще?

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

    SecureBoot — это программная технология, при помощи которой UEFI-совместимая прошивка может проверить подлинность исполняемых ей внешних компонентов (загрузчиков, драйверов и UEFI OptionROM'ов). Эти исполняемые компоненты должны быть подписаны ЭЦП, которая проверяется во время загрузки и в случае ее полного отсутствия, повреждения, отсутствия в списке доверенных (db) или присутствия в списке запрещенных (dbx) запуск соответствующего компонента не происходит (иногда это поведение настраивается, что тоже может сыграть злую шутку, но об этом позже). В качестве алгоритма ЭЦП в данный момент стандартом рекомендуется комбинация из RSA2048 и SHA256, которые и используются почти на всех виденных мной в живую системах.

    Немного о ключах

    SecureBoot использует следующую иерархию ключей:



    На вершине находится PK — главный ключ, устанавливающий доверительные отношения между пользователем платформы и ее прошивкой. Состоит он, как и любой ключ RSA, из открытого ключа PKpub и закрытого ключа PKpriv и хранится в NVRAM в виде self-signed сертификата. Обладателя закрытой части PKpriv спецификация не без оснований называет хозяином платформы.

    В зависимости от необходимого уровня безопасности, PK может быть сгенерирован следующим образом:

    • Собственный ключ для каждого отдельного ПК. Максимальная безопасность, она же — максимальный геморрой с управлением ключами, зато и утечки практически не страшны, и компрометация системы с утекшим ключом не ведет к компрометации соседней с ней.
    • Общий ключ для каждой модели мат. платы. Менее безопасно, но проще в обслуживании, особенно если парк машин собран на одних и тех же платах.
    • Общий ключ каждой линейки мат. плат. То же самое, что и в предыдущем пункте, еще немного меньшая безопасность по цене чуть большего удобства, классический случай security-convenience trade-off.
    • Общий ключ для всех плат производителя. Самое нелепое с точки зрения безопасности, но при этом, к сожалению, чуть ли не самое популярное решение. Ключ при этом хранится прямо в дереве исходных текстов и утекает вместе с ними, после чего никакой SecureBoot на платах этого производителя уже не помеха. При этом исходники чаще всего утекают тихо, и производитель может еще пару лет выпускать заведомо уязвимую продукцию.

    Изначально PK генерируется производителем платформы, и сам не участвует подписывании и проверке подписей исполняемых компонентов, а используется для управления хранилищем ключей KEK. Обладателя KEKpriv спецификация называет авторизованным пользователем. Каждый ключ KEK устанавливает доверительные отношения между производителем исполняемого компонента и прошивкой. Эти ключи используются для управления хранилищами db (где лежат сертификаты и хеши разрешенных к запуску компонентов), и dbx (куда обладатель KEKpriv может внести сертификаты и хеши компонентов, запуск которых необходимо запретить несмотря на правильную подпись).

    Кто тут в цари первый?

    В большинстве конфигураций SecureBoot по умолчанию PK предоставляется производителем мат. платы, в KEK лежит единственный сертификат Microsoft Corporation KEK CA 2011, а в db обязательно присутствует сертификат Microsoft Windows Production CA 2011, но иногда к нему добавляют сертификат Canonical и сертификат производителя платформы, которым подписаны разного рода утилиты для обновления прошивки и вот это все. Хранилище dbx на большинстве систем пустое, но не так давно MS внесли в него несколько записей и теперь требуют их наличия на новых системах для получения сертификата Windows 10 Ready. Получается, что с точки зрения SecureBoot в конфигурации по умолчанию, вашей системой владеет производитель мат. платы, а единственный ее авторизованный пользователь — Microsoft. К счастью (и по большей части благодаря давлению сообщества СПО) эта печальная картина на подавляющем большинстве систем для x86 может быть разрушена удалением стандартных ключей и добавлением собственных из BIOS Setup, но про это я планирую написать отдельно.

    Несовместимость с CSM

    Осталось упомянуть, что SecureBoot не совместим и не должен быть включен совместно с CSM, т.е. если вы до сих пор используете старые ОС, не умеющие загружаться без CSM, то от SecureBoot вам толку не будет ни в каком виде. Самое интересное, что MS до сих пор не желает добавить в Windows 7 поддержку GOP, а без нее загрузка этой ОС без CSM либо вообще не работает, либо происходит «вслепую», что практически наверняка делает Windows 7 несовместимой с SecureBoot, даже если пользователь самостоятельно подпишет загрузчик для нее. Доля же Windows 7 в корпоративном сегменте намного превышает долю более новых ОС, и потому системы с включенной SecureBoot по прежнему малопопулярны там, где она действительно была бы полезна.

    Атаки на SecureBoot

    О векторах

    Для начала следует понять, какие именно части SecureBoot могут быть атакованы и чем грозит успешная атака:

    • NVRAM. Так как и PK, и KEK, и db и dbx, и другие относящиеся к SecureBoot переменные хранятся в NVRAM, то успешная атака на нее чаще всего приводит к отключению или компрометации SecureBoot.
    • Реализация. Если с NVRAM все в порядке, проблемы могут быть в реализации проверки подписи, хранения ключей и т.п.
    • Ключи. Атака одновременно и сложная, и простая. Всего-то надо стащить у кого-нибудь из цепочки доверия его закрытый ключ и подписать им свой вредоносный загрузчик.
    • Доверенный загрузчик. Еще проще, чем предыдущий пункт, особенно для обладателей сертификата Canonical в db. Просто меняем текущий загрузчик на подписанный вышеупомянутым сертификатом GRUB2 из репозиториев Ubuntu, который в свою очередь загрузит что угодно любой степени вредоносности.

    Собственно атаки
    Отключение SecureBoot удалением PK

    Если у атакующего имеется доступ на запись в хранилище NVRAM, что нередко случается у любителей защитить микросхему SPI лишь при помощи пары PR-регистров, то текущий PK можно банально удалить, что автоматически отключит SecureBoot, переведя его в режим установки новых ключей.

    Отключение SecureBoot правкой CurrentMode

    Эта атака — комбинация из атаки на NVRAM и реализацию. На некоторых системах текущий режим SecureBoot управляется записью в переменной Setup, и если она неожиданно для всех имеет флаг RT, то атакующий может отключить SecureBoot просто записав в Setup ноль по нужному смещению, которое, в свою очередь, легко можно найти анализом дампа IFR. Атака тупая как валенок, но до сих пор имеется куча систем, которые ей подвержены.

    Обход SecureBoot правкой ExecutionPolicy

    Вариация предыдущей атаки, но отключается на этот раз не сам SecureBoot, а запрет на продолжение загрузки при несовпадении или отсутствии ЭЦП. Тоже требует флага RT на переменной Setup и встречается чуть реже, чем предыдущий вариант, но зато позволяет обойти SecureBoot тихо, не отключая его.

    Обход SecureBoot повреждением NVRAM

    На некоторых системах для обхода SecureBoot достаточно немного испортить NVRAM (к примеру, заполнив хранилище под завязку), чтобы отключить либо обойти SecureBoot. Встречается такое поведение редко, но атака настолько простая, что есть смысл опробовать ее на любой системе. В крайнем случае, вместо обхода SecureBoot может получиться DoS, если драйвер NVRAM совсем плохой.

    Обход SecureBoot при помощи PCI(e)-устройства

    Теоретически, запуск UEFI OptionROM'ов из PCI-устройств при включенном SecureBoot не должен происходить, если соответствующий OROM не прошел верификацию, но на практике огромно количество систем доверяет PCI-устройствам безоговорочно и запускает оттуда все без каких-либо проверок. Примеров подобного поведения много, а любые системы без SecureBoot подвержены такой атаке автоматически, именно поэтому вынос PCI(e) на внешние разъемы, вроде Thunderbolt, Firewire, PCMCIA, ExpressCard и т.п. — преступление против безопасности платформы, даже без учета того, что любое PCI-устройство может инициировать DMA с любым регионом физической памяти, кроме SMRAM (и то только если производитель платформы не забыл установить защиту) и утащить у ОС и пользователя все их секреты.

    Обход SecureBoot преобразованием загрузчика из PE в TE

    Старая атака на реализацию, которой внезапно оказалось подвержена добрая половина реализаций (следствие того, что почти все IBV используют эталонную реализацию из TianoCore). Суть атаки: UEFI-загрузчик и вообще любой исполняемый файл UEFI может быть либо в формате PE, либо в формате TE (который, по факту, тот же самый PE, только с обрезанными заголовками, чтобы места в кэше занималось меньше). Формат TE очень редко используется для каких-то компонентов прошивки, кроме PEI-модулей (т.к. только в первой половине PEI, до инициализации RAM, есть смысл экономить 240h байт на заголовке), и потому эталонная реализация проверки ЭЦП не проверяла ее у образов в формате TE вообще, а вследствие комбинации двух мелких ошибок проверка такого образа всегда заканчивалась успехом. Преобразование PE ->TE тривиально, и SecureBoot можно было обойти лишь небольшим изменением файла с загрузчиком, поэтому проблема была признана серьезной и быстро исправлена. Тем не менее, до сих пор имеется куча старых систем с этой проблемой, и потому об этой атаке все еще помнят.

    Обход SecureBoot загрузкой с внешнего носителя

    Это даже не совсем атака, а скорее непонимание некоторых пользователей, что SecureBoot вообще не защищает от подмены загрузчика, и физически присутствующий атакующий может загрузить систему со своего носителя. Иногда от этого пытаются защититься паролем на BIOS и меню выбора загрузочного устройства, но добрые разработчики из MS позволяют выбрать его и из Windows, для чего достаточно зажать Shift и выбрать действие «перезагрузка» на экране входа в систему, а затем выбрать в появившемся меню нужно загрузочное устройство. Дорогим товарищам из MS — мое большое спасибо.

    Заключение


    Ну вот, с SecureBoot худо-бедно разобрались, в следующей (надеюсь, что заключительной) части поговорим о ПО и персоналиях.
    Спасибо за внимание, стойкого вам SecureBoot'а.
    Поделиться публикацией

    Похожие публикации

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

      +9
      Это ж надо, — сколько всяких умных инжинеров работало, чтобы родить систему UEFI.
      А из-за повальной кривой реализации получается, что и защиты толком нет, и пользователям геморой.

      Хотелось, как лучше, а получилось, как всегда.
        +6
        Ситуация такая в основном потому, что SecureBoot по прежнему очень редко используется, от этого он недостаточно протестирован и потому кривые реализации продолжают быть кривыми — просто никто не знает о том, что они кривые. При этом SecureBoot — единственная нормальная защита от вредоносных OROMов и загрузчиков, и без него на любой системе можно загрузить UEFI Shell и натворить кучу неприятных дел.
        Вместо распространения вестей о том, что SecureBoot — это злодейское изобретение MS для ограничения свободы пользователя, нужно распространять знания о том, как им пользоваться правильно, как сгенерировать свои собственные PK и KEK, как удалить предустановленные, как подписать собственный загручик и так далее. Я напишу об этом статью после окончания этого цикла.
          +1
          Ого, заранее жду. Особенно будет интересно, как обстоят дела с собственными PK/KEK на всяких ноутбуках.
            +1
            как сгенерировать свои собственные PK и KEK
            А как обстоят дела с ноутбуками? Там тоже всегда можно поставить свои ключи? Или как обычно, поставят «огрызок» и сделать с ним ничего нельзя?
              0
            +1
            Еще помню у какого-то вендора ад с открытым хранением ключей в Setup.
            Их потом intel в блек-лист занесли (ключи, а не вендора ;) ).
            Еще не затронуты атаки на перепрошивку. Там тоже много забавных buffer overflow было.
              0
              Пропустил, каюсь. Их исправили еще пару лет назад и я давно про них не слышал, вот и забыл.
              Для тех, кто не в курсе: суть атаки в том, что обновление и PK и KEK, и db с dbx возможно не только из BIOS Setup, но и из ОС, и в правильной реализации для обновления PK и KEK нужен текущий PKpriv, а для обновления db и dbx — KEKpriv. На некоторых старых реализациях при проверке подписи этих обновленных ключей можно было организовать переполнение буфера ии получить доступ к NVRAM, а дальше просто заменить или удалить PK. Проблему нашли и исправили достаточно быстро, еще в 2012 году, и с тех пор о ней больше не слышно. Прошу прощения, что я про нее забыл.
                +1
                Ну и баг с TE тоже быстро пофиксили, вот я и подумал, что ты описывал не только более-менее актуальные уязвимости, но атаки на SecureBoot в целом.
                  0
                  Правильно подумал, это я оплошал. :)
              +3
              Спасибо за цикл статей.
              А насколько лучше дела обстоят у coreboot и libreboot по сравнению со стандартными прошивками?
              И в одной из прошлых статей вы назвали x86 неподходящей платформой для параноика — а какая из ныне существующих подходящая? =)
                +1
                Пожалуйста, спасибо, что читаете.
                Насколько — не могу сказать точно, мало опыта использования coreboot, но заведомо меньше, т.к. кодовая база намного компактнее и никто не пытается добавить в прошивку все, до чего руки дотянулись и компилятор смог собрать. Будет время — попробую разобраться получше.
                Подходящая платформа для параноика сильно зависит от степени паранойи, кому-то достаточно ARM без TrustZone (хотя их таких пойди еще найди теперь), кому-то можно посоветовать OpenRISC (только вот всего 2,5 процессора ровно одной маленькой компании — это очень грустно), кто-то может посмотреть в сторону отечественных решений или китайских MIPSов (это если вам свои бэкдоры милее чужих).
                  +1
                  Я все бредил собрать/купить себе ноут на arm или mips, а сейчас смотрю — прошивка платы тоже непонятно как собрана, на самих платах физической защиты нет, ядра на процессор в большинстве своем идут с бинарными блобами и древних версий, на gpu вообще дров нет…
                  Свободные novena — тоже замучаешься компилировать все под нее, taurinus — очень спорная штука…

                  Вот и получается, что как ни крути, простому пользователю проще взять себе обычное железо и не переживать почем зря. В крайнем случае получится поставить corebot, но это будут делать совсем уже гики…

                  Грустно это все…
                  Хотя те же мобильники с точки зрения безопасности гораздо большая брешь =)
                    0
                    Совсем забыл про хромбуки
                    Например, от hp.
                    Ram модно доставить, вот с ssd уже хуже — вроде идут только до 128gb…
                    Ну и под 2кг вес с зарядкой — а сейчас эра ультрабуков
                  +3
                  Про корбут отвечу. Это вещь в себе, т.е. можно сказать, что есть UEFI, есть Legacy BIOS и есть coreboot. Заранее скажу, что payload-ы я рассматриваю только со стороны Seabios-а (CSM-а, если смотреть как на UEFI).
                  Исходные коды вполне чистые, особо косячных мест нет, возможно, если дописать своего кода побольше, то удастся испортить cbmem консоль. Защиты от перезаписи нет, видать из идеологических соображений, т.е. перезаписать содержимое флешки может любой юзер, которому в руки попался flashrom. Но тут каждый кузнец своего счастья, добавить защиту PR регистров в него можно особо не гемороясь, благо функционал работы с SPI есть готовый, правда прийдется ещё и #WP ножку помучать, но тут уж извините, либо сами делайте плату, либо дорабатывайте готовую. SMI режим не используется (за блобы ничего не скажу) из тех-же идеологических соображений наверное. Поддержка ACPI… ну… всё плохо для любителей хакинтошей и ценителей «всегда последняя версия стандарта» — 2.0 оно вполне может (если опятьже для вашей платы оные asl-ки написаны, либо вы их напишете), в ограниченном формате, чтобы винда запуститься смогла =), зато с безопасностью проще. Хранение настроек — если не хотите, оно вообще может их нигде не хранить, если хотите — пожалуйста, всё в классическом понимании — CMOS RAM, правда настройки не те, что ожидаются (типа частоты памяти, множителей, приоритета адаптеров), а более отладочные (скорость ком-порта, и т.д.), и опять-же, если для вашей платы оная поддержка сделана.
                  SeaBios — вполне вещь в себе, с безопасностью — как у обычного старого Legacy BIOS, грузится отовсюду, откуда может, OPROM-ы запускает все, что найдет (если при сборке ей об этом сказали). Чистота кода — всяко чище, чем любое творение от IBV, выпущенное после эпохи Pentium1.
                  Кто хочет допом к этому поиметь геммороя — может собрать payload-ом UDK и получить что-то вроде UEFI в виде почти чистого TianoCore. Но что-то особого кол-ва желающих я не замечал.
                    0
                    Спасибо,
                    я от разработки железа далек, рассматриваю чисто со стороны любительского опыта смены прошивки.
                      0
                      Открываете список плат, которые оный корбут умеет. Ищите по ebay/авито/локальнаябарахолка, что там в наличии из желаемого (как вариант для заинтересованного параноика — T60 с интегрированной графикой, тогда наура взлетит libreboot). Также докупаем программатор за 4уе на всякий случай. В результате имеем железку, большинство кода которой можно спокойно изучить и поправить, не используя сильное колдунство вида ida/radare2
                        0
                        Лучше тогда хромбуки
                          0
                          Насколько помню, в T60 (или в T400/500) бонусом идёт видеобиос открытый. А вот про хромбук не уверен.
                  0
                  Осталось упомянуть, что SecureBoot не совместим и не должен быть включен совместно с CSM


                  Купил в этом году материнскую плату – в UEFI включены Secure Boot и CSM одновременно, отключить последний нельзя (при перезагрузке настройка включается опять).
                    0
                    Попробуйте переключить все опции Launch… Option ROM в UEFI Only, перезагрузиться и отключить CSM — должно сработать. Обычно CSM не дает отключить себя если VBIOS загружен, но нармальные реализации UEFI предупреждают об этом сообщением при попытке отключить CSM.
                      0
                      Попробовал еще раз, отключив все опции со словом «Legacy» (хотя я плясал с бубном вокруг отключения CSM и ранее): при перезагрузке CSM все равно включается (и звучат три писка). Мне, впрочем, наличие или отсутствие CSM не критично — материнская плата покупалась для поиска багов (но не в BIOS/UEFI).
                        0
                        Значит недоработка авторов прошивки, как всегда не хватило времени или денег на тестирование в любых режимах, отличных от дефолта.
                    +1
                    Я вот главного не могу понять — предположим, я купил комп с этой хренью на борту. Могу я (теоретически) установить собственный PK-ключ, решить кому и почему я доверяю, прописать их ключи в KEK, db, а если потребуется, то и в dbx? Подписать собственный загрузчик? Если это возможно теоретически, то как с этим дело обстоит на практике? Требуется ли этот функционал каким-либо стандартом/спецификацией или это добрая воля производителей и эта возможность может быть в любой момент заблокирована в новых продуктах?

                    Или это принципиально невозможно? Если так, то это начинает сильно напоминать вендор-лок.
                      +1
                      Это возможно и теоритически, и практически, но некоторые производители сознательно прячут эти настройки от пользователя, не желая описывать их в документации, либо специально блокируя возможность смены ключей, как это сделано на смартфонах и планшетах Microsoft.
                      Я постараюсь рассказать подробнее о настройке SecureBoot в отдельно посте, прошу только подождать немного.

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

                    Самое читаемое