Хакер - Уроки форензики. Реверсим шифровальщика
Содержание статьи
В этой статье мы исследуем вредоносный файл на примере лабораторной работы Ransomed с ресурса CyberDefenders. Мы научимся вручную распаковывать код, определим технику внедрения вредоносной программы в процесс и ответим на ряд вопросов.
Нам предложен такой сценарий: организацию взломали, команда SOC обнаружила загруженный исполняемый файл. Наша задача — исследовать его и разработать индикаторы компрометации для последующего детектирования.
INFO
Исследование вредоносного файла необходимо проводить в изолированной среде. Как создать лабораторию для анализа вредоносов, подробно рассказано в статье «Код под надзором. Создаем виртуальную лабораторию для анализа малвари».
Итак, загружаем вредонос и начинаем его исследовать. По результатам решения кейса необходимо ответить на несколько вопросов, но я покажу, только как его решать, и не буду приводить ответы. Лучше повтори весь процесс самостоятельно, чтобы разобраться и закрепить материал.
ИНСТРУМЕНТАРИЙ
Для исследования вредоносного файла воспользуемся следующим софтом.
- DIE — программа для определения типов файлов.
- PeStudio — программа для поиска артефактов исполняемых файлов.
- IDA Pro — интерактивный дизассемблер, используемый для реверс‑инжиниринга.
- Wireshark — инструмент для анализа сетевого трафика.
- Burp Suite — используется в качестве прозрачного прокси‑сервера с целью анализа взаимодействия вредоносного файла по протоколу HTTPS.
- Loki Scanner — сканер IOCs.
- YaraEditor — программа для тестирования и создания правил YARA.
- ApiLoger — утилита для анализа вызываемых WinAPI-функций исследуемого вредоноса.
- x64dbg — отладчик с открытым исходным кодом для Windows, предназначенный для анализа вредоносных программ.
Анализировать вредоносный модуль мы будем в четыре этапа:
- Статический анализ.
- Поведенческий анализ.
- Динамический анализ.
- Создание индикаторов компрометации.
СТАТИЧЕСКИЙ АНАЛИЗ
В первую очередь получим MD5-хеш‑сумму исполняемого файла и проверим его на VirusTotal. По MD5 a2f33095ef25b4d5b061eb53a7fe6548 VirusTotal выдает нам первичную информацию об исполняемом файле.
Далее скормим исследуемый файл утилите DIE и выясним, какой компилятор и компоновщик использовался при создании вредоноса, а также определим, упакован он или нет.
Итак, мы узнали, что вредоносный модуль разработан на C/C++ и собран для 32-разрядных операционных систем. DIE определяет упаковщик с помощью загруженных сигнатур, но идентифицировать ручной упаковщик не позволяет. Для этого необходимо посмотреть энтропию файла по секциям.
INFO
Что такое энтропия исполняемого файла, рассказано в статье «Энтропия. Как хаос помогает искать вирусы».
Значение энтропии 7,677, значит, файл упакован. Из рисунка выше видно, что исследуемый файл имеет четыре секции, энтропия секции .text
равна 7,844.
Загрузим файл в утилиту PeStudio, чтобы найти всевозможные артефакты. Нам интересны временные метки компиляции файла, загружаемые библиотеки, используемые ресурсы, информация о версии исполняемого файла, характерные строки, а также отладочная информация и файл сборки (Manifest). Все это пригодится нам при создании файловой сигнатуры.
Строка C:\moz\vidaj.pdb
нам интересна для создания правила детектирования. На данном этапе мы выяснили, что исполняемый файл упакован, и получили характерные строки.
Прежде чем приступить к динамическому анализу, изучим поведение вредоносного модуля. На этом этапе выявим сетевое взаимодействие с управляющим сервером, а также используемые функции Windows API.
Запустим утилиту INetSim в виртуальной машине Kali Linux
. Также запустим Burp Suite для анализа взаимодействия по HTTPS и будем слушать сетевой трафик взаимодействия, используя Wireshark.
Запустим Api Loger, выберем исполняемый файл chalenge.exe
и начнем писать логи.
Исполняемый файл использует функцию IsDebbugerPresent
с целью антиотладки. Далее запущенный процесс считывается с помощью функции ReadProcessMemory
, функция VirtualAllocEx
выделяет память и данные записываются в буфер в адресное пространство процесса WriteProcessMemory
. Этот механизм похож на технику внедрения в процесс ProcessHollowing
.
Теперь давай посмотрим на сетевой трафик.
Как видно из рисунка выше, исполняемый файл взаимодействует со следующими доменами: api.2ip[.]ua
, kotob[.]top
, tzgl[.]org
.
В Burp Suite
видно взаимодействие по протоколу HTTPS.
Для определения IP-адреса исполняемый файл делает запрос к https://api.2ip.ua
, а далее загружает с ресурса https://tzgl.org/files/1/
исполняемый файл build3.exe
.
Как мы помним, в INetSim есть файлы‑заглушки. После запроса к tzgl.org
загруженный файл build3.exe
запускается.
Поскольку мы собрали лабораторию для анализа вредоносных файлов, в нашем случае загружается файл‑заглушка утилиты INetSim. Также обнаружен HTTP-запрос к ресурсу tzgk.org
.
Используя утилиту Process Hacker 2, рассмотрим поведение запущенного файла.
Как видно из рисунка, процесс challenge.exe
запускает дочерние процессы build2.exe
и build3.exe
, которые, в свою очередь, запускают conhost.exe
.
Далее происходит шифрование всех файлов, которым назначается расширение .shgv
. В конце каждого зашифрованного файла хранится одинаковая структура, в которой записаны идентификатор и данные в формате base64
.
На данном этапе мы выявили сетевое взаимодействие вредоносного файла, а также обнаружили технику внедрения в процесс Process Hollowing.
Авторы вредоноса часто используют функции Windows API для выделения памяти, чтобы дальше загрузить в это место полезную нагрузку, которая будет распаковывать исполняемый код. Значит, наша задача — обнаружить этот участок кода и выяснить, какие привилегии ему выдавались. Далее мы будем шаг за шагом идти по коду в поисках функции распаковки.
После загрузки файла нажимаем F9 и попадаем в точку входа исполняемого файла.
Нас интересует функция VirtualAlloc, основная задача которой — выделение памяти в адресном пространстве процесса.
Для этого нажимаем Ctrl + G, набираем VirtualAlloc
и переходим в этот участок кода.
Ставим точку останова на входе в данную функцию (клавиша F2).
Спускаемся пошагово ниже (F8), находим участок выхода из данной функции и попадаем на следующий участок кода.
После выхода из функции VirtualAlloc
в регистре EAX 029E0000
хранится адрес выделенной памяти. Затем функция call 2836512
записывает код в выделенное адресное пространство, инструкция jmp dword ptr ss:[ebp-4]
используется для передачи выполнения в шелл‑код. Остановимся на этой инструкции, щелкнем правой кнопки мыши, выберем переход к карте памяти и посмотрим, какие права используются для выделенной памяти по адресу ss:[ebp-4]
.
Как видно из рисунка выше, в выделенной памяти установлены права ERW
на чтение, запись и выполнение. Далее мы попадаем в участок исполняемого кода по адресу, выделенному с помощью функции Windows API VirtualAlloc
.
Здесь вредоносный код получает адреса функций в библиотеках user32.dll
, kernel32.dll
, ntdll.dll
.
Если пролистать ниже, то из библиотеки kernel32 загружается 16 функций: WinExec
, CreateFile
, WriteFile
, CloseHandle
, CreateProcessA
, GetThreadContext
, VirtualAlloc
, VirtualAllocEx
, VirtualFree
, ReadProcessMemory
, WriteProcessMemory
, SetThreadContext
, ResumeThread
, WaitForSingleObject
, GetModuleFileNameA
, GetCommandLineA
.
Давай поговорим о методе, который вредонос использует, чтобы скрывать строки от исследователя, — Stack Strings. Основная идея этого метода заключается в перемещении строки в стек по одному символу. Обычно для этого выделяется блок памяти, далее с помощью инструкции MOV
символ помещается в выделенную область.
После этого вредонос вызывает функцию RegisterClassExA, а затем запутывает две строки — saodkfnosa9uin
и mfoaskdfnoa
. Спустись ниже в коде, и увидишь описанный процесс.
Во время поведенческого анализа мы обнаружили, что после запуска файла создается дочерний процесс, в который передается выполнение, а также из библиотеки kernel32.dll
загружаются функции CreateProcessA
, VirtualAllocEx
, GetThreadContext
, WriteProcessMemory
, SetThreadContext
и ResumeThread
. Значит, вредоносный модуль использует технику Process Hollowing.
Так называется один из популярных методов внедрения вредоносного кода в память процесса. Чтобы добиться результата, вредоносное ПО удаляет легитимный код из памяти целевого процесса и перезаписывает это пространство памяти своим исполняемым файлом.
Сначала вредоносная программа создает новый процесс в приостановленном режиме CreateProces
с флагом CREATE_SUSPENDED
(0x00000004
) и CREATE_NO_WINDOW
(0x08000000
). Основной поток нового процесса находится в приостановленном состоянии и ждет, пока будет вызвана функция ResumeThread
. Затем память целевого процесса отключают с использованием ZwUnmapViewOfSection
либо NtUnmapViewOfSection
и содержимое легитимного файла заменяется вредоносной полезной нагрузкой.
Теперь, когда память отключена, загрузчик выделяет новую память для вредоносного кода с помощью VirtualAllocEx
и использует WriteProcessMemory
для записи каждого из разделов вредоноса в пространство целевого процесса. Далее вредоносный модуль вызывает SetThreadContext
, чтобы указать точке входа новый раздел кода, который он записал. В конце вредоносная программа возобновляет приостановленный поток, вызывая ResumeThread
, чтобы вывести процесс из приостановленного состояния.
Спускаемся ниже по коду, используя клавишу F8
, и попадаем к следующему участку кода.
В регистре ECX
содержится адрес функции CreateProcessA, которая выполняется с параметром dwCreationFlags
, равным 0x08000004
.
Далее происходит выделение памяти с помощью функции VirtualAlloc
.
Память выделяется по адресу 001F0000
. Перейдем к дампу и увидим, что он пока пуст.
Следующим этапом вызывается функция GetThreadContext с целью получить контекст потока.
Вызывается функция ReadProcessMemory для получения дескриптора процесса.
Происходит вызов функции ZmUnmapViewOfSection, которая отключает память целевого процесса.
И наконец, выполняется вызов функции VirtualAllocEx, чтобы выделить память для вредоносного модуля.
Вызываемая функция имеет пять аргументов, что мы и видим в стеке: дескриптор процесса, указатель на адрес области кода, размер выделяемой области, тип выделения памяти и защита памяти для выделенной области. Как видно из стека, параметр 0x00003000
означает MEM_COMMIT (0x00001000) | MEM_RESERVE (0x00002000)
. Значение 0x00000040 (PAGE_EXECUTE_READWRITE)
говорит нам о том, что в выделенной области разрешен доступ на выполнение, запись и чтение.
Адрес 0x00400000
указывает на адрес, где будет располагаться вредоносный код. Далее вызывается функция NtWriteVirtualMemory.
Вызов происходит со следующими параметрами, представленными в стеке.
Значение 0x00000270
— это дескриптор процесса, 0x00400000
— базовый адрес для записи в указанном процессе, 0x29915A0
— адрес буфера, который содержит содержимое для записи в адресное пространство процесса, 0x00000400
— размер для записи в процесс.
Здесь вредоносный код записывает каждый сегмент исполняемого файла в новое адресное пространство. Ниже представлено содержимое стека при каждом вызове функции NtWriteVirtualMemory
.
Спускаемся ниже и видим выполнение функции WriteProcessMemory, которая используется для записи из буфера в адресное пространство процесса.
Стек содержит следующие данные.
Значение 0x029016EC
— это адрес, который содержит данные для записи.
После этого вызывается функция SetThreadContext, которая создает контекст для указанного потока, и функция ResumeThread для возобновления работы нового исполняемого файла.
Перед выполнением функции ResumeThread
мы получим дамп созданного процесса. Для этого воспользуемся плагином ScyllaHide. Нажми на вкладку «Модули → Scylla».
Следующим этапом можно анализировать распакованный код в IDA Pro
, которая имеет удобный плагин HexRays
для декомпиляции кода. Необходимо найти код генерации ключа для шифрования файлов и алгоритм шифрования, но такое исследование выходит за рамки нашей статьи.
На текущем этапе нам удалось распаковать вредоносный модуль, мы разобрались с техникой Process Hollowing
в коде. Теперь нужно разработать индикаторы компрометации.
Создадим простое YARA-правило для детектирования вредоноса. При создании сигнатур для этого семейства шифровальщиков необходимо проанализировать множество файлов, найти общие участки кода и строки. А для этого может пригодиться полезный плагин mkYARA в IDA Pro.
description = "Detect malware ransomware"
uint16(0) == 0x5A4D and all of them
Выпишем также индикаторы компрометации (IOCs), которые можно загрузить в Loki Scanner и Suricata.
- MD5: a2f33095ef25b4d5b061eb53a7fe6548
- SHA1: b38a8cb06507adb966dfdb809403f8f7f64ca534
- URLs: https://api[.]2ip[.]ua
,
https://tzgl[.]org/files/1/build3.exe,
http://tzgl[.]org/fhsgtsspen6/get[.]php?pid=AD4334DBE387EF198B77CC7408B38C8F&first=false` - Domains:
api.2ip.ua
,kotob.top
,tzgl.org
ЗАКЛЮЧЕНИЕ
В этой лабораторной работе мы распаковали вредоносный файл, исследовали его поведение. При динамическом анализе разобрали технику внедрения в процесс Process Hollowing, разработали собственные индикаторы компрометации. Мы выяснили, что вредоносный файл относится к шифровальщикам, главная задача которых — зашифровать важные данные, чтобы затем потребовать выкуп.
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei