Содержание статьи
Для начала загрузим семпл в DiE и посмотрим, что он покажет.
Как видно на скриншоте, DiE отчего-то уверен, что наш семпл написан на Delphi, но это, разумеется, не так. Ты наверняка знаешь, что существуют специальные тулзы, которые умеют склеивать один файл с другим. Создатели LOKI-bot именно так и поступили (обрати внимание на размер секции ресурсов rsrc
в файле относительно его общего размера). Оригинальный LOKI запустится после того, как отработает его «обертка».
INFO
Все эксперименты с боевой малварью я настоятельно рекомендую проводить на изолированной от сети виртуальной машине, иначе есть риск получить заражение банкером LOKI-bot и лишиться своих данных!
Для того чтобы разобраться в механизме самозащиты этого бота, мы должны представлять себе, каким образом вообще малварь может сопротивляться отладке. Обычно так или иначе трой старается получить список процессов в системе, а после этого уже начинаются дальнейшие действия. Давай попробуем двигаться в эту сторону, чтобы изучить механизм самозащиты бота. Как известно, получить список процессов в Windows можно несколькими способами.
- Перечислить процессы при помощи функции
PSAPI EnumProcesses
. - Создать снимок процессов при помощи функции
CreateToolhelp32Snapshot
. - Перечислить процессы при помощи
ZwQuerySystemInformation
. - Применить трюки со счетчиками производительности.
- Использовать Windows Management Instrumentation (WMI).
Безусловно, самый распространенный метод получения процессов — при помощи функции CreateToolhelp32Snapshot
, поэтому мы начнем с установки брейк-пойнта на эту функцию (используется отладчик x64dbg, версия для архитектуры x86).
INFO
Исследование малвари или решение крякмисов может растянуться надолго: не всегда с первого раза ты ставишь брейк-пойнты на нужные функции, не всегда все идет по плану. В любом случае это вереница проб и ошибок. Когда ты читаешь статью, у тебя на это уходит максимум 10–15 минут, но это не значит, что любой взлом или снятие упаковки с файла будет занимать столько же времени. Просто есть «рабочие» моменты, рутина, которой не стоит утомлять читателя и которую автор пропускает. Поэтому создается впечатление, будто любой взлом быстр и элементарен, а автор с первого раза «угадывает», на какие функции WinAPI установить бряки, чтобы победить защиту. Но в жизни это не всегда так! 🙂
Начинаем погружение
Итак, мы оказались в теле функции CreateToolhelp32Snapshot
. Давай выполним ее и сделаем еще один шаг, чтобы вернуться по ret
. В итоге мы попадаем в такой код:
01DC40D8 | 53 | push ebx
01DC40D9 | 6A 02 | push 2
01DC40DB | FF56 0C | call dword ptr ds:[esi+C]
01DC40DE | 8BD8 | mov ebx,eax <----- мы здесь
01DC40E0 | 83FB FF | cmp ebx,FFFFFFFF
01DC40E3 | 0F85 634C0000 | jne 1DC8D4C
01DC40E9 | 33C0 | xor eax,eax
01DC40EB | E9 6AE5FFFF | jmp 1DC265A
Мы стоим на 01DC40DE
, но ты ведь помнишь, что мы только что вернулись из CreateToolhelp32Snapshot
? Стало быть, call, который выше по коду, и есть вызов CreateToolhelp32Snapshot
. Вспоминаем прототип CreateToolhelp32Snapshot
:
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
Как видим, передаются два аргумента, один из которых — push 2
, что говорит о передаче параметра TH32CS_SNAPPROCESS
. Он заставляет CreateToolhelp32Snapshot
сделать снимок всех процессов. Все указывает на вызов CreateToolhelp32Snapshot
, но этот call не похож на стандартный вызов WinAPI в коде. Идем в ds:[esi+C]
и смотрим, что там есть.
Видим какой-то код, похожий на мусор, среди которого прослеживаются имена функций WinAPI. Давай представим весь код в виде DWORD’ов.
Перед нами список функций, которые LOKI получает динамически. По этому списку мы можем судить о том, как работает банкер. В дальнейшем вызовы используемых WinAPI будут выполняться подобными call’ами. Итак, со списком WinAPI разобрались, теперь вернемся в код. Чтобы ты понимал его структуру, приведу листинг части функции поиска процессов (обрати внимание на адреса!):
; CreateToolhelp32Snapshot
01DC40DB | FF56 0C | call dword ptr ds:[esi+C]
01DC40DE | 8BD8 | mov ebx,eax
01DC40E0 | 83FB FF | cmp ebx,FFFFFFFF
01DC40E3 | 0F85 634C0000 | jne 1DC8D4C
01DC40E9 | 33C0 | xor eax,eax
01DC40EB | E9 6AE5FFFF | jmp 1DC265A
00228D4C | 8D85 D4FDFFFF | lea eax,dword ptr ss:[ebp-22C]
00228D52 | 50 | push eax
00228D53 | E9 53ABFFFF | jmp 2238AB
002238AB | 53 | push ebx
002238AC | 89BD D4FDFFFF | mov dword ptr ss:[ebp-22C],edi
; Process32FirstW
002238B2 | FF56 10 | call dword ptr ds:[esi+10]
002238B5 | E9 97EDFFFF | jmp 222651
Как видишь, код сильно фрагментирован и связан переходами (jmp
). Это нас не запугает: ставим точку останова на конец функции получения списка процессов и жмем на выполнение. Далее нас ждет такой код (некоторые не особо интересные функции я буду называть, но не стану в них заглядывать — по названию будет все понятно):
; Имя процесса
007C5D83 | 8D8D F8FDFFFF | lea ecx,dword ptr ss:[ebp-208]
; Считаем число символов имен процессов
007C5D89 | E8 4AD8FFFF | call <str_len>
; Сравниваем размер имени процесса с числом 40h (64)
007C5D8E | 83F8 40 | cmp eax,40
; Все хорошо, продолжаем корректное выполнение трояна
007C5D91 | 0F82 08000000 | jb 7C5D9F
; Все плохо, завершаемся
007C5D97 | 6A 00 | push 0
; ExitProcess
007C5D99 | FF96 AC000000 | call dword ptr ds:[esi+AC]
007C5D9F | E9 E1D1FFFF | jmp 7C2F85
Здесь считается размер имени каждого процесса и сравнивается с числом 40h
, или 64 в десятеричной системе. Если процесс с таким длинным именем найден, то выполняется выход. В чем тут был замысел?
Замысел создателя
Все дело в том, что обычно исследователи в вирусных лабораториях дают имена файлам семплов вредоносных программ в виде их хешей SHA-256, которые как раз имеют длину 64 символа. Если такой файл запустить, LOKI поймет это по числу символов процесса и выполнит выход. Или не поймет? Думаю, что внимательный читатель уже догадался: дело в том, что получаемое при помощи функции CreateToolhelp32Snapshot
имя процесса также содержит его расширение, которое добавляет еще четыре символа к имени — .exe
. Очевидно, разработчик забыл об этом, поэтому его замысел не сработает. Хотя идея достаточно оригинальна. Вывести из строя эту защиту банкера можно, проследив, чтобы в системе не было процессов с именами из 64 символов, включая расширение.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»