Windows 8 – да будет SMEP!

» ); wnd.document.close(); wnd.focus(); }

С приходом нового поколения процессоров Intel на базе архитектуры Ivy Bridge было представлено новое аппаратное средство безопасности. Оно называется Intel SMEP.

Авторы: Артём Шишкин и Илья Смит

С приходом нового поколения процессоров Intel на базе архитектуры Ivy Bridge было представлено новое аппаратное средство безопасности. Оно называется Intel SMEP. Как и бит NX, предотвращающий исполнение кода на странице памяти, оно добавляет головной боли при эксплуатации уязвимостей режима ядра.

В свою очередь Microsoft реализовала поддержку SMEP в Windows 8, таким образом сделав эту ОС ещё безопасней. Однако, первая реализация «в лоб» поддержки SMEP получилась с небольшим изъяном, благодаря которому у атакующего всё ещё есть возможность относительно безболезненной для него эксплуатации уязвимостей.

Что такое SMEP?

SMEP расшифровывается как “Supervisor Mode Execution Prevention” — предотвращение исполнения кода в режиме супервизора. Режим супервизора – это привилегированный режим работы процессора, в котором исполняется ядро ОС Windows 8. В понятиях ОС этот режим называется также режимом ядра. Противоположным ему является режим пользователя – в этом режиме исполняются пользовательские приложения.

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

Привилегированный режим в свою очередь не имеет никаких ограничений, если бы не SMEP. Если он включен, любая попытка выполнить код, находящийся в памяти пользовательского приложения, приведет к ошибке страницы (page fault). В частности, в обработчике ошибок страниц на Windows 8 данная ситуация вызовет bugcheck.

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

А смысл?

Уязвимости режима ядра – самые «вкусные» для атакующего, поскольку при успешной эксплуатации он получает полный контроль над целевой системой. Смысл в том, что при эксплуатации уязвимостей режима ядра атакующий, как правило, выделяет для хранения шелл-кода память в пользовательском режиме.

«Но в режиме ядра теперь нельзя исполнять код со страниц памяти пользователя! А где теперь-то хранить шелл-код? А в чём смысл атаки без собственного шелл-кода? А может, и не надо тогда атаковать?»

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

Первый блин комом

Давайте размышлять. В пользовательском пространстве хранить шелл-код нельзя. Значит, он должен располагаться в памяти ядра (выбор не велик – всего два режима), содержимое этого участка памяти должно быть нам подконтрольно (нельзя же писать из пользовательского режима напрямую), и должна быть возможность узнать адрес этого участка памяти из пользовательского режима (нельзя и читать из пользовательского режима напрямую). Что можно использовать для доставки шелл-кода в ядро?

Самое очевидное решение – использовать объекты Windows. Те самые, с которыми приложения работают через описатели (handle). Это всевозможные таймеры, события, мьютексы, порты завершения ввода-вывода, графические объекты и т.д. Тело такого объекта располагается в памяти ядра, а содержимое может быть изменено из пользовательского режима, и мы можем узнать, по какому адресу в пространстве ядра они расположены!

К примеру, когда мы открываем файл функцией CreateFile(), мы получаем описатель открытого файла. Если приложению нужно считать пару байт этого файла в буфер, то мы вызываем функцию ReadFile(), которая при помощи системного вызова передает управление в ядро ОС, где по таблице описателей находит нужный объект файла. В данном случае объект имеет тип _FILE_OBJECT, и изменяемым полем в нём является имя файла. Т.е. теоретически можно создать файл с именем «xBAADC0DE», которое будет содержать наш шелл-код. Затем мы эксплуатируем некую уязвимость режима ядра и передаем управление на наш шелл-код.

0: kd> dt nt!_FILE_OBJECT
+0x000 Type: Int2B
+0x002 Size: Int2B

+0x050 Flags: Uint4B
+0x058 FileName: _UNICODE_STRING
+0x068 CurrentByteOffset: _LARGE_INTEGER

+0x0c0 IrpList: _LIST_ENTRY
+0x0d0 FileObjectExtension: Ptr64 Void

