stihl не предоставил(а) никакой дополнительной информации.
В этом райтапе я покажу, как провести атаку на базу данных SQLite при помощи собственного загружаемого модуля. Но сначала получим доступ к приватным данным через уязвимость IDOR и захватим учетку пользователя.
Наша цель — получение прав рута на машине Drive с учебной площадки Hack The Box. Уровень машины обозначен как сложный.
И запускаем сканирование портов.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта:
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).
Результат работы скрипта
Сканер нашел два открытых порта:
Главная страница сайта
Доступные файлы
Зато на сайте можно зарегистрироваться и авторизоваться. Сделаем это, чтобы получить доступ к большему числу функций.
Главная страница авторизованного пользователя
После авторизации появилась возможность загружать файлы на сервер.
Форма загрузки файлов
Потратив значительное время на попытки загрузить шелл, я не смог добиться результатов. Найденный файл ничего полезного не содержит.
Содержимое файла
Однако после загрузки собственного файла появляется интересная зацепка. Обрати внимание на путь к странице — /120/getFileDetail/. При этом путь к файлу админа — /100/getFileDetail/.
Результат загрузки файла
Можно перебрать все номера и, возможно, получить доступ к файлам других пользователей (если не реализована система контроля доступа).
Перенаправим запрос из Burp Proxy в Burp Intruder и укажем место перебора.
Burp Intruder — вкладка Positions
На вкладке Payloads нужно установить тип Numbers и указать номера с 1 до 1000 с шагом 1.
Burp Intruder — вкладка Payloads
После запуска атаки сортируем результаты по коду ответа и замечаем несколько документов, которые возвращают ошибку 401.
Результат перебора
Значит, контроль доступа к файлам все же присутствует.
Ответ сервера
Список загруженных файлов
Если кликнуть по ссылке Reserve, нас редиректит на другую страницу — /125/block/.
Страница редактирования файла
Снова перебираем файлы тем же способом. На странице block контроля доступа может и не быть.
Burp Intruder — вкладка Positions
Результат перебора
Фильтруем результат по коду ответа и видим те же страницы, что и раньше, однако теперь вместо кода ответа 401 получаем 200. Значит, мы можем просматривать файлы других пользователей.
Ответ сервера в Render
Открываем найденные страницы через браузер и ищем интересную информацию в файлах. В одном из файлов находим пароль, а в другом — сообщение об устранении ошибок безопасности.
Содержимое файла 79
Содержимое файла 99
С полученным паролем авторизуемся по SSH от имени пользователя martin.
Сессия пользователя martin
или Зарегистрируйся (PEASS) — набор скриптов, которые проверяют систему на автомате и выдают подробный отчет о потенциально интересных файлах, процессах и настройках.
Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим сканирование. Затем посмотрим, что интересного нашел сканер.
В списке прослушиваемых портов — типичные для службы MySQL порты 3306 и 3000.
Прослушиваемые порты
Есть много пользователей, от имени которых можно авторизоваться.
Пользователи с консолью
В каталоге /var/www/backups — несколько бэкапов базы данных SQLite.
Найденные бэкапы
Скачиваем обнаруженные бэкапы на свой хост. Архивы открыть не получится, так как они все защищены паролем, зато откроем файл db.sqlite3 с помощью Для просмотра ссылки Войдиили Зарегистрируйся.
Таблицы в базе данных
В таблице accounts_customuser хранится информация о пользователях, в том числе и хеши их паролей.
Содержимое таблицы accounts_customuser
Сохраняем хеши в файл для брутфорса с помощью знаменитой утилиты hashcat. Однако этой утилите нужно указать тип хеша в параметре -m. Узнать соответствующий режим можно, распарсив справку hashcat.
Справка hashcat
Получаем информацию о хеше и его типе (Hash mode). Теперь собранные хеши можно отправить на перебор по словарю rockyou.txt.
Результат взлома хеша
Из всех хешей поддался взлому только один. Его я решил сразу поспреить по всем пользователям на SSH с помощью Для просмотра ссылки Войдиили Зарегистрируйся.
Однако пароль не подошел ни к одному из логинов.
Спрей паролей на SSH
Пробуем найти другой путь, к примеру через сервис на локальном порте 3000. Но сначала этот порт нужно пробросить до нашей машины.
Теперь весь трафик, который мы пошлем на локальный порт 3000, будет туннелирован на порт 3000 указанного хоста (в данном случае 127.0.0.1) через SSH-хост. Заходим через браузер и обнаруживаем сервис Gitea.
Для просмотра ссылки Войдиили Зарегистрируйся
Этот сервис позволяет без регистрации просмотреть публичные репозитории и пользователей.
Список пользователей Gitea
Там есть знакомый нам юзер martin, от имени которого мы успешно авторизуемся. Теперь нам доступен репозиторий DoodleGrive пользователя cris.
Доступные репозитории
Страница репозитория
У репозитория пять коммитов, которые нужно внимательно просмотреть. В одном из них в скрипте db_backup.sh находим пароль, использованный для шифрования архивов с бэкапами.
Исходный код db_backup.sh
Извлекаем из всех архивов базы, извлекаем из них новые пароли и отправляем на брут, как это делали в прошлый раз. Таким образом получаем еще три новых пароля.
Результат взлома хешей
Теперь есть несколько логинов и паролей, комбинации которых нужно перебрать.
Результат брута пользователей
Когда найдем валидную пару учетных данных, авторизуемся на хосте и заберем первый флаг.
Флаг пользователя
Содержимое домашнего каталога пользователей
При запуске файла считываем имя пользователя и пароль, пропускаем их через функцию sanitize_string и сравниваем со статически указанными учетными данными (строка 28). Если введенные учетные данные верны, вызывается функция main_menu.
Декомпилированный код функции main
Функция sanitize_string просто фильтрует символы, указанные в строке 14.
Декомпилированный код функции sanitize_string
Функция main_menu предлагает пользователю выбрать опцию. В данном случае инструкция в строке 31, ломающая код, представляет собой оператор switch-case. Это становится понятно, если перейти от декомпилятора к дизассемблеру и активировать режим графа.
Декомпилированный код функции main_menu
Функция main_menu в виде графа
Функции в каждом блоке можно снова просматривать в декомпиляторе. Первые четыре интереса не представляют, а вот функцию activate_user_account лучше изучить тщательнее.
Эта функция запрашивает имя пользователя, пропускает через sanitize_string, а потом использует в запросе к базе данных SQLite.
Декомпилированный код функции sanitize_string
Так как никаких фильтров, кроме функции sanitize_string, не используется, следующий запрос уязвим к SQL-инъекции.
UPDATE accounts_customuser SET is_active=1 WHERE username="%s";
В данном случае есть возможность добиться выполнения кода в рамках запущенного процесса через загрузку собственного модуля SQLite. Сделать это мы можем при помощи функции load_extension.
Для этого на скорую руку смастерим библиотеку, которая будет содержать функцию с именем sqlite3_NAME_init, где NAME — имя самой библиотеки. Код в нашей библиотеке установит S-бит файлу командной оболочки /bin/bash.
Скомпилируем библиотеку и сохраним с именем r.
Осталась еще одна сложная часть — внедрить в запрос функцию load_extension. Для этого сначала закроем двойную кавычку, затем вызовем целевую функцию с созданным модулем load_extension("./r") и снова откроем кавычки. Только функция sanitize_string отфильтрует символ /, поэтому нам нужно избежать использования строки "./r". В этом нам помогут возможности базы SQLite: к примеру, можем собрать строку из кодов символов.
Получение кодов символов
В итоге для загрузки модуля через SQL-инъекцию нужно в качестве имени пользователя указать вот такую строку:
Эксплуатация уязвимости
При проверке файла /bin/bash видим установленный S-бит. А значит, можно запустить новый шелл от имени рута.
Флаг рута
Машина захвачена!
Наша цель — получение прав рута на машине Drive с учебной площадки Hack The Box. Уровень машины обозначен как сложный.
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Разведка
Сканирование портов
Добавляем IP-адрес машины в /etc/hosts:10.10.11.235 drive.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.2p1;
- 80 — веб‑сервер Nginx 1.18.0.

