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

Статья Уроки форензики. Изучаем поведение стилера при помощи INetSim и IDA Pro

top

(L3) cache
Пользователь
Регистрация
03.02.2020
Сообщения
252
Реакции
342
В этой статье я покажу, как с помощью утилиты INetSim эмулировать взаимодействие малвари с управляющим сервером. Также рассмотрим работу загрузчика, распакуем основную нагрузку вредоноса и исследуем схему работы стилера.

Мы будем разбирать задание UnPackMe Blue Team Lab с площадки Cyber Defenders. Уровень задания — сложный. В лабораторной работе тебе потребуется ответить на ряд вопросов по итогам прохождения, однако приводить ответы мы не будем — если ты повторишь прохождение, то без труда ответишь на всё сам.

Используемые утилиты​

  1. DIE — программа для определения типов файлов.
  2. PeStudio — программа для поиска артефактов исполняемых файлов.
  3. IDA Pro — интерактивный дизассемблер, используемый для реверс‑инжиниринга.
  4. Wireshark — инструмент для анализа сетевого трафика.
  5. Burp Suite — платформа, которая используется в качестве прозрачного прокси‑сервера для анализа взаимодействия вредоносного файла по протоколу HTTPS.
  6. x64dbg — опенсорсный отладчик для Windows, предназначенный для анализа вредоносных программ.
  7. INetSim — эмулятор работы с интернетом.

Первичный анализ​

Получим первичную информацию об исследуемом образце. Загрузим файл в DIE и выберем анализатор Nauz File Detector.

Информация о файле

Исследуемый образец собран для 32-разрядных систем, разработан на языке C/C++ и скомпилирован в Microsoft Visual Studio. Получим энтропию исполняемого файла по секциям. Перейдем на вкладку Entropy и определим его показатель.

Энтропия исполняемого файла

Энтропия исследуемого файла — 7,389, в секции .text — самое высокое значение. Значит, исследуемый файл упакован.


Исследуем загрузчик​

Загрузим файл в IDA и приступим к анализу. Точка входа указывает на функцию WinMain, а основной поток выполнения реализован в функции sub_468480.

Псевдокод функции WinMain

Перейдем в данную функцию двойным нажатием и декомпилируем, нажав F5.

4.png

В функции WrapGlobalAlloc реализовано получение адреса GlobalAlloc и выделение в куче памяти, равной длине шелл‑кода. Далее в функции WrapVirtualProtect выделенному участку памяти назначаются права на выполнение, чтение и запись (PAGE_EXECUTE_READWRITE) с помощью функции VirtualProtect. Следующим этапом начинается процесс расшифровки шелл‑кода.

Шифрование состоит из преобразования ключа и операции XOR.

Функция преобразования ключа



Функция расшифровки шелл-кода

Начальное значение ключа — 0xD5AF2F45. Для расшифровки шелл‑кода мы разработаем скрипт для IDA, на вход которого передадим адрес зашифрованного шелл‑кода, его размер, начальное значение ключа и имя файла для сохранения данных.
Код:
import struct
import idaapi
HIWORD = lambda x: x >> 16
def GenerateKey(key):
    key = (key * 0x343fd) & 0xffffffff
    key = (key + 0x269ec3) & 0xffffffff
    return key
def DecryptShellcode(data,key):
    result = bytearray()
    for i in data:
        key = GenerateKey(key)
        k =  HIWORD(key) & 0xFF
        result.append(i ^ k)
    return result
def main(start,size,key,filename):
    w = open(filename,'wb')
    b = bytearray()
    for i in range(size):
        x = idaapi.get_byte(start + i)
        b.append(x)
    d = DecryptStage(b,key)
    w.write(d)
    w.close()
Расшифровывать будем в режиме отладки. Поставим точку останова на функции WrapDecryptShellcode (горячая клавиша F2) и запустим отладку (F9). Двойным нажатием на переменную shellcode получим адрес исполняемого кода, а его размер узнаем из переменной size_shellcode.

