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

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

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Привет, в этом посте я буду распаковывать и анализировать инфостилер Vidar из моего выступления на BSides Islamicabad 2021. Образец стейджа поставляется в виде файла .xll с расширением файла надстройки Excel. Это позволяет сторонним приложениям добавлять дополнительные функции в Excel с помощью Excel-DNA, инструмента или библиотеки, которые используются для написания надстроек .NET Excel. В этом случае файл xll содержит вредоносный загрузчик dll, который дополнительно сбрасывает упакованный исполняемый файл Vidar infostealer на компьютер-жертву, исследование всей цепочки заражения выходит за рамки этого поста, однако я буду глубоко копать исполняемый файл (Packed Vidar) в части 1 статьи этого постав блоге, а финальный пайлод во второй части.

SHA256: 5cd0759c1e566b6e74ef3f29a49a34a08ded2dc44408fccd41b5a9845573a34c

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

Я обычно начинаю распаковывать общие упаковщики/загрузчики вредоносного ПО, просматривая его сначала в основных инструментах статического анализа, затем открывая его в IDA и рассматривая с высоты различные разделы для переменных с возможными зашифрованными строками, ключами, импортами или другими глобальными переменными, содержащими важную информацию, проверяя, есть ли у него идентифицированные криптографические подписи, а затем начинаю его отладку. После загрузки в x64dbg я сначала ставлю точку останова на API-интерфейсы выделения памяти, такие как LocalAlloc, GlobalAlloc, VirtualAlloc и API защиты памяти: VirtualProtect, и нажимаю кнопку "Выполнить", чтобы увидеть, срабатывает ли какая-либо из точек останова. Если да, то его довольно просто распаковать и извлечь полезную нагрузку следующего этапа, в противном случае может потребоваться углубленный статический и динамический анализ. Давайте нажмем кнопку запуска, чтобы увидеть, куда это нас приведет дальше.

Извлечение шелл-кода

Итак, первая точка останова в этом случае — это VirtualProtect, вызываемый в области памяти стека размером 0x28A, чтобы предоставить ему защиту Execute Read Write (0x40), как ни странно, верно!

1655048155928.png


Первые несколько опкодов E9, 55, 8B в выгруженных данных в стеке соответствуют инструкциям jmp, push и mov соответственно, поэтому можно предположить, что это шелл-код, помещаемый в стек, а затем предоставляющий защиту от выполнения для последующего его выполнения. Если я нажму выполнить до кнопку возврата на VirtualProtect и проследить обратно в дизассемблер, я вижу шелл-код, хранящийся в виде строк стека прямо перед вызовом VirtualProtect, и список аргументов помещается, как показано на рисунке ниже.

1655048178983.png


Следующие несколько операторов готовятся к выполнению шелл-кода в стеке, получая дескриптор объекта контекста устройства (DC) и передавая этот дескриптор в GrayStringA для выполнения шелл-кода из стека (значение ptr в eax взято из рисунка 1)

1655048189764.png


Давайте теперь приступим к изучению шеллкода.

Отладка шелл-кода для извлечения конечной полезной нагрузки

Как только GrayStringA выполняется, он попадает в точку останова VirtualAlloc, установленную в отладчике, который вызывается для резервирования/фиксации размера памяти 0xAA3CE с MEM_COMMIT | MEM_RESERVE (0x3000) тип выделения памяти.

1655048202188.png


Происходит возврат управления из VirtualAlloc и переход еще раз из ret приводит нас к шеллкоду. Следующие несколько операторов после вызова VirtualAlloc передают указатель на вновь созданный буфер, размер буфера и дескриптор файла для текущего загруженного процесса в стеке для вызова ReadFile

1655048213890.png


Он считывает 0xAA3CE байт данных из образа родительского процесса в буфер, допустим, это buffer1.

1655048225194.png


Дальнейшее выполнение снова достигает точки останова VirtualAlloc, на этот раз выделяя 0x14F0 байт памяти. Теперь я поставлю точку останова записи в область памяти, зарезервированную/зафиксированную вторым вызовом API VirtualAlloc, чтобы увидеть, какие и как данные сбрасываются во второй буфер, buffer2. Повторное нажатие кнопки "Выполнить" прервет выполнение инструкции, показанной на рисунке ниже.

1655048247073.png


Этот цикл копирует 0x14F0 байтов данных из определенного смещения буфера1 в буфер2, следующие несколько операторов снова вызывают VirtualAlloc для выделения еще 0x350DE байтов памяти, скажем, буфер3, помещая возвращенный адрес буфера вместе со смещением из буфера1 в стек для копирования байтов 0x350DE данных из буфера1 в буфер3

1655048258916.png


Цикл на следующем рисунке расшифровывает данные, скопированные в буфер2, следующая инструкция push помещает указатель буфера3 в стек в качестве аргумента подпрограммы, вызываемой из адреса буфера2 в edx, которая должна обрабатывать содержимое буфера3

1655048269540.png


На рисунке ниже показано расшифрованное содержимое окончательного буфера2

1655048279715.png


1655048288026.png


Переход в edx запускает выполнение содержимого буфера 2, где, кажется, сначала помещаются строки стека для kernel32.dll, а затем извлекается дескриптор kernel32.dll путем анализа структуры PEB (Process Environment Block)

1655048440260.png


Полученный дескриптор kernel32.dll передается следующему вызову вместе с другим аргументом с постоянным значением FF7F721A, быстрый поиск этой константы в Google приводит к некоторым общедоступным ссылкам на песочницу, но неясно, о чем именно идет речь. Давайте углубимся в этот момент, обход этой подпрограммы 0x0A4E приводит к разрешенному адресу API GetModuleFileNameW из Kernel32.dll, хранящемуся в eax, что означает, что эта подпрограмма предназначена для разрешения хешированных API.

1655048452272.png


Аналогичным образом второй вызов преобразует хеш-значение 7F91A078 в ExitProcess API. Подпрограмма-оболочка 0x0A4E выполняет итерацию по экспорту библиотеки, а подпрограмма 0x097A вычисляет хэш для входного параметра имени экспорта. Похоже, что шеллкод использует специальный алгоритм для хеширования API, вычисленное хеш-значение перенастраивается обратно в eax, которое сравнивается с входным хэш-значением, хранящимся в [ebp-4]. Если оба хэш-значения равны, API разрешается, а его адрес хранится в еах.

1655048468262.png


Следующие несколько инструкций записывают некоторые ненужные данные в стек, после чего помещают указатель на buffer3 и общий размер содержимого buffer3 (0x350C0) в стек и выполняют подпрограмму 0x0BE9 для дешифрования - эта пользовательская схема дешифрования работает путем обработки каждого байта из буфера3 с использованием повторяющихся отрицаний, вычитания, сложения, sar, shl, not или и xor набор инструкций с жестко закодированными значениями на нескольких уровнях, промежуточный результат сохраняется в [ebp-1]

1655048480618.png


И окончательное значение перезаписывает соответствующее значение buffer3 по смещению [eax]

1655048490295.png


Как только содержимое буфера3 расшифровано, он продолжает разрешать другие важные API в следующей подпрограмме 0x0FB6.

1655048500301.png


Я написал простой POC-скрипт на Python для алгоритма хеширования, реализованного с помощью расшифрованного шеллкода, который можно найти здесь. https://github.com/0x00-0x7F/RE_tips_and_tricks/blob/master/vidar_packer/api_hash_strings.py

1655048511007.png


После того, как все необходимые API были разрешены, он переходит к созданию нового процесса

1655048596939.png


А затем окончательная полезная нагрузка вводится во вновь созданный процесс с использованием API SetThreadContext, структура CONTEXT для удаленного потока настраивается с помощью ContextFlag и требуемых буферов памяти, а API SetThreadContext вызывается с дескриптором текущего потока и структурой CONTEXT удаленного потока для внедрения кода.

1655048547839.png


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

Вот и все, что нужно для распаковки! Скоро увидимся в следующей статье, посвященном подробному анализу инфостилера Vidar.

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


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