Постмортем: компрометация VPS, контейнерный майнер и ложная уверенность в «знакомых IP»
Я пишу этот постмортем как человек, который прошел этот инцидент руками: от первого подозрения по нагрузке до разбора артефактов и проверки гипотез на живом хосте.
Это детальный разбор инцидента на sirius-nql: от первого входа до форензики, гипотез, верификации и выводов. Текст ориентирован на публикацию в Telegraph, но его же можно использовать как внутренний IR-документ.
Executive Summary
Когда я впервые открыл метрики и процессы, это выглядело как типичный «шум на VPS». Но довольно быстро стало понятно: это не шум, а полноценный инцидент.
На сервере был подтвержден security-инцидент:
- получен root-доступ по SSH (парольная аутентификация),
- зафиксированы многочисленные успешные root-сессии,
- внутри контейнера
docs_llm_frontendзапущен криптомайнер и watchdog, - найден валидный конфиг майнинга с пул-инфраструктурой,
- обнаружены PakChoi-like артефакты закрепления внутри контейнера.
Критичный нюанс расследования: часть IP из логов относится к VPN/провайдерской инфраструктуре команды. Это не отменяет компрометацию, но меняет модель атрибуции: опираться нужно на действия и артефакты, а не только на IP.
Контекст и исходные условия
Сервис и среда
- Хост:
sirius-nql.play2go.cloud - ОС: Ubuntu 24.04 LTS
- Контейнерный рантайм: Docker
- Скомпрометированный контейнер:
docs_llm_frontend
Операционный контекст команды
Часть действий, которые в логах могут выглядеть «подозрительно» (пакетные установки, подготовка runtime, изменения docker-окружения), выполнялась штатно в рамках нашего пайплайна AI-агента.
В расследовании эти действия вынесены в отдельную категорию как легитимные, чтобы не смешивать их с подтвержденной вредоносной активностью.
Затронутые компоненты (из инцидент-репорта)
- Хостовая система Linux (root-доступ).
- Контейнерный контур приложения (Next.js frontend + связанные сервисы).
- Секреты, доступные root-пользователю в shell history.
Риск-конфигурация доступа
Это означает прямую поверхность атаки для root SSH brute-force / credential stuffing.
Scope расследования
Я сознательно шел от принципа: сначала сохранить доказательства, потом делать любые разрушительные действия.
- Исторические логи из выгрузок (
server_logs_export,nginx_logs,docker.log,all_raw,all_containers). - Live-forensics на хосте:
- процессы, дерево процессов,
/proc, сеть, docker inspect,docker diff, контейнерные артефакты,- копирование бинарников и конфигов, хэширование.
- Проверка гипотез о host-level persistence.
- Перепроверка атрибуции после уточнения trusted/VPN IP команды.
Главные находки
Ниже — то, что я смог подтвердить фактически, а не предположить.
1) Подтвержденная компрометация root-доступа
В логах зафиксированы успешные входы root по паролю.
Подтвержденные IP с успешными root-входами:
Агрегированно по Accepted password for root:
2) Подтвержден запуск вредоноса внутри контейнера
Активные процессы во время live-сбора:
containerd-shim -> sh -c "npm install && npm run dev -- -H 0.0.0.0 -p 3000" -> {майнер, watchdog}
Наблюдаемая нагрузка (из инцидент-репорта)
- CPU: до ~392% суммарно (многопоточный майнинг).
- RAM: около ~2.4 GB RSS у процесса майнера.
- Эффект: устойчивый рост load average до ручного вмешательства.
3) Подтвержден рабочий майнинг-конфиг
4) Подтвержденные IOC-хэши
aa0c6cdbeb3bc3ce07d5060958e1a38e54287bc89e25f6def98b620999ff4f7a— майнер7d6032764df8e706c458e663e5501ce627e4f2985c16ea61e299f2ac429cbcc9— watchdogeada4bb685c53f0a5b7aa0dad5aa4d31aebba94af8b84f40f2802e828a87f304— конфиг
Дополнительная находка: риск компрометации API-токенов
В shell history были обнаружены переменные вида ANTHROPIC_* и использование стороннего base URL (aiprimetech.io).
Это трактуется как потенциальная компрометация секретов и требует обязательной ротации/отзыва.
5) PakChoi-like stage внутри контейнера
В docs_llm_frontend обнаружено:
pakchoi:x:0:0::/home/pakchoi:/bin/bash/etc/systemd/system/sys-health.service/etc/systemd/system/sys-health.timer- refs на
docker start amco_ee51c4e6 - изменения в
/etc/group,/etc/shadow,/home/pakchoi/.bashrc
6) Host-level persistence именно этим stage не подтверждена
Практический смысл: контейнерный stage есть, но его host-персистентность в текущем виде, вероятно, не работала.
Подробный таймлайн (UTC)
Ниже — ключевые точки, которые я сверил по логам и live-артефактам.
Фаза A: первичный доступ и ранняя активность
2026-04-25 04:00:15— первый подтвержденныйAccepted password for root(45.83.140.194).2026-04-25 04:02:21—Accepted password for root(95.32.25.170).2026-04-25 04:03:59— root выполняетapt update(подтверждено как легитимное действие команды).2026-04-25 04:04:14— root выполняетapt install unzip(подтверждено как легитимное действие команды).2026-04-25 04:04:59— root выполняетbash -(подтверждено как легитимное действие команды).2026-04-25 04:05:08— root выполняетapt install -y nodejs(подтверждено как легитимное действие команды).2026-04-25 04:10:52— создается группаdocker(подтверждено как легитимное действие команды).
Комментарий: эти команды изначально рассматривались как потенциально подозрительные из-за близости по времени к компрометации, но после уточнения команды помечены как штатные админ-действия, связанные с пайплайном AI-агента, и исключены из IOC-логики.
Фаза B: дополнительные успешные root-сессии
2026-04-25 05:11:04— успешный вход (45.83.140.194).2026-04-25 05:13:05— успешный вход (45.83.140.194).2026-04-25 05:19:29— успешный вход (144.31.203.175).2026-04-25 07:00:01— успешный вход (45.83.140.194).2026-04-25 10:10:30— успешный вход (45.83.140.194).
Фаза C: автоматизированная волна root-логинов
2026-04-25 10:47:51— старт серии root-сессий с194.87.220.163(помечено как активность пайплайна AI-агента команды).2026-04-25 10:47:51–11:43:51— частые короткие сессии (accept/disconnect паттерн) (помечено как активность пайплайна AI-агента команды).- Всего в этой волне — 78 успешных
Accepted password for root(помечено как активность пайплайна AI-агента команды).
Комментарий: с учетом уточнений команды этот блок в таймлайне отмечен как автоматизированная активность вашего AI-пайплайна и не используется как самостоятельный индикатор злонамеренной сессии без дополнительных артефактов.
Фаза D: контейнерная активность
2026-04-25 11:23:02— creationdocs_llm_frontend.2026-04-25 11:23:14— container start.2026-04-25 11:23:20–11:23:23—npm install+ запускnext devв логах контейнера.
Комментарий: это штатный рантайм контейнера, но позже он становится хостом для вредоносных процессов.
Фаза E: запуск майнера
2026-04-25 14:49:59— старт watchdog/rjtg0pT.2026-04-25 14:50:08— старт майнера/RKiQ2aLh -c /kBiR -B.- Далее — стабильная высокая CPU-нагрузка и пул-коннекты.
Ключевой момент, который я отдельно перепроверял: запуск вредоноса происходит заметно позже npm install и после окна компрометации root-активности.
Проверка версий и оценка уверенности
Гипотеза 1: «Это не инцидент, просто шум»
Гипотеза 2: «Это npm supply-chain в момент install»
- Вердикт: не основная версия.
- Почему: таймлайн не сходится (install в
11:23, вредонос стартует14:50).
Гипотеза 3: «PakChoi-like stage присутствует»
- Вердикт: подтверждено внутри контейнера.
- Почему:
pakchoi,sys-health.*,amco_*refs, системные правки в container FS.
Гипотеза 4: «Host-level persistence через эти файлы активна»
- Вердикт: не подтверждено.
- Почему: нет host артефактов, нет docker.sock в контейнере, PID1 не systemd.
Гипотеза 5: «По IP можно точно назвать атакующего»
- Вердикт: некорректно (после уточнения trusted/VPN IP).
- Почему: IP может быть shared egress, VPN, proxy или компрометированный endpoint.
Trusted/VPN IP и как это правильно трактовать
Команда подтвердила, что часть IP в логах — потенциально легитимные адреса их инфраструктуры.
Это меняет не факт инцидента, а модель атрибуции:
- Нельзя: «IP = злоумышленник».
- Нужно: «Есть подтвержденные вредоносные действия, источник сессий требует отдельной identity/endpoint-проверки».
То есть фокус переносится с «кто по IP» на «кто по учетке/устройству/сессии».
Для меня это был важный разворот в расследовании: сначала казалось, что IP даст однозначный ответ, но в реальности именно поведение и артефакты дали устойчивую картину.
Root Cause Analysis
Техническая первопричина
Открытый root SSH по паролю на интернет-периметре.
Усиливающие факторы
- нет строгого источникового контроля SSH,
- недостаточная brute-force защита,
- недостаточно раннее обнаружение аномалий,
- присутствие чувствительных данных в shell history.
Impact
Подтверждено
- компрометация root-доступа,
- выполнение несанкционированных действий,
- запуск майнинга и расход вычислительных ресурсов,
- потенциальная компрометация секретов, доступных root-пользователю.
Не подтверждено в текущем scope
- устойчивое host-level закрепление через найденный контейнерный stage,
- точная личная атрибуция субъекта по одному IP.
- подтвержденная массовая эксфильтрация данных (в текущей выборке нет явных индикаторов).
Что отдельно проверяли и не нашли
- host-level
authorized_keys-бэкдор для root; - явную persistence через host cron в собранных срезах;
- новых локальных пользователей на хосте, связанных с контейнерным
pakchoistage.
Важно: «не найдено в текущем scope» не равно «гарантированно отсутствует».
Что уже сделано правильно
- сняты live-артефакты до агрессивной зачистки,
- бинарники/конфиги выгружены и хэшированы,
- выполнена декомпозиция «контейнер vs хост»,
- гипотезы разделены по степени доказанности.
План ремедиации
Немедленно (P0)
- Выключить root password SSH:
- Перевести доступ на SSH-ключи + allowlist.
- Ротировать все секреты/токены.
- Удалить скомпрометированный контейнер и пересобрать из trusted source.
- Блокировать egress к IOC-пулам.
Краткосрочно (P1)
- Проверить endpoints участников команды на stealer/credential theft.
- Провести аудит VPN/SSH сессий и ротацию учетных данных.
- Включить fail2ban/аналог и защиту от brute-force.
- Поднять алерты на root-login spikes, high CPU, suspicious egress.
Среднесрочно (P2)
- Убрать shared-root практики.
- Ввести персонализированный админ-доступ с audit trail.
- Исключить dev-runtime режимы в production.
- Подготовить золотой образ и регламент быстрого rebuild.
Главные уроки
- «Знакомый IP» — это контекст, не гарантия легитимности.
- Компрометацию нужно доказывать поведением и артефактами.
- Root SSH по паролю в интернет — это не «если», а «когда».
- Контейнерная изоляция может ограничить ущерб, но не отменяет инцидент.
Финальный вывод
Инцидент подтвержден: вредоносная майнинг-нагрузка была развернута и запускалась на скомпрометированной инфраструктуре.
Уточнение по trusted/VPN IP делает расследование сложнее в части атрибуции, но не меняет технический факт компрометации.
Корректная итоговая формулировка:
- компрометация подтверждена по действиям и артефактам;
- атрибуция по субъекту требует дополнительной identity/endpoint проверки.
Благодарность
Отдельное спасибо за помощь в разборе: https://t.me/Anon1379