Диспетчер задач показывает 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 Evasion | SSDT, 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).
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 ]
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
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/
Ложноположительные срабатывания chkrootkit
Самое частое -PACKET SNIFFER:
Код:
Checking `sniffer'... br0: PF_PACKET(/sbin/dhclient, 2915, ) PACKET SNIFFER
Bash:
# Проверяем, какой интерфейс в promiscuous mode
ip link show | grep -i promisc
# Смотрим, кто использует PF_PACKET
sudo ss -lp | grep PACKET
bindshell: INFECTED. Проверяется элементарно:
Bash:
# Если chkrootkit жалуется на bindshell - смотрим порт
netstat -tlnp | grep 31337
Volatility и форензика памяти - обнаружение скрытого
Когда руткит перехватил syscalls, подменил таблицы и спрятал свои процессы от ОС, единственный надёжный способ его достать - анализ памяти (memory forensics). Volatility разбирает сырой дамп RAM и восстанавливает структуры данных ядра напрямую, минуя API операционной системы. Руткит может врать ОС, но дамп памяти не врёт.Снятие дампа памяти
Для Windows:
Код:
# WinPmem - рекомендуемый инструмент для дампа
winpmem_mini_x64.exe memdump.raw
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"
Анализ дампа в 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
Поиск вредоносного кода в памяти процессов
Bash:
# malfind - ищет инъецированный код (PAGE_EXECUTE_READWRITE без mapped file)
python3 vol.py -f memdump.raw windows.malfind
Типичный вывод:
Код:
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
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
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
Шаг 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 / ps | pslist vs psscan (Volatility) | Руткит скрывает от ОС |
| Сетевые соединения | netstat / ss | netscan (Volatility) | Скрытые C2-каналы |
| Модули ядра | lsmod / driverquery | modules (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
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.Сравнение инструментов: что, когда и зачем
| Критерий | GMER | rkhunter | chkrootkit | Volatility |
|---|---|---|---|---|
| ОС | Windows | Linux | Linux | Windows/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 показывают одинаковое число процессов - спите спокойно. Если нет - у вас есть чем заняться на выходных.