Загрузим разработанный скрипт, для этого зайдем на вкладку File → Script File. В командной строке Python вызовем функцию main.
Код:
main(start=0x7B96E8,size=0x4e9d3,key=0xD5AF2F45,filename='stage01')
Мы получили значение расшифрованного исполняемого кода. Загрузим его в IDA и проведем статический анализ. Полученный шелл‑код состоит из функций получения адресов используемых WinAPI и расшифровки основной нагрузки.

Функция получения адресов Windows API

Преобразуем декомпилируемый код в читаемый вид. Для этого выберем переменную a1, кликнем правой кнопкой мыши и выберем пункт Create Struct. IDA сформирует структуру. Далее переименовываем каждое значение поля (горячая клавиша N).

Для получения функций WinAPI LoadLibraryA и GetProcAddress из библиотеки kernel32.dll используется хеширование. Из поля InMemoryOrderModuleList структуры PEB процесса считываются имена динамических библиотек. Из каждого имени вычисляется значение хеша и сравнивается со значением 0xd4e88. Такая же процедура производится с именами функций экспорта найденной динамической библиотеки.

Алгоритм хеширования представлен ниже.
Код:
def ApiHashing(name_func,hashing):
    res = 0
    for i in name_func:
        v5 = (ord(i) | 0x60) & 0xff
        res = (res + v5) * 2
    if res == hashing:
        return True
    return False
Значение 0xd4e88 соответствует kernel32.dll.

Функция расшифровки основной нагрузки

Процесс получения основной нагрузки состоит из этапов расшифровки и разархивирования.

Процесс расшифровки и разархивирования

Алгоритм расшифровки тот же, а вот алгоритм декомпрессии сильно обфусцирован и содержит множество переходов (goto). Распакуем нашу нагрузку. Для этого в режиме отладки переходим к выполнению шелл‑кода и находим функцию DecryptUnpackShellcode. Далее спускаемся к выполнению функции Unpack, переходим на вкладку Hex View (клавиша G) и вводим адрес, который хранится в переменной data. Размер получаем из значения переменной unpack_size.

Дампим полученный после разархивирования шелл‑код с помощью IDA API. Для этого переходим в командную оболочку Python и вводим следующую команду:
Код:
idc.savefile('path_filename', 0, address_shellcode, unpack_size)
Мы получили основную нагрузку, она представляет собой шелл‑код, задача которого — загрузить методом Process Hollowing исполняемый файл и начать выполнение с его точки входа. Загрузим полученный файл в Hex-редактор, скопируем данные, начиная с сигнатуры MZ, и приступим к его анализу.

Содержимое основной нагрузки

На этом этапе мы с тобой распаковали основную нагрузку, которая представляет собой исполняемый файл. Работа загрузчика разделена на несколько этапов: сначала расшифровывается исполняемый код, основная задача которого — расшифровать и распаковать шелл‑код следующего этапа. Шелл‑код следующего этапа загружает в память исполняемый файл и продолжает выполнение с его точки входа.

Схема работы загрузчика


Исследуем основную нагрузку​

Получим информацию об исполняемом файле, для этого загрузим его в утилиту DIE.

Информация об основной нагрузке

Основная нагрузка разработана на C/C++, скомпилирована в Microsoft Visual Studio и собрана для 32-разрядных систем. Загрузим файл в IDA и приступим к статическому анализу. Код вредоноса сильно обфусцирован, и граф потока выполнения очень большой.

Поток выполнения функции main

Все строки, используемые в процессе работы модуля, зашифрованы при помощи XOR с однобайтовым ключом. Давай набросаем скрипт для IDA, который будет расшифровывать строки.
Код:
def decrypt_str(data):
    result = ''
    key = data & 0xff
    data = data >> 8
    while data > 0:
        result += chr(~((data & 0xff) ^ key)&0xff)
        data = data >> 8
    return result
На первом этапе модуль проверяет, запущен ли в системе экземпляр, с помощью функции OpenMutexA.
Функция проверки мьютекса

В командной строке Python запустим функцию расшифровки названия мьютекса:
Код:
decrypt_str(0xBABCABAFACA4B832)
Имя мьютекса формируется из константного значения uiabfqwfu, сложенного с именем пользователя. Если мьютекс с таким названием существует, модуль прекращает свою работу.
Далее модуль с помощью функции GetLocaleInfoA узнаёт, какие в системе установлены языки. Если присутствует язык из определенного списка (в него входит русский), то модуль прекращает работу.
Сравнение установленного языкового стандарта

Следом начинается процесс взаимодействия с управляющим сервером. Адрес C2-сервера зашифрован алгоритмом RC4 и закодирован в Base64.
Зашифрованное значение RC4-ключа

Расшифруем ключ, который хранится в переменной RC4_KEY.
Код:
decrypt_str(0x9498D7AB8CAEB2808B9A8E9DDCB4CA11)
Ключ шифрования — $Z2s'ten\@bE9vzR для алгоритма RC4.
Расшифруем адрес управляющего сервера, для этого воспользуемся утилитой CyberChef.
Расшифрование управляющего сервера

Мы получили адрес управляющего сервера:
Код:
https://tttttt.me/ch0koalpengold

Взаимодействие с управляющим сервером​

При обращении к управляющему серверу https://tttttt.me/ch0koalpengold исследуемый образец получает адрес основного сервера C2. Адрес расположен в блоке div, содержащем следующие атрибуты.
Значение атрибута

Основной адрес управляющего сервера зашифрован алгоритмом RC4. Ключ:
Код:
6af7fae138b9752d1d76736dcb534c9d
Шифрование основного адреса управляющего сервера

При обращении к основному адресу управляющего сервера исследуемый образец получает конфиг, зашифрованный алгоритмом RC4 с ключом $Z2s'ten\@bE9vzR.
Приступим к настройке INetSim. Открываем файл sample.html вот по такому пути:
Код:
/var/lib/inetsim/http/fakefiles/sample.html
И добавляем блок div с перечисленными выше атрибутами. Значение gzWH3jR7snsUFO5aZbvXyda3vfp8cjiu зашифровано алгоритмом RC4 с ключом 6af7fae138b9752d1d76736dcb534c9d. В зашифрованную строку добавлены символы, которые удаляются в процессе расшифровки.
Содержимое файла sample.html

В каталоге /var/lib/inetsim/http/fakefiles создадим файл config.json, содержащий зашифрованные настройки.
Зашифрованные настройки

Код:
{
    "_id":"123",
    "au":"files/",
    "ip":"10.10.10.1",
    "location":{"country":"qwe","country_code":"qwe","state":null,"state_code":null,"city":null,"zip":null},
    "c":{"m":null,"lu":null},
    "lu":null,
    "rm":1,
    "is_screen_enabled":1,
    "is_history_enabled":0,
    "depth":3
}
Этот конфиг получен в результате статического анализа кода и нужен для работы образца. Параметр au содержит URL для загрузки библиотеки sqlite3.dll, параметры ip и location — информацию о сетевом адресе зараженной машины, параметр is_screen_enabled необходим для получения снимка рабочего стола, а параметр rm нужен на случай, если потребуется удалить себя после окончания сбора информации.
Также в каталог /var/lib/inetsim/http/fakefiles загрузим файл sqlite3.dll.
В файле /etc/inetsim/inetsim.conf в блоке https_static_fakefile добавим статичные URL.
Конфигурация INetSim

Каждый раз, когда малварь обращается к адресам с подстрокой /config/, загружается файл config.json (конфигурация модуля), а при открытии /config/files/ — библиотека sqlite3.dll.
Перезапустим утилиту INetSim.
Код:
sudo inetsim
Приступим к динамическому анализу исследуемого образца. При динамической отладке не забывай обходить проверку языкового стандарта, если в твоей виртуалке установлен русский язык.
Получив основной адрес управляющего сервера, вредоносный файл начинает устанавливать свое первое соединение.
Первичное соединение с управляющим сервером

