LinkPro Linux Rootkit
Недавняя компрометация среды Amazon Web Services (AWS) выявила ранее недокументированный руткит GNU/Linux, известный как LinkPro. Этот бэкдор примечателен двойным использованием модулей eBPF: один предназначен для сокрытия артефактов, а другой действует как скрытый триггер — «стук», активирующий функцию удалённого управления только после получения специально сформированного TCP-пакета. Цепочка атаки и механизмы руткита демонстрируют искусного оператора, сочетающего злоупотребление контейнером, сокрытие на уровне ядра и гибкую активацию сети, чтобы помешать обнаружению и криминалистической корреляции.
Оглавление
Вектор заражения и первоначальное распространение
Атака началась с эксплуатации уязвимого экземпляра Jenkins, уязвимого к CVE‑2024‑23897 (CVSS 9.8). С этого места злоумышленники внедрили вредоносный образ Docker (kvlnt/vv, впоследствии удалённый из Docker Hub) в несколько кластеров Kubernetes. Образ использовал базу Kali Linux и содержал небольшую папку приложения, предназначенную для обеспечения персистентности, удалённого доступа и поэтапной загрузки бэкдора.
Внутри вредоносного образа Docker
Папка приложения образа содержала три ключевых файла с различными ролями:
start.sh — скрипт оболочки, который запускает службу SSH и выполняет два других компонента.
link — программа с открытым исходным кодом (VNT), скомпилированная/упакованная для работы в качестве VPN/прокси-клиента, обеспечивающая исходящее подключение к vnt.wherewego[.]top:29872. Это позволяет злоумышленнику получить доступ к скомпрометированному хосту из любой точки мира и через него переключиться на другие цели.
app — загрузчик на основе Rust (называемый vGet), который извлекает зашифрованную полезную нагрузку vShell из контейнера S3, а затем устанавливает соединение WebSocket со своим сервером управления и контроля (C2) по адресу 56.155.98[.]37.
Дополнительные полезные данные доставлены на узлы Kubernetes
Наряду с вредоносным изображением операторы также загрузили на узлы два других компонента: дроппер, устанавливающий ещё один бэкдор vShell, и LinkPro, руткит, написанный на Golang. LinkPro работает в одном из двух режимов — пассивном (обратном) или активном (прямом) — в зависимости от конфигурации. В пассивном режиме он ожидает активации специальным сетевым пакетом; в активном режиме он сам инициирует соединение с C2. Прямой режим поддерживает пять транспортных протоколов (HTTP, WebSocket, UDP, TCP, DNS), тогда как обратный режим ограничивает взаимодействие протоколом HTTP.
Как LinkPro сохраняется
Общее поведение вредоносной программы, ее выполнение и сохранение следуют четкой последовательности:
- Установите модуль Hide eBPF. Этот модуль включает программы Tracepoint и Kretprobe eBPF, используемые для сокрытия процессов и сетевой активности LinkPro.
- Если установка модуля Hide eBPF не удалась или он был отключен, установите общую библиотеку в /etc/libld.so и добавьте этот путь в /etc/ld.so.preload в качестве резервного механизма скрытия.
- Для обратного (пассивного) режима работы установите модуль Knock eBPF. Knock содержит программу XDP и программу TC, поэтому канал C2 активируется только после получения определённого «магического пакета».
- Обеспечьте постоянство, создав службу systemd.
- Выполнять команды, полученные от C2.
- При завершении работы или при получении сигнала (SIGHUP, SIGINT, SIGTERM) удалите модули eBPF и удалите/восстановите предварительную загрузку модификации /etc/libld.so, чтобы система вернулась в предыдущее состояние.
Волшебный пакет и механизм активации стуком
Пассивная активация LinkPro зависит от точного TCP-пакета: любой TCP-пакет с размером окна 54321 рассматривается как «магический пакет». Когда Knock обнаруживает такой пакет, он сохраняет IP-адрес источника и помечает его тегом с истечением срока действия в один час. Последующие TCP-пакеты из этого источника отслеживаются, и при необходимости Knock переписывает заголовки, чтобы трафик оператора перенаправлялся на прослушиваемый порт LinkPro (2333). Исходящие пакеты корректируются так, чтобы исходный порт отображался в сети (порт источника заменяется на 2233). Цель проста, но эффективна: позволить злоумышленнику получить доступ к LinkPro через любой порт, разрешенный внешним межсетевым экраном, одновременно затрудняя корреляцию внешних журналов межсетевого экрана с активностью внутри сети хоста.
Как LinkPro скрывает себя
LinkPro использует двухуровневую стратегию маскировки:
Скрытие ядра/eBPF : модуль Hide eBPF устанавливает программы Tracepoint и Kretprobe, которые перехватывают системные вызовы, такие как getdents (для скрытия файлов/каталогов) и sys_bpf (для скрытия собственных программ BPF). Для этого подхода требуется ядро, собранное с включённым параметром CONFIG_BPF_KPROBE_OVERRIDE.
Резервная версия LD_PRELOAD в пользовательском пространстве : если поддержка ядра отсутствует, LinkPro создаёт общую библиотеку (libld.so) и помещает путь к ней в /etc/ld.so.preload. Поскольку /etc/ld.so.preload приводит к загрузке указанной библиотеки в каждый динамически скомпонованный процесс (использующий /lib/ld-linux.so и glibc), имплантированная библиотека libld.so перехватывает функции libc на ранней стадии (до того, как начнет действовать сама glibc) и изменяет возвраты из вызовов libc, чтобы скрыть артефакты, которые в противном случае выявили бы её присутствие.
Возможности руткита и набор команд
LinkPro поддерживает как интерактивные, так и автоматизированные удалённые действия. Реализованные функции включают:
- Запуск псевдотерминала /bin/bash и запуск интерактивных сеансов оболочки.
- Выполнение произвольных команд оболочки.
- Перечисление файлов и каталогов и выполнение файловых операций.
- Загрузка и запись файлов на диск.
- Создание прокси-туннеля SOCKS5 для поворота и проксирования вне сети.
Поддержка сетевых протоколов и поведение C2
В активном (прямом) режиме LinkPro гибок: он может взаимодействовать по протоколам HTTP, WebSocket, UDP, TCP или DNS. В пассивном (обратном) режиме его взаимодействие ограничено протоколом HTTP, но он скрыт, поскольку прослушивает только после того, как магический пакет Knock открывает временное командное окно длительностью один час.
Поведение очистки и удаления
Если процесс получает сигналы завершения, LinkPro стремится удалить следы: он удаляет установленные модули eBPF и удаляет или восстанавливает файл /etc/libld, группируя его в предыдущее состояние, чтобы система выглядела неизменной. Эта преднамеренная процедура очистки указывает на то, что оператор заботится об уклонении от контроля и минимизации долгосрочных криминалистических следов.
Операционный контекст и атрибуция
В кампании использовался высокоуровневый эксплойт Jenkins, вредоносные образы контейнеров, несколько вариантов бэкдора и скрытность на уровне ядра — сочетание, указывающее на мотивированного и компетентного оператора. Точная информация об авторстве не опубликована; однако набор инструментов и очевидное использование взлома для проксирования и постоянного удалённого доступа убедительно свидетельствуют о финансовой мотивации (переключение, проксирование для дополнительных вторжений или перепродажа доступа).
Зависимость от ядра и аварийное поведение
Поскольку LinkPro использует функции переопределения BPF kprobe для скрытого перехвата ядра, он применяет технику сокрытия на уровне ядра только тогда, когда ядро хоста предоставляет CONFIG_BPF_KPROBE_OVERRIDE. Если эта возможность ядра отсутствует, LinkPro намеренно прибегает к методу разделяемой библиотеки LD_PRELOAD, чтобы скрыть себя в пользовательском пространстве, обеспечивая маскировку в широком диапазоне сред.
Заключительное замечание
LinkPro демонстрирует, как современные атаки могут сочетать компрометацию контейнера, промежуточные загрузчики, инструментирование ядра (eBPF) и хитрые сетевые трюки (активацию «магических пакетов» и перезапись портов) для обеспечения скрытности и гибкости. Обнаружение и устранение требуют тщательной проверки на наличие неавторизованных программ eBPF, неожиданных записей в /etc/ld.so.preload, необычных служб systemd и сетевых подключений к указанной инфраструктуре (криминалистическими индикаторами являются IP-адрес 56.155.98[.]37, порты 29872, 2333, 2233 и имя удалённого образа Docker kvlnt/vv).