Процессор виртуальной машины загружен на 75 %, top ничего не показывает, а в cron чужой скрипт: признаки заражения майнером и почему сервер переустанавливают

Что было. Сервер держит 75 % загрузки процессора круглосуточно. Облачный монитор безопасности сообщает о майнере. top при этом не показывает тяжёлых процессов. Автор нашёл в cron записи, которые скачивают и запускают скрипт с внешнего адреса, а htop показал несколько процессов с именем, имитирующим системный поток ядра, по 100 % каждый. Проверка rkhunter показала, что top, netstat, ps и ещё несколько утилит заменены.

Что это значит. Классическая цепочка: вход через слабое место (в обсуждении предположили Redis без пароля на публичном порту или подобранный пароль), закрепление через cron, загрузчик, майнер, и руткит уровня библиотек (/etc/ld.so.preload) или подменённые бинарники, которые скрывают процессы от top и ps. Поэтому «top ничего не показывает» само по себе улика.

Как проверить, не доверяя системным утилитам.

  • cat /etc/ld.so.preload (файла обычно быть не должно); ls -la /proc | wc -l против числа процессов в ps; ls /proc/*/exe -l 2>/dev/null | grep -v '/usr'.
  • Загрузка с другой машины статических бинарников (busybox) или запуск sysdig/unhide, которые читают /proc напрямую.
  • Cron всех пользователей: for u in $(cut -d: -f1 /etc/passwd); do crontab -l -u $u 2>/dev/null; done, плюс /etc/cron.*, /var/spool/cron, systemd-таймеры (systemctl list-timers --all).
  • Новые ключи в ~/.ssh/authorized_keys у всех пользователей, новые пользователи в /etc/passwd, сетевые соединения (ss -ntup) к неизвестным адресам на портах пулов.
  • Неизменяемые файлы: lsattr /etc/cron* /usr/bin/* | grep -- '----i': вредоносное ПО часто ставит атрибут i, чтобы его нельзя было удалить.

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

Как не повторить.

  • Базы и кэши (Redis, MongoDB, Elasticsearch) только на localhost или во внутренней сети и с паролем; проверить ss -ltnp на всё, что слушает 0.0.0.0.
  • SSH по ключам, PermitRootLogin no, fail2ban.
  • Обновления безопасности автоматически.
  • Мониторинг загрузки процессора с оповещением: майнер выдаёт себя за минуты.
  • Минимум панелей и агентов с веб-интерфейсами наружу.

Базовые меры описаны в документации Ubuntu Server.