Бинарные уязвимости и эксплойты: технологии и...

Post on 16-Nov-2014

3.077 Views

Category:

Documents

7 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Различные подходы к поиску уязвимостей

- Метод «белого ящика» Обычно, поиск уязвимостей по исходным текстам.

- Метод «чёрного (серого) ящика» Поиск уязвимостей без исходных текстов, с применением реверс-инжиниринга или без него

К чему применим фаззинг

Сетевые протоколы Уязвимости при обработке файлов Драйверы режима ядра Различные интерфейсы (RPC, ActiveX компоненты) Многое другое

Идеальный фаззер

Обеспечивает полное покрытие кода исследуемого приложения

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

Регистрирует любые аномалии в процессе исполнения исследуемого приложения

Обеспечивает линейную масштабируемость Не существует

Этапы фаззинга

1. Анализ исследуемого приложения, разработка фаззера (опционально)

2. Генерация данных3. Собственно, фаззинг4. Анализ результатов

Генерация данных

- С использованием шаблоновНаиболее эффективный подход, но сложный и долгий в плане реализации

- На основе уже имеющихся данныхПростота, но с сомнительной эффективностью при реализации «в лоб»

На самом деле, предпочтителен промежуточный подход

Подготовка к фаззингу

Анализ покрытия кода

- Позволяет выявить, какие ветви алгоритма приложения исполнялись в процессе фаззинга

- Выбор более подходящих исходных данных для мутационного фаззинга

- Оценка эффективности фаззинга (чем больше покрытие кода – тем лучше)

Реализация фаззинга

Сетевые протоколы с множеством состояний?

Реализация фаззинга

IOCTL запросы к драйверам?

Анализ результатов

Мониторинг исключений[+] DLL injected into the target process 8032[+] Exit on first #AV: YesModuleInit(): From process 'VISIO.EXE' (PID: 8032)[!] EXCEPTION OCCURS:STATUS_ACCESS_VIOLATION at 0x56807161

Access type: Read Address: 0x00000102EAX=0x00000000 EBX=0x05366338

ECX=0x00000001 EDX=0x773270b4ESI=0x0536643a EDI=0x00000000 EBP=0x0012a244

Анализ результатов

Аварийные дампыThe stored exception information can be accessed via .ecxr.(26dc.178c): Access violation - code c0000005 (first/second chance not available)eax=00000700 ebx=02bf0d78 ecx=002590c4 edx=02bf0d38 esi=02bf0d38 edi=002593d8eip=773270b4 esp=00259098 ebp=002590a8 iopl=0 nv up ei pl zr na pe nc*** ERROR: Symbol file could not be found. Defaulted to export symbols for VISLIB.DLL - VISLIB!Ordinal1+0xb18e2:565cf57d 8b4111 mov eax,dword ptr [ecx+11h] ds:0023:00000011=????????ntdll!KiFastSystemCallRet:773270b4 c3 ret773270b5 8da42400000000 lea esp,[esp]773270bc 8d642400 lea esp,[esp]ntdll!KiIntSystemCall:773270c0 8d542408 lea edx,[esp+8]773270c4 cd2e int 2Eh773270c6 c3 ret773270c7 90 nopntdll!RtlRaiseException:773270c8 55 push ebp *** Stack trace for last set context - .thread/.cxr resets itChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong.0025a01c 565cf608 00000001 00000000 00000000 VISLIB!Ordinal1+0xb18e2

Анализ результатов

Отладчик и !exploitable[+] Analyzing "_minidumps\0xC0000005_0x565CF57D_19.05_04.37.29.DMP"[+] Faulting file: 000026ac.vsd[+] Exception 0xc0000005 at address VISLIB.dll+bf57d[+] Main module version: 12.0.6211.1000, fault module version: 12.0.6211.1000

Exploitability Classification: PROBABLY_EXPLOITABLERecommended Bug Title: Probably Exploitable - Data from Faulting Address controls subsequent Write

Address starting at VISLIB!Ordinal1+0x00000000000b18e2 (Hash=0x5502736d.0x39521d59)

The data from the faulting address is later used as the target for a later write.

[+] Analyzing "_minidumps\0xC0000005_0x56807161_19.05_04.37.43.DMP"[+] Faulting file: 0000a4e6.vsd[+] Exception 0xc0000005 at address VISLIB.dll+2f7161[+] Main module version: 12.0.6211.1000, fault module version: 12.0.6211.1000

