Path Traversal в загрузке файлов
Обход пути через параметр file в эндпоинте загрузки файлов (PHP).
easyphpPro
Задача
# Path Traversal: чтение файлов за пределами разрешённой директории
## Сценарий
Перед вами PHP-приложение интернет-магазина SecureShop. Команда разработки реализовала эндпоинт скачивания изображений товаров — клиент передаёт имя файла, сервер находит его в директории со статикой и отдаёт содержимое.
Реализация такой функции выглядит безобидно, но требует строгой проверки: то, что сервер возьмёт из присланного клиентом «имени», должно гарантированно остаться внутри разрешённой публичной директории. В этой реализации проверка пропущена. Любая последовательность, выводящая интерпретатор пути за границы базовой директории, проходит беспрепятственно — и клиент получает доступ к файлам, которые сервер раздавать не собирался.
При старте контейнера в служебной директории операционной системы создаётся файл с CTF-флагом. Ваша задача — найти эндпоинт скачивания, обнаружить отсутствие проверки и через path-traversal payload прочитать этот файл.
## Цели
1. Авторизуйтесь как `demo` / `demo` (для функции скачивания этой лабы аутентификация не критична, но в реальной разведке стоит пройти весь штатный путь приложения, чтобы получить представление о его поведении).
2. Найдите эндпоинт скачивания файлов и эмпирически определите, как он строит путь и проверяет ли границы директории. Один валидный запрос даст полную картину базовой склейки.
3. Сформируйте имя файла, которое выводит сервер за пределы публичной статики, и подтвердите path traversal на безопасной цели — стандартном системном файле с предсказуемым содержимым.
4. Прочитайте файл с CTF-флагом и сдайте его значение.
## Теория
**Path Traversal** (он же Directory Traversal, dot-dot-slash, CWE-22) — атака, при которой пользователь манипулирует именем файла, чтобы выйти за границы предусмотренной директории. Базовый вектор — добавление последовательностей `../` к имени файла: каждая такая последовательность поднимает путь на уровень выше по дереву каталогов. Если приложение склеивает базовую директорию с пользовательским вводом и не проверяет результат, атакующий читает любые файлы, доступные процессу веб-сервера.
В PHP интерфейс файловой системы (`readfile`, `file_get_contents`, `fopen`) не делает никакой проверки на выход за пределы директории — он просто открывает файл по пути, который ему передали. Канонизация пути в PHP — отдельная операция и её нужно вызывать явно.
Одной только нормализации пути недостаточно: канонический абсолютный путь к системному файлу так же легко открывается, как путь к легитимному ресурсу из публичной директории. После канонизации обязательно проверять, что итоговый путь остаётся внутри разрешённой базовой директории — например, через проверку префикса строки.
## Данные для работы
| Параметр | Значение |
|----------|----------|
| Эндпоинт скачивания | `GET /download?file=<имя_файла>` |
| Легитимный пример | `/download?file=hoodie.svg` |
| Базовая директория | `static/img/` относительно корня приложения |
| Где лежит флаг | системная временная директория ОС |
| Пользователь | `demo` / `demo` |
## На что обратить внимание
- Базовый запрос отдаёт SVG-изображение с корректным `Content-Type`. Это значит, что сервер передаёт пользовательский ввод как имя файла напрямую и читает результат через стандартные функции PHP.
- Глубину вложенности базовой директории относительно корня файловой системы можно прикинуть из стандартной структуры Docker-контейнера с PHP-приложением. Если ошибётесь на один-два уровня — `realpath`-нормализация ОС всё равно сходит к одному и тому же абсолютному пути, поэтому добавьте запас по числу `../`.
- Сначала подтвердите уязвимость на безопасной цели — каком-нибудь стандартном системном файле с предсказуемой структурой, который точно есть в любом Linux-окружении, — а потом переходите к артефакту задания.