Публикации

Многофункциональный DDoS-троянец под Linux

В феврале 2014 года на популярном российском ИТ-ресурсе появилась статья с очень интересным заголовком – «Исследуем Linux Botnet «BillGates». В ней описывался троянец с довольно богатым функционалом для осуществления DDoS-атак. Особенно нас заинтересовала его способность проведения атаки типа DNS Amplification. Да и вообще, исходя из статьи, троянец имел сложную многомодульную архитектуру, чего до сих пор мы не наблюдали в мире Linux-зловредов.

Кроме того, в статье имелась ссылка, откуда все файлы троянца (полученные прямиком с зараженной машины) можно было скачать. Что мы и сделали.

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

  • atddd;
  • cupsdd;
  • cupsddh;
  • ksapdd;
  • kysapdd;
  • skysapdd;
  • xfsdxd.

В данный момент файлы cupsdd и cupsddh детектируются продуктами «Лаборатории Касперского» как Backdoor.Linux.Ganiw.a; atddd и остальные – как Backdoor.Linux.Mayday.f.

В архиве с файлами присутствовал также файл конфигурации cron – планировщика задач в Linux. В данном случае утилита используется как средство закрепления троянца в системе. С помощью cron троянец выполняет следующие задачи:

  1. Раз в минуту завершает процессы всех приложений, которые могут помещать его (троянца) работе: .IptabLes, nfsd4, profild.key, nfsd, DDosl, lengchao32, b26, codelove, node24;
  2. Примерно раз в полтора часа завершает работу всех своих процессов:kysapd, atdd, skysapd, xfsdx, ksapd;
  3. Примерно раз в два часа скачивает в папку /etc с адреса http://www.dgnfd564sdf.com:8080/[module_name] все свои компоненты (module_name = имя модуля, например, cupsdd), предварительно удалив эти файлы из /etc
  4. Раз в полтора часа заново запускает все свои модули
  5. Каждую минуту затирает системные логи, историю команд bash и выполняет chmod 7777 [module_name]

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

Backdoor.Linux.Mayday.f (atddd)

Файл atddd представляет собой бэкдор, содержащий функционал для осуществления различных типов DDoS-атак на указанные сервера, и, напомним, детектируется нами как Backdoor.Linux.Mayday.f. Файлы kysapdd, skysapdd, xfsdxd, ksapdd являются практически полными копиями atddd за одним исключением, о котором ниже.

Вначале своей работы бэкдор вызывает функцию daemon(1, 0), таким образом продолжая свое выполнение в фоновом режиме и перенаправляя стандартный ввод, вывод и ошибки в /dev/null

Затем atddd собирает необходимую информацию о системе, а именно:

  1. версию системы (вызов uname())
  2. количество ядер процессора и их частоту (из /proc/cpuinfo)
  3. загруженность процессора (из /proc/stat)
  4. загруженность сети (из /proc/net/dev для интерфейсов с префиксом «eth»)

Эта информация помещается в структуру g_statBase.

bill_gates_botnet1

После этого бэкдор расшифровывает строки, содержащие IP-адрес и порт C&C сервера. Алгоритм шифрования очень простой: зашифрованная строка посимвольно перебирается и если номер символа нечетный, то к его ASCII коду добавляется 1, если четный — вычитается 1. Таким образом из строки «3/3-2/4-269-85» получается IP-адрес «202.103.178.76», а из «2/:82» порт «10991».

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

1-ая строка: 0 //флаг, если 1 — то начать атаку, если 0 — остановить атаку

2-ая строка: 127.0.0.1:127.0.0.1 //диапазон исходящих IP-адресов

3-я строка: 10000:60000 //диапазон исходящих портов для атаки

4-ая строка: пустая строка //доменное имя в случае с DNS-флудом (см. ниже)

Эта информация в дальнейшем передается C&C серверу и может обновляться при помощи команды от C&C.

Далее бэкдор запускает новый поток CThreadTaskManager::ProcessMain(), в котором команды на начало атаки и остановку атаки ставятся в очередь на выполнение. Следом запускается новый поток CThreadHostStatus::ProcessMain(). В нем каждую секунду обновляются данные о загруженности процессора и сети, которые впоследствии могут отправляться C&C серверу при запросе.

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

bill_gates_botnet2_sm

Далее зловред входит в бесконечный цикл обработки сообщений от C&C. Сначала устанавливается соединение с C&C и каждые 30 секунд отправляется информация о версии системы и тактовой частоте процессора, а также данные из структуры g_fakeCfg.

В ответ сервер должен отправить 4 байта, первый из которых является порядковым номером команды — от 1 до 4.

bill_gates_botnet3_sm

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

Подробнее о каждой из команд:

  • 0x01. Команда запуска атаки, в параметрах передаются тип атаки, а также количество используемых потоков. Тип атаки представляет из себя байт со значением от 0x80 до 0x84. Таким образом возможны 5 видов атак:
    • 0x80 — TCP флуд. Порт назначения передается в ответе C&C в качестве параметра. Дипазон портов отправления задан в fwke.cfg. Каждый новый запрос отправляется с нового порта в заданном диапазоне, по порядку. IP-адрес назначения так же задается в параметрах.
    • 0x81 — UDP флуд. Тоже самое, что и 0x80, только в качестве протокола транспортного уровня используется UDP.
    • 0x82 — ICMP флуд. Аналогично предыдущим, только через ICMP.
    • 0x83, 0x84 – две атаки с использованием DNS флуда. Отличаются только доменным именем в DNS-запросе. В первом случае оно генерируется случайным образом, во втором — задается в параметре (4-ая строка в fwke.cfg). По сути обе похожи на 0x81, только в качестве порта назначения используется порт 53 (порт DNS службы по умолчанию).
  • 0x02. Команда остановки атаки. Значение в первой строке fwke.cfg изменяется на 0 и атака прекращается.
  • 0x03. Команда на обновление файла fwke.cfg. В ответе также приходит структура, аналогичная g_fakeCfg, из которой записывается файл fwke.cfg.
  • 0x04. Команда для отправки статуса выполнения текущей команды С&C серверу.

Помимо этого бэкдор содержит несколько пустых (без кода внутри) методов с интересными названиями: CThreadAttack::EmptyConnectionAtk, CThreadAttack::FakeUserAtk, CThreadAttack::HttpAtk. Видимо, автор планировал расширить функционал зловреда и эта версия является не окончательной, а скорее тестовой. И файл cupsdd, о котором мы расскажем ниже, является этому подтверждением.

Файлы kysapdd, skysapdd, xfsdxd, ksapdd являются практически полными копиями atddd, но содержат другие адреса C&C серверов: 112.90.252.76:10991, 112.90.22.197:10991, 116.10.189.246:10991 и 121.12.110.96:10991 соответственно. Также отличаются имена файла конфигурации: fsfe.cfg, btgw.cfg, fake.cfg, xcke.cfg соответственно.

Таким образом, вопреки нашим ожиданиям, файлы atddd, kysapdd, skysapdd, xfsdxd, ksapdd являются не модулями чего-то целого, а отдельными экземплярами троянца, каждый из которых работает со своим C&C сервером. Но самое интересное еще впереди.

Backdoor.Linux.Ganiw.a (cupsdd)

Так же, как и описанные выше файлы, этот является бэкдором с функционалом для осуществления различных DDoS-атак. Но функционал cupsdd значительно богаче и сложнее, чем у его «коллег», хотя его код в некоторых местах очень похож на код файла atddd.

В начале работы бэкдор инициализирует необходимые ему переменные из строки «116.10.189.246:30000:1:1:h:578856:579372:579888» (разделитель — «:»), которую предварительно расшифровывает при помощи алгоритма RSA. Строка распределяется по переменным следующим образом:

g_strConnTgt=116.10.189.246 — IP-адрес С&C сервера

g_iGatsPort=30000 — порт С&C сервера

g_iGatsIsFx=1 и g_iIsService=1 — флаги, используемые в дальнейшем

g_strBillTail=h — постфикс для имени файла, который будет дропнут (см. ниже)

g_strCryptStart=578856, g_strDStart=579372, g_strNStart=579888 — указатели на RSA-данные (зашифрованная строка и ключ)

Далее зловред дропает и запускает файл, находящийся изначально по смещению 0xb1728 от начала файла и имеющий размер 335872 байта, если он еще не запущен. Проверка запущен ли этот файл происходит при помощи попытки забиндить сокет 127.0.0.1:10808. Если это сделать удалось, значит файл не запущен и нужно его дропнуть и запустить.

bill_gates_botnet4

Если же файл уже запущен, то его процесс, PID которого находится в файле /tmp/bill.lock, принудительно завершается (kill(pid, 9)). И потом файл все равно дропается, заменяя собой уже существующий.

Имя дропнутого файла формируется из имени текущего запущенного файла + постфикс из переменной g_strBillTail. В нашем случае файл назывался cupsddh и находился в той же директории, что и дроппер.

Далее текущий процесс форкается и в дочернем процессе происходит вызов функции system(«/path/to/cupsddh»), которая запускает дропнутый файл.

