После небольшого перерыва продолжаем разговор о безопасности 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'а.

Комментарии (23)


  1. SlavikF
    30.09.2015 01:52
    +9

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

    Хотелось, как лучше, а получилось, как всегда.


    1. CodeRush
      30.09.2015 07:55
      +6

      Ситуация такая в основном потому, что SecureBoot по прежнему очень редко используется, от этого он недостаточно протестирован и потому кривые реализации продолжают быть кривыми — просто никто не знает о том, что они кривые. При этом SecureBoot — единственная нормальная защита от вредоносных OROMов и загрузчиков, и без него на любой системе можно загрузить UEFI Shell и натворить кучу неприятных дел.
      Вместо распространения вестей о том, что SecureBoot — это злодейское изобретение MS для ограничения свободы пользователя, нужно распространять знания о том, как им пользоваться правильно, как сгенерировать свои собственные PK и KEK, как удалить предустановленные, как подписать собственный загручик и так далее. Я напишу об этом статью после окончания этого цикла.


      1. monah_tuk
        30.09.2015 11:19
        +1

        Ого, заранее жду. Особенно будет интересно, как обстоят дела с собственными PK/KEK на всяких ноутбуках.


      1. Snowly
        30.09.2015 17:12
        +1

        как сгенерировать свои собственные PK и KEK
        А как обстоят дела с ноутбуками? Там тоже всегда можно поставить свои ключи? Или как обычно, поставят «огрызок» и сделать с ним ничего нельзя?


  1. mark_ablov
    30.09.2015 07:48
    +1

    Еще помню у какого-то вендора ад с открытым хранением ключей в Setup.
    Их потом intel в блек-лист занесли (ключи, а не вендора ;) ).
    Еще не затронуты атаки на перепрошивку. Там тоже много забавных buffer overflow было.


    1. CodeRush
      30.09.2015 08:01

      Пропустил, каюсь. Их исправили еще пару лет назад и я давно про них не слышал, вот и забыл.
      Для тех, кто не в курсе: суть атаки в том, что обновление и PK и KEK, и db с dbx возможно не только из BIOS Setup, но и из ОС, и в правильной реализации для обновления PK и KEK нужен текущий PKpriv, а для обновления db и dbx — KEKpriv. На некоторых старых реализациях при проверке подписи этих обновленных ключей можно было организовать переполнение буфера ии получить доступ к NVRAM, а дальше просто заменить или удалить PK. Проблему нашли и исправили достаточно быстро, еще в 2012 году, и с тех пор о ней больше не слышно. Прошу прощения, что я про нее забыл.


      1. mark_ablov
        30.09.2015 08:06
        +1

        Ну и баг с TE тоже быстро пофиксили, вот я и подумал, что ты описывал не только более-менее актуальные уязвимости, но атаки на SecureBoot в целом.


        1. CodeRush
          30.09.2015 08:11

          Правильно подумал, это я оплошал. :)


  1. MrFrizzy
    30.09.2015 09:53
    +3

    Спасибо за цикл статей.
    А насколько лучше дела обстоят у coreboot и libreboot по сравнению со стандартными прошивками?
    И в одной из прошлых статей вы назвали x86 неподходящей платформой для параноика — а какая из ныне существующих подходящая? =)


    1. CodeRush
      30.09.2015 10:07
      +1

      Пожалуйста, спасибо, что читаете.
      Насколько — не могу сказать точно, мало опыта использования coreboot, но заведомо меньше, т.к. кодовая база намного компактнее и никто не пытается добавить в прошивку все, до чего руки дотянулись и компилятор смог собрать. Будет время — попробую разобраться получше.
      Подходящая платформа для параноика сильно зависит от степени паранойи, кому-то достаточно ARM без TrustZone (хотя их таких пойди еще найди теперь), кому-то можно посоветовать OpenRISC (только вот всего 2,5 процессора ровно одной маленькой компании — это очень грустно), кто-то может посмотреть в сторону отечественных решений или китайских MIPSов (это если вам свои бэкдоры милее чужих).


      1. MrFrizzy
        30.09.2015 20:12
        +1

        Я все бредил собрать/купить себе ноут на arm или mips, а сейчас смотрю — прошивка платы тоже непонятно как собрана, на самих платах физической защиты нет, ядра на процессор в большинстве своем идут с бинарными блобами и древних версий, на gpu вообще дров нет…
        Свободные novena — тоже замучаешься компилировать все под нее, taurinus — очень спорная штука…

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

        Грустно это все…
        Хотя те же мобильники с точки зрения безопасности гораздо большая брешь =)


        1. MrFrizzy
          01.10.2015 16:13

          Совсем забыл про хромбуки
          Например, от hp.
          Ram модно доставить, вот с ssd уже хуже — вроде идут только до 128gb…
          Ну и под 2кг вес с зарядкой — а сейчас эра ультрабуков


    1. JerleShannara
      30.09.2015 17:52
      +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. Но что-то особого кол-ва желающих я не замечал.


      1. MrFrizzy
        30.09.2015 20:06

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


        1. JerleShannara
          01.10.2015 00:04

          Открываете список плат, которые оный корбут умеет. Ищите по ebay/авито/локальнаябарахолка, что там в наличии из желаемого (как вариант для заинтересованного параноика — T60 с интегрированной графикой, тогда наура взлетит libreboot). Также докупаем программатор за 4уе на всякий случай. В результате имеем железку, большинство кода которой можно спокойно изучить и поправить, не используя сильное колдунство вида ida/radare2


          1. MrFrizzy
            01.10.2015 16:09

            Лучше тогда хромбуки


            1. JerleShannara
              01.10.2015 19:06

              Насколько помню, в T60 (или в T400/500) бонусом идёт видеобиос открытый. А вот про хромбук не уверен.


  1. msuhanov
    30.09.2015 12:44

    Осталось упомянуть, что SecureBoot не совместим и не должен быть включен совместно с CSM


    Купил в этом году материнскую плату – в UEFI включены Secure Boot и CSM одновременно, отключить последний нельзя (при перезагрузке настройка включается опять).


    1. CodeRush
      30.09.2015 12:53

      Попробуйте переключить все опции Launch… Option ROM в UEFI Only, перезагрузиться и отключить CSM — должно сработать. Обычно CSM не дает отключить себя если VBIOS загружен, но нармальные реализации UEFI предупреждают об этом сообщением при попытке отключить CSM.


      1. msuhanov
        01.10.2015 22:16

        Попробовал еще раз, отключив все опции со словом «Legacy» (хотя я плясал с бубном вокруг отключения CSM и ранее): при перезагрузке CSM все равно включается (и звучат три писка). Мне, впрочем, наличие или отсутствие CSM не критично — материнская плата покупалась для поиска багов (но не в BIOS/UEFI).


        1. CodeRush
          01.10.2015 22:37

          Значит недоработка авторов прошивки, как всегда не хватило времени или денег на тестирование в любых режимах, отличных от дефолта.


  1. Akela_wolf
    01.10.2015 13:02
    +1

    Я вот главного не могу понять — предположим, я купил комп с этой хренью на борту. Могу я (теоретически) установить собственный PK-ключ, решить кому и почему я доверяю, прописать их ключи в KEK, db, а если потребуется, то и в dbx? Подписать собственный загрузчик? Если это возможно теоретически, то как с этим дело обстоит на практике? Требуется ли этот функционал каким-либо стандартом/спецификацией или это добрая воля производителей и эта возможность может быть в любой момент заблокирована в новых продуктах?

    Или это принципиально невозможно? Если так, то это начинает сильно напоминать вендор-лок.


    1. CodeRush
      01.10.2015 13:09
      +1

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