Се­год­ня я покажу про­цесс ана­лиза APK-при­ложе­ния в Linux. Мы получим дан­ные для дос­тупа к зак­рытому API на сай­те, а затем через уяз­вимость LFI про­чита­ем кри­тичес­ки важ­ные фай­лы на сер­вере и получим сес­сию поль­зовате­ля. Для повыше­ния при­виле­гий взло­маем хеш Werkzeug и извле­чем учет­ные дан­ные из Solar-PuTTY.

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

warning

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

Разведка

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

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

10.10.11.37 instant.htb

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

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

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

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

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '
' ',' | sed s/,$//)
nmap -p$ports -A $1

Он дей­ству­ет в два эта­па. На пер­вом про­изво­дит­ся обыч­ное быс­трое ска­ниро­вание, на вто­ром — более тща­тель­ное ска­ниро­вание, с исполь­зовани­ем име­ющих­ся скрип­тов (опция -A).

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

Ска­нер нашел все­го два откры­тых пор­та: 22 — служ­ба OpenSSH 9.6p1 — и 80 — веб‑сер­вер Apache 2.4.58. Сра­зу идем смот­реть сайт и находим там ссыл­ку на заг­рузку фай­ла APK (фор­мат при­ложе­ний для Android).

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

Точка входа

Для пер­вично­го ана­лиза APK будем исполь­зовать фрей­мворк MobSF. Мож­но ска­чать его с GitHub и раз­вернуть локаль­но либо исполь­зовать обще­дос­тупный вари­ант по адре­су mobsf.live. Я вос­поль­зовал­ся вто­рым вари­антом.

За­ходим на сайт и заг­ружа­ем при­ложе­ние на ана­лиз.

Очередь сканирования
Оче­редь ска­ниро­вания

Спус­тя нес­коль­ко минут ста­тус задачи ска­ниро­вания поменя­ется и будет дос­тупна ссыл­ка с отче­том. Сре­ди общей ста­тис­тики нам так­же дос­тупен деком­пилиро­ван­ный код при­ложе­ния. Хотя для деком­пиляции луч­ше обра­тить­ся к Decompiler.com.

Отчет MobSF
От­чет MobSF

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

Список URL-адресов
Спи­сок URL-адре­сов

Так мы узна­ём о новом домене mywalletv1.instant.htb, поэто­му обновля­ем запись в фай­ле /etc/hosts.

10.10.11.37 instant.htb mywalletv1.instant.htb

Так­же MobSF про­бует най­ти раз­личные сек­реты, токены и клю­чи. Вто­рой очень похож на часть JWT.

Список возможных секретов
Спи­сок воз­можных сек­ретов

По­оче­ред­но прос­матри­ваем деком­пилиро­ван­ные фай­лы Java, в которых исполь­зуют­ся URL-адре­са. В фай­ле AdminActivities.java выпол­няет­ся зап­рос на http://mywalletv1.instant.htb/api/v1/view/profile и исполь­зует­ся токен JWT.

Содержимое файла AdminActivities.java
Со­дер­жимое фай­ла AdminActivities.java

Де­коди­ровать JWT мож­но на сай­те JWT.io. В дан­ных токена видим роль Admin.

Декодированный JWT-токен
Де­коди­рован­ный JWT-токен

При обра­щении к API profile через бра­узер получим ошиб­ку 401.

Ответ сервера
От­вет сер­вера

Од­нако, при­менив най­ден­ный JWT, мы получа­ем код отве­та 200 вмес­те с зап­рошен­ными дан­ными.

Запрос и ответ в Burp Repeater
Зап­рос и ответ в Burp Repeater

JWT рабочий, а зна­чит, мож­но иссле­довать API.

Точка опоры

API

Боль­ше ничего инте­рес­ного я не нашел, поэто­му перехо­дим к сле­дующе­му шагу — деком­пиляции APK на уже упо­мяну­том Decompiler.com.

Декомпилирование APK
Де­ком­пилиро­вание APK

Поп­робу­ем най­ти новые точ­ки API, которые не были ука­заны в MobSF. Для это­го исполь­зуем всем извес­тную коман­ду grep.

grep -iR instant.htb ./
Поиск URL
По­иск URL

И находим новый под­домен — судя по име­ни, это Swagger UI. Обновля­ем запись в фай­ле /etc/hosts и откры­ваем новый сайт в бра­узе­ре.

10.10.11.37 instant.htb mywalletv1.instant.htb swagger-ui.instant.htb
Swagger UI
Swagger UI

Изу­чаем новые API и про­буем для тес­та зап­росить спи­сок поль­зовате­лей.

curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/list/users" -H "accept: application/json" | jq
Ответ сервера
От­вет сер­вера

Сер­вер отве­тил кодом 401. Поп­робу­ем исполь­зовать най­ден­ный ранее JWT.

curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/list/users" -H "accept: application/json" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq
Ответ сервера
От­вет сер­вера

Сер­вер вер­нул дан­ные, а зна­чит, мы можем исполь­зовать API с тем же токеном.

Path traversal

Об­рати вни­мание на API для получе­ния логов /api/v1/admin/read/log.

API для чтения лога
API для чте­ния лога

В парамет­ре log_file_name дол­жно быть переда­но имя фай­ла. Поп­робу­ем выпол­нить обход катало­га и про­читать файл /etc/passwd.

curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../../../../../../../etc/passwd" -H "accept: application/json" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq
Содержимое файла /ect/passwd
Со­дер­жимое фай­ла /ect/passwd

info

Под­робное объ­ясне­ние тех­ники path traversal ты можешь най­ти в статье «File Inclusion и Path Traversal. Раз­бира­ем две базовые веб‑уяз­вимос­ти».

Уяз­вимость path traversal при­сутс­тву­ет, а зна­чит, мы можем читать про­изволь­ные фай­лы в сис­теме. Про­верим, нет ли у поль­зовате­ля зак­рытых клю­чей SSH.

curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../../../../../../../home/shirohige/.ssh/id_rsa" -H "accept: application/json" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq
Закрытый ключ SSH
Зак­рытый ключ SSH

Сох­раня­ем ключ на локаль­ную машину, наз­нача­ем пра­ва (chmod 0600 id_rsa) и под­клю­чаем­ся к сер­веру от име­ни поль­зовате­ля shirohige.

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

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

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

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

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

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

Для локаль­ного хос­та прос­лушива­ются пор­ты 8808 и 8888.

Список активных портов
Спи­сок активных пор­тов

В фай­ле с перемен­ными окру­жения Instant-Api находим сек­ретный ключ.

Переменные окружения из файлов .env
Пе­ремен­ные окру­жения из фай­лов .env

По­лучен хеш пароля из фай­ла базы дан­ных по сле­дующе­му пути:

/home/shirohige/projects/mywallet/Instant-Api/mywallet/instance/instant.db
Файлы базы данных
Фай­лы базы дан­ных

В катало­ге /opt есть дирек­тория backups, дос­тупная текуще­му поль­зовате­лю.

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

Сре­ди недав­но переза­писан­ных фай­лов находим бэкап сес­сион­ных фай­лов Solar-PuTTY.

Недавно перезаписанные файлы
Не­дав­но переза­писан­ные фай­лы

В фай­ле сес­сии Solar-PuTTY /opt/backups/Solar-PuTTY/sessions-backup.dat есть зашиф­рован­ный блоб дан­ных.

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

Для его рас­шифров­ки будем исполь­зовать ути­литу SolarPuTTYDecrypt. Одна­ко для это­го пот­ребу­ется пароль.

Запуск утилиты SolarPuTTYDecrypt
За­пуск ути­литы SolarPuTTYDecrypt

Вер­немся к най­ден­ному фай­лу базы дан­ных instant.db. Ска­чаем его на локаль­ную машину и прос­мотрим с помощью DB Browser. Из таб­лицы wallet_users получим два хеша PBKDF2.

Содержимое таблицы wallet_users
Со­дер­жимое таб­лицы wallet_users

Я не нашел спо­соба переб­рать хеши с помощью hashcat, поэто­му вос­поль­зовал­ся скрип­том WerkzeugHashCracker.

python3 app.py -w Wordlist/small_rockyou.txt 'pbkdf2:sha256:600000$YnRgjnim$c9541a8c6ad40bc064979bc446025041ffac9af2f762726971d8a28272c550ed'
Перебор хеша WerkzeugHashCracker
Пе­ребор хеша WerkzeugHashCracker

С подоб­ранным паролем уда­лось рас­шифро­вать и дан­ные Solar-PuTTY.

Расшифрованный файл Solar-PuTTY
Рас­шифро­ван­ный файл Solar-PuTTY

В фай­ле лежат учет­ные дан­ные поль­зовате­ля root, и нам нич­то не меша­ет авто­ризо­вать­ся от его име­ни по SSH.

Флаг рута
Флаг рута

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