После этого вызывается функция daemon(1, 0), имеющая тот же смысл что и в предыдущем сэмпле (atddd).

Потом обрабатывается ситуация, если cupsdd был запущен ранее и активен в данный момент. Для этого проверяется, существует ли файл /tmp/gates.lock. Если он существует, то текущий процесс завершается (exit(0)). Если же нет, то он (/tmp/gates.lock) создается и в него помещается pid текущего процесса.

Далее, если флаг g_iIsService == 1, то бэкдор прописывает себя в автозагрузку при помощи создания скрипта в /etc/init.d/ с именем DbSecuritySpt следующего содержания:

#!/bin/bash

/path/to/cupsdd

И создает символьные ссылки на него в /etc/rc[1-5].1/S97DbSecuritySpt

bill_gates_botnet6_sm-2

Читает файл конфигурации conf.n (если он существует) из той же директории, что и cupsdd. Первые 4 байта файла — это размер данных идущих далее. Все данные помещаются в структуру g_cnfgDoing.

Читает файл с командами — cmd.n. Формат такой же как и в conf.n. Данные попадают в структуру g_cmdDoing.

Далее получает необходимую информацию о системе, а именно:

  • Имя системы и версию ядра (напр., Linux 3.11.0-15-generic), при помощи вызова uname()
  • Тактовую частоту процессора, из /proc/cpuinfo
  • Количество ядер процессора из /proc/cpuinfo и загруженность процессора из /proc/stat
  • Загруженность сети из /proc/net/dev
  • Размер жесткого диска в мегабайтах из /proc/meminfo
  • Информацию о сетевых интерфейсах из /proc/net/dev
  • Все данные помещаются в структуру g_statBase.

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

  • 0x03. DoConfigCommand(). Обновить файл конфигурации conf.n.
  • 0x05. DoUpdateCommand(). Запускает новый поток CThreadUpdate::ProcessMain, в котором обновляет один из своих компонентов. В качестве параметра команда принимает число от 1 до 3, которое ассоциируется с одной из следующей строк:
    1 — «Alib» — файл /usr/lib/libamplify.so
    2 — «Bill» — дропнутый модуль cupsddh
    3 — «Gates» — дроппер cupsdd

bill_gates_botnet7_sm

В зависимости от параметра обновляется один из компонетов зловреда. Обновление происходит при помощи отправки C&C серверу 6 байт, содержащих строку «EF76#^». Вслед за этим отправляется одна из строк, описанных выше (в зависимости от параметра).

В ответ приходят 4 байта, содержащие длину файла (в байтах), который будет передан далее. Затем С&C передает сам файл пакетами по 1024 байта.

Сначала файл сохраняется в директории /tmp со случайным именем, состоящим из цифр. Затем, в зависимости от того что за файл был получен, заменяет уже существующий файл cupsdd (или cupsddh) или копируется в /usr/lib/libamplify.so

Далее временный файл из /tmp удаляется, а на итоговый устанавливаются права 755 с помощью команды chmod. После чего, в случае обновления cupsddh, уже запущенный процесс завершается, а новый файл запускается. В случае обновления cupsdd, завершающий этап (начиная с копирования их /tmp) осуществляет cupsddh, которому отдается соответствующая команда.

  • 0x07. DoCommandCommand(). Записывает новую команду в cmd.n.
  • 0x02. StopUpdate(). Закрывает текущее соединение, установленное для обновления модулей.

После этого бэкдор cupsdd запускает несколько потоков, в которых одновременно выполняет несколько вспомогательных действий:

  • CThreadClientStatus каждую секунду обновляет данные о загруженности процессора и сети в структуре g_statBase.
  • CThreadRecycle удаляет из очереди заданий уже завершенные.
  • — CThreadConnSender читает команды из очереди и передает их модулю cupsddh через TCP-соединение с 127.0.0.1 на порт 10808. В ответ принимает статус их выполнения.
  • CThreadMonBill каждую минуту проверяет запущен ли модуль cupsddh и если нет, то заново дропает и запускает его.
  • CThreadLoopCmd читает команды из g_cmdDoing (файл cmd.n) и выполняет их через вызов system(cmd).

Далее основной поток входит в цикл приема и обработки команд от C&C сервера. Тут в зависимости от флага g_iGatsIsFx возможны два варианта:

  1. Если флаг установлен (==1), то зловред, как и в предыдущем сэмпле (atddd), в новом потоке просто отправляет информацию о системе и текущую конфигурацию из g_cnfgDoing и ожидает поступления в ответ команд;
  2. Если флаг не установлен, то инициатором сеанса связи выступает C&C. То есть зловред ожидает подключения от C&C и только когда соединение будет установлено начинает передавать указанные выше данные.

