Поддержка
Круглосуточная поддержка

Позвоните

Бесплатно по России:
8-800-333-79-32

ЧаВо | Форум

Ваши запросы

  • Все: -
  • Незакрытые: -
  • Последний: -

Позвоните

Бесплатно по России:
8-800-333-79-32

Свяжитесь с нами Незакрытые запросы: 

Профиль

Профиль

Linux.BackDoor.Wirenet.1

Добавлен в вирусную базу Dr.Web: 2015-03-25

Описание добавлено:

Троянец-бэкдор для заражения компьютеров под управлением ОС Linux. Основное предназначение заключается в краже конфиденциальной информации (логины, пароли), реализации функции кейлоггера (фиксации нажатий пользователем клавиш) и прокси-сервера, снятии снимков экрана. Позиционируется разработчиками как приложение, которое можно использовать для защищенного доступа к своему компьютеру или в качестве шпионской программы. Существуют реализации данного приложения для Windows и Mac OS Х.

Файл конфигурации

Файл конфигурации зашифрован собственной реализацией алгоритма RC4. Ее особенность заключается в том, что контекст шифрования задается однократно при инициализации и более не изменяется. То есть при каждом из последовательных вызовов функций RC4_crypt будет использоваться один и тот же контекст.

Содержание конфигурационного файла имеет следующий вид:

  1. Адрес и порт управляющего сервера. Формат: "address:port;".
  2. Адрес, порт, логин, пароль прокси (при наличии). Формат: "type:address:port:login:pass;".
  3. Имя файла, под которым бэкдор будет установлен в систему.
  4. Каталог, в который будет установлен бэкдор.
  5. Каталог, в который будут сохраняться лог-файлы кейлоггера.
  6. Параметры установки.

Структура, хранящая адрес управляющего сервера, имеет следующий вид:

#pragma pack(push, 1)
struct st_cnc
{
  char szCnC[64];
  _DWORD port;
  st_cnc *Next;
};
#pragma pack(pop)

Бэкдор способен работать со списком из трех таких структур.

Структура, задающая параметры прокси-сервера:

#pragma pack(push,1)
struct st_proxy
{
  _DWORD type;
  char szCnc[64];
  _DWORD port;
  char login[32];
  char pass[32];
  st_proxy *pNext;
};
#pragma pack(pop)

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

Принцип работы

После расшифровки конфигурационного файла троянец устанавливается в систему, сохраняя свою копию в папке "~/.Install/ " под именем mspv.

Дальнейший ход установки зависит от параметров, указанных в конфигурационном файле. Для определения этих параметров бэкдор читает строку из конфигурационного файла ("121"), преобразует ее в число и использует как битовое поле, где каждый разряд отвечает за свой параметр установки:

  • 0x01 — скопировать свой исполняемый файл в директорию, указанную в конфигурационном файле;
  • 0x02 — удалить файл дроппера после установки;
  • 0x04 — заблокировать свой файл;
  • 0x08 — установить собственную копию в автозагрузку через "~/.config/autostart/";
  • 0x10 — установить собственную копию в автозагрузку через crontab;
  • 0x20 — использовать только один экземпляр процесса;
  • 0x40 — запустить кейлоггер;
  • 0x80 — не выводить никаких сообщений.

Установка будет выполнена при наличии соответствующего параметра в файле конфигурации, в процессе инсталляции троянец устанавливается в автозагрузку, создавая файл "~/.config/autostart/mspv/mspv.desktop" следующего содержания:

\n[Desktop Entry]\nType=Application\nExec=\"~/.Install/mspv\"\nHidden=false\nName=mspv\n

В конце установки, если в параметрах установлен бит 0x40, бэкдор создает отдельный поток для кейлоггера.

Сетевой трафик шифруется с использованием алгоритма AES с 256-битным ключом, при этом таблицы для AES-шифрования бэкдор генерирует непосредственно в процессе выполнения.

Генерация сессионного ключа AES-256

Троянец определяет текущее значение времени и использует его в качестве сида для генератора псевдослучайных чисел:

int __cdecl RndGenerator::Init(int num)
{
  int v1;
  int result;
  v1 = currentstate_w ^ currentstate_z & num;
  currentstate_w = v1;
  result = currentstate_z ^ (num | v1);
  currentstate_z = result;
  return result;
}
 
unsigned int RndGenerator::Generate()
{
  currentstate_z = (currentstate_z << 16) + 0x9069 * (unsigned __int16)currentstate_z;
  currentstate_w = (currentstate_w << 16) + 0x4650 * (unsigned __int16)currentstate_w;
  return (currentstate_z << 12) + currentstate_w;
}
 
unsigned int __cdecl RndGenerator::GenerateInLimits(unsigned int low_limit, unsigned int upper_limit)
{
  return RndGenerator::Generate() % (upper_limit - low_limit + 1) + low_limit;
}
 
int __cdecl RndGenerator::FillBuffer(_BYTE *pBuffer, int size)
{
  int i;
  time_t v3;
  int rnd;
  i = 0;
  v3 = time(0);
  rnd = RndGenerator::Init(size ^ v3);
  while ( i < size )
  {
    rnd = RndGenerator::GenerateInLimits(1, 255);
    pBuffer[i++] = rnd;
  }
  return rnd;
}

Таким образом, заполняется буфер размером 32 байта. Затем из файла конфигурации извлекается значение одного из ключей (ключ шифрования) и преобразуется с использованием следующего алгоритма:

int __cdecl GenerateAesKey(const char *key, _BYTE *random, _BYTE *aes_key)
{
  const char *key_; // edx@1
  signed int z; // eax@1
  unsigned int key_len; // kr04_4@1
  signed int key_len_; // ecx@1
  int i; // eax@4
  int result; // eax@7
  int v9; // edx@7
  int v10; // edi@8
  int v11; // edi@8
  int v12; // edx@8
  _DWORD state[32]; // [sp+0h] [bp-90h]@2
  key_ = key;
  key_len = strlen(key) + 1;
  z = 0;
  key_len_ = key_len - 1;
  while ( z < key_len_ )
  {
    state[z] = (unsigned __int8)((key[z] >> 4) | 16 * key[z]);
    ++z;
  }
  for ( i = key_len - 1; i <= 31; ++i )
  {
    key_ = (const char *)(unsigned __int8)(i & (8 * i | ((signed int)(unsigned __int8)i >> 5)));
    state[i] = key_;
  }
  LOBYTE(key_) = state[key_len_ >> 2];
  result = 0;
  v9 = key_len_ ^ (unsigned int)key_;
  do
  {
    LOBYTE(v9) = random[result] ^ v9;
    v10 = v9;
    LOBYTE(v9) = state[result];
    v11 = v9 ^ v10;
    aes_key[result] = v11;
    v12 = 4 * v11;
    LOBYTE(v12) = random[result] ^ 4 * v11;
    aes_key[result] = result ^ (result + key_len_) | ((signed int)(unsigned __int8)v11 >> 5) | 8 * v11;
    ++result;
    v9 = ~v12;
  }
  while ( result != 32 );
  return result;
}

В результате преобразования получаются 32 байта для сессионного ключа AES.

Запросы к управляющему серверу

Для обмена данными с управляющим сервером троянец использует бинарный протокол, при этом все пакеты имеют одинаковую структуру:

#pragma pack(push,1)
struct st_packet
{
  _DWORD size;
  _BYTE cmd;
  _BYTE buffer[];
};
#pragma pack(pop)

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

#pragma pack(push, 1)
struct st_hello
{
  _BYTE rnd_data[32];
  _BYTE iv[16];
  _BYTE hello[16];
};
#pragma pack(pop)

Здесь: 'hello' — ключ шифрования из конфигурационного файла бэкдора; iv и rnd_data — данные, сгенерированные в процессе получения сессионного ключа AES. Значение поля st_packet.cmd для данного пакета равно 3.

Прием команды состоит из четырех шагов:

  1. Бэкдор отправляет пакет ReadyToReceive:
    #pragma pack(push,1)
    struct st_packet_rdytorecv
    {
      _DWORD size; // 5
      _BYTE cmd;  // 2
      _BYTE buffer[];  // NULL
    };
    #pragma pack(pop)
  2. Сервер отвечает значением DWORD, которое является размером следующего пакета. Он не должен превышать 0x800, а для первого ответа сервера должен быть равен 0x41.
  3. Бэкдор, проверив правильность принятых данных, отправляет еще раз пакет ReadyToReceive.
  4. Сервер отвечает пакетом, содержащим команду и аргументы для ее выполнения:
    #pragma pack(push,1)
    struct st_srv_answer
    {
      _BYTE cmd;
      _BYTE args[0x7FF]; // 0x7FF is a max value
    };
    #pragma pack(pop)

