DoxPit HTB
Содержание
Описание #
Челлендж: DoxPit
Сложность: Medium
Категория: Web
Нахождение уязвимостей #
Перед просмотром исходного кода, посмотрим веб страницу челленджа.Мы видим главную страницу форума, где все ссылки ведут на страницу /error, за исключением страницы /hof.При обычном сканировании исходного кода страницы ничего интересного не находим и двигаемся дальше. Также стоит отметить, что форум для фронтенда использует NextJs v14.1.0.На этом этапе оставим веб страницу и попробуем найти что-то полезное в исходном коде проекта, прикрепленном к этому челленджу.При просмотре файла entrypoint.sh заметим, что файл с флагом перемещается в корневую директорию и получает случайное имя при поднятии контейнера.Дальше сразу в глаза бросается то, что в контейнере запущен не один проект а два, второй проект с именем av.Front-end - это приложение на Next.js, которое мы видели в браузере. Проект av написан на Python (Flask) и запущен на порту 3000, но не доступен извне.При изучении кода становится понятно, что проект av из-себя представляет приложение, которое получает от зарегистрированного пользователья директорию, сканирует её, и возвращает результаты выполнения функции scan_directory. Функция scan_directory, в свою очередь, перебирает все файлы рекурсивно с помощью os.walkdir, получает sha256 хеш сумму каждого файла и сравнивает с хешами из черного списка BLACKLIST_HASHES, и в зависимости от того, есть ли хеш в черном списке или нет, показывает разные сообщения.Внутри проекта av есть место, на которое стоит обратить внимание - это проверка валидности названия директорий, и так как название директории далее вставляется в заготовленный шаблон, можно предположить, что разработчик хотел написать защиту от SSTI. Отметим, что Flask использует Jinja для шаблонов.Теперь попробуем запустить проект av и посмотрим как он выглядит.Просканируем какую-нибудь директорию и увидим, что название директории тоже выводится.Перехватим запрос в burp suite и продолжим наши манипуляции там. Исходя из того, что символы из invalid_chars запрещены, попробуем просто напечатать какое-то значение.
{%print(42)%}
Потвердилось наличие уязвимости, теперь попробуем RCE. Но, так как символы “{{” и “}}” запрещены, будем использовать, так называемые, управляющие структуры “{%” “%}”. Даллее, так как мы не можем использовать символ “.” для вызова методов, воспользуемся функцией attr, которая позволяет получить свойство без использования точки. Возьмем шаблон из HackTricks.
{%with a=request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('ls${IFS}-l${IFS}/')|attr('read')()%}{%print(a)%}{%endwith%}
Использовать бекслеши и букву “x” мы также не можем, так что кодирование нижнего подчеркивания на HEX формат нам не поможет, нужно как-то по-другому избавиться от символов нижнего подчеркивания. Немного почитав документацию Jinja2, понимаем, что можно обойти фильрацию нижних подчеркиваний, передавая их через get-параметры.
request|attr(request.args.foo)
Не забываем про точки и используем attr в связке с get. В итоге получаем вот такой шаблон (у меня получилась длинная строка, но возможно у кого-то получится покороче).
{%with a=((((request|attr('application'))|attr(request|attr("args")|attr("get")('globals')))|attr(request|attr("args")|attr("get")('getitem')))(request|attr("args")|attr("get")('builtins'))|attr(request|attr("args")|attr("get")('getitem')))(request|attr("args")|attr("get")('import'))('os')|attr('popen')(request|attr("args")|attr("get")('cmd'))|attr('read')()%}{%print(a)%}{%endwith%}&globals=__globals__&getitem=__getitem__&builtins=__builtins__&import=__import__&cmd=ls -l /
И получаем успешный результат.
Чтобы сформулировать наши дальнейшие шаги, нам нужно взаимодействовать с этим приложением, которое запущено внутри контейнера на порту 3000, и эксплуатировать уязвимость SSTI в наших целях.
Двинемся дальше к приложению фронт-енда на NextJs v14.1.0. На первый взгляд ничего интересного не находим, попробуем найти эту версию в гитхабе и посмотреть нет ли CVE. После поисков находим такие интересные ресурсы с объяснением уязвимости в Server Actions.
1.Github
2.CVE-2024-34351
3.Подробное описание самой уявимости
Вкратце, подменив значение заголовка Host в запросе, мы можем делать запросы, которые кажутся исходящими от самого сервера приложения NextJs. Изучая проект, заметим, что при клике на какую-либо пасту(копипасту) с главной страницы / происходит редирект на страницу /error.Далее для использования SSRF нам нужен Next-Action ID, который определяет идентификатор действия для NextJs. Его можно найти в исходном коде страницы.Попробуем перехватить запрос ngrok_ом, и посмотрим на результат.
Получаем флаг #
Далее воспользуемся python кодом для перехвата и перенаправления запроса из вышеупомянутой статьи и попробуем отправить запрос на приложение Flask.Получим токен.Затем используем SSTI с помощью шаблона, который создали ранее.В результате получим флаг.