bill_gates_botnet8_sm

Команды, поступающие от C&C распределяются в одну из двух очередей: либо на исполнение в текущем модуле (в потоке CThreadTaskGates, описанном выше), либо на передачу модулю cupsddh (поток CThreadConnSender).

Backdoor.Linux.Ganiw.a (cupsddh)

Файл упакован UPX’ом, после распаковки вызывает daemon(1,0). Создает файл /tmp/bill.lock, в который помещает PID текущего процесса. cupsddh заполняет данными о системе структуру g_statBase, точно такую же как в cupsdd.

Далее заполняет структуру g_provinceDns IP-адресами DNS-серверов приведенными к двоичному коду в сетевом порядке расположения байт функцией inet_addr(), из массива строк g_sProvinceDns (смещение в распакованном файле: 0x8f44с, размер 4608 байт).

cupsddh выполняет команду «insmod /usr/lib/xpacket.ko», пытаясь таким образом загрузить модуль ядра в ядро. Однако такой файл отсутствует на «чистой» системе, и зловред не предпринимает никаких попыток скачать его или получить каким либо еще способом.

bill_gates_botnet9_sm

Далее данные из файла /usr/libamplify.so (оказывается, это не библиотека, а очередной конфиг) загружаются в структуру g_AmpResource. Формат файла: 1-ый dword — это количество dword’ов, идущих следом. Судя по всему, содержит список IP-адресов актуальных на данный момент DNS-серверов, подходящих для DDoS-атаки типа DNS Amplification.

После этого запускает два потока: CThreadTask и CThreadRecycle. Первый выполняет команды из очереди, сформированной из пришедших от модуля cupsdd команд. Второй удаляет выполненные команды. Затем основной поток биндит сокет на 127.0.0.1:10808 и в бесконечном цикле начинает принимать команды от модуля cupsdd, которые заносятся в вышеуказанную очередь.

Возможны следующие команды:

  • 0x01. Начинает атаку в соответствии с полученными параметрами. Подробнее ниже.
  • 0x02. Останавливает текущую атаку, устанавляивая соответствующий флаг.
  • 0x03. Обновляет текущую конфигурацию в структуре g_cnfgDoing, которую использует при атаке. Так же обновляет текущий локальный мак-адрес и мак и ip адреса текущего используемого гейта (шлюза) в структуре g_statBase.
  • 0x05. Завершающий этап обновления модуля cupsdd (описан выше).

bill_gates_botnet10-2

Возможны два основных режима атаки: в нормальном режиме и режиме ядра.

Режим ядра

Для этого режима используется встроенный в Linux генератор пакетов уровня ядра pktgen. Его преимущество для злоумышленника состоит в том, что трафик генерируется с максимальной возможной для данного сетевого интерфейса скоростью. И сгенерированные таким образом пакеты нельзя увидеть с помощью обычных снифферов, например, стандартного tcpdump, т. к. пакеты генерируются на уровне ядра.

bill_gates_botnet11_sm

Управляется генератор пакетов при помощи набора скриптов/конфигов в директории /proc/net/pktgen. Но перед этим необходимо загрузить модуль pktgen в ядро при помощи вызова команды «modprobe pktgen». Однако подобные вызовы мною обнаружены не были. Судя по всему, вместо них используется вызов «insmod /usr/lib/xpacket.ko», но, как и было сказано ранее, такой файл по умолчанию отсутствует в системе. Соответственно, в данной версии зловреда режим ядра не функционирует.

Тем не менее, зловред пытается записать несколько файлов в директорию /proc/net/pktgen, а именно:

  1. файл — /proc/net/pktgen/kpktgend_%d — для каждого ядра процессора, где %d — номер ядра, начиная с 0. Содержание файла:
  2. rem_device_all
    add_device eth%d
    max_before_softirq 10000
    bill_gates_botnet12_sm

  3. файл — /proc/net/pktgen/eth%d — для каждого ядра процессора, где %d — номер ядра, начиная с 0. Содержание файла:
  4. count 0
    clone_skb 0
    delay 0
    TXSIZE_RND
    min_pkt_size %d
    max_pkt_size %d
    IPSRC_RND
    src_min %s
    src_max %s
    UDPSRC_RND
    udp_src_min %d
    udp_src_max %d
    dst %s
    udp_dst_min %d
    udp_dst_max %d
    dst_mac %02x:%02x:%02x:%02x:%02x:%02x //MAC-адрес шлюза из g_statBase
    is_multi %d
    multi_dst %s    //если адресов для атаки несколько (т. е. значение в предыдущей строке не равно 0), то они задаются в этих строках, количество которых соответствует предыдущему параметру
    pkt_type %d
    dns_domain %s
    syn_flag %d
    is_dns_random %d
    dns_type %d
    is_edns %d
    edns_len %d
    is_edns_sec %d

    Значения большинства параметров pktgen передаются через параметры команды от cupsdd.

  5. файл — /proc/net/pktgen/pgctrl, содержащий строку «start».

Нормальный режим атаки

Как и в atddd нормальный режим атаки работает через сокеты (raw sockets).

Здесь возможны следующие типы атак:

  • CAttackSyn — TCP-SYN флуд.
  • CAttackUdp — UDP флуд. (как и в atddd)
  • CAttackDns — DNS флуд. (как и в atddd)
  • CAttackIcmp — ICMP флуд. (как и в atddd)
  • CAttackCc — HTTP-флуд.
  • CAttackAmp — DNS Amplification.
  • Особенность последней заключается в том, что пакеты отправляются к уязвимым DNS-серверам с указанием адреса цели атаки в качестве IP-адреса отправителя. Таким образом, злоумышленник отправляет небольшой пакет с DNS-запросом, а DNS-сервер отвечает цели атаки значительно большим по объему пакетом. Список уязвимых DNS-серверов хранится в файле libamplify.so, который записывается после получения соответствующей команды от C&C.

    bill_gates_botnet13-2

    Post Scriptum. BillGates v1.5

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

    Наиболее существенные изменения произошли в модуле «Gates», т.е. в файле cupsdd. Теперь у него есть три режима работы. Выбор режима работы осуществляется на основании того откуда был запущен файл. Конкретнее, если файл запущен из /usr/bin/pojie, то выбирается режим мониторинга, иначе – режим установки и обновления, который в дальнейшем переходит в режим управления модулем «Bill».

    bill_gates_botnet14

    1. Режим установки и обновлений.
    2. Сначала завершает свой процесс, работающий в режиме мониторинга, если таковой имеется. Его PID храниться в файле /tmp/moni.lock

      Далее переустанавливает и перезапускает модуль «Bill».

      Затем, если существует процесс работающий в режиме управления модулем «Bill», то он завершается. Его PID хранится в файле /tmp/gates.lock

      Если установлен флаг g_iIsService (получается тем же образом, что и предыдущей версии) то прописывает себя в автозагрузку тем же способом, что и ранее (в предыдущей версии).

      алее записывает путь до себя в файл /tmp/notify.file и самокопируется в файл /usr/bin/pojie. После чего запускает свою копию, которая, очевидно, будет работать уже в режиме мониторинга, а сам переходит в режим управления модулем «Bill».

    3. Режим мониторинга.
    4. Записывает PID текущего процесса в файл /tmp/moni.lock. Далее запускает два потока для мониторинга модуля «Bill» и мониторинга модуля «Gates», работающего в режиме управления. И если один из этих процессов на данный момент не запущен, то нужный файл заново создается и запускается.

    5. Режим управления модулем «Bill».
    6. Действия, совершаемые модулем Gates в этом режиме, полностью соответствуют действиям, которые совершал этот же модуль в предыдущей версии троянца (после установки модуля Bill и инициализации необходимых ему переменных и структур).

    Таким образом, в новой версии троянца авторы добавили ему немного «живучести», но основной функционал остался без существенных изменений.

    Стоит также отметить, что прописанный в коде IP-адрес C&C сервера остался прежним (116.10.189.246), однако изменился номер порта – 36008 вместо прежнего 30000.

Многофункциональный DDoS-троянец под Linux

Ваш e-mail не будет опубликован. Обязательные поля помечены *

 

Отчеты

StripedFly: двуликий и незаметный

Разбираем фреймворк StripedFly для целевых атак, использовавший собственную версию эксплойта EternalBlue и успешно прикрывавшийся майнером.

Азиатские APT-группировки: тактики, техники и процедуры

Делимся с сообществом подходами, которые используют азиатские APT-группировки при взломе инфраструктуры, и подробной информацией о тактиках, техниках и процедурах (TTPs) злоумышленников, основанной на методологии MITRE ATT&CK.

Как поймать «Триангуляцию»

Эксперты «Лаборатории Касперского» смогли получить все этапы «Операции Триангуляция»: эксплойты нулевого дня для iOS, валидаторы, имплант TriangleDB и дополнительные модули.

Подпишитесь на еженедельную рассылку

Самая актуальная аналитика – в вашем почтовом ящике