Linux - популярная операционная система для серверов и облачных инфраструктур, поэтому неудивительно, что она привлекает интерес угроз, и мы видим постоянный рост и инновации вредоносного ПО, нацеленного на Linux, как, например, недавняя вредоносная программа Symbiote, обнаруженная исследовательской группой Intezer.
OrBit
OrBit получил название в соответствии с одним из имен файлов, используемых вредоносной программой для временного хранения результатов выполненных команд. Он может быть установлен либо с возможностью персистенции, либо как имплант. Вредоносная программа реализует передовые техники уклонения и добивается устойчивости на машине, подключая ключевые функции, предоставляет субъектам угроз возможности удаленного доступа по SSH, собирает учетные данные и регистрирует команды TTY. После установки вредоносная программа заражает все запущенные процессы, включая новые, которые выполняются на машине.
В отличие от других угроз, которые перехватывают общие библиотеки путем изменения переменной окружения LD_PRELOAD, эта вредоносная программа использует два различных способа загрузки вредоносной библиотеки. Первый способ заключается в добавлении разделяемого объекта в конфигурационный файл, который используется загрузчиком. Второй способ заключается в исправлении двоичного файла самого загрузчика, чтобы он загружал вредоносный разделяемый объект.
Дроппер устанавливает полезную нагрузку и подготавливает среду для выполнения вредоносной программы. Вредоносная программа может быть установлена как модуль или с возможностью сохранения. Она получает аргументы командной строки и на их основе извлекает полезную нагрузку в одно из мест. С помощью аргументов командной строки можно изменить путь установки и обновить содержимое полезной нагрузки или полностью удалить ее. (Далее "MALWARE_FOLDER" для обозначения места, куда была установлена вредоносная программа.)
Для установки полезной нагрузки и добавления ее в общие библиотеки, загружаемые динамическим компоновщиком, дроппер вызывает функцию patch_ld. Сначала она считывает символическую ссылку динамического компоновщика /lib64/ld-linux-x86-64.so.2 и проверяет, не загружена ли уже вредоносная полезная нагрузка, ища путь, используемый вредоносной программой. Если он найден, функция может поменять его местами с другим расположением. В противном случае она ищет /etc/ld.so.preload и заменяет его символической ссылкой на расположение вредоносной библиотеки: /lib/libntpVnQE6mk/.l или /dev/shm/ldx/.l (в зависимости от аргумента, переданного дропперу). Наконец, он добавит /etc/ld.so.preload в конец временного файла, чтобы убедиться, что вредоносная библиотека будет загружена первой.
Перед загрузкой вредоносной библиотеки в динамический компоновщик дроппер обязательно сохраняет копию легитимного динамического компоновщика в MALWARE_FOLDER/.backup_ld.so, чтобы в случае необходимости можно было восстановить окружение и использовать легитимные данные для сокрытия вредоносной программы (подробнее об этом в следующем разделе).
Подготовка среды достигается путем установки уникального группового идентификатора (GID) на путь, используемый вредоносной программой. В проанализированном нами примере это значение равно 0xE0B2E, этот же GID будет использоваться и полезной нагрузкой. Кроме того, дроппер копирует python (из /usr/bin/python) в папку
MALWARE_FOLDER и создает 4 дополнительных файла, которые будут использоваться вредоносной программой:
- /lib/libntpVnQE6mk/.logpam
- /lib/lib/libntpVnQE6mk/sshpass.txt
- /lib/libntpVnQE6mk/sshpass2.txt
- /lib/libntpVnQE6mk/.ports
Полезная нагрузка представляет собой разделяемый объект (файл .SO), который может быть размещен либо в постоянном хранилище, например, /lib/libntpVnQE6mk/, либо в shim-памяти под /dev/shm/ldx/. Если он помещен в первый путь, то вредоносная программа будет персистентной, в противном случае - волатильной.
Общий объект подключает функции из 3 библиотек: libc, libcap и Pluggable Authentication Module (PAM). Существующие процессы, использующие эти функции, по сути, будут использовать модифицированные функции, а новые процессы также будут подключаться к вредоносной библиотеке, что позволит вредоносной программе заразить всю машину, собрать учетные данные, обойти обнаружение, получить персистентность и предоставить удаленный доступ злоумышленникам.
При реализации перехвата функций libc сначала вызывается syscall с соответствующим номером системного вызова, как показано на скриншоте ниже. Строки обфусцируются простым XOR с жестко заданным ключом.
SSH-соединение
Одной из возможностей вредоносной программы является установка удаленного соединения на машине. Для этого она подключает 3 функции библиотеки Pluggable Authentication Module: pam_open_session, pam_authenticate и pam_acct_mgmt. Подключив эти функции, вредоносная программа способна похищать информацию из SSH-соединений, предоставлять удаленный доступ злоумышленникам и скрывать сетевую активность.
При вызове подключаемой функции pam_authenticate проверяется, равны ли имя пользователя и пароль жестко заданным значениям, и если это так, то в файл /lib/libntpVnQE6mk/.ports записывается порт, используемый для соединения, и открывается SSH-соединение. В других случаях он проверит, есть ли в файле /lib/lib/libntpVnQE6mk/.logpam и если да, то запишет учетные данные в файл /lib/libntpVnQE6mk/sshpass.txt. По сути, первый файл служит флагом.
Методы уклонения от обнаружения OrBit
Для уклонения от обнаружения вредоносная программа блокирует множество функций, чтобы они не выводили информацию, которая может показать существование вредоносной разделяемой библиотеки в запущенных процессах или файлах, используемых вредоносной программой. Вредоносная программа использует жестко закодированное значение GID (заданное дроппером) для идентификации файлов и процессов, связанных с вредоносной программой, и на основе этого манипулирует поведением подключенных функций. Например, функция readdir проверяет GID вызывающего процесса, и если он не соответствует жестко закодированному значению, все каталоги с заданным значением GID будут пропущены из вывода функции.
Вредоносная программа подключает функции, открывающие файлы: fopen, open, open64 и openat, и проверяет, является ли файл, переданный соответствующей функции open, частью файловой системы proc. Одним из проверяемых путей является /proc/net/tcp, поскольку он может раскрыть сетевой трафик, генерируемый бэкдором. Способ, которым вредоносная программа обрабатывает вывод этого файла, аналогичен другим открываемым файлам и напоминает реализацию в Symbiote. Функция hooked считывает содержимое файла и сравнивает его по одной строке с содержимым файла MALWARE_FOLDER/.ports, в котором хранится информация о портах и адресах, используемых вредоносной программой. Вредоносная программа создает временный файл и записывает в него только те строки, которые не раскрывают вредоносную программу. После завершения работы над файлом вредоносная программа возвращает дескриптор файла временного файла вызывающей стороне.
Следующие пути к файлам показывают текущие отображенные области памяти и их разрешения доступа:
- /proc/%PID%/maps
- /proc/%PID%/smaps
- /proc/%PID%/numa_maps
Когда процесс обращается к одному из этих файлов, он может раскрыть разделяемую библиотеку, поэтому функции hooked open проверяют, не содержит ли вывод путь к директории, используемой вредоносным ПО, аналогично описанному выше.
Еще один проверяемый файл в файловой системе proc - /proc/loadavg. Этот файл используется такими утилитами, как uptime, он предоставляет информацию об использовании процессора и состоянии запущенных процессов. Вредоносная программа будет обрабатывать информацию из этого файла аналогично предыдущим файлам.
Вредоносная программа подключает execve, чтобы обойти обнаружение некоторых утилит, контролировать поведение процессов и поддерживать свою устойчивость путем заражения новых процессов. Логика хука проверяет имя и путь процесса и сравнивает их с различными узулитами в /bin, /usr и /sbin.
Функция execve используется вредоносной программой для скрытия сетевой активности. Вредоносная программа проверяет, является ли новый процесс ip или утилитой iptables (проверяется как /usr/sbin, так и /sbin). Сначала она выполнит команду и передаст вывод в локальный буфер, где проверит записи и проверит, есть ли совпадение между записями и информацией, хранящейся в MALWARE_FOLDER/.net или MALWARE_FOLDER/.fw - запись будет пропущена из вывода команды.
Когда execve вызывается с dmesg, вредоносная программа опускает записи, равные записям в MALWARE_FOLDER/.sys/.dmesg, и записи, содержащие одно из следующих ключевых слов: zapping, tcpdump, promiscuous, libntpVnQE6mk, libdl.so.
execve проверяет, была ли функция вызвана с переменной окружения LD_TRACE_LOADED_OBJECTS, когда эта переменная установлена, вызывает программу для перечисления ее
динамические зависимости. Вредоносная программа сохраняет оригинальный (непропатченный) динамический компоновщик в резервном файле, поэтому при вызове execve с этой переменной вывод будет таким, как если бы был вызван легитимный динамический компоновщик, и в нем не будет перечислена вредоносная библиотека. По сути, выполняется следующая команда:
MALWARE_FOLDER/.backup_ld --list %s
Strace - это еще одна утилита, которую исследует подключенный execve. Поскольку вывод strace может выявить вредоносную библиотеку как одну из библиотек, загружаемых отслеживаемым процессом. Strace может выполняться с флагом -o, указывающим путь к файлу, в который будет передан вывод, если он не задан в команде, вредоносная программа запишет вывод strace в /tmp/.orbit. Подобно другим утилитам, вредоносная программа выполняет команду и получает результат из выходного файла. Далее он опускает записи, содержащие в симлинке одно из следующих значений: вредоносная библиотека (MALWARE_FOLDER/.l), GID, который используется вредоносной программой (920366), и путь к ее папке.
Достижение стойкости
Вредоносная программа использует два метода для достижения стойкости. Оба метода используются для того, чтобы затруднить удаление вредоносной программы с зараженной машины во время ее работы. Первый метод заключается в добавлении пути к вредоносной программе в конфигурационный файл /etc/ld.so.preload. Это инструктирует загрузчик, что вредоносная программа должна быть загружена первой и для всех новых процессов. В случае, если этот метод предотвращается, например, удалением конфигурационного файла на зараженной машине, вредоносная программа использует второй метод, который достигается путем внесения исправлений в двоичный файл загрузчика.
Сначала вредоносная программа делает копию двоичного файла загрузчика, чтобы иметь возможность установить на него патч. Она выполняет простой поиск строки "/etc/ld.so.preload" в двоичном файле. Когда строка найдена, она заменяет ее на путь к файлу в %MALWARE_FOLDER%. Содержимое этого файла содержит путь к библиотеке вредоносного ПО, которая будет действовать как файл конфигурации ld.so.preload. Это означает, что при выполнении загрузчика патча он использует файл в %MALWARE_FOLDER% вместо файла "/etc". Автор вредоносной программы предусмотрел эти два метода в качестве подстраховки на случай, если один из них исчезнет. Например, если администратор захочет остановить загрузку вредоносной программы, удалив конфигурационный файл в каталоге "/etc", чтобы скрытые файлы были открыты, то пропатченный загрузчик, не использующий этот файл, просто загрузит вредоносную программу, которая заново создаст конфигурационный файл. Если администратор вместо этого перезапишет исправленный загрузчик чистой версией, чистый загрузчик загрузит вредоносное ПО из конфигурационного файла "ld.so.preload", который перепатчит загрузчик.
Кража информации
Бэкдор подключает функции чтения и записи для регистрации данных, которые записываются выполняемыми процессами на машине. Бэкдор проверяет флаг: sniff_ssh_session, который определяет, будет ли регистрироваться любой вызов записи или только процессы, выполняемые с помощью sudo или ssh сессий. Оказывается, что функциональность флага не отражает реальный поток функции записи - когда флаг установлен в false, функция hooked проверяет, был ли процесс выполнен с помощью sudo или если вызывающий процесс является ssh, и записывает буфер, который был передан исходной функции записи, данные хранятся по адресу: MALWARE_FOLDER/sshpass2.txt. В противном случае, если флаг установлен в true, буфер записывается в MALWARE_FOLDER/sniff.txt без проверки имени вызывающего процесса. После завершения работы подключенной функции она вернет возвращаемое значение исходного вызова функции.
Для процессов bash и sh, вызывающих execve, будет регистрировать аргумент path, содержащий путь к файлу, который будет выполняться как новый процесс, функция hooked добавит временную метку и полный путь и запишет информацию в MALWARE_FOLDER/execlog.
Сетевые возможности
Бэкдор использует функции из библиотеки libpcap для скрытия сетевой активности. Если функции hooks bind и connect регистрируют порты, которые используются процессами с gid малвари, то порты записываются в MALWARE_FOLDER/.ports. Содержимое этого файла используется бэкдором для управления портами, которые используются в сессиях, открытых в результате деятельности бэкдора. При создании новой SSH-сессии в файл записывается порт и IP-адрес.
Вредоносная программа подключает функции pcap_loop и pcap_packet_callback, чтобы отфильтровать трафик бэкдора. Для выполнения этой задачи функция pcap_packet_callback опускает порты, находящиеся в файле MALWARE_FOLDER/.ports, поскольку он содержит все порты, используемые бэкдором.
Indicators of Compromise
SHA256
- f1612924814ac73339f777b48b0de28b716d606e142d4d3f4308ec648e3f56c8
- 40b5127c8cf9d6bec4dbeb61ba766a95c7b2d0cafafcb82ede5a3a679a3e3020