- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 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 |
|
|
274 Часть 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 |
|
|
|
|
Большинство пользователей имеют права локального администратора, что не может не радовать авторов вредоносного ПО. Это означает, что пользователи имеют администраторский доступ к компьютеру и могут предоставить те же привилегии вредоносному коду.
Специалисты в сфере безопасности не рекомендуют входить в систему в качестве локального администратора, чтобы не дать случайно запущенному вредоносу полный доступ к своей системе. Если же пользователь запустит вредонос, не имея прав администратора, для получения полного контроля тому придется произвести атаку с повышением привилегий.
В большинстве атак такого рода используются широко известные эксплойты, или так называемые уязвимости нулевого дня, нацеленные на локальную ОС. Многие из них можно найти в пакете Metasploit Framework (www.metasploit.com). Для повышения привилегий можно даже использовать изменение порядка загрузки DLL. Если каталог, в котором хранится зараженная библиотека, доступен для записи со стороны пользователя и если его загружает процесс с более высоким уровнем доступа, он получит больше прав. Вредоносное ПО, которое этим занимается, встречается относительно редко, однако аналитики безопасности должны уметь его распознавать.
Иногда вредоносу требуется повышение привилегий даже тогда, когда пользователь вошел в систему как локальный администратор. Процесс, запущенный в Windows, выполняется либо на пользовательском, либо на системном уровне. Пользователи обычно не могут манипулировать системными процессами, даже если они администраторы. Ниже мы рассмотрим, как вредоносные программы повышают свои привилегии, чтобы атаковать в Windows процессы системного уровня.
Использование привилегии SeDebugPrivilege
Процесс, запущенный пользователем, не обладает свободным доступом ко всему подряд и не может, к примеру, вызывать из удаленного процесса такие функции, как TerminateProcess или CreateRemoteThread. Чтобы решить эту проблему, вредонос может установить права для маркера доступа и активизировать привилегию SeDebugPrivilege. В системах семейства Windows маркер доступа представляет собой объект, который содержит дескриптор безопасности процесса. Этот дескриптор используется для описания прав доступа владельца — в данном случае процесса. Маркер доступа можно изменить, вызвав функцию AdjustTokenPrivileges.
Привилегия SeDebugPrivilege задумывалась как инструмент для отладки на системном уровне, но авторы вредоносного ПО используют ее для получения полного контроля над системными процессами. По умолчанию SeDebugPrivilege выдается только учетным записям локальных администраторов — в сущности, это эквивалентно получению прав уровня LocalSystem. Учетная запись обычного пользователя не может выдать сама себе SeDebugPrivilege — любой такой запрос будет отклонен.
|
|
|
|
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 |
|
|
|||
Глава 11. Поведение вредоносных программ 275 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
В листинге 11.6 показано, как вредоносный код активизирует SeDebugPrivilege.
Листинг 11.6. Присваивание маркеру доступа привилегии SeDebugPrivilege
00401003 |
lea |
eax, [esp+1Ch+TokenHandle] |
||
00401006 |
push |
eax |
; |
TokenHandle |
00401007 |
push |
(TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY) ; DesiredAccess |
||
00401009 |
call |
ds:GetCurrentProcess |
|
|
0040100F |
push |
eax |
; |
ProcessHandle |
00401010 |
call |
ds:OpenProcessToken |
|
|
00401016 |
test |
eax, eax |
|
|
00401018 |
jz |
short loc_401080 |
|
|
0040101A |
lea |
ecx, [esp+1Ch+Luid] |
|
|
0040101E |
push |
ecx |
; |
lpLuid |
0040101F |
push |
offset Name |
; |
"SeDebugPrivilege" |
00401024 |
push |
0 |
; |
lpSystemName |
00401026 |
call |
ds:LookupPrivilegeValueA |
|
|
0040102C |
test |
eax, eax |
|
|
0040102E |
jnz |
short loc_40103E |
|
|
... |
|
|
|
|
0040103E |
mov |
eax, [esp+1Ch+Luid.LowPart] |
||
00401042 |
mov |
ecx, [esp+1Ch+Luid.HighPart] |
||
00401046 |
push |
0 |
; |
ReturnLength |
00401048 |
push |
0 |
; |
PreviousState |
0040104A |
push |
10h |
; |
BufferLength |
0040104C |
lea |
edx, [esp+28h+NewState] |
|
|
00401050 |
push |
edx |
; |
NewState |
00401051 |
mov |
[esp+2Ch+NewState.Privileges.Luid.LowPt], eax |
||
004ф1055 |
mov |
eax, [esp+2Ch+TokenHandle] |
||
00401059 |
push |
0 |
; |
DisableAllPrivileges |
0040105B |
push |
eax |
; |
TokenHandle |
0040105C |
mov |
[esp+34h+NewState.PrivilegeCount], 1 |
||
00401064 |
mov |
[esp+34h+NewState.Privileges.Luid.HighPt], ecx |
||
00401068 |
mov |
[esp+34h+NewState.Privileges.Attributes], SE_PRIVILEGE_ENABLED |
||
00401070 |
call |
ds:AdjustTokenPrivileges |
|
Маркер доступа, полученный с помощью вызова OpenProcessToken , передается дескриптору процесса (который вернула функция GetCurrentProcess), при этом указывается желаемый уровень доступа (в данном случае, для того чтобы прочитать и изменить привилегии). Затем вредонос вызывает функцию LookupPrivilegeValueA, которая извлекает локальный уникальный идентификатор (LUID). LUID представляет собой структуру, которая описывает заданную привилегию (в данном случае
SeDebugPrivilege).
Информация, полученная из OpenProcessToken и LookupPrivilegeValueA, используется в вызове AdjustTokenPrivileges . Туда же передается ключевая структура, PTOKEN_PRIVILEGES, которая в IDA Pro помечена как NewState. Обратите внимание, что эта структура устанавливает младший и старший биты идентификатора LUID, используя результат выполнения функции LookupPrivilegeValueA. Эта процедура состоит из шагов и . Для активизации привилегии SeDebugPrivilege разделу
Attributes структуры NewState присваивается значение SE_PRIVILEGE_ENABLED . Это сочетание вызовов часто происходит до выполнения кода, который манипу-
лирует системой. Если увидите функцию с таким кодом, пометьте ее и двигайтесь
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
276 Часть 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 |
|
|
|
|
дальше. Обычно нет необходимости изучать все затейливые приемы, которые использует вредонос для повышения привилегий.
Заметая следы: руткиты, работающие в пользовательском режиме
Вредоносное ПО часто идет на всевозможные ухищрения, чтобы скрыть от пользователей свой запущенный процесс и механизм постоянного присутствия. Наиболее распространенные инструменты для скрытия вредоносной активности называют
руткитами.
Руткиты могут принимать множество форм, но большинство из них занимается изменением внутренней функциональности ОС. В результате этих изменений файлы, процессы, сетевые соединения и другие ресурсы становятся видны другим программам, что усложняет антивирусам, администраторам и аналитикам безопасности задачу обнаружения вредоносной активности.
Некоторые руткиты модифицируют пользовательские приложения, но большинство из них изменяет ядро, поскольку именно там установлены и выполняются механизмы защиты, такие как технология предотвращения запуска инструкций. И руткиты, и защитные механизмы работают более эффективно на уровне ядра. Там руткиту легче повредить систему, чем в пользовательском режиме. Методика перехвата SSDT-таблицы, как и IRP-перехватчики, работающие в режиме ядра, уже обсуждались в главе 10.
Здесь мы познакомим вас с несколькими видами руткитов уровня пользователя, чтобы вы имели общее представление о том, как они работают и как их распознать в реальных условиях (руткитам посвящены целые книги, а в текущем разделе мы лишь слегка затронем эту тему).
Если вы имеете дело с руткитом, который занимается перехватом вызовов на пользовательском уровне, в первую очередь стоит узнать, как именно установлен перехватчик и что он делает. Ниже мы рассмотрим перехват IAT-таблицы и подмену кода.
Перехват IAT-таблицы
Перехват IAT-таблицы — это классический метод, с помощью которого руткиты прячут файлы, процессы и сетевые соединения в локальной системе. Он подразумевает модификацию таблицы адресов импорта или экспорта (import address table, IAT, и export address table, EAT). Пример этого подхода показан на рис. 11.4. Обычная программа вызывает функцию TerminateProcess . В нормальных условиях код использует IAT-таблицу, чтобы получить доступ к этой функции в Kernel32.dll, но, если внутри IAT установлен перехватчик , вместо этого будет вызван вредоносный код руткита. Руткит возвращает управление программе и дает возможность выполнить функцию TerminateProcess, подменив некоторые параметры. В данном примере IAT-перехватчик не дает программе завершить процесс.
|
|
|
|
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 |
|
|
|||
|
|
|
Глава 11. Поведение вредоносных программ 277 |
to |
|
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IAT-перехват функции TerminateProcess. Сверху показан нормальный поток выполнения, а снизу — поток выполнения руткита |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 11.4. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
278 Часть 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 |
|
|
|
|
Это старая методика перехвата, и ее легко обнаружить, поэтому многие современные руткиты используют более продвинутый прием — подмену кода.
Подмена кода
Эта методика подразумевает перезапись кода API-функции, импортированной из DLL, поэтому, прежде чем приступать к выполнению, нужно дождаться загрузки библиотеки. В отличие от IAT-перехвата, здесь изменяется не просто указатель, а сама функция.
Руткит, производящий подмену кода, часто вставляет вместо начального участка переход, который передает управление вредоносному коду, вставленному руткитом. Как вариант, руткит может обойтись без перехода, если модифицирует или повредит содержимое функции.
В листинге 11.7 показан пример подмены кода функции ZwDeviceIoControlFile, которая используется такими программами, как Netstat, для извлечения системной информации о сети.
Листинг 11.7. Пример подмены кода |
|
||
100014B4 |
mov |
edi, offset ProcName; "ZwDeviceIoControlFile" |
|
100014B9 |
mov |
esi, offset ntdll ; "ntdll.dll" |
|
100014BE |
push |
edi |
; lpProcName |
100014BF |
push |
esi |
; lpLibFileName |
100014C0 |
call |
ds:LoadLibraryA |
|
100014C6 |
push |
eax |
; hModule |
100014C7 |
call |
ds:GetProcAddress |
|
100014CD |
test |
eax, eax |
|
100014CF |
mov |
Ptr_ZwDeviceIoControlFile, eax |
Местоположение подменяемой функции определяется в строке . Руткит пытается вставить семибайтный перехватчик в начало функции ZwDeviceIoControlFile, размещенной в памяти.
В табл. 11.2 показана процедура инициализации перехватчика; слева представлены необработанные байты, а справа — ассемблерный код.
Таблица 11.2. Семибайтный перехватчик
Необработанные байты |
Ассемблерный код |
|
|||
|
|
|
|
|
|
10004010 |
db |
0B8h |
10004010 |
mov |
eax, 0 |
10004011 |
db |
0 |
10004015 |
jmp |
eax |
10004012 |
db |
0 |
|
|
|
10004013 |
db |
0 |
|
|
|
10004014 |
db |
0 |
|
|
|
10004015 |
db |
0FFh |
|
|
|
10004016 |
db |
0E0h |
|
|
|
|
|
|
|
|
|