Технологии анализа бинарного кода приложений:...

42
ptsecurity .com Технологии анализа бинарного кода приложений: методы, проблемы, инструменты Константин Панарин Positive Technologies

Transcript of Технологии анализа бинарного кода приложений:...

Page 1: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

ptsecurity.com

Технологии анализа бинарного кода приложений: методы, проблемы, инструментыКонстантин ПанаринPositive Technologies

Page 2: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

• Константин Панарин, Positive Technologies, [email protected]

• Разработчик группы анализа низкоуровневых приложений • Интересы: x86-64 reverse-engineering, C++ Template

Metaprogramming

#whoami

Page 3: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

• Цели анализа бинарного кода• Некоторые методики анализа• Обзор проблем• Обзор современных средств бинарного анализа

Содержание

Page 4: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

• Поиск ошибок• Поиск уязвимостей• Поиск недекларированных возможностей (НДВ)• Восстановление логики работы программы (RE)• Построение тестов

Задачи анализа бинарного кода

Page 5: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокОсобенности бинарного анализа

• Почти полное отсутствие информации о типах*• Гораздо сложнее локализовать различную «метаинформацию»

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

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

(особенно на CISC архитектурах)

*Классы легко распознаются благодаря наличию виртуальных таблиц, но что делать с элементарными типами?

Page 6: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

Типы анализа:• Статический анализ

• Исполнения программы не происходит

• Динамический анализ• Анализ по одной трассе исполнения

• Комбинированный анализТехнологии, применяемые в анализе:

• Символьное исполнение (symbolic execution)• Как правило, используется в статическом анализе

• Анализ помеченных данных (taint analysis)• Как правило, применяется при динамическом анализе

• Fuzzing• Ожидаемые входные данные подменяются случайными

или специально сформированными• И многие другие

Методики анализа бинарного кода

Page 7: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

Типы анализа:• Статический анализ

• Исполнения программы не происходит

• Динамический анализ• Анализ по одной трассе исполнения

• Комбинированный анализТехнологии, применяемые в анализе:

• Символьное исполнение (symbolic execution)• Как правило, используется в статическом анализе

• Анализ помеченных данных (taint analysis)• Как правило, применяется при динамическом анализе

• Fuzzing• Ожидаемые входные данные подменяются случайными или специально

сформированными

Методики анализа бинарного кода

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

Page 8: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокСтатический анализ vs динамический анализ

Динамический анализ• Наличие run-time информации:

карты памяти процесса, адресов неявных вызовов и др.

• Явное исполнение программы может требовать специфического окружения

• Не всегда возможно воспроизвести результаты анализа

Статический анализ• Как правило, работает быстрее• Один анализ покрывает

потенциально бесконечное число путей исполнения

• Работоспособен при отсутствии части исходников / библиотек

• Пасует перед обфускацией и шифрованием

• Отсутствие информации о неявных вызовах

Page 9: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

• Основная идея – замена конкретных входных данных программы (аргументов функции) на символьные

• Символ представляет множество всех возможных значений переменной

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

• Символьное исполнение способно покрывать все возможные пути в программе

• Каждый путь – это «состояние» программы, в котором хранятся условия прохождения по этому пути (path constraints) и набор ограничений на значения символьных данных (value constraints)

• SMT решатель (solver) – инструмент, определяющий совместность (разрешимость) условий для прохождения по заданному пути

Символьное исполнение

Page 10: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

При помощи символьного исполнения найдем значения x и y, при которых исполнение попадет в ERROR

Пример взят из http://www.srl.inf.ethz.ch/pa2015/Lecture8.pdf

Page 11: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

Value constraints:X->x0Y->y0

Path constraints:True

Page 12: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:True

Символьно исполняем вызов функции

Page 13: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 = 2y0

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 != 2y0

Два различных состояния после условного перехода if (x==z)

Page 14: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 =2y0 ^ x0 > y0+10

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 =2y0 ^ x0 <= y0+10

Исследуем условие x==z

Page 15: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 = 2y0 ^ x0 > y0+10

Условие достижимости ERROR:

Page 16: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Символьное исполнение: пример

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 = 2y0 ^ x0 > y0+10

Условие достижимости ERROR:

SMT Solver выдает решение:x0 = 40, y0 = 20

Page 17: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокСимвольное исполнение: общая схема

Транслятор в IR

Ассемблерная инструкция

Набор инструкций IR

Пул состояний (по одному для каждого пути исполнения)

State №1

State №2

State №…

State №500Каждое состояние хранит следующие данные:• Текущий IP (instruction pointer)• Символьный контекст (регистры,

ячейки памяти, символьные ресурсы)• Constraints

Executor (director) – занимается обработкой конкретного состояния

X86: mov eax, ecx ___________________

IR: STR R_ECX:32, , V_00:32 STR V_00:32, , R_EAX:32

Интерпретатор – содержит

обработчики для каждой

инструкции IR

Трансляция

Инструкция перехода по условию X (branch)

Если достигнута контрольная точка программы, проверяем её достижимость: извлекаем path constraints, решаем SMT-задачу

SMT-Solvers: Z3, STP, Boolector

New state a:Constraints += X

New state b:Constraints += ~X

Добавляем новые состояния в пул

Searcher – выбирает состояние из пула

Page 18: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокSymbolic execution: проблемы

• Path explosion (как генерировать меньшее число состояний?)• Cycle-unrolling (что делать с циклами, условие остановки

которых зависит от символьной переменной?)• Symbolic pointers (что делать с операциями load и store, адрес

которых тоже символический?)• Constraint difficulty (не все SMT-solver’ы справятся

с нахождением решения)• External resources (что делать с файлами, хэндлерами

и другими внешними объектами?)

Page 19: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокSymbolic execution: возможные пути решения проблем

• Path explosion – мёрджить (объединять) несколько состояний в одно (но как и когда это делать?)

• Path explosion – распараллелить обработку различных состояний

• Cycle unrolling, symbolic pointers – применять специальные логики, созданные для верифицирования программ (но насколько это эффективно?)

• External resources – создать DSL для описания внешних вызовов в терминах executor’а или SMT-solver’а (насколько это быстро и реализуемо?)

Page 20: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокSymbolic execution: ссылки

• KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs (C. Cadar, D. Dunbar, D. Engler)

• Unleashing MAYHEM on Binary Code (S. Cha, T. Avgerinos, A. Rebert and D. Brumley)

• S2E: A Platform for In-Vivo Multi-Path Analysis of Software Systems (V. Chipounov, V. Kuznetsov, G. Candea)

Page 21: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

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

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

обрабатывала те или иные входные данные

Анализ помеченных данных (taint analysis)

Page 22: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокTaint analysis: базовая идея

• Основные концепции: shadow memory и taint propagation

Shadow memory

Taint propagation

Page 23: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

mov eax, tainted_inputxor eax, eax ; eax is UNTAINTED

-----------------------------------------push tainted_inputpop eax ; eax is TAINTED, dword[esp + 4] is TAINTED -----------------------------------------------------------------xor eax, eax cmp eax, tainted_input ; AF, CF, OF, PF, SF, ZF is TAINTED

Taint propagation: примеры

mov eax, tainted _inputmov ecx, untainted_inputadd ecx, eax ; ecx is TAINTED -----------------------------------------mov eax, tainted_inputmov ecx, untainted_inputmov ax, cx ; ax is UNTAINTED, eax is TAINTED -----------------------------------------------------------------

Пример взят из http://defcon.org.ua/data/1/4_Oleksyk_Code_Analysis.pdf

Page 24: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокTaint analysis: общая схема

Program code:________________push ebpmov ebp, esplea eax, [esp+8]…ret

Анализ исполняемых инструкций во время

исполнения

add eax, [esp+8]

Instruction handler:Синтаксический парсинг инструкции на операнды,разрешение адресов у memory операндов

Taint context

EBX: not tainted

Taint propagation

ECX: tainted

EDI: tainted

EAX: not tainted

SHADOW MEMORY

Операнды:dest - eax,src: eax, 0x7f2300

Чтение контекста:eax – not tainted0x7f2300 - tainted

Запись контекста:eax – tainted

Page 25: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокTaint analysis

Чем полезен taint-analysis:• Tainted EIP говорит о возможности перехвата управления

(например, в результате stack\heap overflow)• Tainted arguments в некоторых функциях (например, форматная строка

в printf или строка команды в system) говорят о возможной уязвимости• Tainted resources (например, хэндлеры, мьютексы и пр., которые не зависят

напрямую от пользовательского ввода) говорят о возможной ошибке в программе

Недостатки:• По своей природе требует детального анализа каждой исполняемой

инструкции, что может быть очень тяжело для набора x86• Идеальный taint analysis должен отслеживать и инструментировать весь код,

исполняемый операционной системой (как в режиме пользователя, так и в режиме ядра) Чревато низкой производительностью анализа

Page 26: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокTaint analysis: ссылки

• All You Ever Wanted to Know About Dynamic Taint Analysis and Forward Symbolic Execution (but might have been afraid to ask) E. Schwartz, T. Avgerinos, D. Brumley

• Dynamic taint analysis: Automatic detection, analysis, and signature generation of exploit attacks on commodity software (J. Newsome , D. Song , J. Newsome, D. Song)

• Program slicing (M. Weiser)

Page 27: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокКомбинированный анализ – concolic execution

Concrete + symbolic = concolic:• Для некоторых символьных переменных используются их «конкретные» значения

при символьном исполнении

Применение:• На контрольных точках создаём снимок всего процесса• Инструментируем конкретную трассу: делаем taint-analysis и одновременно набираем

очередь символьных условий (constraints) для каждой инструкции перехода на пути• После завершения анализа текущей трассы откатываем процесс к контрольной точке,

выбираем символьное условие из очереди, решаем для него SMT-задачу, полученное решение (регистры и участки памяти) подставляем в память и контекст процесса

