MAATRIX / Блог / Три признака майнера, которые видно без антивируса

Три признака майнера, которые видно без антивируса

MAATRIX

Ставить антивирус на linux-сервер ради разовой проверки — оверкилл: пока вы разбираетесь, какой из сканеров ставить и откуда тянуть свежие базы сигнатур, майнер может уже неделями гнать хеши на чужой пул за ваш счёт. На практике для первичной диагностики хватает трёх признаков и трёх встроенных в любой дистрибутив утилит — top, ss, ps. Ниже — как проверить каждый признак и что именно в выводе команды отличает майнер от обычной, пусть и высокой, нагрузки.

Признак первый: CPU держится на максимуме без перерыва

Майнинг — это перебор хешей без остановки: чем больше вычислений в единицу времени, тем больше заработок, поэтому майнинг-процессу незачем делать паузы. В отличие от веб-сервера или API, у которых нагрузка почти всегда пилообразная — пики в рабочие часы, спад ночью, всплески под конкретные задачи, — майнер грузит одно или несколько ядер ровно и непрерывно, сутками, независимо от времени суток и внешнего трафика.

Первая проверка — общий уровень нагрузки:

uptime

Смотрите на load average за 1, 5 и 15 минут. Если все три числа стабильно держатся на уровне числа ядер сервера или выше и не откатываются вниз при обычном для вас трафике — это уже нетипичная картина для большинства нагрузок, у которых есть периоды затишья.

Дальше — кто конкретно ест CPU:

top

или, если установлен:

htop

Ищите процесс, у которого %CPU держится близко к 100% (или кратно 100%, если майнер многопоточный) на всём протяжении времени, что вы смотрите на экран, а не всплесками. Без интерактивного режима, удобно для логов и разбора постфактум:

ps aux --sort=-%cpu | head -20

Отдельно стоит взглянуть на распределение по ядрам — некоторые версии майнеров намеренно не занимают ядро полностью, а держатся на 60-80%, чтобы не бросаться в глаза при беглом взгляде на общий %CPU:

mpstat -P ALL 1 5

Команда выведет загрузку каждого ядра по отдельности за пять интервалов в секунду. Если одно или несколько ядер стабильно заняты, а остальные простаивают, и это не совпадает с тем, как обычно распределяется нагрузка ваших сервисов — стоит копать дальше.

Важная оговорка: сама по себе высокая загрузка CPU не доказывает, что перед вами майнер, — это может быть плохо оптимизированный или зависший в цикле легитимный процесс. Майнинг отличает именно сочетание непрерывности во времени (нагрузка не спадает часами и днями, а не только в моменты, когда вы смотрите в top) и несовпадения с вашими собственными сервисами по имени процесса и по PID.

Признак второй: сервер держит соединение с чужим пулом

Майнер не работает в одиночку — он получает задания от пула (какой блок данных хешировать) и отправляет найденные решения обратно, поэтому обязан держать сетевое соединение наружу. Это второй, независимый от CPU признак, который либо подтверждает первый, либо ставит его под сомнение.

Смотрим установленные исходящие соединения с привязкой к процессу:

sudo ss -tnp state established

Если ss недоступна (на старых системах), похожий вывод даёт:

netstat -tnp

В выводе интересны соединения, у которых:

  • удалённый IP не относится ни к одному из ваших сервисов — не ваша база данных, не CDN, не платёжный шлюз, не внешний API, которым вы реально пользуетесь;
  • соединение держится подолгу, а не открывается и закрывается разово, как обычный HTTP-запрос — протоколы майнинга (в первую очередь Stratum, на котором работает большинство пулов) построены на постоянной сессии: клиент подключается один раз и дальше обменивается короткими сообщениями о заданиях и найденных решениях, не переоткрывая соединение заново;
  • при обрыве соединение восстанавливается почти сразу — это поведение клиента, который запрограммирован держать связь с пулом, а не разового скрипта, который просто сходил и отвалился.

Отдельно стоит сказать про порты: конкретный номер порта здесь ненадёжный маркер. Пулы принимают подключения на разных портах, типичных для протокола Stratum, но завязываться на «майнинг всегда сидит на порте X» не стоит — вы либо пропустите нестандартный порт, либо будете гоняться за числом, которое в следующей версии малвари просто поменяют. Гораздо надёжнее сочетание «долгоживущее исходящее соединение на незнакомый адрес» плюс «процесс, который держит это соединение, мне не знаком» плюс «у того же PID высокая загрузка CPU из первого пункта».

Чтобы связать соединение с конкретным процессом, если ss не показала PID без прав root:

sudo lsof -i -P -n | grep ESTABLISHED

lsof выведет имя процесса, PID и адрес назначения в одной строке — удобно сверять с тем, что вы уже нашли по CPU на предыдущем шаге.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Признак третий: процесс прячет своё настоящее лицо

Третий признак — сам процесс. Авторы майнеров редко называют бинарник прямо — гораздо чаще имя копирует что-то системное: kworker, systemd-worker, .cache, иногда даже с квадратными скобками, как у настоящих потоков ядра. На взгляд из ps aux это может выглядеть совершенно обыденно.

Отличить самозванца от настоящего процесса ядра можно по происхождению. У настоящих ядерных потоков (kworker, kswapd0, ksoftirqd и подобных) всегда:

  • PPID (родительский процесс) равен 2 — это kthreadd;
  • нет исполняемого файла на диске — они существуют только в пространстве ядра и не запускаются из обычного бинарника.

Проверка PPID:

ps -ef | grep <PID>

Восьмая колонка в выводе — PPID. Если у процесса с «ядерным» именем PPID не 2, а что-то другое — это уже несостыковка, достойная внимания.

