На проверке Обнаружение руткитов на практике: GMER, chkrootkit, rkhunter и Volatility — методология и инструменты

Обнаружение руткитов с помощью GMER, rkhunter и Volatility


Диспетчер задач показывает 47 процессов, а дамп памяти - 49. Два «лишних» процесса, невидимых для ОС. Причины бывают разные: завершающиеся процессы, системные артефакты, мусор от снятия дампа. Но если расхождение устойчиво и скрытые процессы ведут себя подозрительно - это классика DKOM (Direct Kernel Object Manipulation). Стандартные средства тут бесполезны, и реальное обнаружение руткитов начинается с инструментов, которые смотрят на систему «снаружи».

Четыре инструмента - GMER, rkhunter, chkrootkit и Volatility - не на уровне man-страниц, а на уровне конкретных артефактов: что запускать, какие флаги передавать и как отличить настоящий руткит от ложного срабатывания.

Почему стандартные средства ОС не видят руткиты​

Прежде чем лезть в инструменты, стоит разобраться с фундаментальной проблемой. Когда вы вызываете ps aux на Linux или открываете Task Manager на Windows, ОС обращается к своим внутренним структурам - списку процессов в ядре. Руткит уровня ядра (kernel rootkit, , тактика Defense Evasion; описана для Linux и Windows, хотя автоматизированные тесты Atomic Red Team пока доступны только для Linux) правит именно эти структуры. ОС честно говорит «всё чисто» - потому что из её точки зрения так и есть. Её просто обманули.

Kernel-руткиты - самые опасные: они перехватывают через SSDT hooking (System Service Descriptor Table), подменяют указатели в IDT (Interrupt Descriptor Table) или манипулируют DKOM напрямую.

Ключевой принцип обнаружения - кросс-обзор (cross-view detection). Идея простая как лом: сравниваем то, что видит ОС, с тем, что видит инструмент, работающий на другом уровне. Расхождения - следы руткита.

Маппинг на MITRE ATT&CK​

Руткиты задействуют целый кластер техник, и понимание маппинга критично для threat hunting:

Техника MITRE ATT&CKТактикаКак проявляется
Rootkit (T1014)Defense EvasionСкрытие процессов, файлов, сетевых соединений
Credential API Hooking (T1056.004)Collection, Credential AccessНекоторые руткиты (банковские, например) совмещают скрытие с перехватом API (LogonUser, CredRead) для кражи учёток
Persistence, Privilege Escalation, Defense EvasionSSDT, IDT, inline hooks
Kernel Modules and Extensions (T1547.006)Persistence, Privilege EscalationЗагрузка вредоносных LKM/драйверов
Defense Evasion, Privilege EscalationВнедрение кода в легитимные процессы
Hidden File System (T1564.005)Defense EvasionСкрытые FS для хранения payload
Disable or Modify Tools (T1562.001)Defense EvasionПодавление работы антируткитов

GMER - обнаружение руткитов Windows через анализ ядра​

GMER - бесплатный антируткит для Windows, работающий по принципу кросс-обзора. Важно: последнее обновление - около 2014 года, и на Windows 10/11 с включённым Secure Boot, HVCI или Credential Guard он может устроить BSOD. Для современных Windows лучше взять Windows Defender Offline, YARA-сканирование или Volatility с дампом памяти. А вот для legacy-систем (Windows 7/XP) GMER по-прежнему хорош. Он сканирует SSDT, IDT, таблицу дескрипторов, IRP-хуки драйверов и сравнивает с эталоном. Это не сигнатурный сканер - GMER ищет аномалии в поведении ядра.

Что именно проверяет GMER​

При запуске выполняется несколько категорий проверок:
  • SSDT hooks - модифицированные записи в System Service Descriptor Table. Если вместо адреса ntoskrnl.exe стоит адрес неизвестного драйвера - это hook
  • IDT hooks - перехваты в Interrupt Descriptor Table
  • IRP hooks - перехваты в стеке драйверов (часто используются руткитами типа TDSS)
  • Inline hooks - подмена первых байт функций ядра на JMP к вредоносному коду
  • Hidden processes - процессы, отсутствующие в PsActiveProcessList, но с выделенными ресурсами
  • Hidden services/drivers - зарегистрированные, но невидимые для sc query драйверы

Практика работы с GMER​

Запускаем с правами администратора. При старте GMER автоматически делает быстрое сканирование. Вкладка Rootkit/Malware - сюда смотрим в первую очередь.

Критический момент: GMER нужно запускать до установки антивируса или параллельно. Многие антивирусы сами ставят легитимные хуки ядра, и GMER их покажет как аномалии. Это не ложное срабатывание в привычном смысле - hook реальный, но легитимный. Отличить один от другого можно по адресу: если hook ведёт в модуль известного антивируса - всё нормально.

На что обращать внимание в выводе:
Код:
.text  ntkrnlpa.exe!ZwCallbackReturn + 2C08  804E26C8  5 Bytes  JMP 00643F5A
# Пример с 32-битной Windows XP (PAE). На других версиях адреса и имя ядра будут отличаться (например, ntoskrnl.exe).
Inline hook в ядре - первые 5 байт функции заменены на безусловный переход. Адрес назначения 00643F5A - ключевой: если он не принадлежит ни одному легитимному драйверу (проверяем через вкладку Modules), перед вами артефакт руткита.

Красные строки в GMER - не приговор. Лично я неоднократно видел, как GMER подсвечивал хуки от Kaspersky, ESET и даже от драйверов VirtualBox. Алгоритм простой: красная строка → смотрим адрес → определяем модуль → если модуль легитимный, игнорируем.

rkhunter - проверка системы Linux на руткиты​

rkhunter (Rootkit Hunter) - стандартный инструмент для обнаружения руткитов Linux, работающий по двум принципам: сигнатурная проверка (известные файлы/директории руткитов) и integrity checking (сравнение контрольных сумм системных бинарей с эталоном).

Установка и первичная настройка​

Bash:
sudo apt-get update
sudo apt-get install -y rkhunter
rkhunter --version
Сразу после установки на заведомо чистую систему:
Bash:
# Обновляем базу сигнатур руткитов
sudo rkhunter --update

# Фиксируем текущее состояние бинарей как эталон
sudo rkhunter --propupd
--propupd записывает контрольные суммы системных файлов как baseline. Правило номер один: никогда не запускайте --propupd на потенциально скомпрометированной системе. Зафиксируете модифицированные бинари как «нормальные» - и rkhunter потеряет способность их обнаружить. Считайте, что вы отравили собственный эталон.

Конфигурация для Ubuntu/Debian​

На Ubuntu не редактируйте /etc/rkhunter.conf напрямую - используйте файл переопределений:
Bash:
sudo tee /etc/rkhunter.conf.local << 'EOF'
UPDATE_MIRRORS=1
MIRRORS_MODE=0

# Уведомления на почту
MAIL_CMD=mail -s "[rkhunter] Scan report - $(hostname)"

# Whitelisting известных ложноположительных
ALLOWHIDDENDIR=/dev/.udev
ALLOWHIDDENDIR=/dev/.static
ALLOWHIDDENFILE=/dev/.blkid.tab
ALLOWHIDDENFILE=/dev/.blkid.tab.old

# Знаменитый false positive на Ubuntu
SCRIPTWHITELIST=/usr/bin/lwp-request

ALLOWPROCDELFILE=/lib/udev/udevd
EOF
Отдельно про /usr/bin/lwp-request - Perl-скрипт из пакета libwww-perl. rkhunter на Ubuntu 22.04+ практически всегда на него ругается. Если не добавить в whitelist, каждый отчёт будет содержать это предупреждение, и вы рискуете привыкнуть игнорировать warnings. На IR это прямой путь к пропущенному инциденту.

Запуск и интерпретация результатов​

Bash:
# Полное сканирование (интерактивный режим)
sudo rkhunter --check

# Автоматический режим - только предупреждения
sudo rkhunter --check --skip-keypress --report-warnings-only

# Запуск конкретного теста
sudo rkhunter --check --tests rootkits

# Список всех доступных тестов
sudo rkhunter --list tests
Типичный вывод:
Код:
[ Rootkit checks ]
  Checking for known rootkit files and directories  [ None found ]
  Checking for Suckit rootkit                       [ Not found ]
  Checking for Adore rootkit                        [ Not found ]

[ System checks ]
  Checking hidden files and directories             [ WARNING ]

[ Applications checks ]
  Checking OpenSSL                                  [ WARNING ]
WARNING - не приговор, а сигнал для расследования. Лезем в лог:
Bash:
sudo grep -i warning /var/log/rkhunter.log
Распространённые ложноположительные:
  • /dev/.udev и /dev/.static - легитимные скрытые каталоги в системах с udev
  • Устаревшие версии OpenSSL - rkhunter предупреждает о CVE, но это вопрос патчинга, а не руткита
  • Файлы пакетного менеджера, которые выглядят подозрительно для rkhunter

Обновление базы после apt upgrade​

После каждого обновления пакетов пересчитывайте baseline:
Bash:
sudo apt-get upgrade -y
sudo rkhunter --propupd
Без этого rkhunter будет ругаться на каждый обновлённый бинарь - контрольная сумма-то изменилась. И реальное предупреждение потеряется в потоке шума.

chkrootkit - быстрый сканер для Linux​

chkrootkit хорош как второй инструмент в связке с rkhunter - они используют разные методы, и совместная работа увеличивает покрытие. chkrootkit проверяет сигнатуры известных руткитов, ищет подозрительную активность LKM (Loadable Kernel Modules, техника T1547.006), обнаруживает сетевые снифферы и аномалии в cron.

Установка и запуск​

Bash:
sudo apt-get install -y chkrootkit

# Полная проверка
sudo chkrootkit

# Тихий режим - только обнаружения
sudo chkrootkit -q

# Проверка конкретной категории
sudo chkrootkit lkm       # LKM-руткиты
sudo chkrootkit sniffer   # сетевые снифферы

# Офлайн-анализ смонтированной файловой системы
sudo chkrootkit -r /mnt/suspect-system/
Последняя команда - находка для incident response: подключаете диск подозрительной системы к чистой forensics-машине и сканируете его, не загружая скомпрометированную ОС. Никакого доверия к бинарям на подозрительном диске.

Ложноположительные срабатывания chkrootkit​

Самое частое - PACKET SNIFFER:
Код:
Checking `sniffer'... br0: PF_PACKET(/sbin/dhclient, 2915, ) PACKET SNIFFER
В 99% случаев это DHCP-клиент или мониторинг, которые легитимно используют raw sockets. Верификация:
Bash:
# Проверяем, какой интерфейс в promiscuous mode
ip link show | grep -i promisc

# Смотрим, кто использует PF_PACKET
sudo ss -lp | grep PACKET
Второй классический false positive - bindshell: INFECTED. Проверяется элементарно:
Bash:
# Если chkrootkit жалуется на bindshell - смотрим порт
netstat -tlnp | grep 31337
Если на порту 31337 (или другом указанном) ничего не слушает - ложное срабатывание. Если сомнения остались - грузитесь с Live CD и повторяйте проверку из чистого окружения.

Volatility и форензика памяти - обнаружение скрытого

Когда руткит перехватил syscalls, подменил таблицы и спрятал свои процессы от ОС, единственный надёжный способ его достать - анализ памяти (memory forensics). Volatility разбирает сырой дамп RAM и восстанавливает структуры данных ядра напрямую, минуя API операционной системы. Руткит может врать ОС, но дамп памяти не врёт.

Снятие дампа памяти​

Для Windows:
Код:
# WinPmem - рекомендуемый инструмент для дампа
winpmem_mini_x64.exe memdump.raw
Для Linux:
Bash:
# LiME (Linux Memory Extractor)
# LiME нужно предварительно скомпилировать под ядро целевой системы:
# git clone https://github.com/504ensicsLabs/LiME && cd LiME/src && make
# Записывайте дамп на внешний носитель, не на диск скомпрометированной системы:
sudo insmod lime.ko "path=/mnt/usb/memdump.lime format=lime"
Дамп снимаем до перезагрузки - руткиты памяти (memory rootkits) исчезают при рестарте, но оставляют артефакты в RAM-дампе, снятом вовремя. Перезагрузились - потеряли улики.

Анализ дампа в Volatility 3​

Volatility 3 - актуальная версия с переработанной архитектурой. Основные команды для обнаружения руткитов в памяти:
Bash:
# Определяем профиль ОС
python3 vol.py -f memdump.raw windows.info

# Список процессов (аналог ps через API)
python3 vol.py -f memdump.raw windows.pslist

# Cross-view: сканирование пулов памяти
python3 vol.py -f memdump.raw windows.psscan

# В Volatility 3 плагин psxview отсутствует.
# Для кросс-обзора сравните вывод pslist и psscan вручную или скриптом:
python3 vol.py -f memdump.raw windows.pslist > pslist.txt
python3 vol.py -f memdump.raw windows.psscan > psscan.txt
# diff pslist.txt psscan.txt

Ключевой приём: pslist vs psscan vs psxview​

Здесь кроется суть кросс-обзорного обнаружения:
  • pslist обходит двусвязный список PsActiveProcessList в ядре - именно его правит DKOM-руткит, удаляя свой процесс из цепочки
  • psscan сканирует всю физическую память, ищет структуры _EPROCESS по сигнатуре пула (Proc). Найдёт процесс, даже если тот вырезан из списка
  • psxview (только Volatility 2) объединяет несколько методов и показывает расхождения. В Volatility 3 аналогичный результат - ручное сравнение windows.pslist и windows.psscan
Процесс виден в psscan, но отсутствует в pslist? Классический артефакт DKOM-руткита. Именно так ловились руткиты семейства Necurs и TDSS - они прятали свои драйверы, удаляя записи из ядерных списков, но физическую память-то не затирали.

Поиск вредоносного кода в памяти процессов​

Bash:
# malfind - ищет инъецированный код (PAGE_EXECUTE_READWRITE без mapped file)
python3 vol.py -f memdump.raw windows.malfind
malfind ищет регионы памяти с правами на исполнение, не имеющие соответствующего файла на диске. Прямой индикатор техники Process Injection (T1055) - код записан в адресное пространство процесса динамически.

Типичный вывод:
Код:
Process: svchost.exe  PID: 1284
  VAD: 0x7f0000 - 0x7f1000  Protection: PAGE_EXECUTE_READWRITE
  Flags: CommitCharge
  Hexdump:
    4d 5a 90 00 03 00 00 00  MZ......
Видите MZ (PE-заголовок) внутри памяти svchost.exe без mapped файла? Это внедрённая DLL. Руткит (или его компонент) загрузил исполняемый код прямо в память легитимного процесса. svchost.exe - излюбленная мишень, потому что его экземпляров в системе десятки, и лишний не бросается в глаза.

Анализ SSDT hooks через Volatility​

Bash:
# Проверка модификаций SSDT
python3 vol.py -f memdump.raw windows.ssdt
Нормальная запись SSDT указывает на функции в ntoskrnl.exe или win32k.sys. Адрес, принадлежащий неизвестному модулю - перехват (Hijack Execution Flow, T1574). Прямая модификация SSDT актуальна преимущественно для 32-битных систем и Windows до Vista SP1; на 64-битных Windows 7+ Kernel Patch Protection (PatchGuard) защищает SSDT, и современные руткиты используют другие методы: callback-объекты, filter drivers, hypervisor-based подходы. Для определения модуля-владельца каждого адреса сопоставляйте вывод windows.ssdt с диапазонами из windows.modules. Записи, указывающие не на ntoskrnl.exe и не на win32k.sys, требуют расследования.

Анализ загруженных модулей ядра​

Bash:
# Список драйверов/модулей ядра
python3 vol.py -f memdump.raw windows.modules

# Для Linux-дампов
python3 vol.py -f memdump.lime linux.lsmod
Ищем модули без цифровой подписи, с подозрительными именами или загруженные из нестандартных путей. Руткит, использующий технику Kernel Modules and Extensions (T1547.006), будет виден здесь как загруженный модуль - даже если lsmod на живой системе его не показывает.

Методология обнаружения руткитов: пошаговый алгоритм​

Одиночный инструмент полной картины не даст. Ниже - алгоритм, который я использую при incident response, когда есть подозрение на руткит.

Шаг 1. Сбор volatile-данных (до перезагрузки)​

Работаем с доверенными инструментами, запущенными с USB-накопителя. Бинари на скомпрометированной системе могут быть подменены - доверять им нельзя.
Bash:
# Снимаем дамп памяти
# Windows: winpmem / Linux: LiME

# Фиксируем сетевые соединения
netstat -anob > connections.txt       # Windows
ss -tunap > connections.txt           # Linux

# Список процессов
tasklist /v > processes.txt           # Windows
ps auxf > processes.txt               # Linux

# Загруженные модули ядра
lsmod > modules.txt                   # Linux
driverquery /v > drivers.txt          # Windows

Шаг 2. Живое сканирование (на подозрительной системе)​

Bash:
# Windows
# Запуск GMER - анализ хуков, скрытых процессов, драйверов

# Linux
sudo rkhunter --check --skip-keypress --report-warnings-only
sudo chkrootkit -q
Запускаем оба Linux-сканера - они дополняют друг друга. rkhunter лучше работает с integrity checking, chkrootkit - с сигнатурным обнаружением LKM-руткитов.

Шаг 3. Офлайн-анализ дампа памяти​

Bash:
# Кросс-обзорный анализ процессов (psxview недоступен в Vol3, сравниваем вручную)
python3 vol.py -f memdump.raw windows.pslist
python3 vol.py -f memdump.raw windows.psscan

# Поиск инъекций
python3 vol.py -f memdump.raw windows.malfind

# Анализ SSDT
python3 vol.py -f memdump.raw windows.ssdt

# Сетевые соединения из памяти
python3 vol.py -f memdump.raw windows.netscan

Шаг 4. Сравнение результатов​

Что сравниваемИнструмент 1Инструмент 2Расхождение = подозрение
Число процессовpslist (Volatility)psscan (Volatility)Скрытые процессы (DKOM)
Процессы ОС vs дампTask Manager / pspslist vs psscan (Volatility)Руткит скрывает от ОС
Сетевые соединенияnetstat / ssnetscan (Volatility)Скрытые C2-каналы
Модули ядраlsmod / driverquerymodules (Volatility)Скрытые драйверы

Автоматизация сканирования и интеграция в IR-процесс​

Для серверов с непрерывным контролем - rkhunter и chkrootkit в одном скрипте с почтовыми уведомлениями:
Bash:
#!/bin/bash
# rootkit-scan.sh - ежедневный скан с отчётом
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')
EMAIL="security@company.local"
RKHUNTER_LOG="/var/log/rkhunter.log"
CHKROOTKIT_LOG="/var/log/chkrootkit.log"

echo "=== Rootkit Scan: $HOSTNAME - $DATE ===" > /tmp/scan_report.txt

# rkhunter
sudo rkhunter --check --skip-keypress --logfile "$RKHUNTER_LOG" 2>&1
RKHUNTER_WARNINGS=$(grep -ci '^Warning:' "$RKHUNTER_LOG" 2>/dev/null || echo 0)
echo "rkhunter warnings: $RKHUNTER_WARNINGS" >> /tmp/scan_report.txt
grep -i '^Warning:' "$RKHUNTER_LOG" >> /tmp/scan_report.txt 2>/dev/null

# chkrootkit
sudo chkrootkit -q 2>&1 | tee "$CHKROOTKIT_LOG" >> /tmp/scan_report.txt
INFECTED=$(grep -c "INFECTED" "$CHKROOTKIT_LOG" 2>/dev/null || echo 0)
echo "chkrootkit infected: $INFECTED" >> /tmp/scan_report.txt

# Отправляем отчёт
if [ "$RKHUNTER_WARNINGS" -gt 0 ] || [ "$INFECTED" -gt 0 ]; then
    SUBJECT="[ALERT] Rootkit warnings on $HOSTNAME"
else
    SUBJECT="[OK] Rootkit scan clean - $HOSTNAME"
fi

mail -s "$SUBJECT" "$EMAIL" < /tmp/scan_report.txt
rm -f /tmp/scan_report.txt
Активация через cron:
Bash:
sudo chmod +x /usr/local/bin/rootkit-scan.sh
echo "0 4 * * * root /usr/local/bin/rootkit-scan.sh" | sudo tee /etc/cron.d/rootkit-scan
Напомню: после каждого apt upgrade запускайте sudo rkhunter --propupd, чтобы обновить baseline. Без этого следующий скан выдаст десятки ложных warnings на обновлённые бинари, и реальное предупреждение утонет в шуме. На одном проекте мы именно так чуть не пропустили подменённый ss - потому что весь отчёт был забит предупреждениями после обновления glibc.

Сравнение инструментов: что, когда и зачем​

КритерийGMERrkhunterchkrootkitVolatility
ОСWindowsLinuxLinuxWindows/Linux/macOS
Тип анализаКросс-обзор ядраСигнатуры + integrityСигнатуры + LKMФорензика памяти
Kernel rootkitsДаЧастичноЧастичноДа
Userland rootkitsЧастичноДаДаДа
Нужен дамп памятиНетНетНетДа
Офлайн-анализНетНетДа (-r флаг)Да
ЛожноположительныеСреднеВысокоСреднеНизко
Сложность интерпретацииСредняяНизкаяНизкаяВысокая

Ни один инструмент не самодостаточен. GMER и chkrootkit/rkhunter работают на живой системе и зависят от её состояния - если руткит перехватил достаточно низкоуровневые функции, он обманет и антируткит. Volatility анализирует «снимок» памяти и после снятия дампа его не обмануть - но для работы с ним нужны навыки форензики и чистая forensics-станция.

Оптимальная комбинация: живое сканирование GMER (Windows) или rkhunter + chkrootkit (Linux) для быстрой оценки, затем дамп памяти и Volatility для подтверждения. Этот подход закрывает и обнаружение руткитов на уровне пользователя, и kernel-level угрозы, которые прячутся от стандартных средств ОС.

Снимите дамп памяти с любого своего сервера и прогоните через windows.psscan / linux.pslist. Если pslist и psscan показывают одинаковое число процессов - спите спокойно. Если нет - у вас есть чем заняться на выходных.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab