LFI, Path Traversal

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

Возникает подобная уязвимость в том случае, если при реализации веб-приложения используются небезопасные функции, например, include, позволяющие включать контент на страницу из локального файла. В нашем случае это выглядит следующим образом:

<?php
	$file = $_GET['file'];
	if(isset($file))
	{
		include("$file");
	}
	?>
<b> <p align="center">Пример веб-приложения, доступный в Интеренте.</p></b>

Благодаря строчке include(“$file”) ****в содержимое страницы будет включаться значение GET-параметра file. Теперь, используя эту уязвимость, нам будут возвращаться локальные файлы, которые мы укажем в параметре.

Статья носит информационный характер. Не нарушайте законодательство.

Обнаружение уязвимости

Как обнаружить уязвимость? Если указать в потенциально уязвимом параметре включение какого-то локального файла, например, index с любым расширением, и этот файл откроется, то однозначно можно утверждать, что параметр отвечает за подкачку файла. Сделать это можно как вручную, так и с помощью различных автоматизированных инструментов, например, сканером уязвимостей Wapiti, или специализированным инструментом LFISuite, который разработан именно под поиск и эксплуатацию LFI-уязвимостей.

Какие здесь могут быть подводные камни? Например, наличие фильтрации, которая будет подставлять в окончание строки расширение файла, например, .php. Таким образом, при попытке включения в страницу файла /etc/passwd мы получим в адресной строке file=/etc/passwd.php, а содержимое этого файла не будет отображаться на странице, так как файла не существует. Но такой фильтр можно обойти с помощью так называемого нулевого байта, который будет «отсекать» все, что будет идти после него. Дело в том, что вся адресная строка при передаче HTTP-запроса кодируется в URL-encode, и в этой кодировке нулевой байт выглядит как %00. Таким образом, строчка /etc/passwd%00.php будет преобразована в /etc/passwd. Однако стоит отметить, что данная проблема является довольно известной и исправлена в версии PHP 5.3+

Другой вариант обхода фильтрации — использование php filter. В параметре, отвечающем за включение файлов, пишем не просто путь до файла, который мы хотим включить, а путь до файла с использованием этой функции. Теперь запрос, который мы будем отправлять, имеет вид:

http://site.test.lan/index2.php?file=php://filter/convert.base64-encode/resource=/etc/passwd

И теперь на странице браузера мы увидим не содержимое файла, а его исходник в кодировке base64, который можно декодировать.

С основными моментами уязвимости LFI разобрались, и теперь понимаем, что при ее эксплуатации можно прочитать локальный файл на удаленном сервере. Но у LFI есть интересная особенность, позволяющая не просто прочитать локальные файлы, а скомпрометировать сервер.

Отравление журнала веб-сервера

Думаю, стоит сразу оговориться, что уязвимость не новая, но тем не менее она до сих встречается и может представлять серьезную угрозу для безопасности веб-сервера. При взаимодействии с веб-приложением любой наш запрос записывается в журналы веб-сервера, как правило, это файлы /var/log/nginx/access.log или /var/log/nginx/error.log если, например, используется веб-сервер Nginx, но названия конечных файлов, разумеется, могут отличаться.

Теперь, составив специальный запрос, мы создадим веб-шелл на сервере, записав его в access.log. Для отправки запроса будем использовать инструмент Burp Suite, позволяющий в режиме реального времени перехватывать и редактировать запросы.

Untitled

Наш веб-шелл <?php system($_GET[cmd]); ?> записан в журнале веб-сервера и готов к использованию.

Почему использовался именно параметр User-Agent? Как уже говорилось ранее, адресная строка кодирует информацию с помощью URL-encode, поэтому для передачи php-кода нужно использовать заголовки, а так как в access.log точно пишется User-Agent, то и используем его. Обратившись к нашему веб-шеллу, получаем возможность выполнять различные команды через параметр cmd:

http://site.test.lan/index2.php?file=/var/log/nginx/access.log&cmd=ls /