Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
В этом райтапе я покажу, как исследовать API сайта на предмет потенциальных лазеек, затем мы напишем собственный прокси‑сервер на Python, а потом применим XSS для эксфильтрации данных и проэксплуатируем сложную уязвимость чтения произвольных файлов.
Упражняться мы будем на виртуальной машине Response с площадки Hack The Box. Ее уровень сложности — Insane, и на сегодняшний день это самая сложная машина на HTB и первая в моей серии райтапов, которую мне не удалось пройти до конца. Однако даже получение двух пользовательских учеток оказалось захватывающим.
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Добавляем IP-адрес машины в /etc/hosts
:
10.10.11.163 response.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.21.6. С SSH ничего не сделать, поэтому сразу переходим к вебу.
Главная страница сайта response.htb
На сайте находим упоминание домена www.response.htb
, поэтому обновляем запись в файле /etc/hosts
:
10.10.11.163 response.htb www.response.htb
Чтобы расширить область тестирования, составим карту сайта с помощью Burp Discovery. Для этого в Burp History выбираем целевой адрес и в контекстном меню Engagement tools → Discover content.
Карта сайта
Так находим нестандартный файл /status/main.js.php
.
Копируем содержимое файла /status/main.js.php
на локальную машину и изучаем. Этот файл содержит данные для обращения к домену api.response.htb
через сайт на домене proxy.response.htb
.
Содержимое файла main.js.php
Так как обращение происходит к поддомену proxy
, добавляем в /etc/hosts
только его.
10.10.11.163 response.htb www.response.htb proxy.response.htb
Затем копируем данные для обращения и повторяем запрос.
POST /fetch HTTP/1.1Host: proxy.response.htbContent-Type: application/jsonContent-Length: 262{"url":"http://api.response.htb/","url_digest":"cab532f75001ed2cc94ada92183d2160319a328e67001a9215956a5dbf10c545","method":"GET","session":"6c2a752c873e8c03fc927a81647402d0","session_digest":"6ce5cbd27651561e9005287bc5d8cf3201aa6c4fe885057ae80b40af0b8951bd"}
Запрос и ответ сервера
Ответ от сервера закодирован в Base64, декодировать можно прямо в Burp Inspector.
Burp Inspector
Так как дальше данные представлены в формате JSON, можно красиво отобразить их при помощи утилиты jq.
Полученные с сервера данные
Просмотрим также страницы /get_chat_status
и /get_servers
.
Обращение к странице /get_chat_status
Ответ сервера
Обращение к странице /get_servers
Ответ сервера
Раскрываем еще один сервис — chat.response.htb
. Добавляем его в файл /etc/hosts
и просматриваем ответ сервера.
10.10.11.163 response.htb www.response.htb proxy.response.htb chat.response.htb
Ответ сервера
Сайт оказался недоступен. Но можно обратиться к нему через сайт proxy
. Правда, для этого нам нужно подтвердить параметр url
подписью в параметре url_digest
, который сами вычислить мы не можем. Но параметр session
, где передается идентификатор веб‑сессии, тоже подтверждается подписью session_digest
.
Запрос /status/main.js.php
Тогда пробуем вместо идентификатора сессии отправить ссылку, чтобы получить подпись для нее.
Получение подписи URL
Как видишь, мы узнаем действительную подпись URL, отправленного вместо идентификатора сессии.
Теперь проверим, придет ли нам ответ, если мы попробуем обратиться к чату. Первым делом сгенерируем для url
действительный url_digest
.
Получение значения url_digest
С подписью можно выполнить запрос к прокси‑сайту.
Получение содержимого страницы chat.response.htb
Способ получения подписи оказался рабочим. Но как бы я ни пытался эксфильтровать данные, все равно пришел к тому, что нужно писать свой проксирующий веб‑сервер. Работать он будет так:
Так как работать будем с сайтом http://chat.response.htb
, сделаем запись в файл /etc/hosts
:
127.0.0.1 chat.response.htb
Сначала напишем оснастку веб‑сервера без всяких функций. В классе сервера ProxyServer
реализуем обработчики do_GET
и do_POST
, которые будут вызывать единый метод do_Multi
. Сперва просто будем выводить URL, к которому обратится браузер.
from http.server import BaseHTTPRequestHandler, HTTPServerfrom socketserver import ThreadingMixInclass ProxyServer(BaseHTTPRequestHandler): def do_GET(self): self.do_Multi('GET') def do_POST(self): self.do_Multi('POST') def do_Multi(self, method): uri = self.path target_url = 'http://chat.response.htb' + uri print(method + " " + target_url)class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): passws = ThreadedHTTPServer(("0.0.0.0", 80), ProxyServer)print("Server started...")try: ws.serve_forever()except KeyboardInterrupt: passws.server_close()print("Server stopped.")
Запускаем сервер и обращаемся к http://chat.response.htb/
.
Логи сервера
Источник: xakep.ru