
Проблема безопасности в прошивке гипервизора некоторых старых чипсетов Qualcomm
CVE-2022-22063 — это проблема безопасности в гипервизорной прошивке некоторых старых чипсетов Qualcomm. Незащищенный аппаратный компонент (так называемый «boot remapper») может быть использован для получения полного доступа на чтение/запись к гипервизору из модифицированной операционной системы (повышение привилегий). Эксплуатация проблемы тривиальна на затронутых платформах, поскольку не требуется знание конкретной версии прошивки (например, адресов или переменных).
Примечание: Хотя Qualcomm предоставила исправления клиентам (с достаточным временем для выпуска обновлений), многие затронутые устройства уже довольно стары и могут не получить исправление от вендора. Проблема может быть использована только из модифицированной или скомпрометированной операционной системы (с использованием другой проблемы безопасности). Поддержание операционной системы в актуальном и безопасном состоянии может быть достаточным, даже если прошивка уязвима.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HПроблема также была опубликована в Бюллетене безопасности Qualcomm за декабрь 2022 года.
Проблема зависит от комбинации аппаратного и программного обеспечения на затронутой цели:
hyp на внутреннем накопителе).APCS_BOOT_START_ADDR_NSEC), которая не защищена гипервизором и поэтому доступна для менее привилегированного ядра операционной системы (например, Linux).Существует несколько других чипсетов, которые, вероятно, имеют затронутое оборудование (например, MSM8909 и MSM8953), но у них нет отдельной прошивки гипервизора, которую можно было бы скомпрометировать.
Повышение привилегий: При уже скомпрометированном ядре операционной системы (например, Linux) проблема позволяет тривиально повысить привилегии до уровня гипервизора (EL1 -> EL2 на ARM). Вся память, управляемая гипервизором, может быть прочитана или записана. Это нарушает изоляцию различных доменов безопасности или виртуальных машин, управляемых гипервизором (если они есть, в зависимости от конфигурации).
(См. также: An introduction to Access Control on Qualcomm Snapdragon Platforms)
Безопасная загрузка: Большинство устройств Qualcomm, доступных в производстве, используют безопасную загрузку для предотвращения несанкционированной модификации прошивки. Прошивка криптографически подписана и проверяется цепочкой загрузки. Проблема позволяет модифицировать или даже полностью заменить загруженную прошивку гипервизора во время выполнения из модифицированной операционной системы (либо через официально поддерживаемую «разблокировку загрузчика», либо через другой эксплойт).
(См. также: Qualcomm Secure Boot and Image Authentication Technical Overview (v1.0) и (v2.0))
Примечание: Проблема была изначально обнаружена на платформе Qualcomm Snapdragon 410 (MSM8916). Некоторые из следующих объяснений могут быть специфичны для MSM8916, например:
Однако общая концепция применима аналогично ко всем затронутым платформам.
Архитектура ARMv8-A 64-bit определяет 4 уровня привилегий (exception levels, EL). Существуют отдельные уровни, которые обычно используются для приложений, ядер операционных систем и гипервизора:
ЦП переключается между уровнями во время исключений, например, из-за входящего прерывания. Также возможно переключение между некоторыми уровнями с помощью специальных инструкций, таких как Hypervisor Call (hvc).
(См. также: AArch64 Exception model)
Гипервизор может размещать одну или несколько виртуальных машин с отдельными ядрами операционных систем. Каждой виртуальной машине может быть предоставлено собственное представление памяти с помощью трансляции второго уровня (stage 2 translation). Все обращения к памяти из виртуальной машины проходят через два этапа трансляции: первый управляется (виртуальной) операционной системой, а второй — гипервизором. Память, используемая гипервизором или другими виртуальными машинами, может быть скрыта путем ее исключения из таблиц трансляции.
(См. также: AArch64 virtualization, AArch64 memory management)
Прошивка гипервизора Qualcomm работает в EL2 и использует трансляцию второго уровня для запрета доступа к памяти гипервизора из основного ядра операционной системы, работающего в EL1 (обычно Linux). Обратите внимание, что в этой конфигурации трансляция второго уровня в основном используется для защиты памяти, без трансляции адресов. Основная операционная система получает прямой доступ к большинству аппаратных компонентов в пространстве memory-mapped input/output (MMIO), например, к контроллеру SD или подсистеме камеры. Доступ к памяти, принадлежащей гипервизору/EL2 (hyp) и монитору безопасности/EL3 (часть tz), ограничен:
Boot remapper не связан с виртуализацией: он необходим во время начальной загрузки ядра ЦП. На этой аппаратной платформе ядра ЦП всегда начинают выполнение с адреса 0x0. Boot remapper — это дополнительный аппаратный компонент, встроенный вокруг ЦП, который перенаправляет первые 64 или 128 КиБ (0x00000 - 0x20000) в настраиваемую область памяти.
По умолчанию boot remapper указывает на загрузочное ПЗУ (первый код, который выполняется при включении устройства). Позже отображение изменяется так, чтобы другие ядра ЦП сразу начинали выполнение в прошивке EL3 (часть tz), загруженной в ОЗУ:
Обратите внимание, что адрес, к которому обращается ЦП (внутри tz), доступен по двум разным физическим адресам: реальному адресу в ОЗУ (0x8650xxxx) и перенаправленному адресу через boot remapper (0x0000xxxx).
На самом деле существуют два отдельных экземпляра boot remapper:
APCS_BOOT_START_ADDR_SEC (= 0x0b010004), но только в безопасном состоянии.APCS_BOOT_START_ADDR_NSEC (= 0x0b010008), даже в небезопасном состоянии.Оба экземпляра boot remapper могут быть настроены с помощью регистра памяти, содержащего базовый адрес для перенаправленной области и два бита конфигурации: REMAP_EN для включения перенаправления и BOOT_128KB_EN для перенаправления первых 128 КиБ вместо 64 КиБ.
(См. также: Qualcomm Snapdragon 410E Technical Reference Manual rev. D, страницы 85 и 116)
Используя знания из предыдущих двух разделов, основная идея проста: Использовать boot remapper для обхода защиты памяти (трансляции второго уровня) гипервизора.
Boot remapper работает не только во время запуска ЦП. Его можно использовать в любое время, и он предоставляет полный доступ на чтение/запись/исполнение к перенаправленной области. Кроме того, гипервизор Qualcomm, похоже, не препятствует операционной системе настраивать и обращаться к небезопасному экземпляру boot remapper на затронутых устройствах (он не защищен с помощью трансляции второго уровня). Таким образом, проблему легко использовать, выполнив:
hyp, начинающаяся с адреса 0x8640xxxx), после чегоПеренаправленная область может динамически сдвигаться (блок за блоком) для доступа к областям памяти, превышающим 64/128 КиБ, доступным через boot remapper. Также возможно использовать это для полного отключения защиты памяти гипервизора (см. Доказательство концепции).
Примечание: Тот же эксплойт не работает для прошивки безопасного мира (tz). Хотя boot remapper позволяет обойти трансляцию второго уровня, область памяти tz в DRAM, по-видимому, защищена дополнительным аппаратным компонентом (вне ЦП), который блокирует доступ после прохождения через boot remapper:
Область памяти tz, вероятно, доступна только в безопасном состоянии. Эксплойт позволяет обойти только защиту памяти гипервизора; другие механизмы безопасности оборудования остаются в силе.
Boot remapper может быть использован для полного отключения и замены оригинальной прошивки гипервизора во время выполнения, без знания версии прошивки. В частности, нет необходимости использовать обратную разработку для получения адресов переменных и функций, которые можно было бы модифицировать. Достаточно знать приблизительную область памяти прошивки гипервизора, например, из резервирования памяти в коде Linux с открытым исходным кодом или путем чтения заголовков ELF двоичного файла прошивки гипервизора (доступного в разделе hyp на внутреннем накопителе).
Общая идея:
hvc) для переключения из операционной системы в гипервизор (с EL1 на EL2).Код, реализующий это, не длинный, но включает низкоуровневую ассемблерную вставку AArch64 и осторожное взаимодействие с кэшами ЦП. Однако основной вопрос остается открытым: куда именно следует записать шелл-код, чтобы он не был привязан к конкретной версии прошивки гипервизора?
Во время гипервызова (или любого исключения в целом) выполнение ЦП принудительно направляется на специальный адрес памяти: вектор исключения. Векторы исключений являются частью большей таблицы векторов, которая содержит код, обрабатывающий различные типы исключений, поступающих с текущего или более низких уровней исключений:
Каждый прямоугольник представляет вектор исключения с пространством для 32 инструкций ассемблера. Этого пространства недостаточно, поэтому они обычно содержат инструкции ветвления, которые переходят куда-то еще, где больше места для дополнительного кода.
Смещения указываются относительно регистра базового адреса векторов (VBAR), который определяет базовый адрес таблицы векторов для каждого уровня исключений. Гипервизор записывает базовый адрес в регистр VBAR_EL2 ЦП.
Гипервызов — это синхронное исключение, сделанное с более низкого уровня исключений (ядро операционной системы, работающее в EL1, к гипервизору в EL2). Если ядро операционной системы работает в 32-битном режиме, ЦП перейдет по адресу VBAR_EL2+0x600, или по адресу VBAR_EL2+0x400 в 64-битном режиме. После использования boot remapper для записи пользовательского кода по этому адресу и совершения гипервызова ЦП начнет выполнение шелл-кода.
К сожалению, VBAR_EL2 не читается ядром операционной системы, работающим в EL1. Он читается только из гипервизора (EL2) или выше. Тем не менее, это знание значительно упрощает угадывание адреса входа с помощью перебора: базовый адрес таблицы векторов должен быть выровнен по (кратному) ее размеру (0x800 = 2 КиБ). Это означает, что существует только 64 возможных местоположения внутри области размером 128 КиБ, или 512 внутри области размером 1 МиБ:
Красные прямоугольники показывают все возможные местоположения, куда ЦП может перейти во время гипервызова. Запись шелл-кода по всем ним достаточна, чтобы сохранить подход независимым от конкретной версии прошивки (которая на самом деле будет иметь таблицу векторов по одному конкретному адресу).
Это можно улучшить еще больше: boot remapper позволяет как чтение, так и запись, поэтому можно добавить некоторую эвристику, основанную на существующем коде/данных, считанных из местоположений памяти. Они должны содержать допустимые инструкции AArch64 (A64) и, возможно, повторяющиеся байты заполнения, такие как NOP или инструкции ветвления. (Пространство для 32 инструкций на вектор исключения часто используется лишь частично, потому что проще перейти в соответствующую функцию с большим пространством.)
Код доказательства концепции, включенный в этот репозиторий, представляет собой модификацию загрузчика Little Kernel (LK) с открытым исходным кодом Qualcomm для платформы Snapdragon 410 (MSM8916/APQ8016), изначально предназначенную для тестирования с платой разработчика DragonBoard 410c. Все это было выбрано для простоты; проблема также может быть использована из других операционных систем (например, Linux), других затронутых платформ и даже устройств с безопасной загрузкой — при условии, что есть способ выполнить пользовательский код внутри ядра операционной системы.
Код реализует подход, описанный выше, для полного отключения работающего гипервизора, а затем заменяет его другой версией. Новый «гипервизор» не поддерживает никакие виртуальные машины, но способен дать Ответ на Главный Вопрос Жизни, Вселенной и Всего Остального с помощью простого гипервызова:``` $ fastboot oem CVE-2022-22063 < waiting for any device > (bootloader) Hypervisor, what is the Answer to The Ultimate Question of (bootloader) Life, the Universe and Everything? (bootloader) Old hypervisor returned answer: -2 (bootloader) Old non-secure boot remapper base address: 0x100000 (bootloader) Setting boot remapper to hypervisor memory (0x86400000) (bootloader) Using boot remapper to copy shell code to hypervisor memory (bootloader) Copying to all possible vector tables (starting at 0x600) (bootloader) Calling shell code to disable running hypervisor (bootloader) Found old EL2 vector base address at 0x86404000 (bootloader) Copying new code directly to hypervisor memory (0x86400000) (bootloader) Hypervisor, what is the Answer to The Ultimate Question of (bootloader) Life, the Universe and Everything? (bootloader) New hypervisor returned answer: 42 OKAY [ 0.015s] Finished. Total time: 0.015s
### Тестирование
Код доказательства концепции можно собрать и протестировать следующим образом:```shell
$ git clone https://git.codelinaro.org/clo/la/kernel/lk.git -b caf_migration/LA.BR.1.2.9.1_rb1.5
$ cp CVE-2022-22063.c lk/platform/msm8916/
$ git apply LK.diff
# Build LK for msm8916 and flash it to device
$ fastboot oem CVE-2022-22063
...
Однако эта конфигурация подходит только для платы разработки DragonBoard 410c и других устройств без безопасной загрузки, где основной загрузчик можно легко (и безопасно) заменить. Код в этом репозитории предоставлен в первую очередь для ознакомления, а не для простого использования/тестирования.
В будущем планируется интегрировать код в новую версию lk2nd, которую можно будет гораздо проще тестировать на различных устройствах без замены основного загрузчика.
Согласно Qualcomm, проблема была исправлена путем запрета доступа к области перераспределения загрузчика с помощью трансляции второго уровня. Конфигурация перераспределения загрузчика (регистр APCS_BOOT_START_ADDR_NSEC) по-прежнему доступна, но теперь обе области памяти заблокированы:
Другой возможный вариант исправления — защитить регистр APCS_BOOT_START_ADDR_NSEC в гипервизоре. В этом случае перераспределенная область может остаться доступной, так как у операционной системы не будет способа перенастроить перераспределитель загрузчика на другие области памяти.
По словам Qualcomm, с этой проблемой было особенно трудно справиться, поскольку их обычные инструменты автоматизации не могли быть использованы. Большинство получаемых ими проблем являются программными, где затронутые устройства можно определить, проверив исходный код. Для этой проблемы требовалась ручная проверка как аппаратного, так и программного обеспечения (есть ли на платформе проблемный регистр и уязвим ли гипервизор). К сожалению, отказ от автоматизации также означал, что проблема не была автоматически запланирована в бюллетене безопасности. Второе продление эмбарго было запрошено для того, чтобы уведомить клиентов о проблеме безопасности и дать им время на установку исправлений. Они работают над улучшением процесса, чтобы избежать подобных проблем в будущих отчетах.
Отчет о CVE-2022-22063 и диаграммы © 2022 by Stephan Gerhold лицензированы в соответствии с Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0).
Код proof of concept (CVE-2022-22063.c) предоставляется под лицензией MIT.