📂 LFI: Local File Inclusion. Дыра, через которую видно всё
Кратко: LFI (Local File Inclusion) — уязвимость, позволяющая читать любые файлы на сервере через веб-приложение. Вместо site.com/page=about.php хакер пишет site.com/page=../../../../etc/passwd и получает пароли системы. А при определённых условиях — может превратиться в выполнение своего кода на сервере (RCE). Старая, как мир, но до сих пор живучая.
▫️ Как это работает Представьте PHP-скрипт, который просто вставляет параметр в путь:
$page = $_GET['page']; include($page . '.php');
Пользователь шлёт page=about. Сервер читает about.php. А теперь злоумышленник шлёт page=../../../../etc/passwd�. include('../../../../etc/passwd' . '.php');
Символ � (нуль-байт) обрезает строку: «Дальше ничего нет, остановись». Старые версии PHP (до 5.3) верили этому. Сервер читал не passwd.php, а сам файл паролей — и отдавал его в ответе. Современные версии не уязвимы к нуль-байту, но LFI живёт в других формах.
▫️ Варианты атаки Чтение системных файлов — классика. Вместо page=contact отправляете page=../../../../etc/passwd. Linux-сервер отдаст список пользователей. Конфиги веб-сервера (/etc/nginx/nginx.conf), логи доступа (/var/log/apache2/access.log), файлы с паролями к базам данных — всё это можно вытащить. Обход фильтров и расширений — разработчики добавляют к параметру префиксы или суффиксы. Например, include('/var/www/pages/' . $_GET['page'] . '.html');. Хакер шлёт ../../../../etc/passwd� — нуль-байт режет строку до .html. Или использует обход через двойную точку слэш: ....//....//....//etc/passwd. Некоторые фильтры удаляют ../ один раз, и такая конструкция после очистки превращается в ../../etc/passwd. Работает ли это сейчас? Да, но реже. Нуль-байт умер, но фильтры бывают кривыми. Некоторые приложения загружают изображения по ?lang=./uploads/avatar123.jpg. Хакер меняет на ?lang=../../config.php. Никакого нуль-байта не нужно — сервер сам добавляет .jpg.
▫️ Превращаем LFI в RCE — выполнение кода Иногда сервер не отдаёт файл, а подставляет его внутрь страницы. Чистое чтение не работает. Тогда LFI превращают в выполнение своего кода (RCE). Самый популярный способ — через логи веб-сервера. Атака: Отправляете запрос с вредоносным кодом в User-Agent: User-Agent: . Сервер пишет эту строчку в access.log. Затем LFI-уязвимостью подставляете этот лог-файл в скрипт: site.com/page?=/var/log/apache2/access.log. PHP выполняет то, что внутри . Другие способы: лог SSH (/var/log/auth.log) — попробовали залогиниться с неверным паролём, вставив код в имя пользователя. Или сессии (/tmp/sess_*) — если PHP хранит сессии в файлах, можно внедрить туда код через параметры запроса.
▫️ Как защищаться 1. Не используйте динамические пути к файлам — лучшее решение. Вместо ?page=about.php храните маппинг: about → about.php, contact → contact.php. Если ключа нет в списке — 404. 2. Отключите опасные функции — в PHP это allow_url_fopen и allow_url_include для защиты от RFI (Remote File Inclusion). 3. Используйте realpath() — нормализует путь, а затем проверяйте, начинается ли он с разрешённой директории. 4. Чистите ввод — удаляйте ../, ..\, нуль-байты.
▫️ Культурный феномен · «Есть LFI? Ищем RCE» — стандартный алгоритм пентестера. LFI редко бывает самоцелью, чаще это трамплин к выполнению кода. · /etc/passwd — стал символом уязвимости. Найти LFI и прочитать этот файл — ритуал посвящения. · Log Injection — классический способ превратить LFI в шелл. Знание расположения логов (/var/log/apache2/access.log, /var/log/nginx/error.log) — базовая эрудиция.
▫️ Современное положение (2026) LFI не умер. Встречается в старых CMS, кастомных PHP-приложениях, модулях для фреймворков (WordPress, Laravel с неправильными маршрутами). Современные фреймворки по умолчанию защищены, но разработчики иногда пишут собственные роутеры с уязвимостями. Особенно опасен LFI в связке с загрузкой файлов.