Эту тач­ку «безум­ного» уров­ня слож­ности я штур­мовал поч­ти три месяца. Чего здесь толь­ко не встре­тилось: уяз­вимость в OpenStack, реверс при­ложе­ния для Android и под­делка сер­тифика­тов, баг в Apache APISIX, ата­ка на ModSecurity, которую уда­лось рас­кру­тить до RCE... Под конец получа­ем дос­туп к ноде Kubernetes, сли­ваем сек­реты и экс­плу­ати­руем баг в minikube CRI-O. В общем, скуч­но не будет!

warning

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

 

Разведка

 

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

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

10.10.11.199 pikatwoo.htb

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

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

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

На­ибо­лее извес­тный инс­тру­мент для ска­ниро­вания — это Nmap. Улуч­шить резуль­таты его работы ты можешь при помощи сле­дующе­го скрип­та:

#!/bin/bash
ports=$(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.4p1;
  • 80 и 8080 — веб‑сер­вер Nginx 1.18.0;
  • 443 — тоже веб‑сер­вер, поле сер­тифика­та commonName рас­кры­вает новый домен api.pokatmon-app.htb;
  • 4369 — служ­ба Erlang Port Mapper; ска­нер заод­но показы­вает нам динами­чес­кий порт ноды Rabbit — 25672 (так­же открыт);
  • 5000 — оче­ред­ной веб‑сер­вер, выпол­няющий редирект на новый домен pikatwoo.pokatmon.htb;
  • 5672 — служ­ба RabbitMQ 3.8.9;
  • 35357 — веб‑сер­вер, выпол­няющий редирект на домен pikatwoo.htb.

Пер­вым делом для новых доменов соз­даем запись в /etc/hosts и про­веря­ем сай­ты.

10.10.11.199 pikatwoo.htb pokatmon-app.htb api.pokatmon-app.htb pokatmon.htb pikatwoo.pokatmon.htb

Зап­рос на порт 80 при­водит нас на сайт Pokatdex со спис­ком геро­ев. Но при выборе любого из них получа­ем ошиб­ку в фор­мате JSON.

Главная страница сайта http://pokatmon.htb
Глав­ная стра­ница сай­та http://pokatmon.htb
Ошибка при выборе персонажа
Ошиб­ка при выборе пер­сонажа

HTTPS-сер­вер сра­зу вер­нул ошиб­ку, зато на пор­те 35357 работа­ет OpenStack.

Ошибка на сайте https://pokatmon-app.htb
Ошиб­ка на сай­те https://pokatmon-app.htb
Ответ сервера на порте 35357
От­вет сер­вера на пор­те 35357

По зап­росу «OpenStack ports» пер­вая ссыл­ка в Google дает понять, что на пор­те 5000 работа­ет сер­вис Keystone, а порт 8080 отве­чает за Swift (OpenStack Object Storage). Для про­вер­ки сде­лаем зап­росы к обо­им сер­висам.

curl -s http://10.10.11.199:8080/info | jq .
Информация о сервисе Swift OpenStack
Ин­форма­ция о сер­висе Swift OpenStack
curl http://10.10.11.199:5000/ -s | jq .
Информация о сервисе Keystone OpenStack
Ин­форма­ция о сер­висе Keystone OpenStack

Пос­коль­ку Burp Suite авто­мати­чес­ки стро­ит кар­ту сай­та, видим, что на pokatmon.htb дос­тупен файл CHANGELOG, из которо­го узна­ём о сущес­тво­вании неко­его при­ложе­ния для Android, а так­же WAF ModSecurity.

Карта сайта
Кар­та сай­та

Мы зна­ем вер­сии уста­нов­ленно­го ПО, поэто­му можем поп­робовать поис­кать в интерне­те опи­сания уяз­вимос­тей и экс­пло­иты.

 

Точка входа

 

OpenStack Keystone

Служ­ба Keystone вхо­дит в облачную плат­форму OpenStack и обес­печива­ет аутен­тифика­цию кли­ентов API, обна­руже­ние служб и рас­пре­делен­ную мно­гополь­зователь­скую авто­риза­цию. В слу­чае с Keystone поиск экс­пло­итов ока­зал­ся нелег­кой задачей, но все же находим уяз­вимость с иден­тифика­тором CVE-2021-38155, которая поз­волит опре­делить сущес­тву­ющих поль­зовате­лей.

Список уязвимостей для Keystone OpenStack
Спи­сок уяз­вимос­тей для Keystone OpenStack

Суть бага в том, что если мы поп­робу­ем нес­коль­ко раз авто­ризо­вать­ся от име­ни сущес­тву­юще­го поль­зовате­ля, то он будет на вре­мя заб­локиро­ван и нам вер­нут соот­ветс­тву­ющее сооб­щение. Для име­ни поль­зовате­ля, акка­унта которо­го не сущес­тву­ет, мы такого сооб­щения не получим. Возь­мем спи­сок имен из набора SecLists и поп­робу­ем авто­ризо­вать­ся с каж­дым из имен и десятью раз­ными пароля­ми с помощью Burp Intruder. Для авто­риза­ции исполь­зуем зап­рос к /v3/auth/tokens со сле­дующи­ми дан­ными.

{
"auth": {
"identity":{
"methods":["password"],
"password":{
"user":{
"password":"§admin§",
"name":"§admin§",
"domain":{
"id":"default"
}}}}}}
Burp Intruder — вкладка Positions
Burp Intruder — вклад­ка Positions
Результат перебора
Ре­зуль­тат перебо­ра

В ито­ге получа­ем двух поль­зовате­лей: admin и andrew. Перебор паролей ничего не дает, поэто­му перехо­дим к дру­гому сер­вису.

OpenStack Object Store (Swift) — ПО для облачно­го хра­нили­ща, поз­воля­ющее хра­нить и извле­кать боль­шое количес­тво дан­ных с помощью прос­того API. По зап­росу «keystone swift» получа­ем до­кумен­тацию, из которой узна­ём о том, что мож­но получить дос­туп к откры­тым дан­ным, зная толь­ко имя поль­зовате­ля и исполь­зуя пре­фикс AUTH_. Поп­робу­ем переб­рать хра­нили­ще поль­зовате­ля andrew.

ffuf -u http://10.10.11.199:8080/v1/AUTH_andrew/FUZZ -t 256 -w directory_2.3_medium_lowercase.txt -ac
Результат перебора каталога
Ре­зуль­тат перебо­ра катало­га

По­луча­ем один каталог, который содер­жит при­ложе­ние для Android.

Файлы в каталоге android
Фай­лы в катало­ге android

Ви­димо, это при­ложе­ние, которое упо­мина­лось в чен­жло­ге. Ска­чива­ем его для ана­лиза.

 

Точка опоры

 

Анализ APK

В качес­тве вир­туаль­ной машины я исполь­зую AVD из Android Studio. Пос­ле запус­ка вир­туаль­ного смар­тфо­на про­верим, опре­дели­лось ли устрой­ство в adb.

adb devices
Устройства adb
Ус­трой­ства adb

Те­перь с помощью adb уста­новим ска­чан­ное при­ложе­ние и запус­тим уже с мобиль­ного устрой­ства.

adb install pokatmon-app.apk
Главное окно приложения
Глав­ное окно при­ложе­ния

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

Ошибка приложения
Ошиб­ка при­ложе­ния

На хос­товой сис­теме запус­каем Wireshark и смот­рим, куда идут зап­росы. В тра­фике отме­чаем DNS-зап­рос для резол­ва api.pokatmon-app.htb.

Перехваченные пакеты в Wireshark
Пе­рех­вачен­ные пакеты в Wireshark

В качес­тве сво­его DNS-сер­вера исполь­зуем dnsmasq. Для най­ден­ного адре­са сде­лаем запись в фай­ле /etc/dnsmasq.conf и запус­тим dnsmasq.

address=/api.pokatmon-app.htb/10.10.11.199

А теперь переза­пус­тим вир­туаль­ную машину, но с ука­зани­ем DNS-сер­вера и пов­торим зап­рос на сер­вер.

emulator -dns-server 10.10.16.46 -avd Pixel_3a_API_33_x86_64
Ошибка приложения
Ошиб­ка при­ложе­ния

На­конец при­ложе­ние может общать­ся с сер­вером. Теперь про­пус­тим весь его тра­фик через Burp Proxy, для чего в нас­трой­ках Burp соз­дадим новый лис­тенер на VPN-интерфей­се. Соз­данный лис­тенер ука­зыва­ем в нас­трой­ках прок­си AVD.

Настройки Burp — листенеры Proxy
Нас­трой­ки Burp — лис­тенеры Proxy
Настройки Proxy AVD
Нас­трой­ки Proxy AVD

Но сно­ва не получа­ем дос­туп к сер­веру. При­чину можем пос­мотреть в логах Burp Proxy. Все дело в SSL-сер­тифика­те.

Логи Burp Proxy
Ло­ги Burp Proxy

Что­бы ошиб­ка исчезла, нам нуж­но уста­новить сер­тификат Burp в вир­туаль­ное устрой­ство. Для это­го сна­чала ска­чива­ем сам сер­тификат, кон­верти­руем его в фор­мат PEM и пере­име­новы­ваем. В Android имя сер­тифика­та — это его кон­троль­ная сум­ма.

wget localhost:8080/cert -O cert.der
openssl x509 -inform der -in cert.der -out cert.pem
openssl x509 -inform pem -subject_hash_old -in cert.pem
cp cert.pem 9a5ba575.0
Вычисление контрольной суммы сертификата
Вы­чис­ление кон­троль­ной сум­мы сер­тифика­та

Те­перь нуж­но сох­ранить наш серт в катало­ге /system/etc/security/cacerts/ устрой­ства. Но прос­то записать его не получит­ся, так как фай­ловая сис­тема вир­туаль­ной машины дос­тупна толь­ко для чте­ния. Переза­пус­тим вир­туаль­ную машину с парамет­ром -writable-system.

emulator -dns-server 10.10.16.46 -avd Pixel_3a_API_33_x86_64 -writable-system

А затем «руту­ем» устрой­ство и перемон­тиру­ем основной каталог. Если все про­ходит успешно, сох­раня­ем сер­тификат Burp.

adb root
adb remount
adb push 9a5ba575.0 /system/etc/security/cacerts/
Запись сертификата на Android
За­пись сер­тифика­та на Android

Пов­торя­ем попыт­ку авто­риза­ции и видим зап­рос в Burp Proxy.

Запросы в Burp Proxy
Зап­росы в Burp Proxy

Я сра­зу отпра­вил зап­рос в Burp Repeater, но ока­залось, что у сер­вера заготов­лены раз­ные вари­анты отве­та. Как мож­но видеть на скри­не, на зап­рос без заголов­ка authorization сер­вер отве­тит, что дан­ные не под­писаны. А при изме­нении дан­ных зап­роса сер­вер сооб­щит о несо­ответс­твии под­писи.

Запросы на сервер
Зап­росы на сер­вер

Тог­да будем работать через само при­ложе­ние. Я поп­робовал отпра­вить базовую наг­рузку ' or 1=1 -- -, это мог­ло бы помочь обой­ти авто­риза­цию, при­сутс­твуй здесь воз­можность для SQL-инъ­екции. Ока­залось, что при­ложе­ние не поз­воля­ет вво­дить некото­рые сим­волы.

Главное окно приложения
Глав­ное окно при­ложе­ния

Тог­да при­дет­ся понять, как фор­миру­ется под­пись. При прос­мотре содер­жимого APK-фай­ла мож­но най­ти два клю­ча RSA.

Содержимое APK-файла
Со­дер­жимое APK-фай­ла

Че­рез две‑три попыт­ки под­писать отправ­ляемые дан­ные с помощью при­ват­ного клю­ча получа­ем валид­ную под­пись!

echo -n "app_beta_mailaddr=ralf@ralf.com&app_beta_code=1234" | openssl dgst -sha256 -sign private.pem | base64 -w0
Формирование подписи данных
Фор­мирова­ние под­писи дан­ных

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

echo -n "app_beta_mailaddr=' or 1=1 -- -&app_beta_code=1234" | openssl dgst -sha256 -sign private.pem | base64 -w0
curl -k -X POST -H 'authorization: signature=oZ3SEZMP1n2xRV33Ruf9NNmW5x19GHJv5+Af/akn2dMfnViDpuTd6gP6vm0Zz42pS0VS6B/ymJsgzoekc1QZAjMyoZh9Q+TxZ1MzFFCx2iqiVD27frr+Bblw83VVDKG3Nx/cKkk6NRHeotNQRPhGmQUQrHLPeFWybleMoN5O3qrFnuPehDnYJVheiVyAMyNnJl1Lm7RGXdEva6CEyssNqIqrApbATs8ZQFFsNZgyQKMZh5u6X1sLuVXiSTkYA3fnmwrEyMNzfuvCJU9LUx4sOGRO/Zv9bVhO3knlriRfXN1DPRDX3YePUzhQrdFNApo72yRnmtsecfVJ08sz/huSgQ==' 'https://api.pokatmon-app.htb/public/validate' --data "app_beta_mailaddr=' or 1=1 -- -&app_beta_code=1234" 2>/dev/null| jq
Ответ сервера
От­вет сер­вера

В отве­те получа­ем поч­товый адрес и ключ‑инвайт. С эти­ми дан­ными авто­ризу­емся в при­ложе­нии и получа­ем редирект на www.pokatmon-app.htb.

Главное окно приложения
Глав­ное окно при­ложе­ния

Этот адрес мы уже посеща­ли, там рас­положен основной сайт, при этом в Burp Proxy видим те же инвайт и поч­товый ящик. Но обра­тим вни­мание и на веб‑сер­вер APISIX 2.10.1.

Ответ в Burp Proxy
От­вет в Burp Proxy
 

Обход каталога в Apache APISIX

По­ищем готовые экс­пло­иты для гей­твея APISIX. Зап­рос «apisix Vulnerabilities» при­водит к под­борке ста­тей про уяз­вимос­ти. Из всех упо­мяну­тых CVE наибо­лее при­мени­ма CVE-2021-43557, которая даст воз­можность обхо­да катало­га. Тут сто­ит вер­нуть­ся к ска­ниро­ванию катало­гов, так как изна­чаль­но я не при­дал зна­чения мно­жес­тву резуль­татов с кодом отве­та 403.

Результат сканирования каталогов
Ре­зуль­тат ска­ниро­вания катало­гов

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии