Детальный анализ бэкдора Linux/Ebury

    Недавно наши исследователи выполнили анализ OpenSSH бэкдора и похитителя паролей Linux/Ebury. Этот анализ является результатом совместной работы ESET с немецким CERT-Bund, шведским центром SNIC и европейской организацией CERN, а также другими организациями, которые входят в международную рабочую группу (Working Group). Linux/Ebury представляет из себя сложный бэкдор, используемый злоумышленниками для похищения аутентификационных данных OpenSSH, а также получения доступа к скомпрометированному серверу (backdoor).



    Согласно предыдущим отчетам, этот бэкдор уже активен как минимум два года. Linux/Ebury может дистрибуцироваться в двух различных формах: вредоносная библиотека и патч к бинарным файлам OpenSSH. Вредоносная библиотека представляет из себя модификацию файла libkeyutils.so. Эта библиотека является общей для компонентов OpenSSH и загружается его исполняемыми файлами, такими как, ssh, sshd и ssh-agent. В анализе будет опубликована информация о том, как вредоносный код осуществляет кражу аутентификационных данных учетных записей и как системные администраторы могут обнаружить зараженную систему.

    Вредоносный код Linux/Ebury является интересным по некоторым причинам. Прежде мы видели вредоносные библиотеки под Windows и это первый случай когда мы наблюдаем схожий модуль для систем POSIX. Он также использует особые приемы для перехвата функций, для внедрения своего кода в адресное пространство процесса, который загружает библиотеку и специальным образом модифицирует код во время исполнения. Мы полагаем, что прежде чем использовать метод внешней библиотеки для получения доступа к OpenSSH процессу, автор Linux/Ebury использовал специальный патч для модификации исходного кода OpenSSH, тем самым добавив «новые возможности» к этому ПО. Первые варианты вредоносного кода выглядели именно так, поскольку мы обнаружили модифицированные бинарные файлы OpenSSH на диске одного из скомпрометированных серверов: ssh, sshd и ssh-add. Мы также наблюдали использование команд rpm для удаления сигнатур из оригинального пакета ПО OpenSSH (openssh-server и openssh-clients), а также модификацию базы данных RPM для обновления хэшей файлов на их вредоносные модифицированные аналоги. Такая модификация позволяет не допустить обнаружения модификации файлов через проверку их хэшей с использованием команды rpm --verify openssh-servers. В то же время команда rpm -qi openssh-servers покажет их отсутствие.

    Более поздние варианты Linux/Ebury не модифицируют файлы OpenSSH напрямую. Вместо этого они используют свой вариант библиотеки libkeyutils.so, которая подключается всеми исполняемыми файлами OpenSSH. Изменения, которые проводятся над оригинальной библиотекой, похожи на те, которые использовались для модификации бинарных файлов OpenSSH, которые мы упоминали выше, за исключением того, что выполняется перехват некоторых функций, а также осуществляется их патчинг в процессе исполнения (runtime patching). Обычно этот файл имеет размер 10 Кб. Вредоносный код добавляет около 20 Кб своего кода к этому файлу, после чего размер файла равен уже 30 Кб.

    Ниже представлены два примера того, как бэкдор устанавливается в системе. Первый показывает зараженный Linux/Ebury файл, который следует за чистым файлом libkeyutils.so. Символьная ссылка модифицирована и указывает на вредоносную версию.



    Следующий скриншот показывает сценарий, при котором библиотека libkeyutils.so перезаписана вредоносной версией.



    Хотя практика размещения вредоносного кода внутри библиотек уже наблюдалась ранее, это первый случай когда мы обнаружили ее в Linux для изменения поведения OpenSSH.

    Для реализации различных функций вредоносного кода, он использует специальную функцию-конструктор (constructor function), которая добавляется в libkeyutils.so. Эта функция будет вызвана загрузчиком при загрузке бинарного файла. Она определяет из какого файла была запущена, после чего выполняет модификацию исполняемого кода и перехватывает функций таблицы импорта.

    В последних обнаруженных вариантах Linux/Ebury злоумышленники зашифровали строки вредоносного кода с использованием простого XOR и статического ключа. После распаковки своего кода вредоносная программа получает адреса необходимых для нее функции с использованием вызова dlsym. После этого она получает адрес в памяти самого бинарного файла через dlopen(NULL, RTLD_NOW) и передает этот адрес (дескриптор) функции dlinfo(handle, RTLD_DI_LINKMAP, …). Такой метод будет работать даже в случае активности ASLR в системе. Вызов этих функций позволяет Linux/Ebury анализировать таблицу импорта исполняемого ELF-файла и заменять его импорты в памяти (перехват). В результате, когда одна из программ sssh, sshd или ssh-add вызовет одну из перехваченных функций, поток исполнения будет перенаправлен на вредоносную реализацию функции из libkeyutils.so. Фрагмент кода ниже демонстрирует вызовы dlopen и dlinfo для нахождения адреса модуля в памяти с последующим анализом информации ELF-заголовка.



    Вредоносный код перехватывает различные функции (когда вредоносная модификация libkeyutils.so загружается в процесс sshd):

    • audit_log_user_message
    • audit_log_acct_message
    • hosts_access
    • connect
    • __syslog_chk
    • write
    • syslog
    • popen
    • hosts_access
    • crypt
    • pam_start

    Эти функции относятся по своей сути к logging-функциям, т. е. могут использоваться для фиксирования активности работы программы. В случае присутствия бэкдора в системе, эти функции будут перехвачены и заменены вредоносными аналогами, что препятствует выполнению их прямых обязанностей. Вредоносный код перехватывает и другие функции, например, pam_start, crypt и connect которые используются, например, для кражи вводимых паролей. Последняя функция перехватывается для дальнейшего получения управления над Xbnd (см. ниже), при этом вызов функции связывания сокета (bind) выполняется перед вызовом настоящего connect.

    В том случае, когда перехват функций с использованием таблицы импорта не представляется возможным, Linux/Ebury осуществляет непосредственную модификацию кода в определенной секции бинарного файла, перенаправляя те или иные ветви кода на свою реализацию. На рисунке ниже показан пример подобного перехвата, ssh программа вызывает функцию key_parse_private_pem и поток исполнения перенаправляется на вредоносный код. Адрес, выделенный красным, выходит за пределы исполняемого образа ssh и указывает на вредоносную модификацию libkeyutils.so. Этот перехват затем вызовет оригинальную функцию, запомнит приватный ключ в памяти и далее передаст его операторам вредоносной программы.



    Перед модификацией инструкций в кодовом сегменте, программа устанавливает специальный обработчик для перехвата исключений (fault), связанных с сегментацией. Такой обработчик будет вызываться в том случае, когда процесс получит сигналы SIGSEGV или SIGBUS. В случае появления сигнала, Linux/Ebury просто прервет свою задачу и позволит OpenSSH выполнить свой код. Перед тем как начать исполнять функции, которые могут привести к краху процесса, он вызывает функцию sigsetjmp для сохранения текущего состояния окружения (снэпшот). Если, в дальнейшем, произойдет какое-либо исключение, siglongjmp будет использоваться для восстановления состояния окружения к исходному состоянию.

    Такая техника модификации кода ограничена, поскольку смещения кода, которые подлежат исправлению, жестко зашиты в теле libkeyutils.so. Таким образом, его эффективность ограничена бинарным файлом, на который направлены эти модификации. На практике, каждая модификация libkeyutils.so будет работать на трех или пяти различных версиях OpenSSH и будет зависеть от дистрибутива Linux.

    Сам бэкдор активируется через отправку специальным образом сформированных данных внутри строки, которая идентифицирует версию протокола, используемую клиентом SSH. Ниже приведена часть спецификации по SSH, которая указывает на использование версии протокола.

    After the socket is opened, the server sends an identification string, which is of the form «SSH-protocolmajor.protocolminor-version», where protocolmajor and protocolminor are integers and specify the protocol version number (not software distribution version). version is server side software version string (max 40 characters); it is not interpreted by the remote side but may be useful for debugging.
    www.openssh.com/txt/ssh-rfc-v1.5.txt — T. Ylonen

    Часть на самом деле может быть чем угодно и не должна интерпретироваться каким-либо образом SSH сервером. В случае с бэкдором Linux/Ebury, поле содержит строку из шестнадцатеричных символов длиной 22 и более символов. Она содержит 11 символов пароля доступа к системе, который зашифрован с использованием значения клиентского IP-адреса, а затем закодирована в виде шестнадцатеричной строки; за паролем также могут следовать четыре необязательных байта команды, которая также зашифрована.

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

    Пример версии используемого протокола SSH, при последующем запуске root shell выглядит следующим образом:

    SSH-2.0-fb54c28ba102cd73c1fe43

    После того как бэкдор проверил пароль, процесс sshd позволит использовать любые символы в качестве пароля для последующей успешной аутентификации. Если в конфигурации опции PermitRootLogin, PasswordAuthentication или PermitEmptyPassword запрещены, вредоносный код включит их. Он также отключит любые операции протоколирования успешного создания нового сеанса, чтобы невозможно было отследить активность злоумышленников. В версиях 1.3.1 и старше, хэш SHA-1 пароля хранится в бинарном файле, а не в 11 символах строки версии протокола как указано выше. Такая практика делает невозможным процесс угадывания пароля, в случае если у вас нет инструмента захвата сетевых пакетов для отслеживания операций входа со стороны операторов. Кроме этого пароль отличается в разных модификациях вредоносного кода. Скорее всего у операторов вредоносной программы есть база данных зараженных серверов с соответствующими паролями для доступа к бэкдорам, так чтобы они могли бы активировать каждый из них в отдельности.



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

    • Пароль от успешной операции входа на зараженный сервер. Всякий раз когда кто-то входит в систему, зараженную Linux/Ebury, демон sshd сохранит этот пароль и отправит его на сервер злоумышленников (exfiltration).
    • Любой введенный пароль для операции входа на зараженный сервер. Даже если попытка входа на сервер была неудачной, введенные имя пользователя и пароль будут отправлены на сервер злоумышленников.
    • Пароль от успешной операции входа с зараженного сервера. Когда кто-либо использует ssh клиент на зараженном сервере, вредоносный код перехватит эту операцию и отправит введенный пароль на сервер злоумышленников.
    • Секретную идентификационную фразу. Когда SSH клиент на зараженном сервере запрашивает у пользователя секретную фразу (private key passphrase) для успешного входа, она будет отправлена на удаленный сервер.
    • Незашифрованный секретный ключ. Когда кто-либо использует секретный ключ для аутентификации на удаленном сервере, его незашифрованная версия перехватывается вредоносным кодом. В отличие от случая с паролями, этот ключ не будет отправлен на удаленный сервер, вместо этого он будет сохранен в памяти. При этом Linux/Ebury будет ждать команды оператора для передачи ключа с использованием команды xcat.
    • Секретные ключи, добавленные к OpenSSH с использованием ssh-add. Ключи (незашифрованная версия ключа и секретная фраза), добавленные к агенту OpenSSH, также перехватываются вредоносной программой.

    Вне зависимости от типа учетных данных, Linux/Ebury сохранит всю необходимую информацию (имя пользователя, IP-адрес системы назначения и порт OpenSSH) для операторов вредоносной программы, которые смогут использовать их в дальнейшем.

    Когда Linux/Ebury перехватывает необходимый пароль, он посылается на удаленный сервер через специальным образом сформированный DNS-запрос. Он создает запрос A записи (regular A record request), которая будет отправлена на порт UDP с номером 53. Поле запрашиваемого имени домена содержит зашифрованные данные в шестнадцатеричном виде, а также IP-адрес. Данные имеют следующий формат:

    <зашифрованные_данные_в_шестнадцатеричном_представлении>.<IP-адрес>

    Первое поле содержит данные одной из учетных записей, которые указаны выше. Они зашифрованы с использованием XOR и 4-байтного статического ключа 0x000d5345, а затем кодируются шестнадцатеричным представлением.

    Этот IP-адрес, указанный в запросе, зависит от типа похищенных учетных данных. Если учетные данные относятся к зараженному серверу, то используется IP-адрес источника, в противном случае, удаленный IP-адрес, который используется для подключения с зараженного сервера. Мы полагаем, что выбранный авторами вредоносной программы способ отправки похищенных данных используется для маскировки в качестве легитимных DNS-запросов, которые отправляются через порт 53, чтобы избежать их блокирования со стороны брандмауэров.

    Существуют два метода, с помощью которых Linux/Ebury может выбрать сервер для отсылки туда DNS пакетов. Во-первых, он может быть явно установлен оператором при использовании команды Xver. Второй метод заключается в использовании алгоритма генерации доменных имен DGA. В таком случае имя домена будет проверено на предмет существования и принадлежности его операторам с использованием записей запроса A и TXT.

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

    • Xcat: распечатать все пароли, секретные фразы и ключи, сохраненные в памяти бэкдора и выйти.
    • Xver: распечатать версию вредоносной программы и выйти. Команда также принимает необязательные четыре байта в качестве аргумента. В случае присутствия этого аргумента, он трактуется как IP-адрес удаленного сервера, на который следует передавать похищенные данные (exfiltration server).
    • Xbnd: принимает четырехбайтовый аргумент – IP-адрес, который используется для операции связывания (bind) клиентского сокета с этим адресом при создании туннельного соединения.

    Авторы Linux/Ebury используют практику встраивания номера версии в бинарный файл вредоносного кода. Это позволяет операторам быть в курсе того, какая версия их вредоносной программы установлена на скомпрометированной системе. С другой стороны, это помогает ресерчерам понять хронологию событий по выпуску версий и правильно отсортировать семплы.

    Например, начиная с версии 1.3.2, Linux/Ebury не будет посылать какую-либо информацию на удаленный сервер, если сетевой интерфейс принятия пакетов находится в режиме «promiscuous». Подобный режим работы интерфейса используется, например, когда инструменты подобные tcpdump захватывают сетевой трафик из сети. Возможно, что авторы вредоносной программы добавили эту возможность в ответ на статью из cPanel о Linux/Ebury, в которой предлагается запускать инструмент tcpdump для отслеживания запросов DNS и фиксировать попытки кражи конфиденциальных данных аккаунтов (индикатор компрометации системы).

    Проверить присутствие в системе бэкдора Linux/Ebury SSH можно двумя способами. Самый простой способ заключается в проверке бинарных файлов SSH на предмет присутствия там вредоносного кода. Более сложный способ заключается в исследовании разделяемых (shared) сегментов памяти, которые используются вредоносной программой.

    Команда ssh –G имеет различное поведение на чистой системе и системе, зараженной Linux/Ebury. На незараженном сервере вывод (в stderr) будет иметь вид:

    ssh: illegal option — G

    На зараженном сервере произойдет вывод сообщения «usage» о правилах использования приложения. Следующая команда может быть использована для обнаружения факта компрометации:

    $ ssh -G 2>&1 | grep -e illegal -e unknown > /dev/null && echo «System clean» || echo «System infected»

    Linux/Ebury полагается на разделяемые сегменты памяти POSIX, которые используются для взаимодействия между процессами (IPC). Текущая версия вредоносной программы использует большие сегменты размером более 3 Мб памяти с широкими правами на доступ к ним, которые позволяют туда писать данные и читать их оттуда (R/W). Другие легитимные процессы также могут создать свои сегменты разделяемой памяти с правами на чтение и запись. При проверке факта присутствия бэкдора с использованием этого способа убедитесь, что сегмент был создан именно процессом sshd (показано ниже).

    Можно обнаружить большой сегмент разделяемой памяти с широкими правами на доступ к нему, запустив следующую команду от root:

    # ipcs -m
    — Shared Memory Segments — key shmid owner perms bytes nattch
    0x00000000 0 root 644 80 2
    0x00000000 32769 root 644 16384 2
    0x00000000 65538 root 644 280 2
    0x000010e0 465272836 root 666 3282312 0
    Для проверки процесса sshd:
    # ps aux | grep root 11531 0.0 0.0 103284 828 pts/0 S+ 16:40 0:00 grep 15029
    root 15029 0.0 0.0 66300 1204? Ss Jan26 0:00 /usr/sbin/sshd

    Видно, что sshd процесс использует разделяемые сегменты памяти, размер которых превышает 3 Мб (3,145,728 байт) с широкими правами на доступ (666). Подобный индикатор свидетельствует о заражении системы.

    Ниже представлены небольшие правила snort для того, чтобы можно было легко определить активность этой вредоносной программы в больших сетях. Первое правило используется для обнаружения поля протокола SSH клиента (SSH Client Protocol), которое используется операторами при подключении к бэкдору. Любой хост, который попытается подключиться к бэкдору по SSH порту, будет обнаружен этим правилом.

    alert tcp $EXTERNAL_NET any -> $HOME_NET $SSH_PORTS (msg:«Linux/Ebury SSH backdoor activty»; content:«SSH-2.0»; isdataat:20,relative; pcre:"/^SSH-2\.0-[0-9a-f]{22,46}/sm"; reference:url,http://www.welivesecurity.com/2014/02/21/an-in-depth-analysis-of-linuxebury/; classtype:trojan-activity; sid:1000001; rev:1;)

    Следующее Snort правило может использоваться для обнаружения зараженного сервера, через который посылаются украденные данные, см. CERT‑Bund.

    alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:«Linux/Ebury SSH backdoor data exfiltration»; content:"|12 0b 01 00 00 01|"; depth:6; pcre:"/^\x12\x0b\x01\x00\x00\x01[\x00]{6}.[a-f0-9]{6,}(([\x01|\x02|\x03]\d{1,3}){4}|\x03::1)\x00\x00\x01/Bs"; reference:url,http://www.welivesecurity.com/2014/02/21/an-in-depth-analysis-of-linuxebury/; reference:url,https://www.cert-bund.de/ebury-faq; classtype:trojan-activity; sid:1000002; rev:1;)

    Заключение

    Вредоносная программа Linux/Ebury, безусловно, представляет из себя сложную угрозу со многими интересными особенностями, такими как, перехват различных функций исполняемого файла, использование обработчиков исключений POSIX и различные методы для маскировки своего присутствия в системе. Основываясь на данных, которые были нами получены, можно констатировать, что, в настоящее время, этим вредоносным кодом заражены тысячи систем. Linux/Ebury распространяется злоумышленниками с использованием украденных учетных данных, которые имелись в наличии у операторов. Имея на руках такие данные отпадает всякая необходимость в использовании каких-либо 0day уязвимостей в ПО или ОС для удаленной установки этой вредоносной программы. Хотя до конца непонятно откуда у злоумышленников оказались первоначальные данные аккаунтов систем, с которых началось первичное заражение.
    ESET NOD32
    0.00
    Company
    Share post

    Comments 11

      –2
      Увлекательно.

      Интересно, а что всё-таки делает добавленный в ssh ключик "-G"?
        0
        Illigal option же, такой ключ не предусмотрен ни в оригинальном ssh, ни в зараженном. Только оригинальная ругается, а зараженная usage выводит.
          0
          Это-то я в тексте статьи видел, да. Но всё же, разбор аргументов командной строки — обычно довольно изолированный код, слабо завязанный на остальную программу. Едва ли такое поведение можно объяснить случайным побочным эффектом от изменений в совершенно другом месте.

          Неужели авторы заражённой версии сделали это изменение просто так и никаких подводных камней за этим ключём нет?
        0
        Исходники предыдущих версий еще нигде не всплывали?
          +6
          А как все-таки зараженная библиотека попадает в систему?
            0
            make install от рута :)
              0
              полагаю, как большинство постороннего кода на серверах: виндовый троян утащил сохраненные пароли из ftp-клиента, или что-нибудь в таком духе.
              –2
              BTW, можно использовать grep -q, вместо перенаправления в /dev/null
                +2
                Опасная тенденция. У меня как-то давно была подобная идея… собирать код из других частей кода...., часть кодировать (как руки Мандрида из фильма ЛЕКС). Такую бяку сложно отловить при проникновении, она мимикрирует под обычную программу, а потом начинает обратать щупальцами, прячась и претворяться мертвой. Но я думаю это всё только цветочки.
                  0
                  Даже не могу себе представить как бы я себя почувствовал увидев «System infected»
                    0
                    вот такой вывод у меня на всех машинах, «скрипт» определяет его как «System clean», но все равно странно, что об этом не написано в статье
                    $ ssh -G
                    ssh: illegal option — G
                    usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
                    [-D [bind_address:]port] [-e escape_char] [-F configfile]
                    [-i identity_file] [-L [bind_address:]port:host:hostport]
                    [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
                    [-R [bind_address:]port:host:hostport] [-S ctl_path]
                    [-w local_tun[:remote_tun]] [user@]hostname [command]


                    CentOS 6, Ubuntu 10.04, Debian 7

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