*** ERROR: Module load completed but symbols could not be loaded for VISIO.EXEExploitability Classification: PROBABLY_NOT_EXPLOITABLERecommended Bug Title: Read Access Violation near NULL starting at VISLIB!

DllCanUnloadNow+0x0000000000233971 (Hash=0x6b3b041d.0x544a027a)

This is a user mode read access violation near null, and is probably not exploitable.

Проблемы фаззинга

- Уязвимости в архитектуреСложно предугадать, где найдёшь следующую

- В результате фаззинга не всегда происходит падениеОсобенно при pool corruption

- Не все найденные уязвимости эксплуатабельныА ведь уникальных воспроизводимых падений может насчитываться сотни и тысячи!

Задачи динамического анализа кода

• Code Coverage– Построение карты покрытия кода: какие инструкции и

сколько раз исполнялись в процессе работы программы

• Taint Analysis– Сопоставление данных с конкретными участками кода,

которые были исполнены при их обработке

• Symbolic Execution– Контроль над исполнением кода для генерации входных

данных, удовлетворяющих конкретным условиям

Code coverage

• Позволяет установить, какие инструкции исполнялись в процессе запуска программы

• Может служить в качестве объективной оценки качества тестирования (фаззинга) программы

• Помогает изучать execution flow в процессе реверс-инжиниринга

• Используется в системах honeypot для детектирования факта эксплуатации каких-либо уязвимостей (в том числе, не известных ранее)

Taint Analysis• Позволяет связать трассу исполнения программы с данными,

которые обрабатывались ней в процессе этого исполнения

• Помогает дать ответ на вопрос о том, как именно программа обрабатывала те или иные входные данные

• Используется для анализа тестовых кейсов, приводящих к аварийному завершению работы исследуемой программы

• Является необходимым фундаментом для реализации Symbolic Execution

Taint Analysis: тезисы

• Данные получают дополнительную характеристику, относительно которой они могут пребывать в двух состояниях: TAINTED и UNTAINTED

• В качестве источника или приёмника дынных в процессе исполнения программы выступают память и регистры процессора

• Тейнтинг передаётся от источника к приёмнику данных при их обработке программой (Taint Propagation)

Taint Propagationmov eax, in_taintedmov ecx, in_untaintedadd ecx, eax ; ecx is TAINTED----------------------------------------------------------mov eax, in_taintedmov ecx, in_untaintedmov ax, cx ; ax is UNTAINTED, eax is TAINTED----------------------------------------------------------mov eax, in_taintedxor eax, eax ; eax is UNTAINTED----------------------------------------------------------push in_taintedpop eax ; eax is TAINTED, dword[esp + 4] is TAINTED----------------------------------------------------------xor eax, eaxcmp eax, in_tainted ; AF, CF, OF, PF, SF, ZF is TAINTED

Taint Analysis и уязвимости

• В качестве начального источника TAINTED данных указываются те данные, которые может контролировать потенциальный атакующий (файлы, сетевые пакеты, параметры командной строки, итд.)

• Если в ходе анализа обнаружилось, что eip – TAINTED, то это является показателем факта успешной эксплуатации уязвимости с передачей управления на контролируемый атакующим код (шеллкод)

Taint Analysis: проблемы и решения

• Taint Analysis по своей природе требует детального анализа каждой исполняемой инструкции

• x86 и x86_64 – CISC архитектуры с огромной системой команд и большим количеством расширений, написать код, который бы корректно анализировал все существующие инструкции – сложно

• Так же существуют и другие популярные архитектуры (ARM, MIPS, PPC), писать реализацию Taint Analysis для каждой из них отдельно – совершенно нерационально

Taint Analysis: проблемы и решения

• Разумно использовать промежуточное представление кода (IR, Intermediate Representation) для работы с ним

• IR представляет собой псевдо-ассемблер с упрощенной системой адресации, небольшим набором базовых инструкций и возможностью преобразования кода для любой из архитектур в обе стороны (native → IR, IR → native)

• Существующие реализации IR:

– VEX: используется в Valgrind– LLVM bytecode: используется в системе LLVM– REIL: используется в продуктах от Zynamics (RIP )– RTL: используется в закрытом исследовательском проекте Phoenix от Microsoft

Research

Taint Analysis: проблемы и решения

• Идеальный анализатор кода для задач Taint Analysis должен отслеживать и инструментирвать весь код, исполняемый операционной системой (как режиме пользователя, так и в режиме ядра)

• Но реализация такого подхода на практике чревата неприемлемо низкой производительностью. В большинстве случаев для Taint Analysis достаточно контроля над всем кодом пользовательского режима, исполняемого в контексте исследуемого процесса

• В ряде случаев, уход вектора исполнения в режим ядра может нарушать Taint Propagation при анализе только кода пользовательского режима (пример – системные вызовы, работающие с memory mappings). Анализатор кода должен уметь корретно обрабатывать такие случаи

• Активное использование IPC при обработке данных – страшнейший кошмар для любого анализатора кода, работающего только в контексте конкретного процесса

Symbolic Execution• Концепция динамического анализа кода, позволяющая решить основной

вопрос реверс-инжинринга: «Может ли переменная X получить значение Y после исполнения определённого набора инструкций? Какие данные должна получить программа на вход, что бы это произошло?»

• Любая программа имеет конечное количество промежуточных и финальных состояний, переход между которыми и является её исполнением

• Входные данные определяют в каком именно состоянии окажется программа на том или ином шаге исполнения

• Symbolic Execution позволяет получить такой набор входных данных для исследуемой программы, обработка которых привёдет вектор исполнения в нужное исследователю промежуточное или финальное состояние программы

Symbolic Execution: применение• В ходе тестирования (фаззинга) программы может использоваться

для генерации такого набора тестовых данных, при обработке которого произойдёт исполнение всех возможных ветвей алгоритма

• Может использоваться для аудита программ на предмет недекларированных функциональных возможностей

• Может использоваться для взлома некоторых типов защит от несанкционированного копирования программы: «Invalid serial number, try again» и «Welcome, thank you for purchasing our program» - это всего лишь состояния программы, переход между которыми осуществляется путём прохода вектора исполнения через промежуточные состояния, соответствующие опеределённым входным данным

Symbolic Execution: как это работает

• Для отслеживания того, как определённый набор вхоных данных влияет на состояние программы на каждом шаге её исполнения используется Taint Analysis

• Для описания конкретного состояния программы относительно входных данных используются символьные выражения, описывающие шаги обработки данных

• Для вычисления набора входных данных, которые позволяли бы получить желаемое состояние относительно известного, используется бескванторная бит-векторная арифметика с конечной точностью (quantifier-free finite-precision bit-vector arithmetic, QF-BV), позволяющая находить точные или приближенные данные, удволтворяющие условиям символьных выражений

Symbolic Execution: примерыПример программы:

val = read_from_user();val = val + 10;if (val == 42) { // state #1 sweet_delicious();} else { // state #2 gtfo_bitch();}

Символьное выражение для state #1:

Символьное выражение для state #2:

Symbolic Execution: примеры• Для решения символьных выражений существуют готовые

библиотеки, например SMT-LIB (Satisfiability Modulo Theories Library)– http://www.smtlib.org/

• Запись рассмотренного ранее примера символьного выражения в формате SMT-LIB:

(benchmark test:status unknown:logic QF_BV:extrafuns ((a BitVec[8])(b BitVec[8])(c BitVec[8])(d BitVec[8])(e BitVec[8])):assumption (= a b):assumption (= c bv10[8]):assumption (= d (bvadd a c)):assumption (= e d):formula (= e bv42[8]))

Symbolic Execution: практика• После поверхностного ознакомления с Symbolic Execution может показаться, что при

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

• Но это не соответствует действительности:– Это достаточно молодое направление исследований, интерес которому больше проявляют

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

серьёзного промышленного применения– Само по себе Symbolic Execution упирается во можество ограничений, основными из которых

являются высокие требования к вычислительным ресурсам и сложность в реализации

• Однако, существуют интересные проекты, в рамках которых удалось реализовать работающие (хотя бы в тесных рамках) инструменты:

– Fuzzgrind (http://esec-lab.sogeti.com/pages/Fuzzgrind)– KLEE (http://klee.llvm.org/)

Symbolic Execution: практика• Если вы хотите получать в процессе поиска уязвимостей максимально

качественный и предсказуемый результат за приемлемое время прямо сейчас – Symbolic Execution вряд-ли в этом поможет

Технологии решения задач• Возможности по отладке кода, предоставляемые процессором

– Отладочные регистры и Last Branch Recording в IA-32 и Intel 64

• Отладчики и отладочный API– ptrace(), Debugging Tools for Windows

• Dynamic Binary Instrumentation (DBI, динамическое инструментирование бинарного кода)– PIN, DynamoRIO, Valgrind

• Intermediate Representation (IR, промежуточное представление кода)– Valgrind, LLVM и инструменты на их базе (Fuzzgrind, KLEE, S²E)

• Эмуляция– BitBlaze, Ether, S²E

Инструменты: отладчики и отладочный API

• [+] В том или ином виде реализованы в любой операционной системе

• [+] Easy to code – easy to use

• [–] Производительность недостаточная даже для задач анализа покрытия кода

Инструменты: DBI

• Используют динамическую рекомпиляцию инструментируемого кода

• Обеспечивают высокую производительность из-за низких накладных расходов на инструментирование одной инструкции (так как нет необходимости в механизмах IPC)

• PIN используется в инструментах BAP и Vera, хотя, как и DynamoRIO, является вполне самодостаточным

Инструменты: DBI• [+] Из всех существующих технологий – наиболее пригодна для

практического применения уже сейчас, недостатки есть, но весьма несущественные

• [+] Существующие инструменты могут работать с IA-32, IA-64 и Intel 64 под Windows, Linux и Mac OS X

• [–] Инструментальный модуль может использовать только тот API, который предоставляется самим движком (в PIN и DynamoRIO)

• [–] Инструментальный модуль вынужден работать только с машинным кодом, который, в случае IA-32, IA-64 и Intel 64, несколько сложен для анализа (а вы ожидали другого от CISC-процессоров?)

Инструменты: Valgrind

• Один из самых мощных открытых фреймворков для профиллировки и инструментирования кода

• Большинству инструментов Valgrind необходимо промежуточное представление кода (VEX)

• Некоторые инструменты (cachegrind) могут работать с машинным кодом используя динамическую рекомпиляцию

Инструменты: Valgrind

• [–] Работает только в Linux и Mac OS X (зато кроме IA-32 и Intel 64 поддерживает PowerPC)

• [–] Полноценное использование всех инструментов возможно только при наличии исходных текстов целевой программы (в противном случае – пригоден только для анализа покрытия кода)

Инструменты: LLVM

Инструменты: LLVM

• Front-end – предназначен для преобразования какого-либо кода (исходного или машинного – не важно) в байт-код LLVM

• Back-end – предназначен для транслирования байт-кода LLVM в машинный код для заданной архитектуры (как статически, так и в JiT)

• Виртуальная машина LLVM – предназначена для исполнения и инструментирования байт-кода LLVM

Инструменты: LLVM• Для языков C, С++ и Objective-C в качестве front-end используется

компилятор Clang

• Реализация front-end для машинного кода IA-32 ведётся в рамках таких проектов как libcpu и S²E

• В реальной жизни трансляция машинного кода в байт-код LLVM возможна только в динамике, что делает LLVM «as is» не пригодным для работы с программами без исходных текстов

• Наиболее известные инструменты для Symbolic Execution, основанные на LLVM:– KLEE: работает только при наличии исходных текстов– S²E: использует модифицированный QEMU для генерации байт-кода LLVM в

процессе исполнения машинного кода

Инструменты: LLVM

• [–] Сам по себе LLVM существует под большинство архитектур и операционных систем, однако, многие фронт-енды и инструменты, основанные на LLVM, имеют проблемы с переносимостью– Windows-версия Clang поддерживает только

Plain C– KLEE и S²E «из коробки» не работают в Windows

Инструменты: BitBlaze

• Представляет собой набор, в состав которого входит модифицированный QEMU (TEMU) а так же ряд инструментов для работы с полученными в ходе его использования трассами исполнения кода

• Изначально предназначен для работы с бинарным кодом без использования исходных текстов

Инструменты: BitBlaze

• [+] В теории – мощный инструмент, который подходит для решения всех озвученных задач (Code Coverage, Taint Analysis, Symbolic Execution)

• [–] На практике – не применим для реальных задач из-за реализации «не от мира сего»– Крайне низкая производительность– Отсутствуют удобные средства для интеграции TEMU

со сторонними системами– Множество сомнительных архитектурных решений

Инструменты: Ether

• Представляет собой достаточно простой трассировщик на базе модифицированного XEN

• Возможность сохранения полной трассы исполнения для указанного исполняемого файла

• Возможность логирования системных вызовов отдельно от трассировки

Инструменты: Ether

• [+] Производительность на уровне DBI• [+] Хорошая, законченная реализация

• [–] Не развивается, работает только с XEN 3.1.0 (4-х летней давности)

• [–] Отсутствуют удобные средства для интеграции со сторонними системами

• [–] Поддерживает только Windows Guests

top related