• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Дело о инфостилере Видар - Часть 2 (Распаковка)

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Дело Vidar Infostealer - Часть 2


Привет. И добро пожаловать во вторую часть моего обзора по анализу Vidar. В 1 части я рассмотрел подробный технический анализ упакованного исполняемого файла, дропнуиый начальным этапом, путем извлечения и изучения встроенного шелл-кода, который распаковывает и самостоятельно вводит конечную полезную нагрузку. Эта часть посвящена подробному статическому анализу финальной внедренной полезной нагрузки: распакованному инфостилеру Vidar, игнорированию методов антианализа, используемых вредоносными программами (расшифровка строк, динамическая загрузка библиотек DLL и разрешение API), автоматизации анализа и, наконец, раскрытию основных функций стилера с помощью деобфусцированных/дешифрованных строк.

SHA256: fca48ccbf3db60291b49f2290317b4919007dcc4fb943c1136eb70cf998260a5

Vidar in a Nutshell

Vidar Stealer — популярный стиллер, написанный на C++, активный с октября 2018 года и замеченный во множестве различных кампаний. Злоумышленники, стоящие за GandCrab, использовали его в процессе распространения программы-вымогателя в качестве полезной нагрузки второго этапа, что помогало увеличить их прибыль. Семейство достаточно гибкое в своих операциях, поскольку его можно настроить для динамического получения конкретной информации. Он получает свою конфигурацию с сервера C2 во время выполнения, что определяет, какие функции активируются, а какая информация собирается и удаляется с компьютера-жертвы. Он также загружает несколько безопасных поддерживающих dll (freebl3.dll, mozglue.dll, msvcp140.dll и nss3.dll) для обработки зашифрованных данных из браузеров, таких как учетные данные электронной почты, данные учетной записи чата, файлы cookie для просмотра веб-страниц и т. д., сжимает все в ZIP-архив, а затем передает архив злоумышленникам с помощью HTTP-запроса POST. Как только это будет сделано, он убивает свой собственный процесс и удаляет загруженные библиотеки DLL, содержимое рабочего каталога и основной исполняемый файл, пытаясь стереть все доказательства своего присутствия с компьютера жертвы.

Технический анализ

Я начну анализ, загрузив этот исполняемый файл непосредственно в IDA, чтобы найти важные строки, окно строк IDA показывает некоторые интересные строки в формате открытого текста и кодированные base64, хранящиеся в разделе .rdata.

1655235977274.png


Eсли я быстро декодирую несколько строк base64 в Cyberchef, это приводит к нежелательным данным, дающим подсказку о том, что строки, возможно, зашифрованы до того, как они были закодированы base64

1655235986457.png


Затем я проверил алгоритм шифрования, но KANAL не смог обнаружить какой-либо потенциальный алгоритм для шифрования строк, как показано на рисунке ниже.

1655235995553.png


Так что давайте начнем копать его статически, чтобы увидеть, как на самом деле работает шифрование строк в этом случае.Для этой цели я дважды щелкну строку в кодировке base64 случайным образом, чтобы увидеть, где она использовалась, найдя ее внешние ссылки, которые приводят нас к подпрограмме sub_423050

1655236007453.png


Эта процедура, по-видимому, обрабатывает большинство строк, закодированных в base64, и сохраняет результат для каждой обработанной строки в глобальной переменной, кроме первых двух переменных, которые, по-видимому, хранят значения открытого текста для возможного ключа дешифрования и домена. Давайте переименуем эту процедуру в wrap_decrypt_strings

1655236017122.png


Как видно из рисунка выше, sub_422F70 в подпрограмме wrap_decrypt_strings повторно вызывается со строками base64, Xref'd примерно 400 раз. Можно предположить, что он обрабатывает зашифрованные строки и может быть переименован в decrypt_strings для нашего удобства, как показано на рисунок ниже;

1655236025964.png


Дальнейшее изучение decrypt_strings путем загрузки исполняемого файла в x64dbg, отладка показывает, что первые два вызова подпрограммы sub_4011C0 просто копируют значения ключа и зашифрованной строки в кодировке base64 в локальные переменные. Следующая подпрограмма sub_422D00 декодирует строку base64, сохраняет декодированное шестнадцатеричное значение в локальную переменную и возвращает адрес этой локальной переменной

1655236034648.png


Декодированную шестнадцатеричную строку base64 также можно проверить в Cyberchef.

1655236043337.png


Позже он вычисляет длину для декодированной в base64 шестнадцатеричной строки и выделяет буфер, эквивалентный этой длине в куче, следующие два вызова подпрограммы sub_401330 выделяют два буфера в куче для ключа и декодированной в base64 шестнадцатеричной строки соответственно, прежде чем он приступит к окончательному расшифрованию данных с использованием функции sub_422980. Быстрая декомпиляция кода этой подпрограммы приводит к трем хорошо узнаваемым циклам RC4.

1655236052756.png


Расшифровку строки можно подтвердить, следуя рецепту Cyberchef:

1655236062602.png


Декомпилированная версия подпрограммы decrypt_strings суммирует все шаги, описанные выше:

1655236070021.png


Как только обработка для wrap_decrypt_strings завершена, она продолжает обрабатывать следующую подпрограмму из _WinMain. Краткий обзор подпрограммы sub_419700 показывает, что она широко использует глобальные переменные, которые были инициализированы в wrap_decrypt_strings, за исключением двух вызовов подпрограмм sub_4196D0 и sub_4195A0 соответственно, которые могут быть дополнительно исследуется путем отладки

1655236080709.png


На рисунке выше подпрограмма sub_4196D0 анализирует структуру PEB, чтобы получить базовый адрес для Kernel32.dll, загруженного в память, путем доступа к структурам _PEB -> PEB_LDR_DATA -> InLoadOrderModuleList соответственно. Следующая вызываемая подпрограмма sub_4195A0 принимает два параметра: 1). базовый адрес kernel32.dll 2) адрес глобальной переменной dword_432204 (LoadLibraryA) при первом вызове и dword_432438 (GetProcAddress) при втором вызове

1655236087950.png


Где sub_4195A0 анализирует заголовок kernel32.dll, переходя от IMAGE_DOS_HEADER -> IMAGE_NT_HEADER -> IMAGE_OPTIONAL_HEADER.DATA_DIRECTORY -> IMAGE_EXPORT_DIRECTORY.AddressOfNames, чтобы получить имя экспорта и сравнить его со значением API, содержащимся во входном параметре, который в данном случае — LoadLibraryA.

1655236103804.png


