- sha256: 0ebdcedc0afeec0cfeb024ff14c30df57d5d05eb
- sha256: 50e5ad854a8504f3202af9c05223766872859521
- sha256: 574cae4767378b8e90df49bdd5182d63e893a35c
- sha256: 77046282917539e33d61e7ea7ec01d6ae4df40f4
- sha256: e99b52cfd83601de8ec144097c338e9aab654d02
- sha256: ed4e00891f6688be21f872ae12e7dbd6872ff69c
Описание
Вредоносная программа для ОС Windows и Linux, написанная на языке Go. Упакована упаковщиком Garble. Представляет собой троян для удаленного доступа. Характерные особенности — обмен данными с управляющим сервером в формате ProtoBuf, наличие двух руткитов в версии трояна для ОС Linux и размещение зашифрованных файлов конфигурации в репозиториях на GitHub.
Принцип действия
В зависимости от ОС скомпрометированной машины цепочка заражения состоит из разного количества этапов.
Версия для ОС Windows
Этап 1. Расшифровка имени приложения и URL репозитория на GitLab.
Этап 2. Сбор информации о системе и проверка на запуск в виртуальном окружении. Системная информация вносится в структуру gMWASkoS_WinSystemInfo при запуске утилиты systeminfo.exe:
struct gMWASkoS_WinSystemInfo
{
string HostName;
string OSName;
string OSVersion;
string OSManufacturer;
string OSConfiguration;
string OSBuildType;
string RegisteredOwner;
string RegisteredOrganization;
string ProductID;
string OriginalInstallDate;
string SystemBootTime;
string SystemManufacturer;
string SystemModel;
string SystemType;
_slice_string Processors;
string BIOSVersion;
string WindowsDirectory;
string SystemDirectory;
string BootDevice;
string SystemLocale;
string InputLocale;
string TimeZone;
string TotalPhysicalMemory;
string AvailablePhysicalMemory;
string VirtualMemoryMaxSize;
string VirtualMemoryAvailable;
string VirtualMemoryInUse;
_slice_string PageFileLocations;
string Domain;
string LogonServer;
_slice_string Hotfixs;
_slice_string NetworkCards;
string HyperVRequirements;
};
Этап 3. Загрузка настроек из репозитория на GitLab.
Конфигурация приходит в виде зашифрованной шестнадцатеричной строки. В качестве шифра применяется XOR, ключом выступает вшитая в тело трояна строка.
Этап 4. Прием команд.
Сначала на С2 отправляется информация о системе, после чего троян ожидает пакет с командой PONG (описание всех команд представлено в таблице ниже). Прием команд продолжается до получения команды Kill_Self. Все команды поступают в зашифрованном виде, для расшифровки используется алгоритм, описанный выше. Затем полученный пакет анализируется ProtoBuf и передается обработчику switch-case, вызывающему реализацию каждой отдельной команды. После выхода из цикла принятия команд троян удаляет себя с помощью командной строки.
Версия для ОС Linux
В трояне реализован ряд функций, из которых основной интерес представляют две, условно называемые main_setup() и main_start_networking().
Функция main_setup()
Этап 1. Проверка наличия следующих зашифрованных строк.
- Список URL, где хранятся настройки. В качестве хранилища выступают CDN блогов, GitLab, GitHub.
- Имя приложения, под которое маскируется троян (8_Bitrue_linux_amd64__console, linux-t, yundun и другие).
Этап 2. Проверка булевой глобальной статической переменной. Если она установлена в true, то в директории /tmp/3391 будет записываться журнал работы трояна.
Этап 3. Проверка переменной APACHESC. Если она не пустая, то ее содержимое исполняется как нативный shell-код.
Этап 4. Сбор информации о системе и заполнение структуры session_info:
struct session_info
{
string os; //общее имя ОС, вшито в исполняемый файл ("linux")
string arch; //имя архитектуры процессора, вшито в исполняемый файл
string OSName; //имя ОС, полученное при чтении поля NAME в файле /etc/os-release
string OSVersion; //версия ОС, полученная при чтении поля VERSION в файле /etc/os-release
string OSKernel; //версия ядра, полученная в результате выполнения программы uname
string OSHost; //имя хоста, полученное в результате выполнения программы uname
string MachineId; //Значение хеша md5 от конкатенации значений OSName+OSVersion+OSKernel+OSHost
string Networks;// список сетевых интерфейсов в системе
string Env; // контекст оболочки
__int64 pid__h;
string uid; //UID пользователя
string User; // имя пользователя, полученное в результате выполнения программы uname
string ExeFile; // путь к исполняемому файлу
bool in_docker; // проверка запуска трояна в Docker путем проверки наличия файла /.dockerenv
bool rootkits_loaded; // выставляется в некоторых случаях
string WinSySInfo;
};
Этап 5. Измерение времени выполнения функции в качестве антидебаг-техники.
Этап 6. Расшифровка строк. На данном этапе троян расшифровывает URL с настройками и имя приложения, под которое он маскируется. В роли шифра выступает XOR. Ключом является строка, вшитая в тело трояна.
Этап 7. Передача URL в функцию main_start_networking().
Функция main_start_networking()
Этап 1. Получение и расшифровка настроек. Троян обращается к серверу, где хранится его конфигурация, и скачивает оттуда настройки, представляющие собой зашифрованные шестнадцатеричные значения в подстроках template_begin и template_end. Процедура расшифровки аналогична описанной выше.
Пример настроек
{"url":"https://103.230.15.187:80/statics/css/",
"tls":true,"tcp_addr":"103.230.15.187:443",
"init_path":"88353","rpc_path":"51362",
"assets_path":"75139","header_user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
"template_begin":"8f11d77c1190d8",
"template_end":"2596aa623fce26cb1b072034ee07c3a050fbf64b9fcd76fc",
"sleep":15,"jitter":20}
Этап 2. Скачивание и установка руткитов, если выставлена глобальная булевая статическая переменная.
- Скачивание и установка eBPF-загрузчика и eBPF-руткита. Для этого выполняется запрос вида %URL_FROM_CONFIG%/%ASSETS_PATH_FROM_CONFIG/%HARCODED_FILENAME% с передачей параметра header_user_agent из конфигурации.
- Выставление переменных _LANG_ID, X_LANG_BTF (необязательный btf-файл) и X_LANG_LIB (содержит путь к основному исполняемому файлу eBPF)
- Запуск eBPF-загрузчика, который представляет собой ELF-файл, написанный с помощью cgo. Его задачей является считывание пути к основному исполняемому файлу из переменной X_LANG_LIB, который реализован в формате разделяемой библиотеки (.so). Запуск производится стандартными вызовами dlopen() и dlsym().
- Загрузка eBPF-руткита, являющегося модифицированным руткитом pidhide из проекта bad-bpf, к коду которого был добавлен массив pid_white_hide. Тот, в свою очередь, представляет собой белый список идентификаторов процессов, от которых скрывать другие процессы не требуется.
Этап 3. Установка LKM-руткита. Если установка eBPF-руткита была успешной, то происходит скачивание LKM-руткита Diamorphine. Для этого в HTTP-запрос добавляется заголовок Sec, значением которого является зашифрованная версия ядра ОС. Злоумышленники хранят на С2-серверах набор руткитов, скомпилированных под разные версии ядра. Установка руткита происходит путем выполнения команды insmod. Руткит скрывает все файлы и директории, имеющие префикс aclsmos_.
Нам известны руткиты для следующих версий ядра:
- 4.14.105 SMP mod_unload modversions
- 4.15.0-143-generic SMP mod_unload modversions
- 4.19.0-22-amd64 SMP mod_unload modversions
- 4.4.0-21-generic SMP mod_unload modversions
- 5.10.60-9.al8.x86_64 SMP mod_unload modversions
- 5.13.5-1.el7.elrepo.x86_64 SMP mod_unload modversions
- 5.15.0-50-generic SMP mod_unload modversions
- 5.4.0-107-generic SMP mod_unload modversions
- 6.1.23-36.46.amzn2023.x86_64 SMP preempt mod_unload modversions
- 6.2.0-20-generic SMP preempt mod_unload modversions
- 5.4.0-107-generic SMP mod_unload modversions
- 5.4.0-107-generic SMP mod_unload modversions
- 5.4.0-107-generic SMP mod_unload modversions
Конечным элементом цепочки заражения является троян удаленного доступа, поддерживающий следующие команды:
Команда | Код | Windows | Linux | Аргументы | Описание |
---|---|---|---|---|---|
PONG | 9 | + | + | Заглушка, используется для подтверждения работоспособности канала | |
set_id | 10 | + | + | string ServerId | Устанавливает идентификатор сервера (используется только при сборе информации о системе) |
Set_sleep | 11 | + | + | uint32 Sleep, uint32 Jitter |
Устанавливает промежуток между запросами к С2-серверу |
switch_TCP | 12 | + | + | Включает прием команд по TCP, используя поле tcp_addr из конфигурации | |
TCP_Tunnel | 13 | + | + | string Target | Реализует TCP-туннель |
switch_HTTP | 14 | + | + | Выключает прием команд по TCP, общение с С2-сервером продолжается дефолтным методом с использованием URL из конфигурации | |
ssh_tunnel | 15 | + | + | string Shell, string Password, string Env, string PreCmd |
Реализует SSH-туннель |
Socks5_tunnel | 16 | + | + | string Target | Реализует SOCK5-туннель |
RunCode | 17 | + | + | uint32 Checksum, bytes Code |
Проверяет целостность полезной нагрузки с помощью CRC32 |
KillSelf | 18 | + | + | Завершает работу трояна | |
Reload_LKM | 19 | + | + | Перезагружает руткит, в версии для ОС Windows отсылает информацию о системе | |
RunCmd | 20 | + | + | int64 CmdId, int64 Timeout, string Cmd, string Args, string Envs |
Содержит shell-скрипт для исполнения и вызов CRC32 для проверки целостности скрипта |
Матрица Mitre
Этап | Техника |
---|---|
Предотвращение обнаружения (TA0005) | Обход средств виртуализации или песочницы (T1497) |
Обнаружение (TA0007) |
Запросы к реестру (T1012) Изучение системной информации (T1082) Обход средств виртуализации или песочницы (T1497) |
Организация управления (TA0011) |
Протокол прикладного уровня (T1071) Прочие протоколы (T1095) Зашифрованный канал (T1573) Туннелирование протокола (T1572) |