Local File Inclusion через include()
Параметр file передаётся напрямую в include() без валидации — атакующий читает произвольные файлы сервера.
easyphpPro
Задача
# Local File Inclusion через include()
## Сценарий
Перед вами PHP-приложение интернет-магазина SecureShop. Команда разработки реализовала простую CMS-подобную систему статичных страниц: «О компании», «Контакты», «Доставка», «Каталог». Каждая страница хранится отдельным шаблоном в публичной директории, а единая точка просмотра принимает короткое имя страницы и подгружает соответствующий шаблон через `include()`.
Реализация выглядит безобидно — ведь имя файла из запроса просто конкатенируется с базовым путём, и существует список «правильных» имён, который разработчик подразумевает по умолчанию. Однако никакой явной проверки в коде нет: то, что попадает с клиента, напрямую участвует в построении пути к файлу для `include()` или `readfile()`. Это и есть классическая уязвимость **Local File Inclusion (LFI)** — CWE-98 (PHP File Inclusion) и CWE-22 (Path Traversal).
## Почему это типовая ошибка
Разработчик мог исходить из «контракта», что фронтенд всегда передаёт одно из четырёх известных имён страниц, и не предусмотрел, что параметр контролируется атакующим. В типовых code-review такие места часто пропускают: внешне это «обычный шаблонизатор», а уязвимость проявляется только при отправке имени файла, выходящего за пределы директории. PHP здесь особенно опасен: `include()` исполняет любой PHP-файл, к которому удалось обратиться, а `readfile()` выводит содержимое как есть — включая системные файлы и переменные окружения процесса.
## Что атакующий получает
Через LFI без какой-либо аутентификации (эндпоинт публичный) возможно:
- Прочитать `/etc/passwd` и подтвердить выход за пределы директории.
- Извлечь переменные окружения процесса через `/proc/self/environ` — в них хранится `LAB_FLAG`.
- Прочитать содержимое файла `/tmp/flag.txt`, куда приложение записывает флаг при инициализации.
- Получить исходный код приложения и базы данных — `internal/env/env.php`, `internal/database/sqlite.php` — что раскрывает дальнейшие векторы атак.
## Цели
1. Найдите эндпоинт, который принимает имя файла-страницы, и эмпирически определите, как он строит путь и проверяет ли границы директории.
2. Подтвердите наличие LFI, прочитав системный файл `/etc/passwd`.
3. Извлеките флаг задания одним из доступных способов (через файл `/tmp/flag.txt` или через переменные окружения процесса).
## Данные
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |
| Авторизация для эндпоинта | Не требуется |