oldi

Технологии защиты приложений в Windows Vista и Windows Server 2008

Алексей Федоров

Проверка переполнения буфера стека

Защита при обработке исключений

Поддержка No eXecute (NX), Data Execution Prevention (DEP) и eXecute Disable (XD)

Случайное распределение адресного пространства — Address space layout randomization (ASLR)

Случайное распределение «кучи»

Определение повреждения «кучи»

 

Ряд расширений, появившихся в новой версии клиентской операционной системы Microsoft Windows Vista, а также планируемых к появлению в Windows Server 2008, предназначен для обеспечения защиты приложений и соответственно пользователей этих приложений от вредоносного кода. В настоящем обзоре мы ознакомимся с некоторыми из этих расширений, реализованными как на уровне ядра операционной системы, так и средствами компилятора Microsoft Visual C++, а также со способами включения этих расширений в «неуправляемый» код, написанный на языках С и С++.

Проверка переполнения буфера стека

Проверка переполнения буфера стека поддерживается на уровне компилятора языка С/С++ начиная с версии Visual Studio .NET 2002. Используя опцию компилятора /GS (она поддерживается по умолчанию в Visual C++, даже если ее нет в командной строке), мы указываем на необходимость вставки кода пролога и эпилога для функции. Этот код генерирует случайное число (называемое Security Cookie), которое помещается в стек функции. Если сгенерированное случайное число окажется «испорченным», вызывается код завершения приложения — таким образом снижается вероятность запуска «эксплойтов», базирующихся на возможности переполнения буфера.

В Visual C++ 2005 код пролога и эпилога выглядит следующим образом:

 

// Пролог

  sub    esp, 8

  mov    eax, DWORD PTR ___security_cookie

  xor    eax, esp

  mov    DWORD PTR __$ArrayPad$[esp+8], eax

  mov    eax, DWORD PTR _input$[esp+4]

// Эпилог

  mov    ecx, DWORD PTR __$ArrayPad$[esp+12]

  add    esp, 4

  xor    ecx, esp

  call   @__security_check_cookie@4

  add    esp, 8

 

Отметим, что компилятор Visual C++ 2005 также включает код, перемещающий данные по стеку, что тоже затрудняет выполнение вредоносных операций. В частности, компилятор позволяет размещать буферы в верхнюю область памяти — это позволяет защитить указатели на функции, расположенные в стеке. Перемещение указателей и аргументов буфера в нижнюю часть памяти также позволяет значительно снизить вероятность атак на буфер и использования переполнения буфера. Разработчикам рекомендуется применять самую актуальную версию компилятора Visual C++ и всегда указывать опцию /GS при компиляции приложений и библиотек.

В Visual C++ 2005 SP1 появился ряд новых прагм (pragma) со следующим синтаксисом:

 

#pragma strict_gs_check([push,] on )

#pragma strict_gs_check([push,] off )

#pragma strict_gs_check(pop)

 

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

С подробным описанием опции комплилятора /GS можно ознакомиться на сайте MSDN по адресу: http://msdn2.microsoft.com/en-US/library/8dbf701c.aspx.

Защита при обработке исключений

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

Компоновщик, входящий в состав Visual Studio 2003 и более поздних версий продукта, имеет опцию (/SafeSEH), позволяющую хранить ссылки на обработчики исключений в заголовке образа исполняемого файла (PE Header).

При возникновении исключительной ситуации операционная система использует адрес обработчика, хранящийся в заголовке PE, — такая функциональность поддерживается начиная с Windows XP SP2 и является стандартной для Windows Server 2003, Windows Vista, Windows Server 2008 и будущих версий клиентской и серверной операционных систем компании Microsoft.

Подробное описание опции компоновщика /SafeSEH можно найти на сайте MSDN по адресу: http://msdn2.microsoft.com/en-US/library/9a89h429.aspx.

Поддержка No eXecute (NX), Data Execution Prevention (DEP) и eXecute Disable (XD)