Если обе строки совпадают, он возвращает адрес API, обращаясь к значению поля IMAGE_EXPORT_DIRECTORY.AddressOfFunctions, разрешенный адрес сохраняется в переменной dword_432898, а второй вызов sub_4195A0 разрешает GetProcAddress, сохраняет разрешенный адрес в dword_43280C, который впоследствии используется для разрешения остальных функций API во время выполнения. Я написал здесь скрипт IDAPython (https://github.com/0x00-0x7F/IDAPython_scripts/blob/master/Vidar/deobfuscate_resolve_Vidar.py) , который сначала расшифровывает строки из wrap_decrypt_strings, разрешает API из подпрограммы sub_419700, добавляет комментарии и дает осмысленные имена глобальным переменным, хранящим разрешенные API, чтобы правильно понять поток кода и его функциональность. Процедура decrypt_strings из сценария IDAPython находит ключ, находит ~ 400 строк, закодированных в кодировке base64, строк декодирования base64 и использует ключ для дешифрования шестнадцатеричных строк, декодированных base64, добавляя дешифрованные строки в качестве комментариев и переименовывая переменные, как показано на рисунке ниже.

1655236112596.png


Подпрограмма resolve_apis из скрипта разрешает ~100 API из 11 библиотек из подпрограммы sub_419700

1655236121462.png


После резолва API следующая подпрограмма sub_41F4A0 проверяет, является ли машина-жертва частью стран СНГ (Содружества Независимых Государств), включая Армению, Азербайджан, Беларусь, Грузию, Казахстан, Кыргызстан, Молдову, Россию, Таджикистан, Туркменистан, Украину и Узбекистан и извлекает идентификатор языка для текущего пользователя, вызывая API GetUserDefaultLangID, и сравнивает возвращенный результат с указанными кодами местоположения

1655236130707.png


где 0x43F соответствует Казахстану, 0x443 Узбекистану, 0x82C Азербайджану и т. д.. Программа продолжает выполнять свои задачи, если идентификатор языка пользователя не попадает в вышеупомянутую категорию. В противном случае программа останавливает выполнение и завершает работу. Следующая подпрограмма sub_41B700 выполняет windows defender антиэмуляцию путем сравнения имени компьютера с HAL9TH и имени пользователя со строками JohnDoe

1655236140051.png


После того, как все необходимые проверки пройдены, вызывается подпрограмма sub_420BE0, которая состоит из модуля захвата стилера. Она подготавливает URL-адреса и строки пути назначения, где должны храниться загруженные dll с сервера C2, прежде чем выполнять какие-либо другие действия.

1655236148821.png


Программа загружает 7 dll в папку C:\Programdata\

1655236157003.png


Затем она создает свой рабочий каталог в C:\Programdata, имя каталога представляет собой случайно сгенерированную 15-значную строку, например C:\ProgramData\920304972255009, где она дополнительно создает четыре подкаталога (автозаполнение, копия, файлы cookie и крипто), которые должны быть создан для хранения украденных данных из браузера, Outlook, криптовалютных кошельков и модулей сбора системной информации

1655236164595.png


Различные типы браузеров нацелены на кражу автозаполнения, кредитной карты, файлов cookie, истории просмотров и учетных данных жертвы. Этот модуль оснащен передовыми методами кражи и шифрования.

1655236172111.png


Далее программа запрашивает реестр о серверах SMTP и IMAP с конфиденциальными данными и паролем, собирает данные о подключенных учетных записях Outlook (если есть) и, наконец, выгружает все данные в файл outlook.txt в своем рабочем каталоге.

1655236180965.png


Позже она сканирует файлы .wallet, .seco, .passphrase и .keystore для ~ 30 криптовалютных кошельков по их установленным путям и копирует отсканированные файлы в crypto в рабочем каталоге.

1655236190677.png


Vidar создает запрос HTTP POST для сервера C&C (http://himarkh.xyz/main.php), чтобы загрузить конфигурацию для захвата модуля во время выполнения, анализирует загруженную конфигурацию и приступает к сбору информации, связанной с хостом, оборудованием и установленным программным обеспечением.

1655236200614.png


Который хранится в файле system.txt в соответствии с указанным форматом, как показано на рисунке ниже.

1655236210221.png


та же процедура также делает снимки экрана, которые хранятся как screenshot.jpg внутри рабочего каталога.

1655236219768.png


Сразу после этого создается zip-файл с форматом имени _8294024645.zip и сжимается украденное содержимое из рабочего каталога (файл сжимается с использованием алгоритма шифрования Zip2, как идентифицировано KANAL)

1655236228188.png


Теперь сжатый файл готов к эксфильтрации на свой C&C-сервер в другом POST-запросе.

1655236237942.png


После выхода из модуля рекурсивного захвата он удаляет загруженные библиотеки DLL и файлы, созданные в рабочем каталоге, которые используются для дампа украденных данных и информации, чтобы удалить их следы с машины-жертвы.

1655236247925.png


В конечном итоге он подготавливает команду «/c taskkill /pid PID & erase EXECUTABLE_PATH & RD /S /Q WORKING_DIRECTORY_PATH\* & exit», которая выполняется с помощью cmd.exe, чтобы убить запущенный процесс стиллера и удалить оставшиеся каталоги, созданные этим процессом, и сам процесс.

Вот и все, что касается углубленного статического анализа и автоматизации анализа Vidar infostealer.

Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://0x00-0x7f.github.io/A-Case-of-Vidar-Infostealer-Part-2/
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх