Всем привет!
Сегодня я хочу поделиться не просто очередным техническим кейсом, а историей, которая, надеюсь, покажет, что для настоящего профессионала нет непреодолимых барьеров, даже если мир вокруг ты воспринимаешь иначе. Мы погрузимся в детали компрометации VDS на Debian 12 через уязвимость WordPress, разберем, как я, будучи незрячим системным администратором, проводил расследование, и какие уроки мы все можем из этого извлечь. Это будет рассказ о технологиях, упорстве и о том, как «читать» систему, когда стандартные визуальные методы недоступны.
Тревожные сигналы: Когда сервер начинает «говорить» на языке проблем
Как это часто бывает, всё началось с автоматики. Системы мониторинга нашего партнерского ЦОД и внешние сервисы вроде AbuseIPDB начали настойчиво сигнализировать: с IP-адреса [CLIENT_IP]
, где крутился VDS клиента на Debian 12, идет какая-то нехорошая активность. Конкретика была следующая:
- “Login Too Frequent (6)”: Сервер слишком часто и безуспешно пытался куда-то залогиниться.
- “Brute-Force Web App Attack”: Сервер был замечен в участии в атаках методом перебора паролей на веб-приложения.
Картина неприятная: сервер клиента, по сути, превратился в «зомби», инструмент в руках злоумышленников. Нужно было срочно вмешаться. Первые попытки подключиться по SSH (клиент предусмотрительно сменил порт на [SSH_PORT]
) были нестабильны – Connection timed out
. Это уже само по себе симптом, который нельзя игнорировать.
Методология расследования: «Читать» систему с помощью NVDA и командной строки
Для меня, как для незрячего сисадмина, работа с сервером – это детальный анализ текстового вывода команд с помощью программы экранного доступа NVDA. Здесь нет места визуальным образам, только логика, опыт и умение интерпретировать данные, которые предоставляет система.
1. Анализ процессов и сетевой активности – В поисках «чужих» среди «своих»
Мой инструментарий здесь стандартен для любого Linux-админа:
ps auxfww
: Детальный анализ вывода этой команды позволяет изучить дерево процессов, пользователей, от имени которых они запущены, и сами команды.htop
(илиtop
): Ориентируюсь на сортировку по CPU/MEM и анализирую строки с аномально высокими показателями.ss -tunapl
(илиnetstat -tunapl
): Тщательный анализ вывода для выявления активных соединений и связанных с ними процессов.
Что же показал анализ вывода ps
? Это был реальный вывод с сервера на момент обнаружения (некоторые данные, не относящиеся к вредоносам, для краткости опущены, PID и время старта могут отличаться от первоначальных из-за перезапусков до полной блокировки):
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.6 167972 12080 ? Ss May18 0:26 /lib/systemd/systemd --system --deserialize=43
... (много системных процессов) ...
www-data 139357 0.0 0.4 97452 7924 ? S [TIME_EXAMPLE] 0:03.29 ./python3.62
... (другие процессы Apache) ...
www-data 194837 0.0 0.2 4432 3428 ? S [TIME_EXAMPLE] 0:00.05 \_ ./python2.64
www-data 194838 14.3 3.7 2253712 69312 ? Sl [TIME_EXAMPLE] 0:07.32 \_ ./python2.64
... (еще процессы Apache и другие системные) ...
Сразу несколько моментов заставили меня насторожиться:
- Запуск из текущего каталога (
./
): Python-скрипты, запущенные отwww-data
с таким путем – это почти всегда плохо. Анализ вывода командls -l /proc/139357/cwd
иls -l /proc/139357/exe
подтвердил, что текущий рабочий каталог – один из подкаталогов сайтаexample.com
, а исполняемый файл находится там же, а не в системных путях. - Подозрительные имена:
python3.62
,python2.64
– явная попытка маскировки под системные интерпретаторы. - Аномальные ресурсы: Процесс с PID
194838
«кушал» 14.3% CPU и 3.7% памяти. Для обычного веб-запроса это слишком много.
Сетевой анализ через ss -tapn | grep 'ESTAB'
выявил более сотни исходящих TCP-соединений от этих Python-процессов на порты 80 и 443 к различным внешним IP. Это было явным свидетельством того, что сервер участвует в какой-то распределенной атаке.
2. Исследование файловой системы – Где притаилась зараза?
После анализа процессов стало ясно, что нужно тщательно «прошерстить» файловую систему. Основное внимание было уделено:
- Стандартным временным каталогам:
/tmp
и/var/tmp
. Это излюбленные места для распаковки и временного хранения вредоносных нагрузок. - Каталогам веб-сайта
example.com
: Особенно тем, куда пользовательwww-data
имеет права на запись (например,wp-content/uploads
, каталоги для кэша и т.д.).
Что нашлось в /tmp
(настоящий зверинец!):
Этот каталог оказался настоящим рассадником. При первичном осмотре с помощью ls -la /tmp
я обнаружил директории, названные явно по типу вредоносов, например, python3.62
и другие, схожие по структуре, содержащие внутри себя различные .py
файлы. Помимо них, присутствовали и другие подозрительные объекты:
- ELF-исполняемые файлы: Часто без расширений. Команда
file [имя_файла]
помогала определить их тип. - Разнообразные Python-скрипты (
.py
): Не только в специализированных папках, но и россыпью. - PHP-скрипты (
.php
): Обнаружены и PHP-скрипты в/tmp
. - Shell-скрипты (
.sh
): Вероятно, для автоматизации загрузки и запуска.
Увидев такую картину в /tmp
, особенно папки, чьи имена совпадали с именами запущенных вредоносных процессов (например, python3.62
), и общее нагромождение явно нелегитимных скриптов, я принял решение не тратить время на детальный анализ каждого отдельного файла в этой “помойке”. Было очевидно, что каталог /tmp
полностью скомпрометирован и используется как плацдарм для вредоносной активности. Приоритетом стала быстрая и полная зачистка этого вектора. Анализ строк (strings
) для выборочных исполняемых файлов перед удалением подтвердил наличие IP-адресов C&C-серверов и характерных для ботнетов ключевых слов, что лишь укрепило решение о немедленной ликвидации всего содержимого /tmp
.
Время создания/модификации этих объектов (stat [имя_файла]
) четко коррелировало с началом зафиксированной аномальной активности сервера.
Что нашлось в каталогах сайта:
Помимо того, что исполняемые ./python3.62
и ./python2.64
были запущены из одного из подкаталогов сайта (что указывало на то, что вредонос не только распаковался в /tmp
, но и смог разместить свои компоненты непосредственно в веб-доступной зоне), был обнаружен и удален подозрительный элемент с именем, содержащим строку “achozobug”. Точную его природу (скрипт, каталог с файлами) без глубокого анализа восстановленных данных определить сложно, но его нетипичное имя и расположение в структуре сайта однозначно указывали на его вредоносность.
Также на этом этапе важно было бы проверить (и это было сделано в рамках общей проверки WordPress после установки Wordfence):
- Наличие других посторонних файлов с расширениями
.php
,.py
,.pl
,.sh
в корне сайта и его подкаталогах, особенно вwp-content/uploads
,wp-content/plugins
,wp-content/themes
. - Даты модификации ключевых файлов WordPress (например,
index.php
,wp-config.php
, файлов активной темы и популярных плагинов) на предмет несанкционированных изменений. Часто злоумышленники внедряют бэкдоры или вредоносный код в существующие легитимные файлы.
3. Анализ логов Apache – Поиск «нулевого пациента»
Логи веб-сервера – это как бортовой самописец. Я использую grep
и awk
для фильтрации и анализа access.log
и error.log
для сайта, размещенного на сервере.
Ключевая находка в access.log
(IP-адреса атакующих реальные, но путь к файлу обезличен):
49.51.47.100 - - [20/May/2025:15:09:15 +0000] "GET /example.com/wp-admin/setup-config.php HTTP/1.1" 200 3874 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"
43.153.79.218 - - [20/May/2025:16:03:26 +0000] "POST /example.com/wp-admin/setup-config.php HTTP/1.1" 200 3939 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0"
Успешные GET и POST запросы к wp-admin/setup-config.php
. Как многие из вас знают, этот файл должен быть недоступен после установки WordPress. Это и была та самая «открытая дверь».
Диагноз: Компрометация через «забытый» файл WordPress – классика жанра
Все улики указывали на одно: злоумышленники воспользовались доступным файлом setup-config.php
, получили возможность выполнить код от имени www-data
, загрузили свои инструменты и превратили сервер в часть ботнета. Логический анализ вывода команд не оставлял в этом сомнений.
Операция “Чистый сервер”: Хирургическое вмешательство
Далее последовали решительные действия:
- Ликвидация вредоносных процессов:
sudo kill -9 139357 194837 194838
(реальные PID с сервера на тот момент). - Стерилизация файловой системы: Полное удаление всего содержимого каталога
/tmp
(sudo rm -rf /tmp/* /tmp/.*
), а также всех обнаруженных вредоносных файлов и каталогов с сайта (включая./python*
скрипты и “achozobug”) с помощьюrm -rf
(конечно, с максимальной осторожностью, перепроверяя пути вне/tmp
). - Проверка на «метастазы» (персистентность):
- Cron: Проверка системных и пользовательских заданий. Чисто.
- Systemd: Анализ сервисов и таймеров. Аномалий не найдено. (Здесь я использую
systemctl list-unit-files
,systemctl list-timers --all
иsystemctl cat [unit_name]
для анализа содержимого юнитов. На тот момент выводsystemctl list-unit-files --type=service --state=enabled
иsystemctl list-timers --all --state=enabled
был таким:# Вывод systemctl list-unit-files --type=service --state=enabled (примерный, только enabled) UNIT FILE STATE PRESET apache2.service enabled enabled apparmor.service enabled enabled console-setup.service enabled enabled cron.service enabled enabled e2scrub_reap.service enabled enabled fail2ban.service enabled enabled getty@.service enabled enabled keyboard-setup.service enabled enabled mariadb.service enabled enabled networking.service enabled enabled systemd-pstore.service enabled enabled systemd-resolved.service enabled enabled systemd-timesyncd.service enabled enabled ssh.service enabled enabled tuned.service enabled enabled ufw.service enabled enabled unattended-upgrades.service enabled enabled # ... и другие стандартные systemd юниты ... # Ничего подозрительного на тот момент не было. # Вывод systemctl list-timers --all --state=enabled (примерный) NEXT LEFT LAST PASSED UNIT ACTIVATES Tue 2025-06-10 21:49:49 CEST 2min 43s left - - systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Tue 2025-06-10 22:09:00 CEST 21min left Tue 2025-06-10 21:39:08 CEST 7min ago phpsessionclean.timer phpsessionclean.service Wed 2025-06-11 00:00:00 CEST 2h 12min left - - dpkg-db-backup.timer dpkg-db-backup.service # ... и другие стандартные таймеры ... # Ничего подозрительного.
- Первая помощь WordPress: Установка и настройка плагина Wordfence. Сканирование подтвердило, что после ручной чистки файлы WordPress чисты.
- Перезагрузка:
sudo reboot
– как контрольный выстрел и для очистки состояния.
Рекомендации “Must-Do”: Уроки, которые я извлек (и вам советую)
Этот инцидент – не просто техническая задача. Для меня это еще одно подтверждение, что даже не имея возможности видеть графический интерфейс или сложные диаграммы, можно эффективно диагностировать и решать проблемы на самом глубоком уровне. Главное – знание системы, логика и умение работать с доступными инструментами, такими как NVDA для взаимодействия с консолью.
И, конечно, универсальные уроки для всех нас, IT-специалистов:
- Парольная гигиена – альфа и омега:
- Немедленная смена ВСЕХ паролей после инцидента:
root
, пользователи ОС, БД, админки, SSH/FTP. - Сложность и уникальность – не обсуждаются. Для SSH – ключи!
- Немедленная смена ВСЕХ паролей после инцидента:
- Безопасность WordPress – это ваша ответственность:
- Аудит и обновление: Удаляйте хлам, обновляйте всё до последних версий из официальных источников.
- Права доступа:
755
(каталоги),644
(файлы),wp-config.php
(400
/440
). define('DISALLOW_FILE_EDIT', true);
вwp-config.php
.- Защита
wp-content/uploads
от PHP. - Удаляйте
wp-admin/install.php
иwp-admin/setup-config.php
! - Используйте Wordfence (или аналог) и настройте его правильно.
- Серверное ПО – всегда свежее:
sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y
. - Файрвол (UFW/nftables) и Fail2Ban – ваши верные стражи.
- Бэкапы – ваш шанс на спасение. Регулярные, автоматические, на внешний ресурс. С проверкой восстановления!
- Логи – это голос вашей системы. Учитесь их анализировать!
Вместо эпилога: Когда ограничения становятся силой
Я часто говорю, что моя работа – это вызов. И такие инциденты это подтверждают. Отсутствие зрения заставляет глубже вникать в суть процессов, полагаться на логику и текстовую информацию, что порой позволяет выявить то, что ускользает от поверхностного взгляда. Я делюсь этим опытом здесь, на loveprod.site, чтобы показать – возможности человека гораздо шире, чем мы привыкли думать.
Надеюсь, этот подробный разбор был для вас полезен. Защищайте свои системы, будьте внимательны к деталям и не бойтесь сложных задач!
Удачи и безопасной работы!