Значения в POST-запросе сформированы следующим образом:
Код:
b=<MachineGuid>_<User>&c=c021300d0074689fde86c87568e215c582272721&f=json
Параметр b описывает идентификатор зараженной машины, который формируется из имени пользователя системы и значения MachineGuid ключа реестра:
Код:
HKLM:\SOFTWARE\Microsoft\Cryptography\MachineGuid
В параметре c указано константное значение. Сформированная строка шифруется по алгоритму RC4 с ключом $Z2s'ten\@bE9vzR. В ответ от сервера управления приходит конфигурация модуля.
Для работы функции сбора данных из браузеров вредоносу необходима динамическая библиотека sqlite3.dll. Параметр au в конфиге указывает на URL, по которому малварь может получить эту библиотеку.
Загрузка sqlite3.dll


Сбор информации о системе​

Рабочий каталог вредоносного файла:
Код:
C:\User\<User>\AppData\LocalLow
В этот каталог загружаются дополнительные модули, а также собранные файлы из системы.
Функция сбора находится по смещению 454A (в моем случае функция sub_56454A), для перехода к коду необходимо на вкладке Function ввести значение смещения. На этапе сбора данных о системе исследуемый образец формирует файл System Info.txt в рабочей директории.
Содержимое файла System Info.txt

Содержимое файла System Info.txt:
  • Строка Raccoon | 1.7.3 описывает версию вредоносного файла, это значение зашифровано алгоритмом шифрования строк.
  • Build compile date установлена в виде константы и указывает на дату компиляции файла.
  • Launched at содержит дату и время запуска.
  • В блоке System Information собрана информация об имени хоста, временной зоне, установленном в системе языке, процессоре, объеме оперативной памяти и дисплеях.
  • В блоке Installed Apps собрана информация об установленных приложениях, данный список получен из ключа реестра SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall.
Если в конфиге, полученном с управляющего сервера, есть значение is_screen_enabled:1, делается снимок рабочего стола пользователя. Функция создания скриншота расположена по смещению 951B.
Функция создания снимка рабочего стола пользователя

После захвата экрана растровое изображение сохраняется в рабочую директорию с именем screen.jpeg.
После сбора всей информации с хоста в рабочей директории создается ZIP-архив. Имя файла берется из параметра _id в конфиге, полученном с C2.
Отправка собранных данных



Содержимое архива данных

Если значение параметра rm — «истина», то вредоносный файл начинает процесс самоудаления. Функция удаления расположена по смещению 5D47.
Функция самоудаления

В переменной cmd формируется команда для удаления следов присутствия малвари в системе. Давай расшифруем значение.
Код:
decrypt_str(0x8FD1DE98D1DE929BBADED8DE928BB0DEC0DEB5BFBBACBCB1B0D1DECECFDEAAD1DE8A8B919B93978ADEBDD1DE9B869BD09A939D01)
Вот что получилось:
Код:
cmd.exe /C timeout /T 10 /NOBREAK > Nul & Del /f /q
Также при первичном анализе исполняемого файла я нашел полный путь к каталогу сборки на компьютере злоумышленника:
Код:
A:\_Work\rc-build-v1-exe\

Выводы​

Эта лаборатория помогла нам научиться эмулировать работу управляющего сервера с помощью утилиты INetSim. Мы разобрали механизм работы стилера, задачей которого была кража криптокошельков, файлов cookie, паролей от браузеров и почтовых серверов и многого другого. Мы изучили работу загрузчика и распаковали основную нагрузку, а также написали скрипты для IDA и потренировались в проведении статического и динамического анализа вредоносных файлов.

Автор @rayhunt454
Источник xakep.ru
 


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