Понимание включения файлов
Давайте углубимся в концепцию «включения файлов» (file inclusion) и связанные с ней потенциальные уязвимости, специально для начинающих.
Включение файлов — это распространенная практика в программировании, особенно в контексте повторного использования кода. Разработчики часто инкапсулируют часто используемые функции или модули в отдельные файлы. Когда эти функции или модули необходимы, они просто включают эти файлы в свой код, устраняя необходимость многократного написания одного и того же кода.
В PHP существует четыре основные функции для включения файлов:
include()
require()
include_once()
require_once()
Вот краткий обзор каждой из них:
include(): Эта функция включает файл при ее вызове. Если файл не найден, PHP выдает предупреждение (warning), но выполнение скрипта продолжается.
require(): Эта функция включает файл до начала выполнения скрипта. Если файл не найден, PHP выдает фатальную ошибку (fatal error) и останавливает выполнение скрипта.
include_once() и require_once(): Эти функции работают аналогично include() и require(), но гарантируют, что файл будет включен только один раз, даже если функция вызывается несколько раз.
Методы включения файлов можно условно разделить на две категории:
- Статическое включение (Static inclusion)
- Динамическое включение (Dynamic inclusion)
Различие между этими двумя типами будет прояснено на примере в следующих разделах.
В нашем курсе мы будем изучать три .php файла, расположенных в директории /home/labex/project/:
lfi_static.php
lfi_dynamic.php
echo.php
Давайте разберемся, что делает каждый файл:
-
lfi_static.php: Этот файл включает файл echo.php статическим способом. Другими словами, путь к файлу echo.php жестко закодирован и не меняется. Этот метод безопасен и не создает уязвимостей.
<?php
include("./echo.php");
?>
-
lfi_dynamic.php: Этот файл включает другие файлы на основе параметра 'file' в URL. Если этот параметр не указан, он просто дает подсказку о том, как его использовать. Однако этот метод может быть рискованным, если параметром управляет злоумышленник (attacker).
<?php
if (isset($_GET['file'])) {
include($_GET['file']);
}
else{
echo "You can use the 'file' parameter to include files";
}
?>
-
echo.php: Этот файл просто выводит сообщение об успехе при включении.
<?php
echo 'Great, now you have successfully included the content of echo.php!'
?>
Используйте следующие команды в терминале для подготовки образа для тестирования lfi:
cd ~/projects
docker build -t lfi-image .
После завершения сборки образа вы можете использовать его для запуска контейнера для тестирования уязвимости lfi:
docker run -d --name lfi -p 80:80 lfi-image
Теперь вы можете протестировать эти файлы в браузере. Например, чтобы получить доступ к файлу lfi_static.php, вам нужно ввести следующий URL:
http://127.0.0.1/LFI/lfi_static.php
Вы увидите, что файл lfi_static.php успешно включил содержимое echo.php. Помните, что этот статический метод включения файлов безопасен.
Теперь давайте посмотрим на файл lfi_dynamic.php. Получите к нему доступ, используя этот URL:
http://127.0.0.1/LFI/lfi_dynamic.php
Вы увидите подсказку с предложением использовать параметр 'file'. Сделаем это и включим echo.php:
http://127.0.0.1/LFI/lfi_dynamic.php?file=./echo.php
Вы увидите, что echo.php успешно включен. Это демонстрирует, как работает включение файлов. Важно помнить, что хотя это пример на PHP, эти принципы применимы и к другим языкам программирования, даже если используемые конкретные функции могут отличаться.