- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 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 |
|
|
. |
|
|
|
|
|
12 |
||||
|
|
|
|
|
|
.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 |
|
|
|
|
Со временем компьютерные системы становятся более сложными, а пользователи — более осведомленными, но и вредоносное ПО не стоит на месте. Например, многие пользователи умеют просматривать процессы с помощью Диспетчера задач Windows, поэтому злоумышленники разработали множество методик, чтобы сделать свои программы незаметными на фоне остальной системы.
Эта глава посвящена технике скрытого запуска — приемам, помогающим авторам вредоносного ПО избегать обнаружения. Здесь вы изучите конструкции кода и другие шаблоны, которые позволят вам распознавать популярные способы незаметного запуска вредоносов.
Загрузчики
Как уже упоминалось в предыдущей главе, загрузчик (не путать с системным загрузчиком) — это вредоносная программа, которая занимается немедленным или отложенным запуском своего или другого вредоносного кода. Он подготавливает среду таким образом, чтобы вредоносная активность была скрыта от пользователя.
Часто загрузчики содержат вредоносный код, который они должны запускать. Обычно он хранится в их разделе ресурсов в виде исполняемого файла или DLL.
В Windows раздел ресурсов используется исполняемым файлом в формате PE, но не считается его частью. В нормальных условиях там хранятся значки, изображения, меню, строки и т. д. Но загрузчики часто используют этот раздел для хранения вредоноса. При запуске загрузчик извлекает оттуда встроенный исполняемый файл или библиотеку.
Как вы уже видели в предыдущих примерах, если раздел с ресурсами сжат или зашифрован, перед загрузкой вредоноса его сначала нужно извлечь. Чаще всего загрузчик использует с этой целью API-функции для работы с ресурсами, такие как
FindResource, LoadResource и SizeofResource.
Загрузчикам вредоносного ПО часто необходимо запускаться с правами администратора или повышать свои привилегии (как было показано в предыдущей главе). Обычный пользовательский процесс неспособен выполнить все обсуждаемые приемы. И тот факт, что загрузчик может содержать код для повышения привилегий, помогает его распознать.
|
|
|
|
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 |
|
|
|||
Глава 12. Скрытый запуск вредоносного ПО 283 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Внедрение в процесс
Самым популярным методом скрытого запуска является внедрение в процесс. Как понятно из названия, это подразумевает изменение другого активного процесса, чтобы он, сам того не зная, выполнил вредоносный код. Злоумышленники используют внедрение в процесс как средство скрытия вредоносной активности своего кода и иногда пытаются таким образом обойти локальные брандмауэры и другие механизмы безопасности, отслеживающие отдельные процессы.
В Windows для внедрения в процесс обычно используются определенные API-вызовы. Например, с помощью функции VirtualAllocEx можно выделить пространство в памяти внешнего процесса, а функция WriteProcessMemory позволяет записать туда данные. Эта связка является ключевой для первых трех методик скрытого запуска, о которых пойдет речь в текущей главе.
Внедрение DLL
Внедрение DLL — это способ заставить процесс загрузить зараженную библиотеку. Данный подход является самым распространенным видом скрытого запуска. Во внешний процесс внедряется код, который загружает в его контексте DLL. После этого ОС автоматически вызывает из зараженной библиотеки функцию DllMain, которую написал ее автор. Эта функция содержит вредоносный код и имеет тот же доступ к системе, что и процесс, в рамках которого она выполняется. Основное содержимое зараженной библиотеки обычно находится внутри Dllmain, и все ее действия будут производиться от имени процесса, в который ее внедрили.
Пример внедрения DLL показан на рис. 12.1. Здесь загрузчик встраивает библиотеку в память Internet Explorer, предоставляя ей такой же доступ к Интернету, как у этого браузера. Загрузчик не мог выйти в Интернет до внедрения, поскольку брандмауэр обнаружил и заблокировал его процесс.
Рис. 12.1. Внедрение DLL: загрузчик не может выйти в Интернет, пока не внедрится в iexplore.exe
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
284 Часть IV • Возможности вредоносного ПО |
||||
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 |
|
|
|
|
Чтобы внедрить DLL в локальную программу, загрузчик сначала должен заполучить ее дескриптор. Для поиска подходящего процесса, в который можно внедриться, обычно используются функции CreateToolhelp32Snapshot, Process32First
иProcess32Next из Windows API. Найдя процесс, загрузчик извлекает его идентификатор (process identifier, PID) и передает его в вызов OpenProcess, который вернет его дескриптор.
Обычно при внедрении DLL используется функция CreateRemoteThread, чтобы загрузчик мог создать и выполнить во внешнем процессе новый поток. Она принимает три важных аргумента: дескриптор процесса (hProcess), полученный с помощью OpenProcess, а также начальную точку внедренного потока (lpStartAddress)
иего параметр (lpParameter). Начальной точкой можно сделать, к примеру, функцию LoadLibrary, передав ей в качестве аргумента имя библиотеки. Таким образом LoadLibrary запустится в рамках заражаемого процесса, получит этот аргумент и загрузит вредоносную библиотеку (предполагается, что вызов LoadLibrary доступен в пространстве памяти заражаемого процесса и что строка с именем библиотеки находится в том же пространстве).
Для создания памяти под строку с именем DLL авторы вредоносного ПО обычно используют функцию VirtualAllocEx, которая выделяет пространство в процессе с заданным дескриптором.
Последней подготовительной функцией, которую нужно вызвать перед операцией CreateRemoteThread, является WriteProcessMemory. Она записывает строку с именем вредоносной библиотеки в пространство памяти, выделенное функцией
VirtualAllocEx.
В листинге 12.1 показан псевдокод на языке C, который производит внедрение DLL.
Листинг 12.1. Псевдокод на языке C для внедрения DLL
hVictimProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, victimProcessID );
pNameInVictimProcess = VirtualAllocEx(hVictimProcess,..., sizeof(maliciousLibraryName),...,...); WriteProcessMemory(hVictimProcess,...,maliciousLibraryName, sizeof(maliciousLibraryName),...); GetModuleHandle("Kernel32.dll"); GetProcAddress(...,"LoadLibraryA");
CreateRemoteThread(hVictimProcess,...,...,LoadLibraryAddress, pNameInVictimProcess,...,...);
В этом листинге предполагается, что PID, который мы передаем в вызов OpenPro cess для извлечения дескриптора процесса, был получен с помощью функции victimProcessID. Затем, передавая этот дескриптор функциям VirtualAllocEx и WriteProcessMemory, мы выделяем место в заражаемом процессе и записываем туда строку с именем DLL. После этого мы используем вызов GetProcAddress, чтобы получить адрес LoadLibrary.
Наконец, в строке функции CreateRemoteThread передаются три важных аргумента, упомянутых выше: дескриптор заражаемого процесса, адрес LoadLibrary
|
|
|
|
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 |
|
|
|||
Глава 12. Скрытый запуск вредоносного ПО 285 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
и указатель на имя вредоносной библиотеки внутри процесса. Распознать внедрение DLL проще всего по характерной цепочке вызовов Windows API в дизассемблированном коде.
Загрузчик никогда не вызывает вредоносную функцию в ходе внедрения DLL. Как уже отмечалось ранее, вредоносный код находится внутри вызова DllMain, который автоматически запускается системой при загрузке библиотеки в память. Цель загрузчика — вызвать функцию CreateRemoteThread, чтобы создать внешний поток LoadLibrary и передать ему в качестве аргумента имя зараженной библиотеки.
На рис. 12.2 показано, как выглядит код внедрения DLL в отладчике. В строках с по можно наблюдать вызовы шести функций, описанных в псевдокоде в листинге 12.1.
Рис. 12.2. Внедрение DLL в окне отладчика
Обнаружив процедуру внедрения DLL в дизассемблированном коде, нужно отыскать строки с именами вредоносных библиотек и заражаемого процесса. На рис. 12.2 этих строк не видно, но доступ к ним должен быть получен до выполнения этого кода. Имя атакуемого процесса часто можно найти в функции strncmp (или ее аналоге) на этапе, когда загрузчик определяет соответствующий PID. Чтобы получить имя вредоносной библиотеки, можно создать точку останова для адреса 0x407735 и просмотреть содержимое стека, а именно значение переменной Buffer, которая передается в WriteProcessMemory.
Если вы смогли распознать процедуру внедрения DLL и получить эти важные строки, то сможете быстро проанализировать и целый подвид вредоносных загрузчиков.