Всем привет, сегодня Рождество, поэтому займёмся чем-нибудь интересным. Например, порешаем задачки на информационную безопасность web-серверов. Сегодня задачка с портала root-me.org, называется "PHP - Filters". За решение задачки дают 25 баллов, ближе к среднему уровню.
Нам предлагают узнать пароль администратора приложения. В помощь документация про LFI и RFI, использование PHP streams и PHP filters. С LFI и RFI мы уже встречались в предыдущих задачках.
Local File Inclusion (LFI) — возможность использования локальных файлов сервера. Уязвимость позволяет удаленному пользователю получить доступ с помощью специально сформированного запроса к произвольным файлам на сервере.
Remote File Inclusion (RFI) — возможность использования файлов с удалённого сервера. Уязвимость позволяет удаленному пользователю с помощью специально сформированного запроса внедрить в код веб-сервера файл с удалённого ресурса, например, по ссылке HTTPS.
Судя по названию задачки работать предстоит с PHP фильтрами.
php://filter
Фильтры данных впервые появились в PHP 5.0 и избавили web-разработчиков от написания лишнего кода и регулярных выражений при выполнении типичных задач. Фильтры выполняют базовые операции с данными перед их использованием, соответственно, можно их использовать в наших целях.
Есть пять категорий фильтров:
- String Filters
- string.rot13
- string.toupper
- string.tolower
- string.strip_tags (устарел)
- Conversion Filters
- convert.base64-encode
- convert.base64-decode
- convert.quoted-printable-encode
- convert.quoted-printable-decode
- convert.iconv
- Compression Filters
- zlib.deflate
- zlib.inflate
- Encryption Filters
- mcrypt.* (устарел)
- mdecrypt.* (устарел)
- Другие фильтры (команда "var_dump(stream_get_filters());" выводит ещё некоторые фильтры)
- consumed
- dechunk
- convert.*
Ссылки
Решение
Переходим на страницу задания:
http://challenge01.root-me.org/web-serveur/ch12/
У нас здесь страничка с неким файловым менеджером. Для просмотра файлов просят залогиниться. И две ссылки:
- home
- login
Проверим что в home. Открывается та же самая страница, на которую мы попали при входе в задание, это было ожидаемо от home.
А теперь обращаем внимание на URL страницы, там в параметр inc передаётся имя файла PHP: accueil.php. И вовсе я не АККУЕЛ. Ладно-ладно, поржали и хватит, с французского это переводится как "приём" или "регистратура", стартовая страничка, в общем. Важно то, что имя файла PHP передаётся в переменную. Похоже на LFI. Не делайте так, друзья! Мало того что имя файла засветили, там мы же можем и своё имя передать. Попробуем позже, смотрим что у нас в login.
А здесь у нас форма логина. В URL в параметре inc видим имя файла login.php.
Пробуем в URL передать что-то своё, например:
/../../../../../../etc/passwd
Формируем URL:
http://challenge01.root-me.org/web-serveur/ch12/?inc=/../../../../../../etc/passwd
А на странице-то используется функция include().
Ошибка, такой путь запрещён. Вероятно, разработчик строго ограничил список PHP файлов, с которыми можно работать. А давайте вместо login.php передадим в параметр фильтр, применённый к этому файлу? Закодируем, к примеру, login.php в BASE64:
php://filter/convert.base64-encode/resource=login.php
И вместо формы логина мы получаем содержимое файла login.php в BASE64. Декодируем:
https://internet-lab.ru/base64_encode_decode
Получаем код PHP странички login.php:
Пароль у нас в параметре $password, а параметр, вероятно, в файле config.php. Аналогично формируем фильтр для config.php:
php://filter/convert.base64-encode/resource=config.php
Получаем содержимое файла config.php в BASE64. Декодируем:
А внутри лежит пароль пользователя admin. Логинимся.
Пароль подходит.
Найденный пароль предлагают использовать в качестве флага. Флаг у нас в руках, валидируем:
Флаг подходит, зарабатываем 25 очков.
Безопасность
В данном примере демонстрируется один из векторов атак Local File Inclusion (LFI), возможность использования локальных файлов сервера. Уязвимость позволила удаленному пользователю получить доступ с помощью специально сформированного запроса к произвольным файлам на сервере, в том числе содержащим конфиденциальную информацию.
Уязвимость может возникнуть в том случае, если при реализации веб-приложения используются небезопасные функции, например, include, как в нашем случае, позволяющие включать контент на странице из локального файла.
Разработчик понадеялся на то, что удалённый пользователь не сможет получить доступ к содержимому PHP файла, потому что тот исполняемый. Однако, использование PHP фильтров позволило нам не выполнить файл, а считать его содержимое. Более того, мы смогли считать содержимое произвольного PHP файла.
Следует более серьёзно проверять пользовательский ввод.