Успех? Пока ещё не совсем. Дело в том, что SMEP на Windows 8 дополняется другим механизмом защиты. Несмотря на то, что код расположен на странице режима ядра, эта страница имеет пометку (бит NX) о том, что она неисполняемая, т.е. на этой странице не может исполняться код! Получается, что объекты Windows защищены от исполнения, следовательно, тоже не подходят для хранения шелл-кода. Это утверждение верно для х64 версии Windows 8. Однако в x86 версии тела графических объектов располагаются в исполняемой памяти!

Самым подходящим объектом для доставки шелл-кода оказалась палитра. Создается она при помощи функции CreatePalette() и структуры LOGPALETTE, содержимое которой и наполняется шелл-кодом. Ещё бы, как валидировать цвета в палитре? Ведь в нашей палитре будут именно те цвета, которые мы захотим! А мы захотим много байт NOP (0x90), и много байт шелл-кода. Вот такая получается «злая» палитра…

Итого имеем схему обхода SMEP на Windows 8 x86: 

А что делать с х64?

Хотите обход SMEP на Windows 8 x64? Их есть у меня! Возможно способ не такой интересный, но зато рабочий. SMEP на x64 обходится при помощи возвратно-ориентированного программирования (ROP). Если кратко, то ROP использует уже присутствующие в памяти участки кода из других модулей. Таким образом, пробрасывать свой шелл-код в ядро не нужно.

Конечно, возможности атакующего при составлении полезной нагрузки в данном случае сильно ограничены. Но всё, что нужно атакующему – отключить SMEP, а для этого в модуле «ntoskrnl» есть «подарочки» в виде функций HvlEndSystemInterrupt() и KiConfigureDynamicProcessor(). Последние байты этих функций позволяют отключить SMEP на заданном процессоре.

HvlEndSystemInterrupt():

 … 

pop rax 

pop rcx 

retn 


KiConfigureDynamicProcessor(): 

… 

mov cr4, rax 

add rsp, 28h retn

// ROP chain to refresh cr4 value


// vTrash vROPChain 

DWORD_PTR dwRopStack[7 + 10] = {0}; 

// HvlEndSystemInterrupt gadget 

dwRopStack[7 + 0] = dwKernelBase + HvlGadgetOffset; 


// New CR4 value 

dwRopStack[7 + 1] = 0x00000000000506F8; 


// KiConfigureDynamicProcessor 

dwRopStack[7 + 3] = dwKernelBase + Cr4GadgetOffset;


// Out address (shellcode) 

dwRopStack[7 + 9] = (DWORD_PTR)pTestBuf;

Долой ограничения

После того как SMEP отключен, атакующий получает возможность исполнять код из пользовательского буфера, т.е. ограничений на размер шелл-кода больше нет. Можно использовать уязвимость ядра, которая была применена для отключения SMEP, для передачи уже на «злой» шелл-код.

Заключение

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

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

P.S. SMEP отключается 13-ю байтами кода. За подробностями прошу по ссылкам ниже.
Как победить SMEP на Windows 8 x86rel=»nofollow»>
Как победить SMEP на Windows 8 x64

rel=»nofollow»>

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

18 октября, 2012

Местные провайдеры на один день заблокировали доступ ко всем ресурсам, содержащим слово ubuntu.

15 октября, 2012

Помимо темы жестких дисков, Торвальдс указал на правовые излишества в сфере патентов.

22 октября, 2012

По мнению министра, отрасль остро нуждается в квалифицированных кадрах, которые необходимо привлекать…

19 октября, 2012

Госдума должна рассмотреть ряд законопроектов, устанавливающих лимит на хранение в Сети пользовательских…

16 октября, 2012

В результате мошеннической деятельности пострадавшему был нанесен ущерб в размере 7,7 млн руб.

18 октября, 2012

Истцы утверждают, что Роскомнадзор бездействовал, пока лицензиат не выполнял требования, предусмотренные…

19 октября, 2012

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

18 октября, 2012

По мнению правообладателей, социальная сеть распространяет определенный контент, не имея на это их согласия.

19 октября, 2012

Правоохранительные органы выиграли суд по блокировке доступа к сайтам с запрещенной книгой.

19 октября, 2012

ФАС возбудила против компании уголовное дело после получения жалобы от одного из пользователей услуг…


22 октября, 201219 октября, 201217 октября, 201215 октября, 201212 октября, 2012

Источник: http://www.securitylab.ru/analytics/430472.php

Источник: lred.ru

Оцените статью
новости для мужчин