В этом райтапе я покажу, как провести атаку на базу данных SQLite при помощи собственного загружаемого модуля. Но сначала получим доступ к приватным данным через уязвимость IDOR и захватим учетку пользователя. Наша цель — получение прав рута на машине Drive с учебной площадки Hack The Box. Уровень машины обозначен как сложный. Разведка Сканирование портов Добавляем 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. Мы, как всегда, начинаем с проверки сайта, поскольку учетных данных от SSH у нас пока нет. Точка входа На странице 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. Чтобы собрать информацию и наметить цели, можно использовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют систему на автомате и выдают подробный отчет о потенциально интересных файлах, процессах и настройках. Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим сканирование. Затем посмотрим, что интересного нашел сканер. В списке прослушиваемых портов — типичные для службы MySQL порты 3306 и 3000. Есть много пользователей, от имени которых можно авторизоваться. В каталоге /var/www/backups — несколько бэкапов базы данных SQLite. Скачиваем обнаруженные бэкапы на свой хост. Архивы открыть не получится, так как они все защищены паролем, зато откроем файл db.sqlite3 с помощью DB Browser. В таблице accounts_customuser хранится информация о пользователях, в том числе и хеши их паролей. Сохраняем хеши в файл для ****форса с помощью знаменитой утилиты hashcat. Однако этой утилите нужно указать тип хеша в параметре -m. Узнать соответствующий режим можно, распарсив справку hashcat. hashcat --example | grep 'sha1\$' -B12 -A1 Получаем информацию о хеше и его типе (Hash mode). Теперь собранные хеши можно отправить на перебор по словарю rockyou.txt. hashcat -m 124 hashes.txt rockyou.txt Из всех хешей поддался взлому только один. Его я решил сразу поспреить по всем пользователям на SSH с помощью CrackMapExec. crackmapexec ssh drive.htb -u users.txt -p john316 Однако пароль не подошел ни к одному из логинов. Пробуем найти другой путь, к примеру через сервис на локальном порте 3000. Но сначала этот порт нужно пробросить до нашей машины. ssh martin@drive.htb -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 tom@drive.htb:~/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. Скомпилируем библиотеку и сохраним с именем 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-бит. А значит, можно запустить новый шелл от имени рута. Машина захвачена!