Первый пакет от сервера приходит в незашифрованном виде и имеет операционный код 0x05, длину 0x41.

Кейлоггер

Реализован на основе API X-сервера. При нажатии клавиши сохраняются дата, код нажатой клавиши, активное окно. Путь к лог-файлу записан в файле конфигурации.

Перед записью данных в лог-файл они шифруются с использованием несложного алгоритма XOR:

int __usercall CryptLog(_BYTE *data, DWORD size)
{
  BYTE x;
  for (DWORD i = 0; i != size; ++i )
  {
    x = data[i];
    x = (x ^ 0x9D) + 0x24;
    data[i] = x;
  }
  return i;
}

Система команд

Ping (0x01)

cmd == 0x01. Команда не имеет аргументов, ответ точно такой же (st_packet.cmd == 1, st_packet.buffer == NULL)

InitSecureConnection (0x05)

Сервер присылает 32 байта данных, которые шифруются мастер-ключом из файла конфигурации для получения ключа AES-256. Далее с его помощью расшифровывается буфер команды с целью проверки правильности шифрования соединения клиент-сервер.

Команда имеет следующий вид:

#pragma pack(push,1)
struct st_packet_initsecureconn
{
  _BYTE cmd;
  _BYTE key_data[32];
  _BYTE signature[16];
};
#pragma pack(pop)

После выполнения инициализации контекста AES троянец сохраняет дескриптор сокета, с которого пришла команда, и контекст AES для дальнейшей расшифровки команд.

Также отправляет ответ серверу в виде команды с параметрами:

st_packet.cmd = 4;
st_packet.buffer = NULL;

Далее собирается различная информация о машине, которая потом будет отправлена на сервер:

  1. Троянец получает или генерирует (при его отсутствии) HostId (уникальный идентификатор компьютера). Для этого проверяет наличие файла "%backdoor_filename%.Identifier". Если файл существует, то он содержит строку с HostId. Если файл отсутствует, то бэкдор создает его и записывает в него строку вида "HostId-%Rand%", где "%Rand%" заменяется на случайные символы из диапазона [A-Za-z].
  2. Троянец получает имя пользователя.
  3. Троянец получает имя компьютера.
  4. Троянец получает версию ОС. Для этого читает файл "/etc/lsb-release". Если он не найден, пытается открыть файл "/etc/redhat-release". Если и он не найден, перебирает все файлы в папке "/etc/" в поисках файла, название которого содержит "release" или "version".

Все эти данные упаковываются в буфер:

snprintf(&s, 0x800u, "%c%.8x%s\a%s @ %s\a%s\a", 2, 0x1056100, hostid, username, 
hostname, release);

И отправляются на управляющий сервер командой:

st_packet.cmd = 5
st_packet.buffer = s (содержимое указано выше).

Download To /tmp/ and Run File (0x06)

В команде приходит хост, порт, путь, по которому следует сохранить файл, и информация о том, нужно ли его запускать. Статус выполнения бэкдор сообщает на сервер пакетом st_packet.cmd = 0x2E с полезной нагрузкой "%d\a%d\ahttp://%s%s\a%s", где в качестве параметров используются счетчик скачанных файлов, статус выполнения команды, хост, путь к файлу, путь сохранения файла.

После запуска файла отправляет пакет st_packet.cmd = 0x08, st_packet.buffer = NULL.

Run File (0x07)

Запускает файл, путь к которому указан в команде.

После запуска файла отправляет команду:

st_packet.cmd = 0x08
st_packet.buffer = NULL

Exit (0x09)

Завершить работу бэкдора и удалить tmp-файл.

Close connection (0x0A)

Закрыть соединение с текущим управляющим сервером.

Uninstall (0x0B)

Удалить себя из автозагрузки и завершить работу.

SetHostId (0x0C)

Установить идентификатор HostId. Значение для установки приходит в команде.

Download File To /tmp/ (0x0D)

Аналогично команде 0x2D

Dummy (0x0E)

Отсылает в ответ пакет st_packet.cmd = 0x0E, st_packet.buffer = NULL

Upload file (0x10)

Загружает файл на сервер. При этом отсылается два пакета:

  1. Пакет st_packet.cmd = 0x10 с лог-файлами
  2. Пакет st_packet.cmd = 0x11, st_packet.buffer = NULL после окончания отправки файла или при его отсутствии
Recursive File Search (0x12)

Принимает два аргумента: название каталога (размер 0x1100 байт) и маску для поиска файлов (размер 0x1000 байт).

Функция осуществляет рекурсивный обход директорий/файлов, подходящих под заданные параметры. В процессе перебора на сервер отсылаются пакеты с st_packet.cmd == 0x13, при этом буфер может иметь два вида:

  • 16\a%root_dir%\a%dir_name%\a — если в результате поиска найден каталог (root_dir — каталог, указанный во входном параметре для поиска);
  • 0\a%filename%\a%filesize%\a%dir%\a — если в результате поиска был найден файл. %filename% — имя файла, %filesize% — размер файла, %dir% — каталог, в котором находится файл.

После завершения поиска на сервер отправляется пакет:

st_packet.cmd = 0x14
st_packet.buffer = NULL

Stop Recursive File Search (0x14)

Останавливает поиск файлов. На сервер отсылается пакет:

st_packet.cmd = 0x14
st_packet.buffer = NULL

Upload File or File Content (0x15)

Save Data To Disk (0x16)

Сохраняет в файл данные, пришедшие в команде.

Close File Handle (0x17)

Copy File (0x18)

Принимает два аргумента: путь к файлу, который следует скопировать, и путь к целевой папке. Каждый буфер имеет размер 0x1100 байт.

Run file or set access rights(0x19)

Разбирает аргументы в поисках трех строк:

  • filename — путь к файлу и аргументы запуска;
  • rights — строковое представление числа, обозначающего права доступа к файлу;
  • flag — флаг. Если он отличен от нуля, то будет произведен запуск файла, иначе выставлены права доступа.

Rename file (0x1A)

Переименование файла. В буфере команды две строки — исходное имя и конечное.

В случае успешного выполнения команды отправляет серверу ответ точно такой же командой.

Delete file (0x1B)

Удаляет файл, путь к которому находится в буфере.

В случае успешного выполнения команды отправляет серверу ответ точно такой же командой.

Create Directory (0x1C)

Создает директорию. Путь указан в буфере.

В случае успешного выполнения команды, отправляет серверу ответ точно такой же командой.

Delete Direcroty Recursively (0x1D)

Рекурсивное удаление директории.

List Or Create Dir(0x1E)

В зависимости от параметра создает директорию или отправляет на сервер список содержимого существующей директории.

Close File Handle (0x1F)

Remote Shell (0x20)

Execute Shell Command (0x21)

Disconnect Remote Shell (0x22)

Get System Info (0x24)

Запаковывает информацию о системе и отправляет на сервер. Перечень собираемой информации:

  1. Версия ОС
  2. Имя пользователя
  3. Имя компьютера
  4. Переменная окружения PATH
  5. Переменная окружения HOME
  6. Адрес управляющего сервера
  7. AES-ключ из конфигурационного файла
  8. Тип управляющего сервера
  9. Свой PID
  10. Имя своего процесса
  11. Каталог с лог-файлами кейлоггера
  12. Статус работы кейлоггера

Get Logon Sessions (0x26)

Get General Info (0x28)

Отправляет на сервер значение времени, когда была загружена система, список процессов.

Kill process by PID (0x2A)

Принимает строковое представление PID процесса, который следует убить.

Enum Windows (0x2B)

Формирует буфер с данными обо всех открытых окнах. По окончании работы отсылает на сервер команду st_packet.cmd = 0x2B. Значение st_packet.buffer может быть NULL или массивом строк "%s\a%d\a", где %s — заголовок окна, %d — окно.

Work With Window (0x2C)

В зависимости от аргумента выполняет команды MAP, UNMAP, закрывает окно или меняет название заголовка окна или его значка.

Download File (0x2D)

В команде приходит хост, порт, путь, по которому следует сохранить файл, и информация о том, нужно ли его запускать. Статус выполнения бэкдор отправляет на сервер пакетом st_packet.cmd = 0x2E с полезной нагрузкой "%d\a%d\ahttp://%s%s\a%s", где в качестве параметров используется счетчик скачанных файлов, статус выполнения команды, хост, путь к файлу, путь, по которому следует сохранить файл.

Send Key Released (0x2F)

Входным параметром является строковое представление кода клавиши.

Send Key Pressed (0x30)

Входным параметром является строковое представление кода клавиши.

Send Notify Event (0x31)

Send Crossing Event (0x32)

Upload Screenshot (0x33)

Бэкдор делает снимок экрана и отправляет его на управляющий сервер. При этом в ходе выполнения команды будут отправлены следующие пакеты:

  1. Сначала будет отправлен пакет st_packet.cmd = 0x33, где в качестве данных используется QWORD-значение размера лога.
  2. Далее пакетами st_packet.cmd = 0x34 будут отправляться данные снимка экрана, фрагментами по 2048 байт.
  3. После завершения отправки лога будет отправлен пакет st_packet.cmd = 0x35, st_packet.buffer = NULL.

Upload Keylogger Logs (0x36)

Бэкдор отправляет на управляющий сервер лог-файлы кейлоггера. При этом отсылается два пакета:

  1. Пакет st_packet.cmd = 0x36 с лог-файлами.
  2. Пакет st_packet.cmd = 0x37, st_packet.buffer = NULL после окончания отправки лог-файлов или при их отсутствии.

Get Keylogger Logs Size (0x38)

На сервер отправляется пакет с st_packet.cmd = 0x38 и содержимым "%s\a%d", где %s — путь к директории с лог-файлами кейлоггера, %d — ее размер.

Delete Logs By Date (0x39)

Удаляет лог-файл кейлоггера за указанную в аргументе дату.

Upload Keylogger Logs By Date (0x3A)

Отправляет на управляющий сервер лог-файл кейлоггера за дату, указанную в аргументе. При этом в ходе выполнения команды будут отправлены следующие пакеты:

  1. В случае отсутствия запрошенного лог-файла будет отправлен пакет st_packet.cmd = 0x3C, st_packet.buffer = NULL и выполнение команды завершится. Иначе сначала будет отправлен пакет st_packet.cmd = 0x3A, где в качестве данных используется QWORD-значение размера лог-файла.
  2. Далее пакетами st_packet.cmd = 0x3B будет отправляться содержимое лог-файла, фрагментами по 2048 байт.
  3. После завершения отправки лог-файла будет отправлен пакет st_packet.cmd = 0x3C, st_packet.buffer = NULL.

Steal Browser's Accounts (0x3D), (0x3E)

Крадет учетные записи пользователей из различных приложений. В качестве аргумента принимает DWORD, обозначающий учетные записи приложения, которые следует украсть.

  • 1 — Mozilla FireFox
  • 3 — Opera
  • 4 — Google Chrome
  • 5 — Chromium
  • 6 — Mozilla SeaMonkey

Если аргумент не совпал ни с одним из перечисленных, то на управляющий сервер будут переданы аккаунты всех браузеров.

Steal Pidgin's Accounts (0x3F), (0x40)

Ищет в файле "~/.purple/accounts.xml" аккаунт и, если он будет найден, высылает содержимое файла серверу. Код команды используется такой же.

Steal Accounts from Mozilla Thunderbird (0x41), (0x42)

Крадет аккаунты от Mozilla Thunderbird. Аргументов не требует. Ответ серверу имеет такой же код операции команды.

Make proxy (0x43)

В качестве аргумента принимает dword4 и порт.

  1. Устанавливает соединение с текущим управляющим сервером, используя порт из пришедшей команды.
  2. Бэкдор отсылает серверу пакет:
    #pragma pack(push,1)
    struct st_packet_proxy_create
    {
      _BYTE cmd; // 0x03
      _DWORD size; // dword4 from command's arg
    };
    #pragma pack(pop)
  3. Сервер посылает в ответ 1 байт. Если он равен 1, тогда следующим пакетом придет порт и IP-адрес, на который нужно будет перенаправлять трафик. В противном случае следующий пакет будет содержать домен и порт.
  4. Сервер присылает 6 байт (WORD port, DWORD ip) или буфер размером 0x100 байт, где содержатся значения домена и порта.
  5. Клиент отправляет один байт статуса серверу: 1 — не удалось создать сокет, 2 — не удалось подключиться к цели, 3 — ОК. При отсутствии ошибок начинает трансляцию трафика.

Рекомендации по лечению


Linux

На загруженной ОС выполните полную проверку всех дисковых разделов с использованием продукта Антивирус Dr.Web для Linux.

Демо бесплатно

На 1 месяц (без регистрации) или 3 месяца (с регистрацией и скидкой на продление)

Скачать Dr.Web

По серийному номеру