• Инструментируем новую трассу

Concolic execution – метод, применяемый для покрытия максимального количества кода

Page 28: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

Теперь воспользуемся техникой concolic execution и найдем значения x и y, при которых исполнение попадет в ERROR

Page 29: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

Предположим, что функция read вернула «конкретные» значения X=22Y=7

Page 30: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

«Конкретные» значения: X=22Y=7Делаем снимок процесса в точке входа в функцию test

Value constraints:X->x0Y->y0

Path constraints:True

Page 31: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

«Конкретные» значения: X=22Y=7Z=14

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:True

Исполняем вызов функции

Page 32: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

«Конкретные» значения: X=22Y=7Z=14

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:X0 != 2*y0Заталкиваем X0 == 2*y0 в пул собранных условий

«Конкретное» исполнение пойдет по ветке else

Page 33: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

«Конкретные» значения: X=2Y=1Z=2Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 = 2*y0

Символьное исполнение вычислит новые x и y, чтобы пойти по ветке true, и «конкретное» исполнение будет перезапущенос точки входа в test

Page 34: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

«Конкретные» значения: X=2Y=1Z=2Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 = 2*y0 ^ x0 <= y0 + 10

Однако «конкретное» исполнение опять не дойдёт до error

Page 35: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

int twice(int v) { return 2 * v; } void test(int x, int y) { z = twice(y); if (x == z) { if (x > y + 10) ERROR; } } int main() { x = read(); y = read(); test(x,y); }

Комбинированный анализ: пример

«Конкретные» значения: X=30Y=15Z=30

Value constraints:X->x0Y->y0Z->2*y0

Path constraints:x0 = 2*y0 ^ x0 > y0 + 10

Символьное исполнение вычислит новые значения x и y для нужных path constraints,откатимся к снимку и подменим x и y, исходяиз новых условий.

Page 36: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокСуществующие инструменты (Open Source)

KLEE• Базируется на llvm IR• Использует символьное исполнение• Автоматическая генерация тестов

(максимальное покрытие исходного кода)• Имеет несколько стратегий выбора состояний

в процессе symbolic executionKLEE используется в S2E – платформе для анализа исполнения приложений в «реальной» среде

Page 37: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокСуществующие инструменты (Open Source)

Triton • Реализует схему concolic execution• Переводит инструкции непосредственно в выражения solver’а

(Z3), минуя внутреннее представлениеДругие: FuzzBall, BitBlaze, Avalanche и прочие• Как правило, нет инструментов надлежащего продуктового

качества• Каждый инструмент «заточен» под решение некоторой своей

специфичной задачи

Page 38: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокСуществующие инструменты (Closed Source)

MAYHEM • Создан для поиска и автоматической генерации exploit’ов • Есть продвижение в работе с символьными адресами• Победитель конкурса DARPA в 2016

CodeSurfer, VeraCode• Платные инструменты бинарного анализа• Очень мало информации о деталях их работы

Page 39: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокОбщий вывод

• Методики бинарного анализа все еще нуждаются в глубоких исследованиях

• В данный момент не существует универсального инструмента бинарного анализа

• Каждый инструмент решает какую-либо конкретную задачу, обходя известные ограничения за счет качества анализа

• Positive Technologies работает над своим инструментом – STAY TUNED!

Page 40: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокBackup

Page 41: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

ЗаголовокСимвольное исполнение: общая схема

Транслятор в IR

Ассемблерная инструкция

Набор инструкций IR

Пул состояний (по одному для каждого пути исполнения)

State №1

State №2

State №…

State №500

Searcher – выбирает состояние из пула.Возможные стратегии выбора:• DPS

BPS• Random choice• Best coverage state

Каждое состояние хранит следующие данные:• Текущий IP (instruction pointer)• Символьный контекст (регистры, ячейки

памяти, символьные ресурсы)• Path constraints

Executor (director) – занимается обработкой конкретного состояния

mov eax, ecx ___________________

STR R_ECX:32, , V_00:32 STR V_00:32, , R_EAX:32

Интерпретатор – содержит

обработчики для каждой

инструкции IR

Трансляция

Логическая или арифметическая микроинструкция:xor, and, or, bvadd, bvsub и пр. – изменить символьный контекст обрабатываемого состояния

Обработка внешнего вызова: изменить символьный контекст в соответствии с семантикой, приписанной (в DSL) конкретной сторонней функции

База с семантикой внешних функций

Микроинструкции аллокации памяти / работы с памятью: создание новой или изменение существующей символьной ячейки памяти для обрабатываемого состояния

Микроинструкции передачи управления по условию X

Если достигнута контрольная точка программы, проверяем её достижимость: извлекаем path constraints, решаем SMT-задачу

SMT-Solvers: Z3, STP, Boolector

New state a:Constraints += X

New state b:Constraints += ~X

Добавляем новые состояния в пул

Page 42: Технологии анализа бинарного кода приложений: требования, проблемы, инструменты

Заголовок

ptsecurity.com

Спасибо!Спасибо!