
Outil hautement configurable pour vérifier la vulnérabilité d'un serveur face à CVE-2023-44487 en envoyant rapidement des trames HEADERS et RST_STREAM et en documentant les réponses du serveur.
CVE-2023-44487 est une exploitation du protocole HTTP2 lui-même. En HTTP2, les requêtes de données sont initiées par l'envoi d'une trame HEADERS. Après réception de cette trame, un serveur commence à traiter votre requête, puis envoie des trames DATA jusqu'à ce que toutes les données soient transmises. HTTP2 définit également une trame RST_STREAM, qui peut être utilisée pour fermer un flux à tout moment. Pour prévenir les attaques, les serveurs limitent généralement le nombre maximal de flux ouverts simultanément (à 100 par défaut). Si les clients attendent réellement que toutes les ressources soient consommées, cette limite est rarement atteinte. L'attaque fonctionne pour une raison simple : un client peut envoyer une trame RST_STREAM à n'importe quel moment. Une trame RST_STREAM ferme un flux, et les flux fermés ne sont pas comptés comme des flux simultanés. Cela signifie qu'un client peut envoyer des requêtes rapidement, sans jamais atteindre cette limite, simplement en fermant une connexion juste après avoir envoyé une requête. Le serveur attaqué, dans certains cas, commence quand même à charger les données, créant une charge excessive.
Cet outil vise à vérifier la vulnérabilité d'un serveur à cette attaque. Il établit une ou plusieurs connexions HTTP2 concurrentes, puis envoie les nombres spécifiés de trames HEADER, suivies de trames RST_STREAM.
Il fournit également de nombreuses autres options de configuration, comme le délai entre les trames HEADERS et RST_STREAM, le nombre de flux à ouvrir, le nombre de trames à envoyer par flux, etc.
Une fois l'attaque terminée, il affiche un résumé contenant des informations sur le nombre de trames reçues, ainsi que le nombre d'erreurs et de trames GOAWAY reçues.
Cela peut vous aider à déterminer si vos services sont vulnérables à CVE-2023-44487.
Pour l'instant, cet outil est distribué uniquement sous forme de code source, ce qui signifie qu'une installation de Go est requise. L'outil peut être exécuté en lançant go run main.go <options>.
Il existe également un script Python qui peut être utilisé pour tracer les informations de latence écrites dans le fichier monitor.log.
De plus, j'ai créé un nouvel outillage Python pour des mesures plus précises et plus étendues.
Le fichier runner.py situé dans le dossier tooling lira les valeurs définies dans votre config.py (voir config-sample.py pour plus de détails) et exécutera tous les tests pour tous les conteneurs Docker définis.
Il exécutera ensuite le test le plus réussi (latence médiane + moyenne la plus élevée) pour tous les chemins définis dans le tableau paths. Il produira des graphiques et des fichiers journaux pour chaque test exécuté.
Cet outillage est encore en cours de développement. Je ne l'ai créé que parce que j'étais trop paresseux pour exécuter manuellement tous ces tests pour notre article de recherche.
N'hésitez pas à soumettre une PR pour le nettoyer ou le rendre réellement utilisable au-delà de notre cas d'usage.
Actuellement, les options CLI suivantes sont implémentées :
L'outil affichera beaucoup d'informations de débogage, ainsi qu'un résumé. Les informations de débogage contiennent des détails sur la manière dont la connexion a été établie, sur la progression actuelle et sur le type de trames en cours d'envoi.
Le résumé ressemblera à ceci (selon votre configuration)
####################SUMMARY####################
Packet types received:
PING: 2
HEADERS: 12
SETTINGS: 0
DATA: 11
GOAWAY: 3
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Attack ending reasons (per receiving thread):
GoAway events: 3
Timeout events: 0
Error events: 0
Summary for connection 2
PING: 1
HEADERS: 9
SETTINGS: 0
DATA: 6
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Summary for connection 1
PING: 1
HEADERS: 3
SETTINGS: 0
DATA: 5
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Summary for connection 0
PING: 0
HEADERS: 0
SETTINGS: 0
DATA: 0
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Si vous pensez qu'il y a d'autres statistiques à collecter, n'hésitez pas à me contacter ou à créer une issue !
Cet outil est destiné UNIQUEMENT à des fins de recherche. Il n'est pas destiné à lancer des attaques contre des serveurs qui ne vous appartiennent pas ou que vous ne gérez pas. Je décline toute responsabilité quant à l'exactitude des statistiques fournies, ainsi que pour les attaques et leurs conséquences sur les serveurs et les services.
| Option | Défaut | Signification |
|---|
| frames | 1 | le nombre de trames HEADERS et RST_STREAM à envoyer sur chaque flux |
| connections | 1 | le nombre de connexions TLS sur lesquelles exécuter l'attaque (en parallèle) |
| consecutiveSends | 1 | nombre de trames HEADERS à envoyer avant d'envoyer les trames RST_STREAM (par flux) |
| connectAttempts | 1 | nombre de connexions consécutives sur lesquelles exécuter le test (par routine de connexion) |
| delay | 0 | le temps (en ms) à attendre entre l'envoi des trames HEADERS et RST_STREAM |
| ignoreGoAway | false | si vrai, les flux GOAWAY ne provoqueront pas la terminaison de la routine de réception. Elle attendra plutôt qu'aucune trame n'ait été reçue pendant plus de 10 secondes. |
| monitor | false | activer la surveillance des performances |
| monitorDelay | 100 | le temps (en ms) à attendre entre les tests de latence de réponse |
| monitorLog | ./monitor.log | le fichier dans lequel écrire les journaux de délai de surveillance |
| routines | 1 | le nombre de flux à attaquer |
| skipValidation | true | si vrai, le certificat du serveur ne sera pas validé (c'est le comportement par défaut - la sécurité ne nous importe pas puisque nous sommes de toute façon l'attaquant) |
| timeout | 1000 | temps à attendre de nouvelles trames avant de considérer la tentative de connexion comme invalide et de l'arrêter |
| url | https://localhost:433/ | l'URL contre laquelle exécuter l'attaque |