- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 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 |
|
|
404 Часть 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 |
|
|
|
|
Продолжив анализировать этот код, мы обнаружили, что он сканирует список процессов с помощью функций CreateToolhelp32Snapshot, Process32Next и т. д. Операция strncmp сравнивает строку VMwareTray.exe с результатом преобразования processentry32.szExeFile в кодировку ASCII. Это позволяет определить, находится ли имя процесса в списке. Как видно в строке 0x4010c2, в случае обнаружения процесса VMwareTray.exe программа немедленно завершается.
От этого можно защититься несколькими способами.
Модифицировать двоичный файл во время отладки, чтобы исключить переход по адресу 0x4010a5.
Заменить в hex-редакторе строку VMwareTray.exe на XXXareTray.exe, чтобы сравнение было неудачным (поскольку процесса с таким именем нет).
Удалить из системы пакет VMware Tools, чтобы служба VMwareTray.exe больше не запускалась.
Поиск следов в памяти
В ходе виртуализации VMware оставляет в памяти множество следов. Это могут быть важные процессорные структуры, которые в результате работы виртуальной машины перемещаются или изменяются, оставляя характерные «отпечатки». Поэтому вредоносное ПО часто ищет в оперативной памяти строку VMware, благодаря чему, как мы обнаружили, можно найти сотни таких артефактов.
Уязвимые инструкции
У виртуальной машины есть программа мониторинга, которая следит за ее выполнением. Эта программа работает в основной ОС и предоставляет гостевой ОС виртуальную платформу. Она обладает несколькими уязвимостями, с помощью которых вредоносное ПО может распознать виртуализацию.
ПРИМЕЧАНИЕ
Проблемы выполнения инструкций x86 в виртуальных машинах, рассмотренные в этом разделе, были описаны Джоном Робином иСинтией Ирвин в статье
Analysis of the Intel Pentium’s Ability to Support a Secure Virtual Machine Monitor («Анализ способности Intel Pentium поддерживать безопасный мониторинг виртуальных машин») на конференции USENIX 2000.
Врежиме ядра VMware использует для эмуляции трансляцию двоичного кода.
Вэтом режиме интерпретируются и эмулируются некоторые привилегированные инструкции — таким образом они не выполняются на реальном процессоре. В пользовательском же режиме код работает напрямую в ЦПУ, и практически любая инструкция, взаимодействующая с оборудованием, является привилегированной или
генерирует ловушку/прерывание в ядре. VMware перехватывает и обрабатывает все
|
|
|
|
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 |
|
|
|||
Глава 17. Методы противодействия виртуальным машинам 405 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
прерывания, чтобы виртуальная система думала, что она выполняется на обычном компьютере.
На платформе х86 некоторые инструкции обращаются к информации, связанной
соборудованием, но не генерируют при этом прерываний. Среди них можно выделить sidt, sgdt, sldt и cpuid. Чтобы их корректно виртуализировать, VMware пришлось бы проводить двоичное преобразование для каждой из них (и не только для тех, что работают в режиме ядра), что существенно бы снизило производительность. VMware пытается избежать эмуляции всех инструкций подряд, позволяя некоторым из них выполняться без надлежащей виртуализации. Фактически это означает, что некоторые цепочки инструкций возвращают разные результаты в зависимости от того, работают они внутри VMware или на настоящем компьютере.
Процессор использует определенные ключевые структуры и таблицы, которые из-за отсутствия полноценной трансляции загружаются с разными сдвигами. Таблица векторов прерываний (interrupt descriptor table, IDT) — это внутренняя структура данных ЦПУ, с помощью которой операционная система определяет подходящую реакцию на прерывания и исключения. На платформе x86 любое обращение к памяти проходит через таблицу дескрипторов — локальную (local descriptor table, LDT) или глобальную (global descriptor table, GDT). Эти таблицы содержат сегментные дескрипторы, которые предоставляют подробности о доступе к каждому сегменту, включая его базовый адрес, тип, длину, права доступа и т. д. IDT (IDTR), GDT (GDTR) и LDT (LDTR) — это внутренние регистры, которые содержат адреса и размеры соответствующих таблиц.
Стоит отметить, что эти таблицы могут не использоваться на уровне операционных систем. Например, в Windows реализована плоская модель памяти, и по умолчанию ей достаточно только GDT, а таблица LDT игнорируется.
Для получения местоположения этих таблиц предусмотрены три деликатные инструкции: sidt, sgdt и sldt, — каждая из которых сохраняет содержимое соответствующего регистра в память. Обычно они используются операционной системой, но в архитектуре x86 они не являются привилегированными, поэтому их можно выполнять из пользовательского пространства.
Процессор на платформе x86 имеет лишь три регистра для хранения адресов этих трех таблиц. Следовательно, содержимое этих регистров должно быть корректным
сточки зрения основной ОС и отличаться от значений, которые ожидаются в виртуальной (гостевой) среде. Поскольку инструкции sidt, sgdt и sldt можно в любой момент вызвать из пользовательского кода без применения ловушек или виртуализации со стороны VMware, они позволяют обнаружить присутствие виртуальной машины.
Использование методики Red Pill
Red Pill (дословно «красная пилюля») — это методика анти-ВМ, основанная на выполнении инструкции sidt и извлечении содержимого регистра IDTR. Программа мониторинга виртуальной машины должна переместить IDTR гостевой системы, чтобы избежать конфликта с одноименным регистром основной ОС. Но, поскольку
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
406 Часть 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 |
|
|
|
|
она не знает, когда именно виртуальная машина запускает sidt, в результате возвращается гостевой вариант IDTR. Метод Red Pill состоит в проверке этого несоответствия, что позволяет обнаружить применение VMware.
В листинге 17.2 показано то, как Red Pill может использоваться во вредоносном коде.
Листинг 17.2. Применение Red Pill во вредоносе
push |
ebp |
|
mov |
ebp, esp |
|
sub |
esp, 454h |
|
push |
ebx |
|
push |
esi |
|
push |
edi |
|
push |
8 |
; Size |
push |
0 |
; Val |
lea |
eax, [ebp+Dst] |
|
push |
eax |
; Dst |
call |
_memset |
|
add |
esp, 0Ch |
|
lea |
eax, [ebp+Dst] |
|
sidt |
fword ptr [eax] |
|
mov |
al, [eax+5] |
|
cmp |
al, 0FFh |
|
jnz |
short loc_401E19 |
|
Вредонос вызывает инструкцию sidt , сохраняющую содержимое IDTR в ячейку памяти, на которую указывает EAX. IDTR состоит из шести байтов, а сдвиг по пятому байту содержит начало базового адреса. Этот пятый байт сравнивается со значением 0xFF — сигнатурой VMware.
Методика Red Pill подходит только для однопроцессорных компьютеров. Она не будет стабильно работать с многоядерными процессорами, поскольку каждому ядру (гостевому или основному) назначается отдельная таблица IDT. Следовательно, результат инструкции sidt будет варьироваться, и сигнатура, которая используется в Red Pill, может оказаться ненадежной.
Чтобы нивелировать этот прием, используйте многоядерный процессор или просто замените инструкцию sidt на NOP.
Использование методики No Pill
Применение инструкций sgdt и sldt для обнаружения VMware носит название No Pill. В отличие от Red Pill, данная методика основана на том факте, что структура LDT назначается процессору, а не операционной системе. И поскольку в Windows эта структура обычно не используется, VMware обеспечивает ее виртуальную поддержку. В результате таблицы этого типа будут иметь предсказуемые различия: в основной системе LDT находится по нулевому адресу, а в виртуальной машине ее
|
|
|
|
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 |
|
|
|||
Глава 17. Методы противодействия виртуальным машинам 407 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
адрес будет иметь ненулевое значение. Достаточно лишь проверить на ноль результат выполнения инструкции sldt.
Использование sldt можно сделать бесполезным, если отключить в VMware ускорение. Для этого выберите пункт меню VM Settings Processors (VM Настрой ки Процессоры) и установите флажок Disable Acceleration (Отключить ускорение). В качестве ответной меры No Pill может воспользоваться инструкцией smsw, если sldt завершится неудачно. Этот подход подразумевает проверку незадокументированных старших битов, которые возвращает smsw.
Обращение к порту ввода/вывода
Вероятно, самый популярный сегодня способ борьбы с VMware заключается в обращении к порту ввода/вывода. Эта методика часто встречается в червях и ботах, таких как Storm и Phatbot.
Для взаимодействия между виртуальной машиной и основной системой VMware использует виртуальные порты ввода/вывода. Это позволяет поддерживать такие возможности, как буфер обмена между двумя системами. Чтобы обнаружить присутствие VMware, вредонос может обратиться к такому порту и сравнить результат с магическим числом.
Успех этого подхода зависит от инструкции in на платформе x86. Она имеет два операнда: первый определяет исходный порт, из которого будут копироваться данные, а второй описывает место в памяти, куда эти данные попадут. VMware отслеживает использование инструкции in и перехватывает ввод/вывод, проходящий через канал 0x5668 (VX). Таким образом, чтобы проверить наличие VMware, второй операнд должен содержать VX, что происходит только в случае, когда в регистре EAX находится магическое число 0x564D5868 (VMXh). Регистр ECX должен иметь значение, соответствующее действию, которое вы хотите выполнить с портом. Байт 0xA означает «получить тип версии VMware», а 0x14 — «получить размер памяти». Для обнаружения виртуальной машины можно использовать оба этих значения, но 0xA более популярно, так как позволяет определить версию VMware.
Ботнет Phatbot, также известный как Agobot, отличается простотой в использовании. Одной из его особенностей является встроенная поддержка методики обнаружения на основе порта ввода/вывода (листинг 17.3).
Листинг 17.3. Обнаружение VMware в Phatbot
004014FA |
push |
eax |
004014FB |
push |
ebx |
004014FC |
push |
ecx |
004014FD |
push |
edx |
004014FE |
mov |
eax, 'VMXh' |
00401503 |
mov |
ebx, [ebp+var_1C] |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|
|||
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|
|||
w |
|
|
to |
|
|
408 Часть V |
• |
Противодействие обратному проектированию |
||||
w Click |
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
o |
m |
|
|
||||
|
w |
|
|
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
00401506 |
mov |
ecx, 0xA |
||
|
|
|
|
|
|
|
|
00401509 |
mov |
dx, 'VX' |
||
|
|
|
|
|
|
|
|
0040150E |
in |
eax, dx |
||
|
|
|
|
|
|
|
|
0040150F |
mov |
[ebp+var_24], eax |
||
|
|
|
|
|
|
|
|
00401512 |
mov |
[ebp+var_1C], ebx |
||
|
|
|
|
|
|
|
|
00401515 |
mov |
[ebp+var_20], ecx |
||
|
|
|
|
|
|
|
|
00401518 |
mov |
[ebp+var_28], edx |
||
|
|
|
|
|
|
|
|
... |
|
|
||
|
|
|
|
|
|
|
|
0040153E |
mov |
eax, [ebp+var_1C] |
||
|
|
|
|
|
|
|
|
00401541 |
cmp |
eax, 'VMXh' |
||
|
|
|
|
|
|
|
|
00401546 |
jnz |
short loc_40155C |
|
|
|
|
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 магическое число 0x564D5868 (VMXh). Затем он копирует в регистр EBX локальную переменную var_1c, содержащую адрес в памяти, по которому VMware вернет ответ. ECX содержит значение 0xA, чтобы получить тип версии VMware. Число 0x5668 (VX) определяет порт ввода/ вывода; в строке оно загружается в DX, чтобы впоследствии его можно было использовать в качестве операнда для инструкции in.
Во время выполнения инструкция in отлавливается и эмулируется виртуальной машиной. В качестве параметров она использует регистры EAX (магическое число), ECX (операция) и EBX (возвращаемое значение). Если магическое число совпадает с VMXh и код работает в виртуальной среде, система мониторинга VMware запишет соответствующий результат на участок памяти, адрес которого указан в регистре EBX.
Проверка определяет, выполняется ли код в виртуальной машине. Поскольку было выбрано значение 0xA, в регистре ECX будет находиться тип VMware (1 = Express, 2 = ESX, 3 = GSX и 4 = Workstation).
Для борьбы с этой методикой проще всего вставить команды NOP вместо инструкции in или модифицировать условный переход, чтобы он происходил независимо от результата сравнения.
Использование инструкции str
Инструкция str извлекает из регистра TR сегментный селектор, который указывает на сегмент состояния задачи (task state segment, TSS), выполняемой в текущий момент. С помощью этой инструкции авторы вредоносного ПО могут определить присутствие виртуальной машины, поскольку значения, которые она возвращает, варьируются в зависимости от того, основная это система или гостевая (этот подход не работает для многопроцессорного оборудования).
На рис 17.2 в строке 0x401224 показана инструкция str, которая используется во вредоносе, известном как SNG.exe. Эта команда загружает в TSS 4 байта, начиная с var_1 и заканчивая var_4 (метки, сгенерированные в IDA Pro). На участках 0x40125A и 0x401262 происходит два сравнения, которые определяют наличие VMware.
|
|
|
|
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 |
|
|
|||
Глава 17. Методы противодействия виртуальным машинам 409 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Инструкции анти-ВМ на платформе x86
Мы рассмотрели самые популярные инструкции, которые используются во вредоносном ПО для борьбы с виртуальными машинами:
sidt;sgdt;sldt;smsw;str;
in (второй операнд должен быть равен VX);
cpuid.
Обычно вредоносные программы используют эти инструкции с одной целью — обнаружить VMware. Вам достаточно модифицировать двоичный файл, чтобы предотвратить их вызов. Эти инструкции практически бесполезны в пользовательском режиме, поэтому их наличие, скорее всего, говорит об использовании в коде методики анти-ВМ. В VMware виртуализации «не поддаются» примерно 20 инструкций, и те из них, которые чаще других используются во вредоносном ПО, перечислены выше.
Выделение кода анти-ВМ в IDA Pro
В IDA Pro поиск инструкций, перечисленных в предыдущем разделе, можно выполнить с помощью скрипта IDAPython, показанного в листинге 17.4. Этот скрипт ищет инструкции, выделяет их красным цветом и показывает в окне вывода IDA, сколько всего их было найдено.
Листинг 17.4. Скрипт для IDA Pro, который ищет инструкции анти-ВМ
from idautils import * from idc import *
heads = Heads(SegStart(ScreenEA()), SegEnd(ScreenEA())) antiVM = []
for i in heads:
if (GetMnem(i) == "sidt" or GetMnem(i) == "sgdt" or GetMnem(i) == "sldt" or GetMnem(i) == "smsw" or GetMnem(i) == "str" or GetMnem(i) == "in" or GetMnem(i) == "cpuid"):
antiVM.append(i)
print "Number of potential Anti-VM instructions: %d" % (len(antiVM)) for i in antiVM:
SetColor(i, CIC_ITEM, 0x0000ff) Message("Anti-VM: %08x\n" % i)
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
410 Часть 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 |
|
|
|
|
На рис. 17.2 показана часть результата работы этого скрипта для файла SNG.exe. В окне выделена инструкция str по адресу 0x401224. IDA Pro позволяет быстро определить, используется ли она для борьбы с виртуальными машинами. Дальнейшее исследование показывает, что эта инструкция участвует в обнаружении VMware.
Рис. 17.2. Методика анти-ВМ на основе str в файле SNG.exe
Использование ScoopyNG
ScoopyNG (www.trapkit.de) — это бесплатная утилита для обнаружения VMware, в которой реализовано семь разных приемов распознавания виртуальных машин.
Первые три проверки ищут инструкции sidt, sgdt и sldt (Red Pill и No Pill).Четвертая проверка ищет str.