- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 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 |
|
|
156 Часть II • Продвинутый статический анализ |
||||
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 |
|
|
|
|
Связный список — это структура данных, состоящая из последовательности элементов, каждый из которых содержит поле со ссылкой на следующий элемент. Принципиальным преимуществом связного списка перед массивом является то, что порядок размещения элементов в списке может отличаться от того, как эти элементы хранятся в памяти или на диске. Благодаря этому связный список позволяет добавление и удаление узлов в произвольной позиции.
В листинге 6.29 показан пример связного списка и его обхода на языке C. Данный список состоит из набора структур под названием pnode и проходит через два цикла. Первый цикл создает и наполняет данными десять узлов, а второй перебирает все записи и выводит их содержимое.
Листинг 6.29. Обход связного списка в языке C
struct node
{
int x;
struct node * next;
};
typedef struct node pnode;
void main()
{
pnode * curr, * head; int i;
head = NULL;
for(i=1;i<=10;i++)
{
curr = (pnode *)malloc(sizeof(pnode)); curr->x = i;
curr->next = head; head = curr;
}
curr = head;
while(curr)
{
printf("%d\n", curr->x); curr = curr->next ;
}
}
Чтобы понять дизассемблированный код, лучше всего определить две конструкции в методе main. В этом и заключается суть данной главы: способность распознавать такие конструкции упрощает анализ.
В листинге 6.30 мы сначала определим цикл for. Переменная var_C соответствует счетчику цикла i. var_8 и var_4 представляют переменные head и curr. var_4 — это указатель на структуру с двумя значениями, присвоенными на шагах и .
|
|
|
|
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 |
|
|
|||
Глава 6. Распознавание конструкций языка C в ассемблере 157 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Цикл while (от до ) перебирает связный список. Внутри цикла for значению var_4 присваивается следующий элемент списка .
Листинг 6.30. Ассемблерный код для обхода связного списка из листинга 6.29
0040106A |
mov |
[ebp+var_8], 0 |
00401071 |
mov |
[ebp+var_C], 1 |
00401078 |
|
|
00401078 |
loc_401078: |
|
00401078 |
cmp |
[ebp+var_C], 0Ah |
0040107C |
jg |
short loc_4010AB |
0040107E |
mov |
[esp+18h+var_18], 8 |
00401085 |
call |
malloc |
0040108A |
mov |
[ebp+var_4], eax |
0040108D |
mov |
edx, [ebp+var_4] |
00401090 |
mov |
eax, [ebp+var_C] |
00401093 |
mov |
[edx], eax |
00401095 |
mov |
edx, [ebp+var_4] |
00401098 |
mov |
eax, [ebp+var_8] |
0040109B |
mov |
[edx+4], eax |
0040109E |
mov |
eax, [ebp+var_4] |
004010A1 |
mov |
[ebp+var_8], eax |
004010A4 |
lea |
eax, [ebp+var_C] |
004010A7 |
inc |
dword ptr [eax] |
004010A9 |
jmp |
short loc_401078 |
004010AB loc_4010AB: |
|
|
004010AB |
mov |
eax, [ebp+var_8] |
004010AE |
mov |
[ebp+var_4], eax |
004010B1 |
|
|
004010B1 |
loc_4010B1: |
|
004010B1 |
cmp |
[ebp+var_4], 0 |
004010B5 |
jz |
short locret_4010D7 |
004010B7 |
mov |
eax, [ebp+var_4] |
004010BA |
mov |
eax, [eax] |
004010BC |
mov |
[esp+18h+var_14], eax |
004010C0 |
mov |
[esp+18h+var_18], offset aD ; "%d\n" |
004010C7 |
call |
printf |
004010CC |
mov |
eax, [ebp+var_4] |
004010CF |
mov |
eax, [eax+4] |
004010D2 |
mov |
[ebp+var_4], eax |
004010D5 |
jmp |
short loc_4010B1 |
Чтобы распознать связный список, вам сначала нужно найти объект, который содержит указатель на другой объект того же типа. Их рекурсивная природа делает их связанными, и именно это вам нужно искать в ассемблерном коде.
Обратите внимание на шаг : значение var_4 присваивается регистру еах. Это можно определить по операции [eax+4], которая сама стала результатом предыдущего присваивания var_4. Это означает, что структура var_4, какой бы она ни была, должна содержать указатель размером 4 байта, который связан с другой структурой, тоже содержащей указатель того же размера на еще одну структуру, и т. д.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
158 Часть II • Продвинутый статический анализ |
||||
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 |
|
|
|
|
Цель этой главы — научить вас абстрагироваться от подробностей. Этот прием постоянно применяется в анализе безопасности. Не позволяйте себе увязнуть в низкоуровневых деталях — выработайте навык распознавать принцип работы кода на более высоком уровне.
Мы продемонстрировали вам все основные конструкции в языке C и ассемблере, чтобы вы могли быстро их выявлять во время анализа. Мы также показали несколько примеров принятия компилятором совершенно разных решений, как в случае со структурами (когда использовался совсем другой компилятор) и вызовами функций. Понимание этого аспекта поможет вам находить в коде новые конструкции, которые будут встречаться в реальных условиях.
Лабораторные работы
Эти лабораторные работы должны помочь вам понять общую функциональность программы путем анализа конструкций языка. В каждой работе вы получите возможность обнаружить и проанализировать новую структуру. Каждая следующая лабораторная работа основывается на предыдущей, предлагая вам таким образом одну сложную вредоносную программу, состоящую из четырех частей. Выполнив все задания, вы сможете быстрее распознавать эти отдельные конструкции, если они вам встретятся в зараженном коде.
Лабораторная работа 6.1
Проанализируйте вредоносную программу Lab06-01.exe.
Вопросы
1.Какая основная конструкция содержится в единственном ответвлении, вызываемом функцией main?
2.Какое ответвление вызывается по адресу 0x40105F?
3.Каково назначение этой программы?
Лабораторная работа 6.2
Проанализируйте вредоносный код в файле Lab06-02.exe.
Вопросы
1.Какие операции выполняет первое ответвление в функции main?
2.Какое ответвление находится по адресу 0x40117F?
3.Что делает второе ответвление, вызываемое из main?
|
|
|
|
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 |
|
|
|||
Глава 6. Распознавание конструкций языка C в ассемблере 159 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
4.Конструкция какого типа используется в этом ответвлении?
5.Имеет ли эта программа какие-либо сетевые индикаторы?
6.Каково назначение этого вредоноса?
Лабораторная работа 6.3
Проанализируйте вредоносную программу Lab06-03.exe.
Вопросы
1.Сравните вызовы в функциях main этой и предыдущей лабораторной работы. Вызов какой новой функции был добавлен?
2.Какие параметры принимает эта новая функция?
3.Какая основная конструкция содержится в этой функции?
4.Что эта функция умеет делать?
5.Имеет ли данный вредонос какие-либо локальные индикаторы?
6.Каково назначение этой программы?
Лабораторная работа 6.4
Проанализируйте вредоносную программу Lab06-04.exe.
Вопросы
1.Какая разница между вызовами, сделанными внутри функции main в этой и предыдущей лабораторных работах?
2.Какие новые конструкции были добавлены в main?
3.Чем отличается функция для разбора HTML в этой и предыдущих лабораторных работах?
4.Как долго будет работать эта программа (если предположить, что она подключена к Интернету)?
5.Содержит ли данный вредонос какие-либо новые сетевые индикаторы?
6.Каково назначение этой программы?