Здравствуйте, коллеги! Одной из самых интересных функций в веб-приложениях является загрузка файлов. Уязвимости в этой области часто приводят к серьёзным последствиям. Давайте разберём один из сценариев, с которым я столкнулся во время работы.
Предположим, что целевой домен — target.com.
Во время исследования я обнаружил поддомен edu.target.com. Сервис, предоставляемый этой программой, представляет собой образовательную платформу, на которой существуют различные пользователи, такие как студенты и преподаватели. Цель платформы — помочь студентам изучать технические дисциплины, такие как разработка программного обеспечения, робототехника и другие.
Пожалуй начнем
Я наткнулся на функцию загрузки файлов и попытался загрузить изображение, чтобы проанализировать, как работает эта функция.
Давайте попробуем загрузить PHP-скрипт
Я обнаружил, что сервер не отвечает.
После анализа поведения приложения я выяснил, что, если запрос не проходит проверку, соединение закрывается, и сервер не отвечает на запрос.
Попытка обхода валидации PHP-расширений
Чтобы обойти валидацию, необходимо определить, использует ли приложение «белый список» допустимых расширений или «чёрный список» запрещённых. Для этого я попробовал загрузить файл с произвольным расширением. Если файл загружается успешно, это значит, что приложение использует чёрный список. Если загрузка не проходит, приложение, вероятно, использует белый список с разрешёнными расширениями.
Я решил попробовать загрузить файл с расширением image.omar.
Файл был успешно загружен, что свидетельствует о том, что приложение использует чёрный список для валидации расширений.
Для обхода ограничений я попробовал загрузить файл с расширением rce.pHp.
И он успешно загрузился
На этом этапе я уже ожидал, что через несколько дней на мой банковский счёт поступит награда в размере $5000.
Теперь я отправил запрос к загруженному PHP-скрипту, чтобы выполнить функцию phpinfo().
Rce.pHp не отработал
Тогда мне пришла в голову мысль, что, возможно, мы смогли обойти проверку чёрного списка, но разработчики реализовали безопасный механизм, который предотвращает удалённое выполнение кода (RCE).
Это может быть реализовано несколькими способами, и один из них — добавление флага в файл .htaccess, который не позволит серверу исполнять PHP-файлы в каталоге загрузки изображений:
php_flag engine off
Примечание: Файл .htaccess — это распределённый конфигурационный файл, который позволяет изменять настройки сервера для конкретного каталога. Я думаю, что разработчики использовали этот способ в каталоге, чтобы предотвратить RCE.
В связи с этим, мне пришло в голову два возможных сценария:
Первый сценарий: Перезапись конфигурации и Path Traversal
1.1 Возможно, разработчики загрузили файл .htaccess в каталог sub-dir-1/. В этом случае каталог sub-dir-1/ и его подкаталоги, включая каталог для загрузки PHP-скриптов, не смогут исполнять PHP-файлы. Мы можем использовать эту ошибку конфигурации, загрузив файл .htaccess в каталог sub-dir-1/sub-dir-2/sub-dir-3/.htaccess с изменённой конфигурацией, которая позволит исполнять PHP-скрипты.
php_flag engine on
1.2 В случае, если разработчики уже загрузили файл .htaccess в каталог sub-dir-1/sub-dir-2/sub-dir-3/ и его конфигурация блокирует выполнение PHP-скриптов, я могу попытаться перезаписать этот файл, загрузив свой файл с именем .htaccess, который содержит указанную конфигурацию для разрешения выполнения PHP.
Однако, к сожалению, я вспомнил, что имя файла будет перезаписано случайной строкой символов, и в таком случае файл .htaccess не окажет никакого эффекта на конфигурацию сервера.
Второй сценарий: Path Traversal
2.0 Во втором сценарии я проверю вариант (в случае провала первого), используя технику Path Traversal в параметре имени файла. Таким образом, я смогу выйти за пределы каталога, где файл .htaccess ограничивает выполнение PHP-скриптов. В результате мой файл будет загружен в другой каталог, где нет ограничений на выполнение PHP, например:
https://target-domain.com/edu/edu/32-random-chars.pHp
Как известно, разработчики могут извлекать расширение из имени файла и вставлять его в URL-адрес. Если они используют слабое регулярное выражение для обработки расширений файлов, добавив точку (.) и применив Path Traversal, мы сможем загрузить наш скрипт в другой каталог, минуя ограничения.
Не сработало, потому что, как видно, разработчики правильно реализовали проверку с помощью регулярных выражений (если они использовали их, а не встроенную функцию PHP, такую как pathinfo()).
SQL Injection
Разработчики, при загрузке изображений, связывают каждое изображение с его пользователем.
Как они это делают?
Правильно, с использованием базы данных.
Как видно, разработчики сохраняют параметр имени файла где-то в базе данных. Этот момент вызывает у меня подозрения. Можно попробовать провести атаку с использованием SQL-инъекции, если параметры имени файла напрямую используются в запросах к базе данных, не подвергаясь должной очистке.
Это классическая уязвимость SQL-инъекции, где мы можем попробовать внедрить SQL-выражения через имя файла (для изменения поведение запросов), скомпрометировать данные или выполнить произвольные команды на сервере базы данных.
Итак, на следующем шаге, чтобы протестировать параметр «filename» на SQLI, я использовал burp suite.
Но ничего не получилось.
Публичные эксплойты:
Возможно, разработчики использовали библиотеку для обработки загруженных изображений, которая может быть уязвима.
Поэтому я начал тестировать некоторые эксплойты для распространенных библиотек, таких как ImageTragic, который использует библиотеку ImageMagick.
CVE-2016–3714, CVE-2016–3718, CVE-2016–3715, CVE-2016–3716, CVE-2016–3717
Вы можете найти эксплойты на сайте imagetragick.com.
Но это тоже не сработало. Если я не могу получить критическую уязвимость, тогда попробую найти уязвимость средней тяжести.
Stored-XSS:
Первый сценарий: Я начал тестировать stored-XSS, загружая изображение в формате SVG, которое содержало нашу XSS-нагрузку.
Теперь запросим нашу полезную нагрузку .svg XSS
Но, к сожалению, ответ приложения принудительно устанавливает заголовок Content-Type: image/jpeg, поэтому мы не сможем достичь XSS таким способом.
Второй сценарий:
На странице https://edu.target.com/teacher/profile-id
Как я уже упоминал ранее, серверная часть добавляет расширение к имени изображения.
Похоже, что расширение в параметре имени файла является лучшим местом для внедрения полезной нагрузки XSS.
XSS.omar» onmouseover=alert(1)
Однако, похоже, что приложение использует кодирование HTML-сущностей для нашей полезной нагрузки, поэтому нам не удается экранировать двойные кавычки.
DOS-атака на уровне приложения:
Приложение выполняет проверку размера изображения на стороне клиента и разрешает загрузку только изображений размером менее 1 МБ.
Я попытался осуществить DoS-атаку, загрузив изображение большего размера. Для тестирования я использовал изображение, размер которого превышал 1 МБ, чтобы проверить, есть ли валидация размера на серверной стороне. Однако снова соединение было закрыто, и сервер не ответил, что означает, что существует проверка размера изображения для предотвращения таких атак.
Раскрытие информации:
Однако я заметил, что моя полезная нагрузка не была изменена, что означает, что если я загружу изображение, то все метаданные в изображении не будут изменены.
Теперь настало время применить последний вариант.
Я загрузил изображение, которое содержит данные GPS-координат.
Вы можете найти его здесь https://github.com/ianare/exif-samples/blob/master/jpg/tests/67-0_length_string.jpg.
После загрузки изображения в веб-приложение я снова загрузил его, чтобы проверить, были ли удалены данные о географическом местоположении.
Для проверки можно использовать ExifTool для извлечения метаданных:
┌──(omar㉿kali)-[~/Downloads]
└─$ exiftool /Downloads/exif-test.jpg
Как видно, веб-приложение не удаляет данные о географическом местоположении из изображения
После того как я сообщил о проблеме, команда безопасности приняла ее как P2, поскольку большинство пользователей образовательной платформы — это несовершеннолетние студенты, и разглашение такого рода информации нарушает их конфиденциальность.
Предложенное решение:
-
Скачайте последнюю версию ImageMagick.
-
Используйте метод stripImage(), чтобы удалить эти метаданные из изображений.
Пример кода на PHP:
<?php $imageFilePath = ‘uploaded image’; $img = new imagick(); $img->readImage($imageFilePath); $img->stripImage(); $img->writeImage($imageFilePath); $img->destroy(); ?>
Надеюсь, вам понравился мой отчет!
ссылка на оригинал статьи https://habr.com/ru/articles/860808/
Добавить комментарий