Фазили, фазили … и наконец нафазили. А дальше что?

Так уж получилось, что я по большей части «фаззю для того что бы фаззить». Спортивный интерес. Однако, для того что бы отделить обычные сбои от сбоев, которые могут привести к уязвимости безопасности, полезно представлять текущее положение в деле выявления возможных уязвимостей. Поэтому я написал небольшой обзор. На полноту он не претендует, но для «погружения в тему», думаю, сойдет.

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

  • удаленно выполнить код;
  • инициировать отказ обслуживания;
  • обойти заданную политику безопасности (например, повысить привилегии).

Вопрос автоматической классификации сбоев по рискам безопасности интересует многих исследователей [1,2,3]. Главный вопрос, который приходится решать при подобной автоматической классификации: могут ли данные, приведшие к сбою, быть изменены посредством пользовательского ввода. К примеру, предположим, что сбой произошел на следующей инструкции: call [eax]. Исключение 0xc0000005 — STATUS_ACCESS_VIOLATION. Произошла попытка обращения к неверному участку памяти. В случае если значение регистра eax равно NULL и логика программы не дает возможность изменить содержимое данного регистра, максимальное последствие к которому может привести сбой – отказ обслуживания. Другое дело, если значение регистра можно изменить (например, в результате переполнения). В этом случае это уже потенциальная возможность передачи управления на заданный адрес.

Наиболее распространенный вид сбоев – необработанное программное или аппаратное исключение. В таблице ниже приведены виды исключений и риски безопасности при данном виде сбоя[2]    .

Исключение Возможна ли эксплуатация Комментарий
Нарушение прав доступа для операции записи Практически всегда Попытка записи в область памяти не разрешенную для записи
Нарушение прав доступа для операции чтения на указателе команды (нарушение прав доступа на EIP) Практически всегда Есть возможность установить EIP на заданный участок памяти
Нарушение прав доступа для операции чтения Возможна В случае если исключение происходит при копировании с префиксом rep при большом ecx или, если читаемое значение позже используется как счетчик
Не возможна При чтении по нулевому адресу или по неизменяемому адресу
Деление на нуль Не возможна Если обработчик не подменен
Исключение C++ Не возможна Если обработчик не подменен

Таким образом, при анализе сбоя на предмет возможности эксплуатации можно пользоваться схемой, изображенной на рисунке 1.


Рисунок 1 – Схема анализа сбоя на возможность эксплуатации[2]

 

Задача автоматического определения возможности влияния пользовательскими данными на данные, приводящие к сбою, успешно решается с помощью taint-анализа[3]. Суть метода заключается в анализе параметров инструкций и оценке их влияния друг на друга. В качестве параметров инструкции могут выступать следующие контейнеры:

  • регистры процессора общего назначения;
  • специальные регистры, такие как EFLAGS;
  • ячейки памяти;

Параметры, явные и неявные, разделяются на входные и выходные. Значение контейнеров входных параметров получается либо на предыдущих шагах программы, либо являются константами. Любые данные получаемые от пользователя (через поля ввода, из фалов, из сети) считаются не доверительными, контейнеры в которые они располагаются, помечаются. Далее, если помеченные контейнеры участвуют в операции и влияют на результат, то контейнер результата так же получает метку. Метка может быть отменена, если в контейнер будут помещены данные из непомеченного контейнера. Рассмотрим пример:


mov ebx, eax
add ecx, ebx
xor eax, eax
mov [ecx],9090h

Будем считать, что регистр eax получил свое значение из пользовательского ввода (например, через параметр функции), а значит он автоматически помечается. Оператор mov ebx, eax копирует значение регистра eax в ebx. После этой операции ebx так же следует пометить. Оператор xor eax, eax действует так же как mov eax, 0. В eax помещается значение, на которое априори не может повлиять пользовательский ввод. С этого момента регистр eax теряет метку. Однако ecx все еще отмечен и по этой причине команда mov [ecx], 9090h является уязвимым местом, она позволяет записать 9090h (две операции nop) в область памяти, которую можно задать через пользовательский ввод.

Taint-анализ используется во многих утилитах[1, 3, 5]. Для анализа дампов сбоев такой анализ используется в модуле !exploitable[ 1 ] для отладчика WinDbg компании Microsoft. Модуль позволяет выполнить следующие основные функции:

  • из наборов дампов для сбоев выделить уникальные;
  • оценить риск безопасности для сбоя по шкале: может быть использован, вероятно может быть использован, вероятно не может быть использован, не может быть использован.

Другой модуль для того же отладчика vdt_trace[3] позволяет отследить поток данный и предоставляет данные необходимые для подготовки эксплоита.

  1. Страница проекта Microsoft !exploitable. http://msecdbg.codeplex.com.
  2. Abouchaev, Adel; Hasse, Damian; Lambert, Scott; Wroblewski, Greg. Analyze crashes to find security vulnerabilities in your apps. http://msdn.microsoft.com/en-us/magazine/cc163311.aspx
  3. Rodrigo Rubira Branco. Dynamic Program Analysis and Software Exploitation. 2010.
  4. Страница проекта WinAppDbg. sourceforge.net/projects/winappdbg/.