Обзор трояна SafeRAT

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
В декабре 2023 года, в ходе постоянного отслеживания новых угроз ИБ, изучая в PT Sandbox и других песочницах вредоносные образцы и генерируемый ими трафик, мы обнаружили подозрительное сетевое взаимодействие, с которого наше дальнейшее исследование и началось. Надо сказать, обратили мы внимание на это еще и благодаря внезапно увеличившемуся количеству похожих семплов. Сами злоумышленники, видимо призрачно надеясь на убедительность, назвали в коде свой троян удаленного действия SafeRAT, с именованием которого мы, конечно, не согласны, но довольно спойлеров! Ниже мы постарались детально описать вредонос, который ранее исследователям не встречался, чтобы показать его НЕбезопасность.

Загрузчик​

Каждый загрузчик представляет собой довольно простой бинарный файл формата PE (EXE) с единственной функцией. Загрузчик распространяется по почте в письмах с расширением .bat. Оказавшись на компьютере жертвы, загрузчик с помощью функций библиотеки WinHTTP обращается к зашитому внутри него удаленному серверу (C2) за получением дополнительной полезной нагрузки следующего этапа.
a8803c094aac156d2b2080630c6841f4.png



Предполагаем, что код загрузки взят из примера MSDN, поскольку в некоторых семплах используется User-Agent:WinHTTP Example/1.0.

d4a1ea8c9ab245c3dee76a4927f8eae1.png



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

Шеллкод​

64-битный шеллкод отдается C2 в ответ на GET-запрос /payload.bin в открытом виде.
7f2a4e4e9dc95a65d1cb334bbd3868ce.png


Значение User-Agent не всегда такое, как на скриншоте выше. Например, мы встречали такие User‑Agent, как Chromium, Google, souhu, sougou, File Downloader, baidu, cpp-httplib/0.14.3, ShellcodeDownloader, python-requests/2.25.1, Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

Далее исполнение стартует с 0-го байта.
a96bd43b11f1b40410376af7ad425a13.png



Шеллкод получает свой адрес с помощью простого выражения.

ccc9a77822c996abf9408e1ebb1f81b6.jpg


В конце шеллкода указаны адрес C2 и порт, как выделено на скриншоте выше. Они хранятся в следующем виде:
Код: Скопировать в буфер обмена
Код:
struct C2 {
  uint32_t port;       
  char addr[256];
};
После этого шеллкод получает адреса API-функций с помощью кастомного алгоритма хеширования их имен:def hash_exp(name, poly):
Код: Скопировать в буфер обмена
Код:
def hash_exp(name, poly):
    result = poly
    for i in range(len(name)):
        result = (result * 0x21) & 0xFFFFFFFFFFFFFFFF     
        v = struct.unpack_from('<b', name, i)[0]
        i += 1
        result += v
    return result
В процессе исследования мы столкнулись с двумя последовательными шеллкодами, имеющими как похожие функции, так и различия.

Шеллкод № 1 (payload.bin)​

В этом шеллкоде параметр poly равен 0x85967AEFDADF5658. Он находит следующие функции из ntdll:
  • LdrLoadDll (0xD33201CB07BB2036)
  • RtlInitUnicodeString (0x4E80BBE9CCE6585C)
  • NtAllocateVirtualMemory (0xD1A4739FEC736F3F)

Шеллкод загружает библиотеку ws2_32.dll, а также получает адрес ее функции для создания сокета (TCP) и запроса шеллкода следующего этапа. Для этого отправляет следующий пакет на тот адрес C2, который зашит в конце шеллкода.
ede07d68bbc61ce85807e9678921a64c.jpg



Первый DWORD — это длина пакета, далее следует захардкоженная строка efaSnigoL (перевернутая строка LoginSafe).
a15200844e58d8cb282cb10f08f4069c.jpg



В ответ на этот пакет приходит шеллкод второго этапа, которому передается управление. Также шеллкод № 1 передает шеллкоду № 2 адрес C2.

5ce97b4840113da3a49575c3a521af28.jpg


Шеллкод № 2​

Второй шеллкод вначале также получает адреса API-функции из ntdll по тому же хеш-алгоритму, что и первый, только в этом случае используется следующее значение poly: 0x8596741254585658.
Назначение шеллкода — загрузка PE-модуля, который располагается после самого шеллкода.
2063953e55d4ed36ddc550c616a04964.jpg


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

Основной модуль​

Модуль является x64 DLL с единственным экспортом — Online. Дата и время компиляции (из заголовка) — 05.11.2023 03:00:19. Имя библиотеки в таблице экспорта — online.dll.

Online​

Вначале создается событие Global\safeRat — именно по нему мы и дали впоследствии название вредоносу.
6d3a13036ef5e04829d705f912465b5e.jpg



После этого модуль избавляется от перехватов библиотечных функций, которые могли быть установлены антивирусом или XDR-системой.
43e190fdba42870903c3fa2da2f479e5.jpg



Суть метода состоит в том, что бинарный файл с помощью CreateFileMappingA отображает в памяти файл библиотеки из системной директории, затем устанавливает на секцию TEXT загруженного в процесс модуля права RWX и перезаписывает секцию в модуле содержимым отображенного файла — чтобы содержание модуля соответствовало файлу. После этого возвращаются ранее установленные права на секцию.

Среди других функций Online:
  • установка обработчика исключений верхнего уровня, единственная задача которого состоит в том, чтобы перезапустить процесс в случае необрабатываемого исключения;
  • поиск адреса функции NtTraceEvent и патчинг первого байта этой функции на 0xC3 (ret), чтобы от вредоносного процесса не регистрировались ETW-события для EDR-системы и других средств защиты;
  • поиск и сохранение номера syscall NtQueryInformationProcess для дальнейшего использования;
  • создание путей для файлов wallet.safe и clip.safe в директории C:\ProgramData (файл clip.safe — для сохранения содержимого буфера обмена, а файл wallet.safe — для результатов работы кейлоггера);
  • считывание из реестра сохраненного адреса C2 (в дальнейшем семпл может запросить у текущего сервера новый адрес и сохранить его в реестре, но вначале это значение отсутствует);
  • хранение адреса C2 и других значений по пути HKCU\Software\<computer_name> (если имя компьютера получить не удалось, то вместо него используется строка UnKnow).
aa22e8b69562d64d5eaa77ac9b033f9f.jpg



Упомянутое выше новое значение сервера хранится в параметре Mov, закодированное base64 и зашифрованное побайтным XOR (0x46).

8decb7c425ac3b3ed5dc340078bb6e1c.jpg



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

Стоит отметить, что в этом объекте есть несколько вложенных объектов класса CBuffer, который предоставляет динамический буфер для хранения отправляемых и принимаемых данных. Далее объект клиента подключается к серверу по TCP. Прием и обработка входящих пакетов выполняются в отдельном потоке. Следующим этапом становится создание объекта класса CKernelManager, который наследуется от класса CManager и служит своего рода оркестратором для рабочих потоков и плагинов, получаемых от C2. В конструкторе CKernelManager создается отдельный поток, отвечающий за работу кейлоггера. Причем получение данных с клавиатуры выполняется через интерфейс IDirectInput8A и устройство SysKeyboard.

29bbcddd379f2dc5bb60b2f2c5e5396f.jpg



После этого семпл собирает начальную информацию о системе для отправки на сервер. В нее входят:
  • IP-адрес зараженного устройства,
  • имя компьютера,
  • имя пользователя,
  • PID вредоносного процесса,
  • список установленных антивирусов,
  • статус пользователя (является ли он администратором),
  • разность тиков процессора: GetTickCount64 − GetTickCount64() (вероятно, для проверки работы в ВМ),
  • локальное время.
Результат можно представить в виде следующей структуры:

Код: Скопировать в буфер обмена
Код:
#pragma pack(push, 1)
struct system_info
{
    char sz;
    char host_ip_addr[130];
    char reg_remark_or_comp_name[50];
    char username[51];
    uint32_t curr_pid;
    char gap_EC[64];
    char AVs[128];
    char reg_cfg_Group_val;
    char gap_1AD[63];
    char is_admin;
    char module_filename[255];
    char reg_cfg_Run_val[3];
    char gap_2EF[5];
    uint32_t ticks_diff;
    SYSTEMTIME localtime;
};
#pragma pack(pop)
Данные о системе отправляются на сервер. Для этого они сжимаются Zlib и шифруются RC4. Для шифрования генерируется случайный ключ с помощью rand % 511. Либо задается как 123. Далее это число форматируется в виде строки и используется для RC4.

24155f9a42dc7c99ddb77dfc5dff1141.jpg



Структуру пакета клиента можно представить следующим образом:
Код: Скопировать в буфер обмена
Код:
struct packet
{
  uint32_t key;
  uint32_t packet_size;
  uint32_t payload_size;
  uint8_t payload[payload_size];
};
Стоит отметить, что указывается длина разжатого пейлоада в переменной payload_size. От C2 приходит пакет аналогичной структуры, за исключением того, что поля key и packet_size поменяны местами, то есть размер пакета содержится в нулевом DWORD, а ключ — в первом. В трафике это выглядит следующим образом:

55cfb2fa0a807446371fc98d1bd378c4.png


Расшифрованную сессию можно посмотреть в «Кибершефе».

После расшифровки и распаковки пакета от сервера семпл проверяет нулевой байт, в котором содержится идентификатор команды (в данном случае 0e). Обработку команд выполняет объект CKernelManager. В ответ клиент посылает серверу отстук в виде той же самой команды.

589f8f07edd6d8b92239e8023cea97ae.jpg


Идентификатор команды
Описание
0​
Разлогинивает текущего пользователя Windows​
2​
Устанавливает флаг завершения работы​
3​
Сохраняет в реестре новое значение параметра Remark​
4​
Сохраняет в реестре новое значение параметра Group​
6–12, 14–17, 19–21, 25, 32–34​
Запускает плагин (номер команды — идентификатор плагина)​
13​
Вызывает BSOD с помощью NtRaiseHardError, предварительно получив привилегию SeShutdownPrivilege​
18​
Запускает поток клиппера (стилер буфера обмена)​
22​
Обновляет C2​
23​
Запускает кейлоггер​
24​
Запускает поток клиппера (стилер буфера обмена)​
26–31​
Получает и запускает новый модуль​
35​
Сохраняет в реестре новое значение параметра Run​
36–42​
В зависимости от номера команды стилер похищает данные:
· QQBrowser,
· Telegram,
· Chrome,
· Firefox,
· 360 Secure Browser,
· Sogou Explorer

Заключение​

Исходя из оригинального имени в сервисе VirusTotal и некоторых целей SafeRAT (Sogou, 360 Secure Browser, QQBrowser), предполагаем, что вредонос рассчитан на китайскоговорящих пользователей.
Судя по именам классов (CKernelManager, CClientSocket) и общей архитектуре кода, можно сделать вывод, что SafeRAT — это очередная поделка, основанная на утекших исходниках Gh0st, только с урезанной функциональностью.

Автор Ксения Наумова, Антон Белоусов
Источник habr.com
 
Сверху Снизу