Точка входа
На странице Home есть файл, который в данный момент недоступен.
Зато на сайте можно зарегистрироваться и авторизоваться. Сделаем это, чтобы получить доступ к большему числу функций.

После авторизации появилась возможность загружать файлы на сервер.

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

Однако после загрузки собственного файла появляется интересная зацепка. Обрати внимание на путь к странице — /120/getFileDetail/. При этом путь к файлу админа — /100/getFileDetail/.

Можно перебрать все номера и, возможно, получить доступ к файлам других пользователей (если не реализована система контроля доступа).
Перенаправим запрос из Burp Proxy в Burp Intruder и укажем место перебора.

На вкладке Payloads нужно установить тип Numbers и указать номера с 1 до 1000 с шагом 1.

После запуска атаки сортируем результаты по коду ответа и замечаем несколько документов, которые возвращают ошибку 401.

Значит, контроль доступа к файлам все же присутствует.

Точка опоры
В списке загруженных файлов есть еще одна интересная функция — зарезервировать файл.
Если кликнуть по ссылке Reserve, нас редиректит на другую страницу — /125/block/.

Снова перебираем файлы тем же способом. На странице block контроля доступа может и не быть.


Фильтруем результат по коду ответа и видим те же страницы, что и раньше, однако теперь вместо кода ответа 401 получаем 200. Значит, мы можем просматривать файлы других пользователей.

Открываем найденные страницы через браузер и ищем интересную информацию в файлах. В одном из файлов находим пароль, а в другом — сообщение об устранении ошибок безопасности.


С полученным паролем авторизуемся по SSH от имени пользователя martin.

Продвижение
Теперь нам необходимо собрать информацию. Я буду использовать для этого скрипты PEASS.Справка: скрипты PEASS
Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Для просмотра ссылки ВойдиЗагрузим на хост скрипт для Linux, дадим право на выполнение и запустим сканирование. Затем посмотрим, что интересного нашел сканер.
В списке прослушиваемых портов — типичные для службы MySQL порты 3306 и 3000.

Есть много пользователей, от имени которых можно авторизоваться.

В каталоге /var/www/backups — несколько бэкапов базы данных SQLite.

Скачиваем обнаруженные бэкапы на свой хост. Архивы открыть не получится, так как они все защищены паролем, зато откроем файл db.sqlite3 с помощью Для просмотра ссылки Войди

В таблице accounts_customuser хранится информация о пользователях, в том числе и хеши их паролей.

Сохраняем хеши в файл для брутфорса с помощью знаменитой утилиты hashcat. Однако этой утилите нужно указать тип хеша в параметре -m. Узнать соответствующий режим можно, распарсив справку hashcat.
hashcat --example | grep 'sha1\$' -B12 -A1

Получаем информацию о хеше и его типе (Hash mode). Теперь собранные хеши можно отправить на перебор по словарю rockyou.txt.
hashcat -m 124 hashes.txt rockyou.txt

Из всех хешей поддался взлому только один. Его я решил сразу поспреить по всем пользователям на SSH с помощью Для просмотра ссылки Войди
crackmapexec ssh drive.htb -u users.txt -p john316
Однако пароль не подошел ни к одному из логинов.

Пробуем найти другой путь, к примеру через сервис на локальном порте 3000. Но сначала этот порт нужно пробросить до нашей машины.
ssh [EMAIL]martin@drive.htb[/EMAIL] -L 3000:127.0.0.1:3000
Теперь весь трафик, который мы пошлем на локальный порт 3000, будет туннелирован на порт 3000 указанного хоста (в данном случае 127.0.0.1) через SSH-хост. Заходим через браузер и обнаруживаем сервис Gitea.
Для просмотра ссылки Войди
Этот сервис позволяет без регистрации просмотреть публичные репозитории и пользователей.

Там есть знакомый нам юзер martin, от имени которого мы успешно авторизуемся. Теперь нам доступен репозиторий DoodleGrive пользователя cris.


У репозитория пять коммитов, которые нужно внимательно просмотреть. В одном из них в скрипте db_backup.sh находим пароль, использованный для шифрования архивов с бэкапами.

Извлекаем из всех архивов базы, извлекаем из них новые пароли и отправляем на брут, как это делали в прошлый раз. Таким образом получаем еще три новых пароля.
hashcat -m 124 hashes.txt rockyou.txt

Теперь есть несколько логинов и паролей, комбинации которых нужно перебрать.
crackmapexec ssh drive.htb -u users.txt -p pass.txt

Когда найдем валидную пару учетных данных, авторизуемся на хосте и заберем первый флаг.

Локальное повышение привилегий
В домашнем каталоге пользователя присутствует приложение doodleGrive-cli с установленным S-битом.
Справка: бит SUID
Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь, запускающий этот файл, получает повышение прав до пользователя — владельца файла в рамках запущенного процесса. После получения повышенных прав приложение может выполнять задачи, которые недоступны обычному пользователю. Из‑за возможности состояния гонки многие операционные системы игнорируют S-атрибут, установленный shell-скриптам.
То есть если мы найдем уязвимость в бинаре, то сможем полностью захватить сервер. Скачиваем файл на локальный хост через SSH для анализа. Открываем в любом удобном дизассемблере с декомпилятором, я использую IDA Pro.
scp [EMAIL]tom@drive.htb[/EMAIL]:~/doodleGrive-cli ./
При запуске файла считываем имя пользователя и пароль, пропускаем их через функцию sanitize_string и сравниваем со статически указанными учетными данными (строка 28). Если введенные учетные данные верны, вызывается функция main_menu.

Функция sanitize_string просто фильтрует символы, указанные в строке 14.

Функция main_menu предлагает пользователю выбрать опцию. В данном случае инструкция в строке 31, ломающая код, представляет собой оператор switch-case. Это становится понятно, если перейти от декомпилятора к дизассемблеру и активировать режим графа.


Функции в каждом блоке можно снова просматривать в декомпиляторе. Первые четыре интереса не представляют, а вот функцию activate_user_account лучше изучить тщательнее.
Эта функция запрашивает имя пользователя, пропускает через sanitize_string, а потом использует в запросе к базе данных SQLite.

Так как никаких фильтров, кроме функции sanitize_string, не используется, следующий запрос уязвим к SQL-инъекции.
UPDATE accounts_customuser SET is_active=1 WHERE username="%s";
В данном случае есть возможность добиться выполнения кода в рамках запущенного процесса через загрузку собственного модуля SQLite. Сделать это мы можем при помощи функции load_extension.
Для этого на скорую руку смастерим библиотеку, которая будет содержать функцию с именем sqlite3_NAME_init, где NAME — имя самой библиотеки. Код в нашей библиотеке установит S-бит файлу командной оболочки /bin/bash.
Код:
#include <stdlib.h>
#include <unistd.h>
void sqlite3_r_init() {
setuid(0);
setgid(0);
system("/usr/bin/chmod +s /bin/bash");
}
Скомпилируем библиотеку и сохраним с именем r.
gcc -shared r.c -o r.so -nostartfiles -fPIC
Осталась еще одна сложная часть — внедрить в запрос функцию load_extension. Для этого сначала закроем двойную кавычку, затем вызовем целевую функцию с созданным модулем load_extension("./r") и снова откроем кавычки. Только функция sanitize_string отфильтрует символ /, поэтому нам нужно избежать использования строки "./r". В этом нам помогут возможности базы SQLite: к примеру, можем собрать строку из кодов символов.

В итоге для загрузки модуля через SQL-инъекцию нужно в качестве имени пользователя указать вот такую строку:
"+load_extension(char(46,47,114))+"

При проверке файла /bin/bash видим установленный S-бит. А значит, можно запустить новый шелл от имени рута.

Машина захвачена!