Содержание статьи
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Разведка
Сканирование портов
Добавляем IP-адрес машины в /
:
10.10.11.126 unicode.htb
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.
#!/bin/bashports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)nmap -p$ports -A $1
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A
).
Мы нашли два открытых порта:
- 22 — служба OpenSSH 8.2p1;
- 80 — веб‑сервер Nginx 1.18.0.
Начнем с исследования сайта.
На первой же странице видим открытый редирект. Это стоит отметить, так как редиректы можно использовать для обхода ряда фильтров и проверок. Также на сайте есть возможность зарегистрироваться и авторизоваться. Сделаем и то и другое. Работу желательно вести в Burp Proxy, чтобы у нас оставались все записи.
После логина видим редирект с присвоенным идентификатором сессии auth
. И сразу подмечаем несколько новых возможностей после авторизации.
Удалось найти форму загрузки файлов, но ее тестирование ни к чему не привело. Вернемся к идентификатору сессии — это JWT. JSON Web Token состоит из трех частей: заголовка (header), полезной нагрузки (payload) и подписи. Заголовок и полезная нагрузка представляют собой объекты JSON, при этом нагрузка может быть любой, это именно те критически важные данные, которые передаются приложению. Заголовок содержит определенные поля:
-
alg
— алгоритм, используемый для подписи/шифрования. Это обязательный ключ; -
typ
— тип токена. Это поле должно иметь значениеJWT
.
Третий элемент вычисляется на основании первых и зависит от выбранного алгоритма. Токены могут быть перекодированы в компактное представление: к заголовку и полезной нагрузке применяется алгоритм Base64-URL, после чего добавляется подпись и все три элемента разделяются точками. К примеру, можно с помощью Burp Inspector декодировать заголовок.
Попробуем разобрать эти данные. Для этого нам понадобится либо приложение jwt_tool, либо онлайновый ресурс jwt.io. Я буду использовать второй вариант. В заголовке у нас присутствует параметр jku
. Он определяет URI, который указывает на ресурс, где находится ключ проверки подписи в представлении JWKS (JSON Web Key Set). В качестве подписанных данных используется имя пользователя.
Вернемся к параметру jku
, там мы находим еще один домен, который допишем в файл /
.
10.10.11.126 hackmedia.htb unicode.htb
JSON Web Key Set (JWKS) — это набор открытых ключей, которые используются для проверки веб‑токена, выпущенного сервером авторизации и подписанного с использованием алгоритма подписи RS256. RS256 генерирует асимметричную подпись. Чтобы подписать JWT, должен использоваться закрытый ключ, а для проверки подписи нужен другой открытый ключ. Просмотреть структуру JWKS мы можем, обратившись к URL, указанному в jku, — http://
.
Дальнейший вектор очевиден: необходимо изменить имя пользователя на admin
, что даст нам привилегированный контекст, подписать новые данные, сгенерировать новый JWT и заменить старый на веб‑сервисе.
Точка входа
Теперь разберемся с подписью. В заголовке указан адрес JWKS, что дает нам следующую идею: сгенерировать свою пару ключей для подписи токена и соответствующий им JWKS. Мы поместим JWKS на своем веб‑сервере и затем в заголовке пропишем адрес, указывающий на этот сервер. Для генерирования ключей воспользуемся сайтом mkjwk.org. Выставим используемые параметры и получим ключи.
Теперь вернемся к токену на jwt.io. Изменим имя пользователя на admin
, в параметре jku
укажем файл на своем сервере (веб‑сервер запускаем командой python3
). Файл должен содержать данные из формы Public Key. Для подписи используем пару ключей из форм Private Key (X.509 PEM Format) и Public Key (X.509 PEM Format).
Вставляем данный токен в Burp и после запроса получаем ответ об ошибке проверки jku
.
При этом на наш веб‑сервер запрос не пришел. Значит, есть проверка того, какой сервер указан в jku
. Тогда используем открытый редирект! Он будет перенаправлять на наш сервер запросы, совершаемые для проверки jku
:
http://hackmedia.htb/static/../redirect/?url=10.10.14.73/jwks.json
При использовании нового JWT видим, что на наш сервер пришел запрос.
Но доступ мы не получаем. Скорее всего, это связано с данными в файле JWKS. Просмотрим тогда файл с сервера и изменим в нем только параметр n
(e
и так совпадает). Вновь посылая запрос через Burp, получаем новый ответ. Переходим в браузер и, используя расширения вроде Cookie Editor, вставляем новый JWT и обновляем страницу.
В итоге получаем административную панель.
Точка опоры
Изучая сайт, сразу натыкаемся на страницу, которая передает контент в параметре.
Попробуем указать там какой‑нибудь файл, например /
. Но получаем ошибку и сообщение о том, что используется фильтр.
Тогда я применил словарь, в котором содержатся разные способы обхода фильтров для LFI, и получил отличную от остальных реакцию сервера.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»