ID2_6741:::https://habr.com/ru/company/aladdinrd/blog/33... Загрузка ОС на ARM Перейти к объекту с этой ссылкой на главной ::: Перейти на страницу объекта с этой ссылкой

    ID_753:ID2_6741 :: Копия содержания страницы:
  https://habr.com/ru/company/aladdinrd/blog/33... [открыть в этом окне]
Загрузка ОС на ARM

Размер содержания копии:     0.00023 Гб. / 0.23657 Мб. / 242.25195 Кб. / 248066 байт

Аладдин Р.Д.Информационная безопасность
vlk7727 сентября 2017 в 11:06

Загрузка ОС на ARM

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

Загрузка ARM в четырех прямоугольниках — под катом.

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

Разновидности процессоров ARM


Если вы знаете про ARM, то этот раздел можно смело пропустить.

В производстве и эксплуатации сейчас встречаются процессоры ARM пяти архитектур: ARMv4, ARMv5, ARMv6, ARMv7 и ARMv8. Компания ARM дает этим архитектурам коммерческие названия, поэтому ARMv4 называется, например, ARM7, ARMv5 – ARM9, а название Cortex имеют процессоры на архитектурах ARMv6, v7, v8. Следующая таблица перечисляет основные разновидности.
АрхитектураКоммерческое названиеРаспространенные видыЗапуск Linux
ARMv4ARM7ARM7TDMIНецелесообразно
ARMv5ARM9ARM926EJ-SДа
ARMv6ARM11ARM1176JZF-SДа
Cortex-M0Cortex-M0Нет
ARMv7Cortex-MCortex-M3Нецелесообразно
Cortex-ACortex-A9Да
Cortex-RCortex-R4Да
ARMv8Cortex-ACortex-A53Да

Например, кнопочные телефоны в основном используют ARM7, а смартфоны – Cortex-A. Современные смартфоны строятся преимущественно на ARMv8, единственных 64-битных. Процессоры ARM7 и ARM9 широко применялись в различных промышленных контроллерах, сетевом оборудовании, а сейчас фокус переходит на использование в них Cortex-A. В различной бытовой технике, мелких электронных приборах, в области безопасности и т.п. применяются микроконтроллеры Cortex-M.

Вообще все устройства ARM можно условно разбить на микроконтроллеры и Application Processor.


Долгое время одни и те же архитектуры ARM7, ARM9 использовались как для построения процессоров, так и микроконтроллеров. С появлением линейки Cortex произошло разделение, и теперь микроконтроллеры называются Cortex-M, а процессоры Cortex-A и Cortex-R.

Виды ОС


Какие есть варианты запуска ОС:


Например, в планшетах и смартфонах используется Android, iOS или вариант Linux. В телекоммуникационном оборудовании может быть Linux или один из вариантов RTOS. В более простом оборудовании может применяться RTOS или программа без ОС.

В дальнейшем мы будем говорить только о запуске ОС (Linux, Android) или RTOS на ARM. По способу запуска “большие” RTOS попадают в одну группу с Linux, а “малые” RTOS объединяются с программами без ОС.

Для запуска Linux хорошо подходят процессоры ARM9, ARM11, Cortex-A. Усеченную версию Linux также можно загрузить на ARM7, Cortex-M4 и Cortex-M7, но это нецелесообразно.

Для запуска малых RTOS подходят микроконтроллеры и процессоры ARM7, ARM9, Cortex-M. В некоторых случаях для RTOS используют начальные модели Cortex-A, например, Cortex-A5. Большинство же процессоров Cortex-A столь сложны, что их возможности можно использовать только совместно с поставляемым производителем Linux/Android SDK, что и определяет выбор в пользу Linux.

Загрузчик ОС


С точки зрения разработчика системное ПО устройства делится на загрузчик и ОС. Основную функцию всегда выполняет программа, работающая под управлением ОС или RTOS.

Загрузчик обеспечивает загрузку ОС и сервисные функции, такие, как:


В случае RTOS загрузчик зачастую пишется разработчиком устройства и представляет собой небольшую специализированную программу. В случае с ОС общего применения широко применяются загрузчики с открытым исходным кодом, например, u-boot.

Таким образом, с точки зрения разработчика изделия запуск ОС выглядит следующим образом:


Здесь знаком // отмечен момент подачи питания или сброса процессора. Такой простой способ запуска был у некоторых процессоров ARM7. В последовавших за ними версиях процесс запуска в реальности сложнее, чем на приведенной схеме, но для разработчика конечного решения это обычно не существенно.

Схема “Загрузчик-ОС” очень удобна из практических соображений, ведь загрузчик берет на себя всю низкоуровневую работу:


Например, для запуска Linux на ARM загрузчик должен инициализировать память, хотя бы один терминал, загрузить образ ядра и Device Tree в память и передать управление на ядро. Все это описано в <https://www.kernel.org/doc/Documentation/arm/Booting>. Код инициализации ядра Linux не будет делать сам то, что должен делать загрузчик.

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

Рассмотрим работу загрузчика на примере u-boot, загружающего Linux, по шагам.

  1. После включения или сброса процессор загружает образ u-boot, хранимый в Flash-памяти, в ОЗУ и передает управление на первую команду этого образа.
  2. u-boot инициализирует DDRAM.
  3. u-boot инициализирует драйверы загрузочного носителя (ЗН), например, eMMC, NAND Flash.
  4. u-boot читает с ЗН область переменных конфигураций. В конфигурации задан скрипт загрузки, который u-boot далее исполняет.
  5. u-boot выводит в консоль предложение прервать процесс загрузки и сконфигурировать устройство. Если за 2-3 секунды пользователь этого не сделает, запускается скрипт загрузки.
  6. Иногда скрипт начинается с поиска подходящего образа ОС для загрузки на всех доступных носителях. В других случаях ЗН задается в скрипте жестко.
  7. Скрипт загружает с ЗН в DDRAM образ ядра Linux (zImage), файл Device Tree с параметрами ядра (*.dtb).
  8. Дополнительно скрипт может загрузить в DDRAM образ initrd – маленькой файловой системы с необходимыми для старта драйверами устройств. Современные дистрибутивы Linux иногда используют initrd, а иногда – нет.
  9. Разместив загруженные 2 или 3 файла в памяти, скрипт передает управление на первую команду образа zImage (ядро Linux).
  10. zImage состоит из распаковщика и сжатого образа ядра. Распаковщик развертывает ядро в памяти, и загрузка ОС начинается.

Запуск загрузчика – предзагрузчик


Однако в реальности почти никогда не бывает, чтобы команды загрузчика выполнялись первыми после включения или сброса процессора. Это еще было на процессорах ARM7, но почти не встречалось далее.

Любое ядро процессора ARM при сбросе начинает исполнение с адреса 0, где записан вектор “reset”. Старые серии процессоров буквально начинали загружаться с внешней памяти, отображенной по нулевому адресу, и тогда первая команда процессора была командной загрузчика. Однако для такой загрузки подходит только параллельная NOR Flash или ROM. Эти типы памяти работают очень просто – при подаче адреса они выдают данные. Характерный пример параллельной NOR Flash – микросхема BIOS в персональных компьютерах.

В современных системах используются другие виды памяти, потому что они дешевле, а объем больше. Это NAND, eMMC, SPI/QSPI Flash. Эти типы памяти уже не работают по принципу: подал адрес — читаешь данные, а значит, для прямого исполнения команд из них не подходят. Даже для простого чтения тут требуется написать драйвер, и мы имеем проблему «курицы и яйца»: драйвер нужно откуда-то заранее загрузить.

По этой причине в современные процессоры ARM интегрировано ПЗУ с предзагрузчиком. ПЗУ отображено в памяти процессора на адрес 0, и именно с него начинает исполнение команд процессор.

В задачи предзагрузчика входят следующие:


Конфигурация предзагрузчика обычно устанавливается одним из двух способов:


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

Подобный предзагрузчик устанавливается как в процессорах ARM, таких, как Cortex-A, так и в микроконтроллерах, даже таких маленьких, как Cortex-M0. Вместе с предзагрузчиком процедура запуска ОС выглядит так:

Анализ угроз на этом этапе


Исходный код предзагрузчика пишется производителем процессора, а не компанией ARM, является частью микросхемы как продукта компании-производителя и защищен авторским правом. Например, в процессорах ARM компаний Atmel и NXP предзагрузчики написаны, соответственно, Atmel и NXP.

В некоторых случаях предзагрузчик можно прочитать из ROM и проанализировать, но иногда доступ к нему ограничен. Например, предзагрузчик процессора серии Psoc4000 компании Cypress был закрыт несколькими слоями защиты (но был взломан талантливым хакером).

Использования предзагрузчика в большинстве сценариев избежать нельзя. Можно рассматривать его как вариант BIOS, которого в ARM-системах нет.

Скрытый текст
Сам по себе предзагрузчик в ROM несет в себе угрозу нарушения порядка загрузки и выполнения произвольного кода. Но после того как управление передано загрузчику ОС, предзагрузчик уже безвреден. Мы можем просто не передавать ему управление, перенастроить все обработчики прерываний и так далее.

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

Это в общем случае небезопасно, но встречается только в некоторых микроконтроллерах на архитектуре ARM. На таких микроконтроллерах обычно запускаются программы без ОС или малые RTOS, и дизайнер системы может оценить риски.

Загрузка с TrustZone


В процессоры ARM Cortex-A и Cortex-R встраивается технология TrustZone. Эта технология позволяет на аппаратном уровне выделить два режима исполнения: Secure (Безопасный) и Non-Secure (Гостевой).

Эти процессоры в основном нацелены на рынок смартфонов и планшетных компьютеров, и TrustZone используется для создания в режиме Secure доверенной “песочницы” для исполнения кода, связанного с криптографией, DRM, хранением пользовательских данных.

В режиме Secure при этом запускается специальная ОС, называемая в общем случае TEE (Trusted Execution Environment, доверенная среда исполнения), а нормальная ОС, такая, как Linux, Android, iOS, запускается в режиме Non-Secure. При этом права доступа к некоторым устройствам ограничены для нормальной ОС, поэтому ее еще называют гостевой ОС.

Из-за наложенных ограничений гостевая ОС вынуждена время от времени вызывать функции TEE для исполнения некоторых операций. TEE продолжает существовать параллельно с гостевой ОС все время, и гостевая ОС не может ничего с этим поделать.

Например, гостевая ОС использует функции TEE для:


При этом, с точки зрения безопасности, на время таких вызовов управление передается в неизвестный нам, непроверенный код. Мы не можем однозначно сказать, что делают Samsung KNOX или QSEE от Qualcomm.

Почему же разработчики систем соглашаются на такой режим функционирования? В процессоры с поддержкой TrustZone встроен и механизм Secure Boot в том или ином виде.

С Secure Boot предзагрузчик проверяет подпись загружаемого образа с помощью прошитого на этапе производства открытого ключа. Таким образом, гарантируется, что загружен будет только подписанный образ. Это функция безопасности.

То есть загрузка ОС становится следующей:

  1. стартует предзагрузчик в ROM. Он загружает ключи для проверки подписи TEE из ROM;
  2. предзагрузчик загружает в память образ TEE, проверяет подпись. Если проверка прошла успешно, запускается TEE;
  3. TEE настраивает режимы Secure и Non-Secure. Далее TEE загружает основной загрузчик ОС и переходит на него в режиме Non-Secure. Сам TEE остается в режиме Secure и ждет;
  4. загрузчик основной ОС загружает ОС как обычно;
  5. ОС вынуждена время от времени вызывать функции TEE для выполнения некоторых задач.

Однако производитель, как правило, поставляет подписанные образы загрузчика и TEE в составе SDK для процессора и поставляет процессоры, уже “зашитые” ключом производителя. В этом случае предзагрузчик из ROM не станет выполнять любой загрузчик, если он не подписан производителем. Все основные процессоры для смартфонов сейчас поставляются уже “прошитыми” под исполнение собственного TEE перед исполнением загрузчика ОС.

Далее действует лень — c TEE все работает, а без TEE даже не запускается. Разработчики используют SDK с TEE, вызывают закрытый бинарный код из ядра Linux и не волнуются.

Как проверить свой проект на обращения к TrustZone


Может даже показаться, что всей этой TrustZone не существует, по крайней мере, в вашей конкретной разработке. Проверить это совсем несложно.

Дело в том, что все процессоры с TrustZone стартуют в режиме Secure, а только потом переключаются в Normal. Если ваша ОС запущена в режиме Normal, то какая-то Secure OS (TEE) существует в системе и перевела ее в этот режим.

Лакмусовой бумажкой является обращение к TEE для включения кэш-памяти 2-го уровня. По какой-то причине архитектура ARM не позволяет этого делать из Normal World. Поэтому для включения кэша ядру ОС потребуется сделать хоть один вызов к TrustZone. Делается это единственной командой: smc #0, и вы можете поискать ее сами в ядре Linux или Android.

Разумеется, мы и сами поискали, и нашли такие вызовы в коде поддержки ряда процессоров Qualcomm, Samsung, Mediatek, Rockchip, Spreadtrum, HiSilicon, Broadcom, Cavium.

Загрузка ARM Cortex-A и анализ угроз


Итак, обещанный процесс загрузки ОС на ARM (здесь — Cortex-A) в четыре блока:

На схеме пунктиром обозначен путь обращения из ядра ОС в TEE.

В двух блоках — неизвестный нам код. Посмотрим, чем это грозит.

Технически, любой из компонентов системного ПО может содержать ошибки, намеренные закладки и так далее. Однако в большинстве случаев загрузчик, ОС и системное ПО можно проверить, изучив исходные коды. Сконцентрируемся на возможных угрозах, исходящих от предзагрузчика и TEE, исходные коды к которым закрыты.

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

Гораздо более интересной точкой атаки является TEE, так как его функции вызываются в процессе работы ОС, когда все периферийные устройства работают, а коммуникационные протоколы настроены. Создание шпионской закладки в коде TEE позволяет практически неограниченно следить за пользователем СВТ.

В небольшом исследовании мы показали реализуемость закладки в TEE, незаметно перехватывающей системные вызовы ОС Linux. Для активации закладки нужно только одно обращение из ядра Linux в TEE (например, то самое, для кэша второго уровня), после чего система становится полностью управляемой. Это позволяет:


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

Выводы


Мы рассмотрели процесс загрузки различных микроконтроллеров и процессоров ARM.

У микроконтроллеров наиболее уязвимым местом в процессе загрузки является загрузчик ОС.

Современные процессоры ARM Cortex-A включают в себя TrustZone — и от этого никуда не уйти. TrustZone предполагает запуск перед ОС доверенной среды исполнения TEE.

TEE является самой уязвимой точкой в процессе загрузки ОС на ARM Cortex-A, потому что обращения к TEE приводят к выполнению закрытого системного кода, известного производителю, но скрытого от нас.

Без контроля над TEE невозможно обеспечить безопасность и доверенность исполнения любой ОС на ARM Cortex-A.
Теги:
Аладдин Р.Д. 0,00Информационная безопасность17,0Карма0,0Рейтинг12Подписчики6Подпискиvlk77ИнженерПоделиться публикацией

ПОХОЖИЕ ПУБЛИКАЦИИ

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

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


Меня зовут Валера и я хочу запустить 2 вирусных идеи, которые искал уже давно, ЧТОБЫ ИЗМЕНИТЬ ЧТО-ТО В ЭТОМ МИРЕ. Во-первых это символ +2800 значение которого совершенно противоположно +100500:

И он для того, чтобы рассказать о еврейском фашизме, 2800 рабах каждому еврею, а главное о каббалистическом языке и каббалистических методах и электронном концлагере который нам готовят и как его избежать. Я думаю многие из вас слышат об этом первый раз и не понимают о чем это я:-) Но это интересно, важно знать каждому и каждому важно рассказывать об этом другим. Подробнее об этом на сайте plus2800.ru.

А во-вторых волшебный третий нос на лбу:-) Это как у пастофарианцев друшлак на голове.

Тоже религиозный символ, но тройного назначения.

Во 1-ых это тоже религиозный символ придуманный для того, чтобы рассказать о +2800 и его значениях.

Во 2-ых наделяет сверхспособностью о которой мечтал один английский комик.

В 3-их он может спасти тому кто его носит жизнь!

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

У учительницы их Химок были проблемы из-за того, что она пришла в школу с друшлаком на голове и вела в таком виде урок. Из-за этого у неё были проблемы и это была разовая акция. А ношение третьего носа можно обосновать и практическими соображениями перечисленными выше. Но при этом все равно все будут знать откуда взялась такая мода, для чего и какие смыслы несет.

И подробней об этом на сайте plus2800.ru.

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

Хм... Возможно поможет если объяснить, что это вредная ложь и они то как раз и создают проблемы, которые решают. Но как ни странно это тоже малоэффективно.

А знаете в чем причина? Людей зазомбировали и научили так, что им кажется. что они думают сами, а на самом деле думают чужими мыслями и никакие аргументы и факты ничего не изменят. Вот если телевизор скажет и в то, что будут говорить люди вокруг они поверят скорее чем логике и здравому смыслу. Поэтому чтобы они "услышали" логику и здравый смысл, нужно чтобы миллионы людей говорили об этом. И для этого и был придуман волшебный третий нос на лбу.

И вот если миллионы, десятки миллионов, сотни миллионов будут носить волшебный третий нос и рассказывать о том, что зашифровано в символе +2800, то они вдруг услышат здравый смысл и логике и вдруг они "поймут"... Хотя на самом деле нет, а просто опять поверят авторитету. Но в принципе это на данном этапе и не важно - главное результат. Но в общем идея такая и подробнее об этом на сайте plus2800.ru



Скачать все эти страницы с ссылками
и привязанными к ним файлами