[Перевод] Введение в аппаратную защиту стека (Windows 10)

[Перевод] Введение в аппаратную защиту стека (Windows 10) Под катом представлен перевод статьи «Understanding Hardware-enforced Stack Protection«.

Авторы: Kernel protection team — Jin Lin, Jason Lin, Niraj Majmudar, Greg Colombo

Это первая (обзорная) публикация задуманной серии из двух переводов о внедрении Intel’овской технологии Control-flow Enforcement в Winsows 10.


Мы стремимся сделать Windows 10 одной из самых безопасных операционных систем для наших клиентов, и для этого мы инвестируем во множество функций безопасности. Наша философия заключается в создании функций, которые снижают эффективность широкого класса уязвимостей (в идеале без изменения кода приложения). В MSDN есть отдельная статья «Mitigate threats by using Windows 10 security features», которая агрегирует все технологии, ориентированные на безопасность, которые мы встроили в Windows на протяжении многих лет. В этой статье так же описано, как каждая из функций обеспечивает безопасность наших клиентов. А так же есть еще презентация Matt Miller и David Weston, которую можно рекомендовать к прочтению после статьи MSDN. Презентация углубляется в нашу философию безопасности.

В настоящее время мы изучаем функции безопасности, основанные на аппаратной интеграции. Это позволит нам существенно поднять планку защиты от атак. Благодаря глубокой интеграции ядра Windows с аппаратным обеспечением злоумышленникам станет сложно и дорого проводить масштабные атаки.

Основываясь на проведенных исследованиях (Evolution of CFI attacks, Joe Bialek), можно заявить, что атаки на основе ROP (Return Oriented Programming, Возвратно-ориентированное программирование) стали очень распространенным инструментом злоумышленников. Следовательно, они являются следующей целью для встроенных упреждающих технологий безопасности Windows. В этой публикации мы опишем наши усилия по укреплению целостности потока управления в Windows 10 с помощью аппаратной защиты стека.

Уязвимости безопасности памяти

Наиболее распространенным классом уязвимостей, встречающимся в системном программном обеспечении, являются уязвимости безопасности памяти. Этот класс включает переполнения буфера, висячие указатели (dangling pointers), неинициализированные переменные и прочее.

Каноническим примером переполнения стекового буфера является копирование данных из одного буфера в другой без проверки границ (использование strcpy). Если атакующий контролирует данные исходного буфера и размер, то целевой буфер и важные компоненты стека (например: адрес возврата) могут быть повреждены, что бы указывать на нужный злоумышленнику код.

Висячие указатели (dangling pointers) возникают, когда память, на которую ссылается указатель, освобождена, но указатель на эту память все еще существует. В эксплойтах use-after-free (использование после освобождения) атакующий может читать/писать через висячий указатель, который теперь указывает на совершенно другую память (а не на ту, что рассчитывал программист).

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

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

Исполнение произвольного кода

Мы формулируем нашу стратегию противодействия исполнению произвольного кода в форме четырех столпов:

Code Integrity Guard (CIG) предъявляет обязательное требование к подписи загружаемых двоичных файлов.

Arbitrary Code Guard (ACG) гарантирует, что подписанные страницы неизменны, а динамический код не может быть сгенерирован, что гарантирует целостность загружаемых двоичных файлов.

С введением CIG и ACG злоумышленники все чаще прибегают к перехвату управления с помощью косвенных вызовов и возвратов, известных как Call/Jump Oriented Programming (COP/JOP) и Return Oriented Programming (ROP).

Мы внедрили Control Flow Guard (CFG) в Windows 10 для обеспечения целостности при косвенных вызовах (контроль прямой передачи управления, forward-edge CFI). А аппаратная защита с помощью теневых стеков (Shadow Stacks) обеспечивает целостность обратной передачи управления (backward-edge CFI).

Суть ROP

В системном программном обеспечении, если злоумышленник обнаружит в коде уязвимость безопасности памяти, обратный адрес может быть взломан для передачи управления на определенный атакующим адрес. Здесь начинаются трудности для злоумышленника: невозможно передать управление на произвольный адрес, благодаря уже внедренным технологиям Data Execution Prevention (DEP) и Address Space Layout Randomization (ASLR). Но управление может быть передано фрагментам кода (гаджетам) в существующей исполняемой памяти. Злоумышленники могут найти гаджеты, которые заканчиваются командой RET (или другими инструкциями ветвления), а цепочкой из нескольких гаджетов можно воспользоваться для выполнения вредоносных действий (отключить функции зашиты), что бы в конце концов выполнить произвольный нативный код.

Стоит отдельно отметить, что аппаратная защита стека будет работать только на чипсетах с Intel’овскими инструкциями Control-flow Enforcement Technology (CET). Подробности о CET можно почерпнуть в официальном документе от Intel.

В этой публикации мы в общих чертах опишем соответствующие части реализации Windows 10. Эта технология работает одновременно с обычным стеком программных вызовов, сохраняя записи об адресах возврата в теневой стек (Shadow Stack). Во время обработки каждой инструкции CALL адрес возврата помещается как в стек вызовов, так и в теневой стек. А в момент обработки инструкции RET выполняется сравнение адресов возврата из обычного стека вызовов и теневого стека, чтобы гарантировать, что целостность не нарушена.

Если адреса не совпадают, процессор генерирует исключение защиты управления (control protection, #CP). Ядро Windows реагирует на исключение процессора и уничтожает процесс, что бы гаранитровать безопасность.

Теневой стек (Shadow Stack) хранит только адреса возвратов, что позволяет минимизировать дополнительные затраты памяти.

Теневые стеки (Shadow Stacks) CET

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

Оборудование имеет новый регистр SSP, который содержит адрес (указатель) теневого стека. Аппаратное обеспечение также подразумевает расширение таблиц страниц для идентификации страниц теневого стека и защиты этих страниц от атак.

Для управления страницами теневого стека были добавлены новые инструкции:

  • INCSSP — инкремент SSP (например для раскрутки теневого стека)
  • RDSSP — чтение SSP в регистр общего назначения
  • SAVEPREVSSP/RSTORSSP — сохранение/восстановление теневого стека (например, для переключения контекста)

Более детальную информацию о реализации можно найти в Intel’овском мануале по CET.

Компиляция с аппаратной поддержкой защиты стека

Для включения аппаратной поддержкой защиты стека в вашем приложении появился новый флаг линкера, выставляющий соответствующий бит в PE заголовке, который запрашивает новые функции защиты у ядра.

Если у приложения выставлен этот бит, а текущая версия Windows и аппаратное обеспечение поддерживают теневые стеки, то ядро будет поддерживать работу теневых стеков на всем протяжении работы программы. Если ваша версия Windows или аппаратное обеспечение не поддерживают теневые стеки, то соответствующий бит в PE заголовке игнорируется.

Такая модель применения защиты (opt-in: опциональное использование при желании и возможности) позволит разработчикам сначала внимательно протестировать свое приложение с аппаратной защитой стека, а уже затем добавить флаг совместимости в релиз.

Функция аппаратной защиты стека находится в стадии разработки, но попробовать в ознакомительном режиме ее можно в Insider preview-сборках Windows 10. Если у вас есть аппаратное обеспечение, совместимое с Intel’овской CET, вы можете включить приведенный выше флаг компоновщика в своем приложении для тестирования на последних Insider preview-сборках Windows 10.

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

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


Мини конкурс

Бонусом, для дочитавших (или просколливших) до конца я предлагаю небольшой конкурс. Если кто-то случайно (или не случайно) догадался перевод какой статьи (уже опубликованной в интернете на текущий момент) я готовлю во второй части — пишите в комментарии. Призом для первого угадавшего будет… ну, например, плюс в карму 🙂 Если нужны идеи, то в качестве подсказки можно посмотреть в самое начало этой публикации.

 

Источник

CET, Control Flow, Control Flow Enforcement, Return Oriented Programming, ROP, Shadow Stack

Читайте также