Ряд технологий — No eXecute (NX) компании Advanced Micro Devices (AMD), Data Execution Prevention (предотвращение выполнения данных, DEP) компании Microsoft и eXecute Disable (XD) компании Intel — предотвращает возможность выполнения кода в сегментах, предназначенных для хранения данных. Все современные процессоры компаний Intel и AMD поддерживают технологии XD и NX соответственно. Поддержка Data Execution Prevention была впервые реализована в Windows XP SP2 и является одной из ключевых для обеспечения безопасного выполнения кода в Windows Vista, особенно когда она используется совместно с технологией Address Space Layout Randomization (ASLR), которую мы рассмотрим ниже. В силу определенной специфики Data Execution Prevention несовместима с приложениями, содержащими самомодифицируемый код, а также с приложениями, реализующими компиляцию в режиме выполнения, — при запуске таких приложений произойдет ошибка. Если создаваемые вами приложения содержат самомодифицирущийся код или выполняют компиляцию в режиме выполнения, следует использовать функцию VirtualProtect() с аргументом PAGE_EXECUTE_READ для определения наличия защиты от выполнения кода в сегментах, предназначенных для хранения данных, и для корректного завершения приложения с соответствующим сообщением об ошибке.

Разработчикам рекомендуется протестировать работу приложения под процессорами, поддерживающими технологии XD и NX, внести необходимые корректировки в код и перекомпилировать приложения, используя опцию компилятора /NXCOMPAT.

 

Настройки Data Execution Prevention
в Windows XP SP2 и Windows Vista

Получение данных о Data Execution Prevention через WMI

На уровне операционной системы в Windows XP SP2 и Windows Server 2003 настройка Data Execution Prevention определяется параметрами в файле Boot.ini — эти параметры могут задаваться в панели управления: System Properties => Advanced => Performance => Data Execution Prevention . Windows поддерживает четыре возможных значения для Data Execution Prevention — при каждом из них может применяться как программная, так и аппаратная реализация этой технологии.

Возможные настройки Data Execution Prevention показаны в табл 1.

Таблица 1

Настройка

Описание

OptIn

Используется по умолчанию. На компьютерах, оснащенных процессорами с поддержкой DEP, функция DEP включена по умолчанию для ограниченного числа системных файлов
и программ. При этом по умолчанию защищаются только системные файлы Windows

OptOut

По умолчанию функция DEP включена для всех процессов. В диалоговом окне Система панели управления можно вручную создать список приложений, для которых следует отключить DEP. Для отключения функции DEP для одной или более программ можно использовать Application Compatibility Toolkit — в этом случае будут применены исправления, обеспечивающие совместимость программ с DEP

AlwaysOn

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

AlwaysOff

Функция DEP отключена для всей системы независимо от наличия аппаратной поддержки DEP. Процессор не работает в режиме PAE, если в файле Boot.ini не указан параметр /PAE

Если на уровне системы для функции DEP выбран режим OptIn, то основные программы и файлы Windows будут защищены как программной, так и аппаратной реализацией DEP.

Если система не может использовать аппаратную реализацию DEP, то указанные программы и файлы Windows будут защищены только программной реализацией DEP.

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

Параметры, указываемые в файле Boot.ini, выглядят так:

 

/noexecute=[AlwaysOn, AlwaysOff, OptIn или OptOut]

 

Содержимое файла Boot.ini может выглядеть следующим образом:

 

[boot loader]

timeout=30

default=multi(0)disk(0)rdisk(0)partition(1)\

WINDOWS

[operating systems]

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=”Microsoft Windows XP Home Edition” /fastdetect /NoExecute=OptIn

multi(0)disk(0)rdisk(0)partition(2)\WINDOWS=”Windows XP x64 Edition 2003" /fastdetect

 

Для проверки поддержки Data Execution Prevention на аппаратном уровне можно воспользоваться одним из следующих методов: использовать утилиту WMIC или утилиту WBEMTest.

В первом случае мы выполняем следующую команду:

 

C:\>wmic OS Get DataExecutionPrevention_Available

 

Если возвращается значение True, аппаратная поддержка DEP доступна, в противном случае возвращается значение False. Уровень поддержки DEP можно определить командой

 

C:\>wmic OS Get DataExecutionPrevention_SupportPolicy,

 

которая может вернуть одно из следующих значений: 0 — AlwaysOff, 1 — AlwaysOn, 2 — OptIn (значение по умолчанию) или 3 — OptOut.

С помощью утилиты WBEMTest мы можем выполнить следующие действия:

  1. В диалоговой панели Windows Management Instrumentation Tester нажмем кнопку Connect и укажем значение root\cimv2 .
  2. Нажмем кнопку Enum Instances и в диалоговой панели Class Info введем Win32_OperatingSystem .
  3. В диалоговой панели Query Result выберем самый первый элемент и двойным щелчком мышью перейдем в Object Editor .
  4. В списке свойств найдем DataExecutionPrevention_Available и обратим внимание на значение этого свойства — оно может иметь одно из значений, описанных нами при обсуждении использования утилиты WMIC.

С помощью Windows PowerShell также можно получить информацию о настройках Data Execution Prevention.

Сначала выполним команду:

 

PS C:\> Get-WMIObject Win32_OperatingSystem | Get-Member DataExecutionPrevention*

 

для получения всех возможных свойств объекта Win32_OperatingSystem, используемых для хранения данных о DEP. Таких свойств четыре: Data Execution Prevention_32BitApplications, Data Execution Prevention_Available, Data Execution Prevention_Drivers и Data Execution Prevention_SupportPolicy. После этого мы можем получить значения каждого из перечисленных выше свойств (табл. 2).

Таблица 2

Свойство

Возможные значения

Data Execution Prevention_32BitApplications

TRUE — DEP активирована для приложенийFALSE — DEP не активирована для приложений

Data Execution Prevention_Available

TRUE — DEP активированаFALSE — DEP не активирована

Data Execution Prevention_Drivers

TRUE — DEP активирована для драйверовFALSE — DEP не активирована для драйверов

Data Execution Prevention_SupportPolicy

0 — DEP запрещена для всех процессов1 —  DEP разрешена для всех процессов2 — DEP разрешена для системных компонентов Windows3 — DEP разрешена для всех компонентов, кроме помеченных специальным образом

Например:

 

$OS = Get-WMIObject Win32_OperatingSystem

Echo $OS.Data Execution Prevention_32BitApplications

 

Более подробно о функции VirtualProtect() можно узнать на сайте MSDN по адресу: http://msdn2.microsoft.com/En-US/library/aa366898.aspx, о процессорах ADM — на сайте http://www.amd.com/us-en/Processors/ (в описании процессора должна быть указана поддержка NX). Информация о процессорах Intel приведена на сайте http://www.intel.com/products/processor/ (в описании процессора должна быть указана поддержка XD).

Технология Data Execution Prevention описана на сайте Microsoft по адресу: http://support.microsoft.com/kb/875352. Также см. статью Memory Protection Technologies на сайте Microsoft TechNet по адресу: http://technet.microsoft.com/en-us/library/bb457155.aspx.

Подробное описание опции компоновщика /NXCOMPAT приведено на сайте MSDN по адресу: http://msdn2.microsoft.com/en-US/library/ms235442.aspx.

Случайное распределение адресного пространства — Address space layout randomization (ASLR)

Технология случайного распределения адресного пространства (ASLR) перемещает бинарный образ исполняемого кода в случайную область памяти — поддерживается до 255 различных адресов, что значительно снижает вероятность успешного проведения атаки типа return-to-libc и схожих с ней. По умолчанию в Windows Vista случайным образом загружаются системные исполняемые файлы (EXE) и динамические библиотеки (DLL). Исполняемые файлы и днамические библиотеки, создаваемые сторонными разработчиками, должны быть слинкованы (используется компоновщик Microsoft Linker версии 8.00.50727.161 или более поздней) с применением опции /DYNAMICBASE для того, чтобы на них распространялась ASLR.

Случайное распределение «кучи»

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

Случайное распределение стека

При создании потока для процесса, помеченного с помощью опции /DYNAMICBASE, Windows Vista перемещает стек потока в случайным образом выбранную область памяти. Тем самым снижается шанс успешного выполнения атаки, основанной на переполнении буфера, располагаемого в стеке.

Определение повреждения «кучи»

С помощью функции HeapEnableTerminationOnCorruption() можно включить проверку повреждения «кучи», что приведет к завершению процесса при обнаружении повреждений. Далее приведен пример кода, показывающий использование данной функции:

 

BOOL SetHeapOptions()

{

 HMODULE hLib = LoadLibrary(L”kernel32.dll”);

 if (hLib == NULL) return FALSE;

 typedef BOOL (WINAPI *HSI) (HANDLE, HEAP_INFORMATION_CLASS ,PVOID, SIZE_T);

 HSI pHsi = (HSI)GetProcAddress(hLib,”HeapSetInformation”);

 if (!pHsi)

 {

  FreeLibrary(hLib);

  return FALSE;

 }

 #ifndef HeapEnableTerminationOnCorruption

#define HeapEnableTerminationOnCorruption

(HEAP_INFORMATION_CLASS)1

 #endif

BOOL fRet = (pHsi)(NULL,HeapEnableTerminationOnCorruption,

NULL,0) ? TRUE : FALSE;

 if (hLib) FreeLibrary(hLib);

  return fRet;

}

 

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

 

В начало В начало

КомпьютерПресс 7'2007