Атака на Intel SGX, позволяющая извлечь конфиденциальные данные или выполнить код в анклаве

Исследователи из Оборонного научно-технического университета Народно-освободительной армии Китая, Национального университета Сингапура и Швейцарской высшей технической школы Цюриха разработали новый метод атаки на изолированные анклавы Intel SGX (Software Guard eXtensions). Атака получила название SmashEx и вызвана проблемами с реентерабельностью при обработке исключительных ситуаций в процессе работы runtime-компонентов для Intel SGX. Предложенный метод атаки даёт возможность при наличии контроля за операционной системой определить конфиденциальные данные, размещённые в анклаве, или организовать копирование своего кода в память анклава и его исполнение.

Прототипы эксплоитов подготовлены для анклавов с runtime на базе Intel SGX SDK (CVE-2021-0186) и Microsoft Open Enclave (CVE-2021-33767). В первом случае продемонстрирована возможность извлечения RSA-ключа, применяемого на web-сервере для HTTPS, а во втором удалось определить содержимое, полученной утилитой cURL, запущенной внутри анклава. Уязвимость уже устранена программным путём в выпусках Intel SGX SDK 2.13 и Open Enclave 0.17.1. Кроме пакетов Intel SGX SDK и Microsoft Open Enclave уязвимость также проявляется в SDK Google Asylo, EdgelessRT, Apache Teaclave, Rust SGX SDK, SGX-LKL, CoSMIX и Veracruz.

Напомним, что технология SGX (Software Guard Extensions) появилась в процессорах Intel Core шестого поколения (Skylake) и предлагает серию инструкций, позволяющих выделять приложениям пользовательского уровня закрытые области памяти – анклавы, содержимое которых не может быть прочитано и изменено даже ядром и кодом, выполняемым в режимах ring0, SMM и VMM. Передать управление коду в анклаве невозможно традиционными функциями перехода и манипуляциями с регистрами и стеком – для передачи управления в анклав применяются специально созданные новые инструкции EENTER, EEXIT и ERESUME, выполняющие проверку полномочий. При этом помещённый в анклав код может применять классические методы вызова для обращения к функциям внутри анклава и специальную инструкцию для вызова внешних функций. Для защиты от аппаратных атак, таких как подключение к модулю DRAM, применяется шифрование памяти анклава.


Проблема связана с тем, что технология SGX позволяет операционной системе прервать выполнение анклава через генерацию аппаратного исключения, а в анклавах должным образом не реализуются примитивы для атомарной обработки подобных исключений. В отличие от ядра операционной системы и обычных приложений, код внутри анклавов не имеет доступ к примитивам для организации атомарных действий во время обработки асинхронно возникающих исключений. Без указанных атомарных примитивов анклав может быть в любое время прерван и возвращён к выполнению, даже в моменты когда в анклаве выполняются критические секции и он находится в небезопасном состоянии (например, когда не сохранены/восстановлены регистры CPU).


Предоставляемые в SDK runtime-окружения для анклавов включают обработчики сигналов и исключительных ситуаций, но некорректно реагируют на реентерабельность. Атака SmashEx основывается на эксплуатации недоработок в SDK из-за которых должным образом не обрабатывается ситуация повторного вызова обработчика исключения. Важно, что для эксплуатации уязвимости атакующий должен иметь возможность прервать выполнение анклава, т.е. должен контролировать работу системного окружения.

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

Система затем может вернуть управление обратно в анклав, но так как стек анклава во время прерывания не был настроен, анклав будет выполняться со стеком, находящимся в памяти системы, что можно использовать для применения методов эксплуатации на основе возвратно-ориентированного программирования (ROP – Return-Oriented Programming). При использовании техники ROP атакующий не пытается разместить свой код в памяти, а оперирует уже имеющимися в загруженных библиотеках кусками машинных инструкций, завершающихся инструкцией возврата управления (как правило, это окончания библиотечных функций). Работа эксплоита сводится к построению цепочки вызовов подобных блоков (“гаджетов”) для получения нужной функциональности.




Release. Ссылка here.