Детективная история взлома одного коммерческого хостинга с наказанием и рекомендациями

Ко мне поступил сервер с Linux CentOS 5.3 64bit, выполняющий роль коммерческого хостинга сайтов (WHM/cPanel), который был взломан и взломщики не потрудились вытереть за собой все инструменты, которые они использовали.
Проанализировав их, я смог составить цепочку событий, которая привела к взлому сервера и компрометации рутовой учетной записи.
Никаких логов небыло, так как они все были почищены, так что взломщик не оставил за собой следов, и я начал поистине детективное расследование — с уликами и подозреваемыми.

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

После этого, используя найденную уязвимость, в /tmp заливается Remote Backdoor Shell — perl скрипт, открывающий доступ к командной строке сервера, работающий с правами вебсервера, в данном случае — nobody.
Через этот скрипт в /tmp были установлены

  • набор взломщика (см. ниже)
  • червь для автоматизации работы со сканерами RFI ботнета, само ищет сайты на Joomla 1.x, пытается взломать через них сервер и залить весь этот комплект, автоматически скачивает эксплойты с Milw0rm и пытается их применить(!) в публичном доступе мной не найден
  • модифицированный сканер RFI, который исключает из проверки уже взломанные сайты, обмениваясь информацией по IRC с такими же скриптами ботнета, за основу взят FeeLCoMz RFI Scanner Bot
  • скрипт для выполнения приказов типа scan, ddos и тд, простой, в публичном доступе мной не найден
  • модифицированный Jheefry RFI Scanner Bot

Все скрипты написана на Perl и управляются через IRC на порту 6667, взломанный сервер заходит под случайным логином в
специальный канал на хаккерском IRC сервере, который в свою очередь так-же устанавливается скриптами на один из взломанных серверов.

Теперь о том, что включает в себя набор взломщика, который скрипты ботнета заливают автоматически:

  • psybnc скрипты
  • бинарный файл irc севера собранный статически и переименованный в httpd (!)
  • бинарный файл proc неизвестного назначения, собран статически, и служит скорее всего для запуска irc сервера в контексте httpd (!)
  • скрипт run: ./proc «/usr/local/apache/bin/httpd -DSSL» httpd JaM5, выполняющий подключение irc сервера в контексте httpd (!!!)
  • бинарник неизвестного формата с названием xh, вероятно эксплойт, не рабочий, выполняющий подключение irc сервера в контексте httpd для FreeBSD

Итак, на сервере взломщики получили доступ к запуску файлов от имени вебсервера, но как же я определил, что они получили там доступ к root?

Когда я в профилактических целях остановил вебсервер httpd, то в процессах оставался висеть один httpd процесс. Как это возможно?
На самом деле это был perl скрипт, который маскировался под /usr/bin/httpd, тем самым себя выдав, так как httpd запускался из /usr/local/apache/bin/httpd. Он использовал маскировку под procname, где procname — имя процесса:


$rm=»rm -rf»;
qx ($rm $0);
$0 =
$procname. ««;

Но самое интересное было не это, а то, что файл с правами nobody находился в /var/lib/mysql, куда может писать только
пользователь mysql! И я решил проверить подозреваемого целостность пакета mysql-server:
#rpm -V MySQL-server
.M5…T /usr/sbin/mysqld
M — означало смену прав, 5 — содержимого (сравнение по MD5 хешу), T — времени. Само собой понятно, что был взломан именно mysql, тем более, что shell у пользователя mysql установлен в /bin/bash, чего быть не должно.

Итак, взломщик при помощи сканов уязвимостей ядра нашел лазейку в ядре, после чего использовал эксплойт для получения консоли с правом root и запустил руткит для mysqld, который при старте запускает бекдор, маскирующийся под процесс /usr/sbin/httpd!

Наказание за небрежное администрирование сервера, точнее — за его полным отсутствием, по причине желания экономии
на сисамдине заказчиком — форматирование и переустановка ОС, восстановление из резервных копий.
Ввыоды:

  • perl под nobody — зло, suexec рулит
  • исходящие коннекты с сервера —зло, но порой необходимое, а вот прикрыть irc порт никогда не помешает
  • каждый скрипт должен работать от своего владельца, а не от nobody, fastcgi рулит
  • надо своевременно обновлять ядро — отсутствие известных уазвимостей в публичном доступе еще не означает их отсутствие в ядре
  • если смонтировать разделы, доступные пользователю на запись с noexec — любой эксплойт будет отдыхать

P.S. По ссылке — увлекательная история с ботнетом и infobox.ru.

UPD. Про perl, апач, nobody и suexec:
Все дело в том, что как правило скрипты на Perl запускают с правами владельцев через suexec. И это хорошо, так как в случае проблем будут видны права владельца, через которого закачали бэкдор.
Но если права на запуск Perl доступны для всех, то его можно запустить через функцию exec () PHP. А PHP работает у большинства хостеров от nobody.
Таким образом разрешение запуска Perl от nobody — зло, так как непонятно через какого пользователя заливают бекдор.

UPD2 — ЧАВО

  • Уязвимость с ld.so, которая позволяла запустить бинарник с раздела, смонтированного noexec — уже давно закрыта.
  • Для хаккера все равно какой ID будет в шелле — юзерский или апача. А сисадмину — это важно знать, так как будет видно какой пользователь имеет уязвимый сайт, просто сделав ps axuwf. Именно по этому php-fastcgi предпочительней mod_php
  • Исходящие коннекты нужны для многих вещей — RPC-Ping»ов, Яндекс.Маркета, бирж ссылок, именно по этому невозможно закрыть все исходящие коннекты