9.5 KiB
Upgrade Header Smuggling
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
-
Découvrez The PEASS Family, notre collection exclusive de NFTs
-
Obtenez le swag officiel PEASS & HackTricks
-
Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
-
Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
H2C Smuggling
HTTP2 sur texte clair (H2C)
Une connexion HTTP normale dure généralement seulement pendant la durée d'une seule requête. Cependant, H2C ou "http2 sur texte clair" est là où une connexion http transitoire normale est mise à niveau vers une connexion persistante qui utilise le protocole binaire http2 pour communiquer en continu au lieu d'une seule requête en utilisant le protocole http en texte clair.
La deuxième partie de la contrebande se produit lorsqu'un proxy inverse est utilisé. Normalement, lorsque des requêtes http sont effectuées vers un proxy inverse, le proxy gère la requête, traite une série de règles de routage, puis transfère la requête vers l'arrière-plan et renvoie ensuite la réponse. Lorsqu'une requête http inclut un en-tête Connection: Upgrade
, comme pour une connexion websocket, le proxy inverse maintiendra la connexion persistante entre le client et le serveur, permettant la communication continue nécessaire pour ces protocoles. Pour une connexion H2C, le RFC exige que 3 en-têtes soient présents :
Upgrade: h2c
HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
Connection: Upgrade, HTTP2-Settings
Où se trouve la faille ? Lors de la mise à niveau d'une connexion, le proxy inverse cessera souvent de traiter les demandes individuelles, en supposant que une fois la connexion établie, son travail de routage est terminé. En utilisant H2C Smuggling, nous pouvons contourner les règles qu'un proxy inverse utilise lors du traitement des demandes telles que le routage basé sur le chemin, l'authentification ou le traitement WAF, à condition que nous puissions établir une connexion H2C en premier.
Proxies vulnérables
Notez dans l'explication de la vulnérabilité que le serveur proxy doit transférer l'en-tête Upgrade, et parfois l'en-tête Connection doit également être transféré avec succès.
Par défaut, les services suivants transfèrent les en-têtes Upgrade et Connection lors de la transmission par proxy, permettant ainsi la contrebande h2c dès la sortie de la boîte :
- HAProxy
- Traefik
- Nuster
Par défaut, ces services ne transfèrent pas les en-têtes Upgrade et Connection lors de la transmission par proxy, mais peuvent être configurés de manière non sécurisée (en passant des en-têtes Upgrade et Connection non filtrés) :
- AWS ALB/CLB
- NGINX
- Apache
- Squid
- Varnish
- Kong
- Envoy
- Apache Traffic Server
Exploitation
Le billet de blog original souligne que tous les serveurs ne transféreront pas les en-têtes requis pour une mise à niveau de connexion H2C conforme. Cela signifie que les équilibreurs de charge tels que AWS ALB/CLB, NGINX et Apache Traffic Server, entre autres, empêcheront une connexion H2C par défaut. Cependant, à la fin du billet de blog, il mentionne que « tous les backends n'étaient pas conformes, et nous pouvions tester avec la variante non conforme Connection: Upgrade
, où la valeur HTTP2-Settings
est omise de l'en-tête Connection
».
{% hint style="danger" %}
Notez que même si l'URL de proxy_pass
(le point final vers lequel le proxy transfère la connexion) pointait vers un chemin spécifique tel que http://backend:9999/socket.io
, la connexion sera établie avec http://backend:9999
, vous pouvez donc contacter tout autre chemin à l'intérieur de ce point final interne en abusant de cette technique. Il n'est donc pas important qu'un chemin soit spécifié dans l'URL de proxy_pass.
{% endhint %}
En utilisant les outils https://github.com/BishopFox/h2csmuggler et https://github.com/assetnote/h2csmuggler, vous pouvez essayer de contourner les protections imposées par le proxy en établissant une connexion H2C et accéder aux ressources protégées par le proxy.
Suivez ce lien pour plus d'informations sur cette vulnérabilité dans Nginx.
Contrebande de WebSocket
Similaire à la technique précédente, celle-ci au lieu de créer un tunnel HTTP2 vers un point final accessible via un proxy, elle créera un tunnel WebSocket à la même fin, contournant les limitations potentielles des proxies et communiquant directement avec le point final :
Scénario 1
Nous avons un backend qui expose une API WebSocket publique et a également une API REST interne non disponible de l'extérieur. Un client malveillant veut accéder à l'API REST interne.
À la première étape, le client envoie une demande de mise à niveau au proxy inverse, mais avec une mauvaise version de protocole dans l'en-tête Sec-WebSocket-Version
. Le proxy ne valide pas l'en-tête Sec-WebSocket-Version
et pense que la demande de mise à niveau est correcte. Ensuite, il traduit la demande vers le backend.
À la deuxième étape, le backend envoie une réponse avec le code d'état 426
car la version du protocole est incorrecte dans l'en-tête Sec-WebSocket-Version
. Cependant, le proxy inverse ne vérifie pas suffisamment la réponse du backend (y compris le code d'état) et pense que le backend est prêt pour la communication WebSocket. Ensuite, il traduit la demande vers le client.
Enfin, le proxy inverse pense que la connexion WebSocket est établie entre le client et le backend. En réalité, il n'y a pas de connexion WebSocket - le backend a refusé la demande de mise à niveau. En même temps, le proxy inverse maintient la connexion TCP ou TLS entre le client et le backend en état ouvert. Le client peut facilement accéder à l'API REST privée en envoyant une requête HTTP sur la connexion.
Il a été constaté que les reverse proxies suivants sont affectés :
- Varnish - l'équipe a refusé de corriger le problème décrit.
- Envoy proxy 1.8.0 (ou plus ancien) - dans les versions plus récentes, le mécanisme de mise à niveau a été modifié.
- Autres - À déterminer.
Scénario 2
La majorité des reverse proxies (par exemple NGINX) vérifient le code d'état du backend pendant la partie de poignée de main. Cela rend l'attaque plus difficile mais pas impossible.
Observons le deuxième scénario. Nous avons un backend qui expose une API WebSocket publique et une API REST publique pour la vérification de l'état de santé et a également une API REST interne non disponible de l'extérieur. Un client malveillant veut accéder à l'API REST interne. NGINX est utilisé comme proxy inverse. L'API WebSocket est disponible sur le chemin /api/socket.io/
et l'API de vérification de l'état de santé sur le chemin /api/health
.
L'API de vérification de l'état de santé est invoquée en envoyant une requête POST, le paramètre portant le nom u
contrôle l'URL. Le backend atteint la ressource externe et renvoie le code d'état au client.
À la première étape, le client envoie une requête POST pour invoquer l'API de vérification de l'état de santé mais avec un en-tête HTTP supplémentaire Upgrade: websocket
. NGINX pense qu'il s'agit d'une demande de mise à niveau normale, il ne recherche que l'en-tête Upgrade
en ignorant les autres parties de la demande. Ensuite, le proxy traduit la demande vers le backend.
À la deuxième étape, le backend invoque l'API de vérification de l'état de santé. Il atteint la ressource externe contrôlée par des utilisateurs malveillants qui renvoie une **réponse HTTP avec le code d'état `101