- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 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 |
|
|
|||
|
|
|
|
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 |
|
|
|||
Глава 8. Отладка 201 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Основным способом передачи контроля над запущенной программой отладчику являются исключения. На них основаны даже точки останова, хотя они применяются и в ситуациях, никак не связанных с отладкой, например при некорректном обращении к памяти или делении на ноль.
Исключения не имеют прямого отношения к анализу безопасности или отладке. Часто их причиной являются программные ошибки, поэтому отладчики и занимаются их обработкой. Однако исключения можно также использовать для управления потоком выполнения в обычных условиях, без применения отладчика. Имеющаяся функциональность дает возможность работать с исключениями как отладчику, так и отлаживаемой программе.
Первый и второй этапы обработки исключений
Отладчики обычно получают две возможности обработать одно и то же исключение: на первом и на втором этапе.
Если при появлении исключения отладчик подключен, отлаживаемая программа перестает выполняться, а отладчику предоставляется первый шанс установить контроль. Он может обработать исключение сам или передать его программе (во время отладки вам придется решить, как обрабатывать исключения, даже если они не имеют отношения к коду, который вас интересует).
Если программа зарегистрировала обработчик исключения, она получает возможность приступить к его обработке вслед за отладчиком. Например, программакалькулятор может зарегистрировать обработчик исключения, которое возни кает при делении на ноль. Если произойдет такая исключительная операция, обработчик сможет проинформировать о ней пользователя и продолжить работу. Именно это и происходит, когда программа выполняется без подключенного отладчика.
Но если программа не обрабатывает исключение, отладчик получает второй шанс — второй этап обработки. Это означает, что, если бы отладчик не был подключен, программа завершилась бы сбоем. Отладчик должен уладить эту ситуацию, чтобы позволить приложению продолжить работу.
При анализе вредоносного кода нас обычно не интересуют программные ошибки, поэтому на первый этап обработки часто можно не обращать внимания (как будет продемонстрировано в главах 15 и 16, вредонос может специально генерировать исключения первого этапа, чтобы усложнить отладку).
Второй этап обработки игнорировать нельзя, иначе программа не сможет продолжить работу. Такие исключения могут свидетельствовать о критических ошибках во вредоносной программе, но скорее ей просто не подходит среда, в которой она запущена.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
202 Часть III • Продвинутый динамический анализ |
||||
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 |
|
|
|
|
Существует несколько исключений, которые встречаются чаще других. Самое распространенное из них возникает, когда выполняется инструкция INT 3. У отладчиков имеется специальный код для обработки таких исключений, но для ОС они ничем не отличаются от остальных.
Программа может содержать собственные инструкции для обработки исключений INT 3, но, если подключен отладчик, первый шанс обработки достается ему. Программа тоже может его обработать, если отладчик даст ей такую возможность.
Пошаговое выполнение на уровне ОС также реализовано в виде исключений. Для этого используется флаг-ловушка в регистре FLAGS. Когда этот флаг установлен, процессор выполняет инструкцию и сразу же генерирует исключение.
Исключение, вызванное нарушением доступа к памяти, генерируется, когда код пытается обратиться к участку, который ему недоступен. Это исключение обычно возникает из-за указания некорректного адреса, но причиной также может быть отсутствие доступа к защищенной памяти.
Некоторые инструкции можно выполнить, только если процессор находится в привилегированном режиме. Если программа, находящаяся вне этого режима, попытается их вызвать, процессор сгенерирует исключение.
ПРИМЕЧАНИЕ
Привилегированный режим — это режим ядра, а непривилегированный — режим пользователя. Эти термины чаще всего используются при обсуждении процессора. Привилегированными, к примеру, являются инструкции, которые обращаются к оборудованию в режиме записи или изменяют таблицы со страницами памяти.
Управление выполнением с помощью отладчика
С помощью отладчиков можно влиять на работу программ. Вы можете редактировать управляющие флаги, указатели на инструкции или сам код, изменяя тем самым ход выполнения программы.
Например, чтобы избежать вызова функции, вы можете указать перед ним точку останова, при срабатывании которой можно будет перенаправить указатель на инструкцию, идущую за этим вызовом. Если эта функция играет важную роль, ее пропуск может привести к некорректной работе или даже преждевременному завершению программы. Если же она не затрагивает остальные участки кода, программа может продолжить выполнение без каких-либо проблем.
Отладчик можно использовать для изменения указателя на инструкцию. Скажем, у вас есть функция для обработки строк под названием encodeString, но вы не знаете, где именно она вызывается. С помощью отладчика вы можете выполнить ее независимо от остального кода. Например, чтобы узнать, какой результат вернет encodeString, если ей передать строку "Hello World", присвойте значению со сдвигом
|
|
|
|
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 |
|
|
|||
Глава 8. Отладка 203 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
esp+4 указатель на эту строку. После этого перенаправьте указатель инструкции на первую строку функции encodeString и пошагово ее выполните, чтобы увидеть, что она делает. Конечно, при этом у программы разрушится стек и она уже не сможет продолжить нормальную работу после завершения функции, но, если вам просто нужно понять, как ведет себя определенный участок кода, эта методика может оказаться чрезвычайно полезной.
Изменение хода выполнения программы на практике
Последний пример в этой главе основан на реальном вирусе, который вел себя по-разному в зависимости от языковых настроек зараженного компьютера. Если в качестве языка был указан упрощенный китайский, вирус удалял себя из системы и не причинял никакого вреда. В системах с английским языком он выводил всплывающее окно с плохо переведенным сообщением You luck's so good. Японским и индонезийским пользователям вирус перезаписывал содержимое жесткого диска бессмысленными данными, пытаясь вывести компьютеры из строя. Посмотрим, как бы мы проанализировали поведение этой программы в японской системе без изменения языковых настроек.
В листинге 8.6 показан ассемблерный код, который зависит от установок языка. Сначала программа вызывает функцию GetSystemDefaultLCID. Затем, в зависимости от полученного значения, вызывается одна из трех функций. Английский, японский, индонезийский и китайский языки имеют следующие региональные идентификаторы: 0x0409, 0x0411, 0x0421 и 0x0C04 соответственно.
Листинг 8.6. Ассемблерный код, зависящий от языковых настроек
00411349 |
call |
GetSystemDefaultLCID |
0041134F |
mov |
[ebp+var_4], eax |
00411352 |
cmp |
[ebp+var_4], 409h |
00411359 |
jnz |
short loc_411360 |
0041135B |
call |
sub_411037 |
00411360 |
cmp |
[ebp+var_4], 411h |
00411367 |
jz |
short loc_411372 |
00411369 |
cmp |
[ebp+var_4], 421h |
00411370 |
jnz |
short loc_411377 |
00411372 |
call |
sub_41100F |
00411377 |
cmp |
[ebp+var_4], 0C04h |
0041137E |
jnz |
short loc_411385 |
00411380 |
call |
sub_41100A |
Если установлен английский язык, этот код вызывает функцию по адресу 0x411037, если японский или индонезийский — 0x41100F, если китайский — 0x41100A. Чтобы тщательно проанализировать данную программу, мы должны выполнить код, который вызывается для японского и индонезийского языков. С помощью отладчика мы можем заставить код выбрать этот путь, не изменяя языковые настройки системы: для этого нужно указать точку останова , чтобы изменить возвращаемое
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
204 Часть III • Продвинутый динамический анализ |
||||
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 |
|
|
|
|
значение. В частности, если в системе в качестве языка выбран американский английский, в регистре EAX будет храниться значение 0x0409. Мы можем воспользоваться отладчиком и заменить это значение на 0x411, после чего продолжить выполнение программы, позволив ей выполнить код, предназначенный для системы с японским языком. Естественно, это следует делать в изолированной виртуальной машине.
Итоги главы
Отладка крайне важна в анализе вредоносных программ: она позволяет получить информацию, добыть которую посредством одного дизассемблирования было бы очень сложно. Вы можете использовать отладчик для пошагового прохода по программе, чтобы увидеть, что именно происходит внутри, или указывать с его помощью точки останова, чтобы исследовать определенный участок кода. С использованием отладчика также можно изменить ход выполнения программы для извлечения дополнительных сведений.
Для эффективного анализа вредоносного ПО с применением отладчика требуется определенный опыт. Следующие две главы посвящены особенностям отладчиков OllyDbg и WinDbg.