Cgi сканнер: от и до.


Добре =).
Что будем делать? Разбираться.

Немного теории.

Для запроса какого-либо документа с сервера надо сначала установить с ним connect по 80 порту (по умолчанию). Затем послать запрос содержащий имя нужного нам скрипта, и обработать ответ. Как выглядит запрос. Каждый запрос, как и ответ сервера, состоит из трех частей: самой строки запроса (ответа), раздела заголовка и тела. Вот пример запроса default.htm:

GET /default.htm HTTP/1.0
User-Agent: Oslik_IE (WinBug)
Accept: */*

Итак первая строка состоит из команды HTTP (метода) GET которая запрашивается документ default.htm, и указывает версию протокола HTTP с которым может работать. Далее идет заголовок, который может содержать различную инфу о клиенте, хосте, типе коннекта и т.д. Тела здесь нет. Завершается заголовок пусто строкой. Теперь сервер отвечает:
в первой строке (строке состояния) содержится три поля: версия HTTP, код состояния и описание. Код состояния - это трехразрядное число, говорящее нам о результате обработки сервером запроса.

НТТР/1.0 200 OK

После строки состояния сервер дает нам инфу заголовка, которая содержит данные о сервере и о запрашиваемом документе. Завершает заголовок пустая строка.

Date: Fri, 13 Jan 2002 14:07:36 GMT
Server: Apache/1.3.20 (Unix) PHP/4.0.5
Last-modified: Mon, 10 Jan 2002 08:43:25 GMT
Content-type: text/html
Content-length: 1745

Ну а дальше он передает то, что ты просил - документ или результат выполнения скрипта. Если же такого дока нет или скрипт сглючил, то передаются данные, которые разъяснют что не так.

Походу с теорией все.

Итак. Как работает CGI-сканнер? Все просто до безумия. Мы соединяемся с сервером и спрашиваем есть ли на нем нужное нам файло. Делаем мы это с помощью метода HTTP - HEAD, который аналогичен GET, только сервер ничего не передает в информационной части ответа, т.к. метод запрашивает только информацию заголовка о файле или ресурсе. Нам передавать собственный заголовок нет нужды. Поэтому строка будет выглядеть так:

HEAD /somedir/file.ext HTTP/1.0

В конце надо передавать две пустые строки. Это сигнализирует серверу, что запрос окончен. После запроса мы должны обработать ответ сервера. Который нам и скажет - есть или нет. Основные для обработки коды ответа: 200 - Все пучком, 404 - нет тут такого (если хочешь знать больше, то читай соответствующую инфу). Значит нам надо всего лишь тестить ответ сервака на наличие в нем цифры 200 и радостно орать если такой найдется.

Привожу пример на перле.

use IO::Socket;
$c=@ARGV;
if ($c cmp '2')
{
print 'usage: cgiscan.pl <host> <cgifile> ';
exit;
}
$host=@ARGV[0];
$file=@ARGV[1];
$port=80;
open(CGI,$file) || die("Error: file not fouund!\n");
while ($string =<CGI>)
{
$socket=IO::Socket::INET->new(PeerAddr=>$host, PeerPort => $port,Proto => "TCP") || die("Vo mlya, ne mogy\n");
$string=substr($string,0,length($string)-1);
print $socket "HEAD $string HTTP/1.0\n\n";
@buffer=<$socket>;
$reply=@buffer[0];
if ($reply =~/200/)
{
print "$string Found!\n";
}
}
close(CGI);

Вот собственно и все. Сканнер готов. Здесь мы только использовали положительный код ответа сервера - 200. Т.е. что документ (скрипт) есть и доступен. Но есть еще и 403 - Forbidden, по которому можно судить о том что док (скрипт, дирректория) есть, но вот доступа к нему нету. Советую почитать инфу об HTTP протоколу. Там много интересного 8)...

Я думаю вам не составит труда переделать этот код на Delphi. Я юзал перл, потому что проще и кода меньше, как раз для статьи. Для гуру перла сообщаю - я не кодер на перле, поэтому кое-что можно было сделать и проще, но я не гуру, поэтому как есть...
Если что-то не понятно и есть вопросы, пожалуйста, мыльте на rashray@inbox.ru.

PS
У кого голова на месте, могут догадаться, что идентификация веб сервера для них теперь не проблема ;)