- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 0. Анализ вредоносных программ для начинающих
- •Цель анализа вредоносных программ
- •Методики анализа вредоносного ПО
- •Общие правила анализа вредоносного ПО
- •Глава 1. Основные статические методики
- •Сканирование антивирусом: первый шаг
- •Хеширование: отпечатки пальцев злоумышленника
- •Поиск строк
- •Упакованное и обфусцированное вредоносное ПО
- •Формат переносимых исполняемых файлов
- •Компонуемые библиотеки и функции
- •Статический анализ на практике
- •Заголовки и разделы PE-файла
- •Итоги главы
- •Глава 2. Анализ вредоносных программ в виртуальных машинах
- •Структура виртуальной машины
- •Запуск виртуальной машины для анализа вредоносного ПО
- •Использование виртуальной машины для анализа безопасности
- •Риски при использовании VMware для анализа безопасности
- •Запись/воспроизведение работы компьютера
- •Итоги главы
- •Глава 3. Основы динамического анализа
- •Песочницы: решение на скорую руку
- •Запуск вредоносных программ
- •Мониторинг с помощью Process Monitor
- •Сравнение снимков реестра с помощью Regshot
- •Симуляция сети
- •Перехват пакетов с помощью Wireshark
- •Использование INetSim
- •Применение основных инструментов для динамического анализа
- •Итоги главы
- •Уровни абстракции
- •Архитектура x86
- •Итоги главы
- •Глава 5. IDA Pro
- •Загрузка исполняемого файла
- •Интерфейс IDA Pro
- •Использование перекрестных ссылок
- •Анализ функций
- •Схематическое представление
- •Повышение эффективности дизассемблирования
- •Плагины к IDA Pro
- •Итоги главы
- •Глава 6. Распознавание конструкций языка C в ассемблере
- •Переменные: локальные и глобальные
- •Дизассемблирование арифметических операций
- •Распознавание выражений if
- •Распознавание циклов
- •Соглашения, касающиеся вызова функций
- •Анализ выражений switch
- •Дизассемблирование массивов
- •Распознавание структур
- •Анализ обхода связного списка
- •Итоги главы
- •Глава 7. Анализ вредоносных программ для Windows
- •Windows API
- •Реестр Windows
- •API для работы с сетью
- •Отслеживание запущенной вредоносной программы
- •Сравнение режимов ядра и пользователя
- •Native API
- •Итоги главы
- •Глава 8. Отладка
- •Сравнение отладки на уровне исходного и дизассемблированного кода
- •Отладка на уровне ядра и пользователя
- •Использование отладчика
- •Исключения
- •Управление выполнением с помощью отладчика
- •Изменение хода выполнения программы на практике
- •Итоги главы
- •Глава 9. OllyDbg
- •Загрузка вредоносного ПО
- •Пользовательский интерфейс OllyDbg
- •Карта памяти
- •Просмотр потоков и стеков
- •Выполнение кода
- •Точки останова
- •Трассировка
- •Обработка исключений
- •Редактирование кода
- •Анализ кода командной оболочки
- •Вспомогательные возможности
- •Подключаемые модули
- •Отладка с использованием скриптов
- •Итоги главы
- •Драйверы и код ядра
- •Подготовка к отладке ядра
- •Использование WinDbg
- •Отладочные символы Microsoft
- •Отладка ядра на практике
- •Руткиты
- •Загрузка драйверов
- •Итоги главы
- •Глава 11. Поведение вредоносных программ
- •Программы для загрузки и запуска ПО
- •Бэкдоры
- •Похищение учетных данных
- •Механизм постоянного присутствия
- •Повышение привилегий
- •Заметая следы: руткиты, работающие в пользовательском режиме
- •Итоги главы
- •Глава 12. Скрытый запуск вредоносного ПО
- •Загрузчики
- •Внедрение в процесс
- •Подмена процесса
- •Внедрение перехватчиков
- •Detours
- •Внедрение асинхронных процедур
- •Итоги главы
- •Глава 13. Кодирование данных
- •Простые шифры
- •Распространенные криптографические алгоритмы
- •Нестандартное кодирование
- •Декодирование
- •Итоги главы
- •Глава 14. Сетевые сигнатуры, нацеленные на вредоносное ПО
- •Сетевые контрмеры
- •Безопасное расследование вредоносной деятельности в Интернете
- •Контрмеры, основанные на сетевом трафике
- •Углубленный анализ
- •Сочетание динамических и статических методик анализа
- •Понимание психологии злоумышленника
- •Итоги главы
- •Искажение алгоритмов дизассемблирования
- •Срыв анализа слоя стека
- •Итоги главы
- •Глава 16. Антиотладка
- •Обнаружение отладчика в Windows
- •Распознавание поведения отладчика
- •Искажение работы отладчика
- •Уязвимости отладчиков
- •Итоги главы
- •Глава 17. Методы противодействия виртуальным машинам
- •Признаки присутствия VMware
- •Уязвимые инструкции
- •Изменение настроек
- •Побег из виртуальной машины
- •Итоги главы
- •Глава 18. Упаковщики и распаковка
- •Анатомия упаковщика
- •Распознавание упакованных программ
- •Способы распаковки
- •Автоматизированная распаковка
- •Ручная распаковка
- •Советы и приемы для работы с распространенными упаковщиками
- •Анализ без полной распаковки
- •Итоги главы
- •Глава 19. Анализ кода командной оболочки
- •Загрузка кода командной оболочки для анализа
- •Позиционно-независимый код
- •Определение адреса выполнения
- •Поиск символов вручную
- •Окончательная версия программы Hello World
- •Кодировки кода командной оболочки
- •NOP-цепочки
- •Поиск кода командной оболочки
- •Итоги главы
- •Глава 20. Анализ кода на C++
- •Объектно-ориентированное программирование
- •Обычные и виртуальные функции
- •Создание и уничтожение объектов
- •Итоги главы
- •Какой смысл в 64-битном вредоносном ПО?
- •Особенности архитектуры x64
- •Признаки вредоносного кода на платформе x64
- •Итоги главы
- •Приложения
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
430 Часть V • Противодействие обратному проектированию |
||||
w Click |
|
|
|
|
|
|
||||
|
|
|
|
|
o |
m |
||||
|
w |
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
ПРИМЕЧАНИЕ
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Иногда авторы вредоносного ПО используют сразу несколько упаковщиков. Это удваивает объем работы для аналитика безопасности, но при достаточном упорстве обычно можно справиться даже с двойной упаковкой. Стратегия здесь простая: распакуйте первый слой, применяя методики, которые мы только что описали, и затем повторите то же самое со вторым слоем. Принцип остается прежним вне зависимости от количества использованных упаковщиков.
Советы и приемы для работы с распространенными упаковщиками
Этот раздел охватывает популярные упаковщики, с которыми вы, скорее всего, столкнетесь при анализе вредоносного ПО. Для каждого упаковщика приводится описание и стратегия по ручной распаковке. В некоторых случаях указаны автоматические распаковщики, но они не всегда работают. Каждый подраздел содержит инструкции по нахождению ОТВ и описание потенциальных осложнений.
UPX
Во вредоносных программах чаще всего применяется упаковщик под названием UPX (Ultimate Packer for eXecutables). Он бесплатен, прост в использовании, имеет открытый исходный код и поддерживает широкое разнообразие платформ. UPX сжимает исполняемые файлы и создан с упором на производительность, а не на безопасность. Свою популярность он получил в связи с высокой скоростью декомпрессии, небольшим размером и умеренным потреблением памяти при распаковке.
UPX не предназначен для того, чтобы усложнять разбор кода, и не представляет особой проблемы для аналитика безопасности. Он может сам распаковать большинство программ, упакованных с его помощью: для этого в нем предусмотрен параметр -d.
С этим упаковщиком довольно легко справиться, поэтому он хорошо подходит для изучения методов распаковки вредоносного кода. Однако многие зараженные файлы выглядят так, как будто в них использовался UPX, хотя на самом деле они упакованы с помощью другого инструмента (или с применением видоизмененной версии UPX). В таких случаях UPX не сможет распаковать исполняемый файл.
Многие из стратегий поиска ОТВ, описанные ранее в этой главе, применимы и к UPX. Вы также можете воспользоваться пунктом меню Find OEP by Section Hop (Найти ОТВ по границе раздела) в OllyDump или просто прокрутить вниз код за- глушки-распаковщика, пока не обнаружите хвостовую рекурсию. OllyDump позволяет успешно сбросить файл на диск и восстановить его таблицу импортов.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
PECompact
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
Глава 18. Упаковщики и распаковка 431 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
PECompact — это коммерческий упаковщик, нацеленный на скорость и производительность. Авторы вредоносного ПО часто используют бесплатную версию для студентов, которая больше не поддерживается. Распаковать программы, упакованные с помощью PECompact, может оказаться непросто, поскольку они содержат антиотладочные исключения и обфусцированный код. Этот продукт поддерживает систему плагинов, что позволяет интегрировать в него сторонние инструменты. Этим часто пользуются авторы вредоносного ПО, чтобы сделать процесс распаковывания еще более сложным.
Ручная распаковка PECompact во многом похожа на аналогичную процедуру
сUPX. Программа генерирует определенные исключения, поэтому вы должны возвращать их обратно с помощью OllyDbg. Это было подробно описано в главе 16.
ОТВ можно найти по хвостовой рекурсии. При пошаговом выполнении функций
собходом вы увидите инструкцию jmp eax, за которой следует большое количество байтов 0x00.
ASPack
Основной чертой упаковщика ASPack является безопасность. Он использует методики для усложнения распаковки программы и модифицирует собственный код, что затрудняет создание точек останова и проведение анализа в целом.
Создание точки останова в программах, упакованных с помощью ASPack, может привести к их преждевременному завершению. Тем не менее распаковку можно выполнить вручную, используя аппаратные точки останова внутри стека. Кроме того, благодаря популярности ASPack для него написано много автоматизированных распаковщиков. Они работают с разной степенью успешности, но автоматическая распаковка всегда стоит того, чтобы попробовать ее в первую очередь.
Если у вас есть файл, запакованный методом ASPack, вполне возможно, что вам удастся его распаковать с помощью автоматизированных инструментов, однако в большинстве случаев для этого требуется ручное вмешательство. Для начала нужно открыть код заглушки-распаковщика. В верхней его части вы увидите инструкцию PUSHAD. Определите, какой адрес стека используется для хранения регистров, и создайте в одном из них аппаратную точку останова. Убедитесь в том, что она прерывает работу на операции чтения. Точка останова сработает при вызове соответствующей инструкции POPAD, которая находится совсем рядом с хвостовой рекурсией, ведущей к ОТВ.
Petite
Упаковщик Petite во многом похож на ASPack. Помимо прочего, в нем используются механизмы антиотладки, которые усложняют обнаружение ОТВ, а также одношаговые исключения для передачи управления отладчику. С этим можно бороться,
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
432 Часть V • Противодействие обратному проектированию |
||||
w Click |
|
|
|
|
|
|
||||
|
|
|
|
|
o |
m |
||||
|
w |
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
возвращая исключения обратно в программу, как было показано в главе 16. Как и в случае с ASPack, лучшим вариантом поиска ОТВ является создание аппаратной точки останова в стеке. Petite использует в своей обертке сложные структуры, которые заметно отличаются на фоне оригинального кода, поэтому, подобравшись близко к ОТВ, вы сможете быстро ее обнаружить.
Petite хранит в исходной таблице импорта как минимум по одному вызову из каждой библиотеки. И, хотя это не влияет на сложность распаковки, вы можете с легкостью определить, какие DLL-файлы использует вредонос, — для этого его даже не нужно распаковывать.
WinUpack
WinUpack — это упаковщик с графической оболочкой, созданный с прицелом на максимальное сжатие, но без заботы о безопасности. У него есть консольная версия под названием UPack, а также автоматизированные распаковщики, предназначенные как для UPack, так и для WinUpack.
И хотя WinUpack не делает акцент на безопасности, он все же содержит механизмы, усложняющие обнаружение ОТВ и делающие бесполезными такие приемы, как поиск хвостовой рекурсии или использование OllyDump. В листинге 18.5 показана хвостовая рекурсия для этого исполняемого файла.
Листинг 18.5. Хвостовая рекурсия в программе, упакованной с помощью UPack
010103A6 |
POP ECX |
010103A7 |
OR ECX,ECX |
010103A9 |
MOV DWORD PTR SS:[EBP+3A8],EAX |
010103AF |
POPAD |
010103B0 |
JNZ SHORT Sample_upac.010103BA |
010103B2 |
MOV EAX,1 |
010103B7 |
RETN 0C |
010103BA |
PUSH Sample_upac.01005F85 |
010103BF |
RETN |
010103C0 |
MOV EAX,DWORD PTR SS:[EBP+426] |
010103C6 |
LEA ECX,DWORD PTR SS:[EBP+43B] |
010103CC |
PUSH ECX |
010103CD |
PUSH EAX |
010103CE |
CALL DWORD PTR SS:[EBP+F49] |
010103D4 |
MOV DWORD PTR SS:[EBP+555],EAX |
010103DA |
LEA EAX,DWORD PTR SS:[EBP+447] |
010103E0 |
PUSH EAX |
010103E1 |
CALL DWORD PTR SS:[EBP+F51] |
010103E7 |
MOV DWORD PTR SS:[EBP+42A],EAX |
В этом листинге хвостовая рекурсия находится посреди заглушки-распаков- щика, поэтому ее сложно заметить. Для нее крайне характерна последовательность из инструкций push и return. Прежде чем дойти до хвостовой рекурсии, код выполняет переходы в разные места, что усложняет обнаружение. Чтобы сделать
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
Глава 18. Упаковщики и распаковка 433 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
переход в ОТВ еще менее заметным, упаковщик модифицирует инструкцию push, за которой идет retn, незадолго до ее вызова. Сам переход не очень длинный, поэтому вы не можете его определить по слишком удаленному адресу. ОТВ находится в одном разделе с заглушкой-распаковщиком, что исключает автоматическое обнаружение хвостовой рекурсии по границе между разделами.
Лучшая стратегия определения ОТВ в программе, упакованной с помощью UPack, — это создание точки останова для вызова GetProcAddress и пошаговый перебор последующих инструкций в поиске циклов, которые находят адреса функций импорта. Если создавать точки останова для всех инструкций jmp и call подряд, пошаговое выполнение может занять целую вечность, но, если их плотность окажется слишком низкой, программа, скорее всего, пропустит прерывание и отработает до завершения.
Не стоит расстраиваться, если ваши точки останова не сработали. Просто перезапустите приложение в отладчике и повторите попытку. Ошибки тоже являются частью процесса. Рано или поздно вы наткнетесь на инструкцию, которая представляет собой хвостовую рекурсию.
Иногда распознавание хвостовой рекурсии может оказаться нетривиальным. Часто это связано с тем, что переход выполняется примерно на 0x4000 байт. Размер большинства заглушек-распаковщиков меньше 0x4000, поэтому переход такой длины обычно ведет в ОТВ. Чтобы в этом убедиться, можно исследовать код вокруг оригинальной точки входа: он должен выглядеть заурядно на фоне заглушки. За- глушка-распаковщик часто содержит посреди своей функции множество условных переходов и инструкций retn, чего нельзя сказать о коде, окружающем ОТВ.
Для UPack подходит еще одна стратегия: вы можете создать точку останова для вызова GetModuleHandleA или GetCommandLineA, в зависимости от того, оконная это программа или консольная. В Windows эти функции вызываются вскоре после перехода в ОТВ. Как только точка останова сработает, вернитесь назад по коду и найдите оригинальную точку входа.
Иногда WinUpack использует PE-заголовок, который некорректно интерпретируется отладчиком OllyDbg и приводит к его сбою. В главе 16 мы показали, что OllyDbg не является идеальным инструментом и имеет проблемы с разбором двоичных файлов, которые нормально работают вне режима отладки. В таких ситуациях, прежде чем приступать к изучению ошибки интерпретации, всегда старайтесь использовать WinDbg.
Themida
Themida — довольно сложный упаковщик со множеством возможностей, большинство из которых относятся к противодействию отладке и анализу. Поэтому он очень надежен и плохо поддается распаковке и анализу.
Themida поддерживает методики, направленные против анализа с помощью VMware, отладчиков и программы Process Monitor (procmon). У этого инструмента