Упаковщик: отсутствует
Дата компиляции: 28.05.2018 23:14:08
SHA1-хеш:
- e70a5ce00b3920d83810496eab6b0d028c5f746e
Описание
Многофункциональный троян-бэкдор для 64-битных операционных систем семейства Microsoft Windows. Предназначен для установки зашифрованного соединения с управляющим сервером и несанкционированного управления зараженным компьютером. Имеет функции файлового менеджера, прокси и Remote Shell. Применялся в целевых атаках на государственные учреждения Казахстана и Киргизии, где наряду с BackDoor.PlugX, использовался для первичного проникновения в сетевую инфраструктуру.
Принцип действия
Представляет собой динамическую библиотеку с экспортируемой функцией MyInstall. При заражении устанавливается в директорию C:\Windows\System32\oci.dll.
Запуск программы происходит следующим образом. При старте ОС запускается служба координатора распределенных транзакций Microsoft Distributed Transaction Coordinator — MSDTC. В реестре Windows находятся параметры этой службы, которые хранят имена загружаемых библиотек. Ключи OracleOciLib и OracleOciLibPath в ветке HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\MTxOCI по умолчанию имеют значения oci.dll и %systemroot%\system32 соответственно. При сохранении трояна в %systemroot%\system32\oci.dll он будет автоматически загружен в память при старте службы MSDTC.
При инициализации создает мьютекс gfhfgh6y76734d,1111, после чего происходит загрузка библиотеки и вызов экспортируемой функции MyInstall.
MyInstall
Троян способен определять необходимость использования прокси-сервера, проходить базовую авторизацию и аутентификацию по протоколу NTLM. В процессе работы ведет журнал и сохраняет его по адресу c:\programdata\logos.txt.
Устанавливает соединение с управляющим сервером, после чего обменивается с ним ключами. Все последующие пакеты между трояном и сервером шифруются. Для шифрования используется алгоритм на основе XOR-операции с длиной буфера 28 байт. Все пакеты шифруются со сквозным смещением в буфере, однако для шифрования и дешифровки используются раздельные счетчики.
Для запроса команд у сервера и отправки результатов используется следующая структура:
#pragma pack(push, 1)
struct st_getcmd
{
_DWORD sig;
_DWORD cmd;
_DWORD res;
_DWORD dwordc;
};
#pragma pack(pop)
Параметр sig всегда имеет значение 0x03. Для запроса команды у сервера cmd выставляется в 0x200, а параметры res и dwordc — в ноль. В случае отсутствия поступления от сервера любых данных в течение 44 секунд троян посылает пакет с параметром cmd в значении 0x00. Эти действия повторяются до тех пор, пока от сервера не будет получен какой-либо ответ.
Список команд
Ниже представлены команды, которые может выполнить троян, и ответы на них:
- 0x00 — отсутствие ответа, ожидание следующей команды;
- 0x01 (сбор информации о боте) — отвечает структурой cmd_botinfo:
#pragma pack(push, 1) struct cmd_botinfo_int { _DWORD sig; // 0x03 _DWORD OSMajorVersion; _DWORD OSMinorVersion; _DWORD OSPlatformId; _DWORD userpriv; _DWORD botip; _QWORD MemTotalPhys; _BYTE macaddr[6]; wchar_t szCSDVersion[128]; wchar_t hostname[64]; wchar_t username[64]; char connect_string[256]; }; struct cmd_botinfo { _BYTE sig; // 0x03 _WORD len; // 0x3AC _WORD cmdid; _BYTE gap[10]; cmd_botinfo_int info; }; #pragma pack(pop)
- 0x02 (запуск remote shell) — отвечает пакетом, аналогичным полученному от сервера;
- 0x03 (запуск расширенного файлового менеджера) — отвечает пакетом, аналогичным полученному от сервера;
- 0х05 (запуск remote shell v2) — отвечает пакетом, аналогичным полученному от сервера;
- 0x06 (запуск менеджера прокси) — отвечает пакетом, аналогичным полученному от сервера;
- 0x100 (команда ping) — отвечает cmd=0x00;
- 0x400 (команда на переподключение к серверу) — отвечает cmd=0x300;
- 0x600 (функция-заглушка) — отвечает cmd=0x600; res=0xffffffff;
- 0x700 (запуск команды через ShellExecute) — отвечает cmd=0x700; в случае неудачи — res=0xffffffff.
Обмен ключами
Обмен ключами с управляющим сервером происходит следующим образом.
Троян случайными значениями инициализирует буфер размером 28 байт. Затем берет зашитый массив данных размером 52 байта.
Шифрует байты с 15 по 43 алгоритмом на основе XOR-операции, используя случайно генерируемые байты, и отправляет полученный буфер на сервер. В ответ должно прийти 5 байт, где нулевой байт — 0x16, а результат функции htons от WORD, начиная с третьего байта, является размером следующего пакета, который не должен превышать 0x3FF9 байт.
После этого принимает следующий пакет, данные которого не используются в дальнейшем обмене.
Затем троян использует второй зашитый буфер размером 332 байта.
Шифрует байты с 9 по 265 и с 304 по 332 алгоритмом на основе XOR-операции, используя случайно генерируемые байты. 28 байт, начиная с 276 байта, заменяются данными, сгенерированными при первой инициализации буфера. В ответ должно прийти 5 байт, где нулевой байт — 0x14, а результат функции htons от WORD, начиная с третьего байта, является размером следующего пакета, который не должен превышать 0x3FF9 байт.
После этого принимает следующий пакет, данные которого не используются в дальнейшем обмене.
Затем троян принимает от сервера 5 байт, где нулевой байт — 0x16, а результат функции htons от WORD, начиная с третьего байта, является размером следующего пакета, который должен быть равен 0x38 байт.
Принимает следующий пакет от сервера и передает 0х38 байт в функцию инициализации ключа шифрования:
__int64 __fastcall CCrypt::GenKeys(ccrypt *this, _BYTE *ext_key)
{
__int64 result; // rax
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; i < 28; ++i )
{
this->key[i] ^= ext_key[i];
this->key[i] ^= ~(_BYTE)i;
if ( !this->key[i] )
this->key[i] = ~(_BYTE)i;
result = (unsigned int)(i + 1);
}
return result;
}
Функция Remote Shell
Троян копирует %WINDIR%\System32\cmd.exe в %WINDIR%\alg.exe. Инициализирует новое подключение к управляющему серверу и посылает следующий пакет:
#pragma pack(push,1)
struct cmd_remoteshell
{
_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x02
_BYTE gap[10];
_BYTE macaddr[6];
};
#pragma pack(pop)
Затем запускает скопированный alg.exe с перенаправлением ввода/вывода в пайпы. Если запуск провалился, то вместо alg.exe запускает cmd.exe. При наличии данных в пайпе вывода функции троян отправляет данные на управляющий сервер в пакете:
#pragma pack(push,1)
struct cmd_remoteshell_out
{
_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x202
_BYTE gap[10];
wchar_t buffer[];
};
#pragma pack(pop)
При этом троян периодически проверяет наличие данных от управляющего сервера и, когда они приходят, парсит полученную команду.
Список команд Remote Shell
Команда | Описание | Аргумент | Ответ |
---|---|---|---|
0x100 | Режим keep-alive | - | cmd = 0x00 |
0x102 | выполнить команду в Remote Shell | Команда | - |
0x103 | запустить файловый менеджер (запись в конец существующего файла) | путь до файла, конечный размер файла | значение cmd идентично значению в пакете сервера; res = -1 в случае неудачи; res = 0 в случае успеха. |
0x203 | запустить файловый менеджер (чтение файла) | путь до файла, смещение в файле | |
0x703 | запустить приложение | путь до исполняемого файла и аргументы | res = -1 в случае неудачи;
res = 0 в случае успеха. |
все остальные варианты | поведение по умолчанию | - | значение cmd идентично значению в пакете сервера; res = 1. |
Remote Shell v2
Троян копирует %WINDIR%\System32\cmd.exe в %WINDIR%\alg.exe. Инициализирует новое подключение к управляющему серверу и посылает следующий пакет:
#pragma pack(push,1)
struct cmd_remoteshell
{
_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x02
_BYTE gap[10];
_BYTE macaddr[6];
};
#pragma pack(pop)
Далее запускает скопированный alg.exe; если запуск провалился, то вместо alg.exe запускает cmd.exe. Ввод/вывод в запущенный процесс осуществляется с помощью прикрепления процесса трояна к консоли запущенного процесса alg.exe/cmd.exe при помощи WINAPI AttachConsole.
В остальном принцип работы аналогичен таковому в обработчике Reverse Shell.
Файловый менеджер
Троян инициализирует новое подключение к управляющему серверу и посылает следующий пакет:
#pragma pack(push,1)
struct cmd_fileop
{
_WORD sig; // 0x03
_WORD len;
_WORD cmd;
_WORD gap;
_DWORD res;
_DWORD filesize;
_BYTE macaddr[6];
};
#pragma pack(pop)
Значение cmd выставляется аналогичным значению в пакете сервера. Далее принимает команды от сервера.
- 0x103:
проверяет наличие файла, если его нет — отправляет пакет со значением res = 0xB7; пытается открыть файл в режиме дописывания. В случае неудачи отправляет пакет со значением res = 0x52;
получает размер файла и в последующих пакетах выставляет поле filesize в соответствующее значение;
в цикле получает пакеты от сервера со значением cmd = 0x303 и пишет данные в файл, пока размер файла не станет больше или равным тому, что сервер указал в первом пакете.
- 0x203:
пытается открыть файл в режиме чтения. В случае неудачи отправляет пакет со значением res = 0x02;
получает размер файла и посылает его в пакете на сервер;
в цикле читает файл со смещения, указанного в filesize первого пакета сервера, и отправляет данные в пакете со значением cmd = 0x303 на сервер, пока файл не будет прочитан до конца.
- 0x403:
если управляющий сервер аргументом присылает путь, тогда перечисляет файлы и папки по указанному пути (не рекурсивно) и высылает собранную информацию на сервер со значением cmd = 0x403;
если сервер не указывает аргумент; если первый символ аргумента '/' или '\\', тогда перечисляет все диски и собирает данные, включающие тип диска, его размер и количество свободного места, затем отправляет на сервер в пакете со значением cmd = 0x403.
- 0x503:
перемещает файл (изначальный и конечный пути указывает управляющий сервер). В ответ высылает пакет со значениями cmd = 0x503 и res = 0 в случае успеха; в случае провала — со значением res = -1.
- 0x603:
удаляет файл, путь до которого указал сервер. В ответ высылает пакет со значениями cmd = 0x603 и res = 0 в случае успеха; в случае провала — со значением res = -1.
- 0x703:
запускает указанное сервером приложение с определенными аргументами. В ответ высылает пакет со значениями cmd = 0x703 и res = 0 в случае успеха; в случае провала — со значением res = -1.
Менеджер прокси
Троян инициализирует новое подключение к управляющему серверу и посылает следующий пакет:
#pragma pack(push,1)
struct cmd_proxy
{
_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x06
_BYTE gap[10];
_BYTE macaddr[6];
};
#pragma pack(pop)
Далее принимает команды от сервера.
- 0x106:
открывает какой-либо доступный порт;
отправляет управляющему серверу пакет со значением cmd = 0x506;
устанавливает соединение с целевым сервером, IP и порт которого сообщил управляющий сервер;
ожидает входящее соединение на своем порте. При получении данных пересылает их на сервер, к которому подключился;
если от целевого сервера приходят данные, посылает их на управляющий сервер в пакете со значением cmd = 0x116;
Вновь ожидает входящее соединение на своем порте. При получении данных пересылает их на сервер, к которому подключился;
- 0x116:
при наличии входящего подключения к ранее открытому порту пересылает данные клиенту в открытом виде, без использования стандартного для данного трояна шифрования.
- 0x126:
останавливает работу прокси и закрывает открытые соединения.
- 0x206:
посылает управляющему серверу пакет со значением cmd = 0x506;
открывает порт, указанный управляющим сервером;
ожидает входящее соединения на указанном порте;
подключается к целевому серверу, указанному управляющим сервером;
пересылает трафик с локального порта на удаленный сервер и обратно в открытом виде, без использования стандартного для данного трояна шифрования.
- 0x306:
принимает аргументом два порта;
посылает управляющему серверу пакет со значением cmd = 0x506;
открывает первый порт (мастер-порт) и ожидает соединения;
открывает второй порт (клиентский порт) и ожидает соединения;
открывает случайный порт и отправляет его номер тому, кто в данный момент подключен к мастер-порту. Затем ожидает входящее соединение на указанном порте;
перенаправляет трафик между клиентами, подключенными к мастер-порту и случайному порту.
- 0x406:
получает аргументом две пары IP:port;
подключается к первому серверу и принимает от него 2 байта — номер порта;
подключается к этому же серверу по полученному порту;
подключается ко второму серверу, указанному во входных аргументах;
перенаправляет трафик между установленными ранее соединениями;
- 0x606:
прекращает работу прокси.