Тестирование веб-приложений на присутствие LFI-уязвимостей
Введение
Цель данного документа – помочь пентестерам и студентам в поиске LFI-уязвимостей, которые обычно обнаруживаются во время тестирования веб-приложений при помощи техник, описанных в этой статье. Кроме того, описанные методы обычно используются участниками различных хакерских конкурсов в формате CTF (Capture the Flag; Захват флага).
Что такое LFI-уязвимость?
LFI-уязвимости (Local File Inclusion; Включение локальных файлов) позволяют злоумышленникам через браузер подключать файлы на сервере. Эта брешь присутствует там, где отсутствует корректная обработка входящих данных, и злоумышленник может манипулировать входящей информацией, инжектировать символы типа path traversal и включать другие файлы с веб-сервера.
Пример уязвимого кода
Код, показанный ниже, имеет брешь, связанную с включением локального файла.
<?php
$file = $_GET['file'];
if(isset($file))
{
include("pages/$file");
}
else
{
include("index.php");
}
?>
Нахождение LFI-уязвимостей внутри веб-приложений
Проблемы, связанные с включением локальных файлов, легко найти и эксплуатировать. Любой скрипт, который подключает файл с веб-сервера, является хорошим кандидатом для поиска LFI-уязвимостей. Например:
/script.php?page=index.html
Пентестер может попробовать поэксплуатировать эту брешь при помощи манипуляции параметром, связанным с местонахождением файла. Например, так:
/script.php?page=../../../../../../../../etc/passwd
Трюк, показанный выше, позволяет посмотреть содержимое файла /etc/passwd в системах на базе UNIX / Linux.
На рисунке ниже показан пример успешной эксплуатации LFI-уязвимости в веб-приложении:
Рисунок 1: Вывод содержимого файла /etc/passwd в системе, содержащей LFI-уязвимость
PHP-обертки
В интерпретаторе PHP есть несколько оберток, которые можно использовать для обхода фильтров входящих данных.
Обертка expect://
Обертка expect:// позволяет выполнять системные команды. К сожалению, этот модуль по-умолчанию не разрешен.
Пример:
php?page=expect://ls
Обертка file://
В примере ниже полезная нагрузка отправляется на сервер через POST-запрос (при помощи конструкции php://input выполняем команду ls).
/fi/?page=php://input&cmd=ls
Запрос:
Рисунок 2: POST-запрос, содержащий конструкцию php://input
Ответ веб-приложения:
Рисунок 3: Результат выполнения команды ls
Обертка php://filter
Обертка php://filter позволяет пентестеру подключать локальные файлы и кодировать выходной поток в base64. Таким образом, чтобы получить читабельное содержимое, нужна дешифровка.
Пример:
vuln.php?page=php://filter/convert.base64-encode/resource=/etc/passwd
Рисунок 4: Отображение файла /etc/passwd, закодированного в base64
Декодируем файл /etc/passwd при помощи следующей команды:
Рисунок 5: Раскодированный файл /etc/passwd
Обертку php://filter можно использовать и без кодирования выходного потока:
Пример:
?page=php://filter/resource=/etc/passwd
Рисунок 6: Отображение незакодированного файла /etc/passwd при помощи обертки php://filter
Обертка zip://
Обертка zip:// обрабатывает загруженные .zip файлы на стороне сервера. При помощи данной функции пентестер может загрузить .zip файл, используя уязвимую функцию, предназначенную для загрузки, а затем осуществить выполнение через распаковщик zip и локальное включение. Типичная атака выглядит следующим образом:
- Создаем обратный PHP-шелл.
- Упаковываем файл в .zip архив.
- Загружаем сжатую полезную нагрузку на сервер.
- Используем обертку zip:// для распаковки полезной нагрузки при помощи следующей команды: php?page=zip://path/to/file.zip%23shell
- После выполнения команды из пункта 4 появится файл shell. Если сервер не принимает файл shell, поменяйте имя на shell.php.
Если сервер не принимает .zip архивы, можно попробовать обойти функцию загрузки файлов.
Включение локальных файлов через /proc/self/environ
Если получается подключение /proc/self/environ при помощи бреши, связанной с включением локальных файлов, возможна атака через заголовок User Agent. Как только код инжектирован в заголовок User Agent, в дальнейшем используется LFI-уязвимость для выполнения /proc/self/environ и перезапуска переменных окружения, что, в свою очередь, позволяет запустить обратный шелл.
Полезные трюки
Далее будут приведены методы, которые полезны в сочетании с техниками, указанными выше:
Пример:
<? system('uname -a');?>
Добавление пустого байта
Инжектирование пустого байта помогает обойти фильтры при помощи добавления к URL закодированного пустого байта (например, %00). Обычно этот трюк позволяет обойти базовые фильтры путем добавления пустых символов, которые допустимы и не обрабатываются серверной частью веб-приложения.
Практические примеры, связанные с инжектирование пустого байта, с целью включения локального файла:
vuln.php?page=/etc/passwd%00
vuln.php?page=/etc/passwd%2500
Техники, связанные с укорачиванием
Укорачивание – еще одна техника, направленная на обход фильтров. При инжектировании длинного параметра в механизм с LFI-уязвимостью, веб-приложение может обрезать входной параметр, что поможет обойти фильтр входных данных.
Примеры трюков, связанных с укорачиванием:
vuln.php?page=/etc/passwd…………………………………………………………………………….
vuln.php?page=../../../../../../../../../../../../../../../../../../../../../../../../etc/passwd
vuln.php?page=/etc/passwd/../../../../../../../../../../../../../../../../../..
Инжектирование в лог-файл
Метод основан на внедрении исходного кода через другие внешний службы в лог-файл целевой системы. Например, инжектирование PHP-кода обратного шелла в URL сподвигнет службу syslog на создание записи в логе доступа веб-сервера Apache записи с ошибкой 404 (страница не найдена). Затем лог апача можно распарсить при помощи ранее обнаруженной LFI-уязвимости и запустить инжектированной PHP-код.
После добавления исходного кода в лог(и) целевой системы следующий шаг – поиск местонахождения этих файлов. После обнаружения типа целевой системы и веб-сервера следует поискать логи по стандартным путям, используемым в данной конкретной системе и веб-сервере. Полезные нагрузки, заточенные под LFI-уязвимость в сочетании с приложением Burp Intruder можно использовать для нахождения путей, где лежат логи в целевой системе.
Некоторые популярные внешние службы в системах Linux / UNIX перечислены ниже:
Apache / Nginx
Инжектируем код в журнал доступа или журнал ошибок веб-сервера при помощи netcat. После успешного внедрения парсим файл серверного лога, используя ранее обнаруженную LFI-уязвимость. Если журнал доступа / ошибок слишком длинный, на запуск инжектированного кода может уйти некоторое время.
Отправка обратного шелла по электронной почте
Если целевая машина перенаправляет почту напрямую или через другую машину в сети, а также хранит почту пользователя www-data (apache) в системе, становится возможной атака через отправку обратного шелла при помощи электронной почты. Если для текущего домена отсутствуют MX-записи, но есть внешняя служба SMTP, можно подключиться к целевому почтовому серверу и отослать почту пользователю www-data / apache. Почта отсылается пользователю, от имени которого запускается apache (например, www-data), с целью проверки, что права файловой системы позволяют получить доступ на чтение к файлу /var/spool/mail/www-data, который содержит инжектированный обратный шелл код, написанный на PHP.
Вначале проверяем присутствие пользователя www-data при помощи скрипта smtp-user-enum:
Рисунок 7: Проверка присутствия пользователя www-data
На рисунке ниже показан процесс отправки почты пользователю www-data через telnet:
Рисунок 8: Процесс пересылки обратного PHP-шелла через SMTP при помощи telnet
Рисунок 9: Включение файла www-data, который содержит код отосланного обратногоPHP-шелла
В результате обратный шелл подключается к netcat-слушателю:
Рисунок 10: Подсоединение обратного PHP-шелла к netcat
Ссылки
Информационные источники, используемые в этой статье:
https://highon.coffee/blog/lfi-cheat-sheet/
https://www.owasp.org/index.php/PHP_File_Inclusion
Уязвимое приложение DVWA (использовалось в примерах с демонстрацией LFI-уязвимостей): http://www.dvwa.co.uk/