Вопрос или проблема
Я тестирую веб-приложение и обнаружил уязвимость загрузки файлов, при которой я могу загружать php-файлы на сервер с возможностью узнать путь.
Проблема в том, что когда я перехожу по пути к файлу, php-файл (который является моей оболочкой) загружается. Мне нужна помощь, чтобы найти способ выполнить файл вместо этого. Есть идеи, которые я мог бы попробовать?
Функция загрузки файла, позволяющая загружать PHP-скрипты, сама по себе не является уязвимостью. Судя по вашему описанию, веб-сервер не выполняет PHP-скрипты в директории загрузки, так что кажется, что существует по крайней мере какая-то защита от атак выполнения кода.
Есть (по меньшей мере) два варианта, которые могут позволить вам все же выполнить код. Однако обратите внимание, что нет гарантии успешного выполнения кода. Может оказаться, что уязвимость вовсе отсутствует.
Используя атаку обхода по пути, вы могли бы попробовать заставить веб-сервер сохранять загруженные файлы в директорию, которая поддерживает выполнение скриптов. Возможно это или нет, зависит от того, как именно функция загрузки строит целевой путь для файла. Например, типичный PHP-код для сохранения загруженного файла выглядит так:
move_uploaded_file($tmp_name, $upload_dir.$some_infix.$filename);
Переменная $upload_dir
будет содержать путь (законной) директории загрузки, $filename
— целевое имя файла, предоставленное вами или сервером, а $some_infix
— это (возможно пустая) строка, например, подкаталога в папке загрузки или префикса к имени файла.
Вы можете попытаться вставить сегменты пути (такие как ../some-executable-dir-above-the-upload-folder
) как через $filename
, так и через $some_infix
. Если $filename
использует ключ name
из $_FILES
, то он не подвержен инъекции, потому что это значение автоматически очищается от любой информации о пути. Однако PHP 8.1 ввёл ключ full_path
, который позволяет клиенту предоставить полный путь. Если вам повезет, функция загрузки использует full_path
вместо name
. Если вы не можете вставить сегменты пути через имя файла, то проверьте, можете ли вы контролировать $some_infix
(если он существует). Например, если файлы имеют префикс с вашим именем пользователя, это может быть вариантом для инъекции слешей.
Если вы не можете выйти за пределы директории загрузки, то второй вариант — найти уязвимость локальной инклюзии файлов в существующем скрипте. Если этот скрипт позволяет вам указать путь к вашему загруженному PHP-скрипту, это может привести к выполнению кода.
Ответ или решение
Исполнение PHP-файлов после загрузки
Если вы обнаружили возможность загрузки PHP-файлов на сервер вашего веб-приложения, но эти файлы загружаются в директорию, где PHP-скрипты не исполняются, вам нужно рассмотреть несколько направлений для анализа и возможного обхода ограничений.
1. Доступ к исполняемым директориям
Первый шаг — выяснить, возможно ли запустить загруженный файл из директории, где он по умолчанию сохранён. Если сервер не обрабатывает PHP-скрипты в данной директории, у вас есть несколько вариантов:
А. Атака с использованием обхода путей (Path Traversal)
Попробуйте определить, есть ли возможность манипулировать путём, в который загружается файл. Например, многие функции загрузки файлов выглядят следующим образом:
move_uploaded_file($tmp_name, $upload_dir . $some_infix . $filename);
Здесь $upload_dir
— это путь к легитимной директории загрузки, а $filename
— имя файла. Вы можете попробовать внедрить сегменты пути (например, ../some-executable-dir
), чтобы файл сохранялся в исполняемой директории, такой как public_html
или www
, где PHP-скрипты могут выполняться.
Обратите внимание, что если $filename
использует ключ name
массива $_FILES
, путь может быть автоматически очищен, чтобы избежать подобных атак. Однако в PHP версии 8.1 была добавлена возможность использовать ключ full_path
, который позволяет клиенту указывать полный путь. Если функция загрузки использует именно этот ключ, у вас есть потенциал для внедрения пути.
Б. Внедрение через $some_infix
Если $filename
не поддаётся модификации, посмотрите на возможность управления переменной $some_infix
, которая может представлять собой префикс к имени файла или подкаталог. В некоторых случаях разработчики включают префиксы, основанные на именах пользователей, что может позволить вам вставить слеши и изменить структуру пути.
2. Уязвимость локального включения файлов (Local File Inclusion)
Если вам не удалось обойти директорию загрузки, следующим шагом будет поиск локальной уязвимости включения файлов. Это означает, что в скрипте приложения может быть уязвимость, позволяющая вам указать путь к вашему загруженному PHP-файлу. Например, если есть скрипт, который на основании пользовательского входа включает файлы, вы можете попробовать указать путь к вашему загруженному файлу.
Заключительные рекомендации
- Обязательно проводите все тесты в контролируемой среде, гарантируя, что вы не нарушаете закон или правила.
- Предпочитайте использовать эти знания с целью улучшения безопасности приложений, а не для злонамеренных действий.
- Сфокусируйтесь на дополнении защиты вашего приложения, включая проверки типа файлов, ограничения по размерам и другие меры безопасности.
Если ни один из этих подходов не сработает, возможно, стоит рассмотреть другие аспекты конфигурации сервера или даже обратиться к специалистом по безопасности за консультацией.