Невозможно отучить людей изучать самые ненужные предметы.
Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3
Надо знать обо всем понемножку, но все о немногом.
Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы
Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)
Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода
Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5
Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости
Справочник от А до Я
HTML, CSS, JavaScript
Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы
Помогли мы вам |
Не буду скрывать, я — фанат программы баг‑баунти VK на HackerOne. Иногда холдинг приобретает новые компании, и программа расширяется, что дает баг‑хантерам неплохой шанс собрать «низко висящие фрукты» — уязвимости, которые могут быть найдены без существенных затрат времени и усилий.
По своему опыту могу сказать, что получить доступ к чему‑то, что до тебя никто не пытался взломать, очень выгодно. На площадке HackerOne есть возможность подписаться на интересующую тебя программу и получать обновления о любых изменениях в правилах. Этим я и воспользовался, чтобы быть одним из первых, кто начнет тестировать недавно добавленный сервис.
В течение 2021 года я не очень активно хантил и не следил за обновлениями в избранной программе. Именно по этой причине я пропустил уведомление о том, что платформа Seedr, которая помогает быстро распространять видео в интернете (сейчас уже не действующая), была добавлена в скоуп.
Моя первая встреча с Seedr состоялась в октябре 2021 года. Я начал тестировать и сразу же обнаружил несколько банальных XSS-уязвимостей, но решил не сообщать о них, так как шанс получить дубликат был слишком высок.
В настоящее время ты можешь просмотреть раскрытые отчеты других баг‑хантеров и заметить, насколько нетипичные для современных приложений уязвимости они нашли в Seedr:
Подумав, что мой поезд ушел, я решил не тратить силы на этот проект и продолжил прокрастинировать.
Я вернулся к тестированию Seedr во время декабрьского отпуска в другой стране, где с собой у меня был лишь рюкзак и ноутбук. После некоторого времени пребывания в таких условиях у меня просыпается «баг‑баунти‑голод» и появляется желание найти что‑нибудь интересное. Для разогрева я обычно возвращаюсь к уже знакомым сервисам и стараюсь взглянуть на них свежим взглядом.
На этот раз я уделил больше внимания разведке Seedr, а именно поиску и перечислению поддоменов, сканированию портов, перебору веб‑директорий и так далее. К счастью, я нашел более заманчивые вещи: GitLab, Grafana, несколько хостов API, cron-файлы в веб‑директории, трассировки стека и многое другое. Чем больше точек входа находишь, тем выше шанс отыскать что‑то интересное. Хотя ни одна из находок не оказалась стоящей того, чтобы о ней сообщить, кое‑что все же привлекло мое внимание.
В исходном HTML-коде страницы https://
я заметил следующий комментарий:
https://player.seedr.ru/video?vid=cpapXGq50UY&post_id=57b6ceef64225d5b0f8b456c&config=https%3A%2F%2Fseedr.com%2Fconfig%2F57975d1b64225d607e8b456e.json&hosting=youtube
Готов поспорить, что более опытный читатель уже захотел изменить GET-параметр config
на свой хост для получения входящего HTTP-соединения, что я и сделал. Но после нескольких попыток не получил ни одного отстука и продолжил экспериментировать с другими параметрами.
Когда я открыл в браузере ссылку https://
, я заметил, что метатеги заполнены по разметке Open Graph и содержат информацию о видео: название, описание, превью и так далее.
После нескольких тестовых запросов я понял, что GET-параметры post_id
и config
не оказывают существенного влияния на ответ, поэтому упростил URL до https://
.
Предположив, что плеер, скорее всего, поддерживает не только YouTube, я изменил GET-параметр hosting
на coub
и vimeo
.
Итак, похоже, в зависимости от значения GET-параметра hosting
сервер с помощью PHP-функции file_get_contents(
выполняет HTTP-запрос к YouTube, Vimeo или Coub API, загружает метаданные о видео (GET-параметр vid
), обрабатывает их и возвращает HTML-страницу плеера с видео и заполненными по разметке Open Graph метатегами.
GET-параметр vid
является точкой инъекции, так как он позволяет контролировать последнюю часть пути в функции file_get_contents(
с помощью символов обхода пути (/..
) и других полезных символов (?, #, @ и так далее).
Что еще интересно, в случае с Vimeo сервер делает запрос к http://
. И оказывается, что при использовании расширения .
в пути Vimeo возвращает не JSON, а сериализованные данные!
Я предположил, что после функции file_get_contents(
сервер десериализует ответ от Vimeo с помощью функции unserialize(
.
Ого, неужели у нас здесь небезопасная десериализация? Безопасная, пока ответ контролирует Vimeo.
В тот момент у себя в голове я уже видел три возможных сценария атаки:
file_get_contents()
с целью добиться слепой SSRF, то есть выполнить HTTP-запрос на подконтрольный мне ресурс и в теории добиться небезопасной десериализации.vimeo.com
и добиться небезопасной десериализации.vimeo.com
→ SSRF → небезопасная десериализация.После нескольких часов различных модификаций GET-параметра vid
и локального фаззинга функции file_get_contents(
я не нашел ничего полезного и параллельно решил поделиться всей имеющейся информацией об этой находке с несколькими надежными товарищами.
Итак, первый сценарий не сработал, поэтому я перешел к следующему — контролируемому ответу на vimeo.
.
Эндпоинт с контролируемым ответом должен отвечать следующим требованиям:
Ниже представлены некоторые из моих попыток найти требуемое поведение на vimeo.
.
Первая: injection
is not a valid method.
Недостатки: код ответа HTTP 404 Not Found, не поддерживаются символы {
, ""
.
Вторая: injection
is not a valid format.
Недостатки: код ответа HTTP 404 Not Found, не поддерживаются символы {
, ""
.
Третья: jаvascript callback.
Недостатки: /
в начале строки, не поддерживаются символы {
, ""
.
Четвертая: экспорт чата прямой трансляции.
Недостатки: дата и имя в начале строки, требуется аутентификация.
К сожалению, второй сценарий также не сработал, поэтому моей последней надеждой оставалось найти открытый редирект на vimeo.
. Ранее я уже встречал опубликованный отчет на HackerOne от 2015 года с открытым редиректом на vimeo.
, поэтому предположил, что есть небольшой шанс найти еще один. На самом деле я одновременно искал открытый редирект еще во время проверки второго сценария, но снова ничего не нашел.
Все это время, пока я раскручивал уязвимость, я думал о статье Harsh Jaiswal Vimeo SSRF with code execution potential. Я отчетливо помнил, что для успешной эксплуатации использовалось несколько открытых редиректов на vimeo.
. Уязвимость была найдена еще в 2019 году, поэтому я ожидал, что описываемые в статье открытые редиректы уже исправлены. Но поскольку, вероятно, это был мой единственный шанс, я начал копать в этом направлении.
Из‑за того, что информация на скриншотах была недостаточно скрыта, удалось предположить уязвимый эндпоинт по используемым GET-параметрам. Учитывая это, я немного погуглил и почитал документацию Vimeo API и смог определить, какой именно эндпоинт использовал Harsh в своей цепочке. В любом случае оставалось неясным, какие значения GET-параметров я должен передать.
Я редко прошу кого‑то о помощи, не считая нескольких друзей, но, поскольку я был в тупике, Harsh был моей последней надеждой.
После того как я написал ему и предоставил всю имеющуюся информацию, он поделился со мной рабочей ссылкой с открытым редиректом, которая оказалась такой же, как я и подозревал, но с верными значениями GET-параметров. По этой ссылке я понял, что это не баг на vimeo.
, а фича (действительно, это не шутка).
Итак, теперь у меня есть работающий открытый редирект на vimeo.
, осталось только его применить.
Отлично, я наконец‑то словил HTTP-запрос на свой хост. Прежде чем перейти к десериализации, я решил немного поиграть с SSRF. Результаты смотри на скриншотах.
Из‑за того что возвращаемое значение из функции file_get_contents(
передается сразу в функцию unserialize(
, у меня не получилась полная SSRF, чтобы читать успешные ответы от внутренних сервисов. Но по крайней мере, у меня уже была полуслепая SSRF с возможностью выполнять сканирование портов.
Как только я понял, что использовал почти весь потенциал этой SSRF, я переключился на эксплуатацию функции unserialize(
.
Вкратце объясню, что необходимо для успешной эксплуатации небезопасной десериализации в PHP:
__wakeup()
, __destroy()
, __toString()
и так далее);Как видишь, на тот момент выполнялось только одно требование из четырех. О серверном коде на хосте я знал слишком мало, поэтому единственный способ эксплуатации — это вслепую попробовать все известные цепочки гаджетов. Для этого я использовал инструмент PHPGGC, который по сути является набором полезных нагрузок для эксплуатации функции unserialize(
вместе с инструментом для их генерации. В то время он содержал почти 90 доступных нагрузок. Большая часть из них предназначена для различных CMS и фреймворков, таких как WordPress, ThinkPHP, TYPO3, Magento, Laravel, которые в моем случае были совершенно бесполезны. Поэтому я сделал ставку на такие широко используемые библиотеки, как Doctrine, Guzzle, Monolog и Swift Mailer.
|
|