- Упаковщик: отсутствует
- Даты компиляции:
- 30.08.2020 18:02:53 (загрузчик ccL100U.dll)
- 30.08.2020 18:01:38 (полезная нагрузка)
- SHA1-хеши:
- 14a652b5b9d71171224541ce2b950cf55da38190 (загрузчик ccL100U.dll)
- f76ae6ee508cf22f52b8533d704667a1893860d9 (полезная нагрузка)
Описание
Бэкдор, написанный с использованием языков C и C++ и работающий в среде 32- и 64-битных операционных систем семейства Microsoft Windows. Предназначен для коммуникации с управляющим сервером посредством DNS-запросов и несанкционированного управления зараженным компьютером. Состоит из загрузчика, представляющего собой DLL-библиотеку, и основного модуля, работающего в оперативной памяти. Имеет множественные пересечения в коде с бэкдором Cotx.
Принцип действия
Представляет собой DNS-бэкдор — общение с управляющим сервером происходит с помощью чтения TXT-записей определенным образом сформированных субдоменов.
Модуль-загрузчик
Оригинальное название из таблицы экспорта — Stager.dll. Библиотека имеет целый ряд экспортируемых функций.
При этом большинство функций никаких действий не выполняет. Единственной рабочей функцией является InitLoad — в ней происходит запуск бэкдора, эта же функция вызывается из DllMain.
Бэкдор распаковывает полезную нагрузку из своих ресурсов, она находится в ресурсе DAT в сжатом при помощи RtlCompressBuffer виде. В распакованном основном модуле загрузчик ищет строку CQKUZXadCXS, которая является заглушкой для конфигурации. Найдя строку, загрузчик заменяет ее актуальной конфигурацией. В рассмотренном образце это строка AB1d3d3MS5kb3RvbWF0ZXIuY2x1Yjsw.
После этого запускается процесс %WINDIR%\\System32\\dllhost.exe, в который происходит внедрение основного модуля. Если третий символ в конфигурации равен нулю, то исполняемый файл процесса, в контексте которого работает загрузчик, а также файл самого загрузчика удаляются.
Работа основного модуля
Основной модуль написан на С++ с широким использованием библиотеки STL.
В начале работы бэкдор проверяет зашитую конфигурацию, ранее подмененную загрузчиком. Если первые два символа не совпадают с AB, то считает, что конфигурации нет, и завершается. В противном случае декодирует конфигурацию из Base64, начиная с 4-го символа: www1.dotomater.club;0.
Формат конфигурации прост и представляет собой домен управляющего сервера и IP-адрес DNS-сервера, разделенные точкой с запятой. Если адрес DNS-сервера не указан или указан нулевым, тогда использует DNS-серверы, которыми пользуется зараженный компьютер.
Далее бэкдор создает несколько потоков, первый — для отправки heartbeat-пакетов.
В ответ сервер отвечает строкой вида heartbeat%d, где %d является тем же числом, какое было в пакете от бота.
Второй поток предназначен для разбора очереди пакетов и их отправки на управляющий сервер.
После этого отправляет информацию о зараженной системе:
sprintf(Str, "%s;%s;%s;%d;%s", szCompName, szUserName, szOSVer, isx64, szCurDateTime);
Далее бэкдор входит в цикл приема и обработки команд от управляющего сервера.
Код команды | Описание команды |
---|---|
1 | Установить ID бота |
2 | Запустить командную оболочку с перенаправлением ввода-вывода в пайпы |
3 | Выполнить команду в запущенной ранее оболочке (командой № 2) |
4 | Получить информацию о диске или листинг директории |
6 | Выслать файл на управляющий сервер |
7 | Скопировать файл |
8 | Удалить файл |
9 | Получить размер файла |
10 | Сохранить файл по указанному пути |
11 | Изменить интервал обращения к управляющему серверу |
13 | Самоудалиться |
Протокол связи с управляющим сервером
Из данных, которые отправляются на управляющий сервер, сначала формируется структура:
#pragma pack(push, 1)
struct st_packet
{
_BYTE magic; // 0x65
_WORD botid;
_DWORD pktid;
_BYTE data[];
};
#pragma pack(pop)
- botid изначально имеет значение 0, но оно изменяется командой управляющего сервера, содержащей opcode == 1, которая приходит в ответ на информацию о зараженной системе;
- pktid изначально имеет значение 0, но оно изменяется после каждого принятого пакета от управляющего сервера;
- data содержит данные пакета, включая идентификатор команды.
Полученный пакет зашифровывается функцией:
В качестве ключа в эту функцию передается строка dadadadadadadada.
Полученные зашифрованные данные кодируются в Base64. Из закодированных данных формируется имя субдомена для домена, указанного в конфигурации. При этом, если длина закодированных данных превышает 62 символа, то после каждого 62-го символа добавляется точка.
Далее формируется DNS-запрос на получение TXT-записи сформированного домена.
Ответ сервера расшифровывается аналогичным образом — сперва декодируется из Base64, потом дешифруется с ключом dadadadadadadada. Полученные данные имеют следующий вид:
#pragma pack(push, 1)
struct st_recv_packet
{
_BYTE magic; // 0x65
_DWORD pktid;
_BYTE opcode;
_BYTE data[];
};
#pragma pack(pop)