Проверка исполняемого файла:

ls -la /proc/<PID>/exe

У настоящего потока ядра эта команда вернёт ошибку доступа — читать нечего, файла нет. А вот у процесса-самозванца она покажет реальный путь к бинарнику, и здесь обычно всё проясняется: временные каталоги вроде /tmp, /dev/shm, /var/tmp, скрытые директории с точкой в начале имени — места, доступные на запись любому пользователю, куда ничего системного класть не принято. Легитимные системные бинарники живут в /usr/bin, /usr/sbin, /bin, /usr/lib.

Отдельный приём маскировки — удалить файл с диска сразу после запуска, оставив процесс работать из памяти. В этом случае ls -la /proc/<PID>/exe покажет путь с пометкой (deleted) в конце строки. Сам факт, что процесс работает от файла, которого больше нет на диске, — почти однозначный маркер: легитимные сервисы так не поступают.

Ещё один источник информации — реальная команда запуска:

cat /proc/<PID>/cmdline
cat /proc/<PID>/status

cmdline покажет, с какими аргументами процесс был запущен, — если она совсем не похожа на то, что должно быть у процесса с таким именем, или содержит явно посторонние флаги, сомнений становится меньше.

Наконец, если процесс периодически меняет имя — сейчас в top он один, через десять минут уже другой, — это тоже способ маскировки. Отследить его можно, только повторив ps/top через некоторое время и сравнив: PID у процесса не меняется, даже если отображаемое имя стало другим.

Как проверить все три признака за один заход

Если вы разбираете конкретный подозрительный сервер, а не читаете теорию, удобнее пройти все три пункта подряд, не переключаясь между вкладками. Примерная последовательность для SSH-сессии:

# 1. Общая загрузка и топ процессов по CPU
uptime
ps aux --sort=-%cpu | head -15

# 2. Загрузка по ядрам за несколько секунд
mpstat -P ALL 1 5

# 3. Установленные исходящие соединения
sudo ss -tnp state established

# 4. Для каждого подозрительного PID — происхождение и бинарник
ps -ef | grep <PID>
ls -la /proc/<PID>/exe
cat /proc/<PID>/cmdline

Если по итогам на руках один и тот же PID, который одновременно: держит CPU без пауз, имеет долгоживущее соединение на незнакомый внешний адрес и запущен из подозрительного пути или с уже удалённого с диска бинарника — совпадение всех трёх признаков на одном процессе снимает почти все сомнения. Отдельно взятый признак ещё можно списать на случайность (нагруженный легитимный сервис, ваш собственный VPN-туннель, процесс с непривычным, но объяснимым именем), но втроём вместе они у легитимной нагрузки практически не встречаются.

Более широкий разбор признаков заражения и сценариев проникновения, не ограниченный этими тремя пунктами, — в статье как проверить сервер на майнер и вирусы. А если стандартные ps и top вообще не показывают ничего подозрительного, но загрузка при этом не сходится с суммой процессов — вероятно, задействован руткит, подменяющий вывод утилит, и здесь нужен более глубокий разбор — см. скрытые процессы на сервере: как найти.

Что делать, если признаки подтвердились

Три признака выше — это диагностика, не лечение. Если вы нашли процесс, который бьёт по всем трём пунктам, воздержитесь от одного соблазна — просто kill -9 <PID> и забыть. Это не сработает: у майнеров почти всегда есть автозапуск через cron или systemd, а нередко и сторожевой процесс, который поднимает основной заново за секунды после убийства. К тому же сам факт постороннего процесса означает, что у кого-то было выполнение произвольных команд на вашем сервере, — а значит, потенциально скомпрометированы не только CPU-циклы, но и пароли из конфигов, ключи доступа, содержимое баз данных.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Может ли майнер сидеть тихо, а высокая загрузка CPU быть ни при чём?

Да, некоторые версии намеренно ограничивают себя долей CPU, чтобы не выделяться на графике нагрузки. В этом случае первый признак смазан, и решающими становятся второй и третий — сетевое соединение и происхождение процесса.

Что если ss или netstat не показывают ничего подозрительного?

Возможно, инструмент запущен не под root и не видит чужие сокеты, соединение недолгое, либо в системе установлен руткит, подделывающий вывод сетевых утилит. Тогда стоит свериться напрямую с /proc/net/tcp и посмотреть, совпадает ли количество записей там с тем, что показывает ss.

Отсутствие всех трёх признаков гарантирует, что сервер чист?

Нет. Это признаки для быстрой ручной проверки без специализированного ПО, а не полноценный аудит безопасности. Если есть отдельные основания подозревать компрометацию — аномалия в счётчике трафика хостинга, подозрительные записи во входах по SSH — стоит провести более глубокую проверку, вплоть до анализа с загрузочного live-образа.

Почему нельзя просто ориентироваться на конкретные порты пулов?

Потому что порт — это настройка на стороне пула и клиента, а не фиксированный стандарт: разные пулы принимают подключения на разных портах, и вредонос легко меняет порт от версии к версии. Устойчивый признак — не число порта, а поведение соединения: долгая сессия, автоматическое переподключение, привязка к процессу, который не относится к вашим сервисам.

Стоит ли вообще ставить антивирус на сервер, если эти признаки и так работают?

Специализированный сканер полезен как второй слой проверки, особенно против уже известных сигнатур, но требует установки, регулярного обновления баз и не ловит всё — свежие или сильно замаскированные версии он может пропустить. Ручная проверка по трём признакам не заменяет полноценный аудит, но занимает несколько минут и не требует ничего, кроме SSH-доступа.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →