jeudi 25 août 2011

Apache range header et CVE-2011-3192

Apache est vulnérable à une attaque par déni de service. L'origine de ce CVE débute le 20 Août sur la mailing liste full disclosure par un message de Kingcope. Il propose en effet un petit outil en perl killapache.pl réalisant un denial of service sur les serveurs web apache, toutes versions confondues. Je propose une analyse rapide de celui-ci en deux points: tout d'abord une explication de cette attaque, ensuite les moyens d'en réduire l'impact.

1/ L'attaque
Une lecture rapide du code perl montre qu'il utilise le header HTTP Range. Une explication claire de ce header HTTP est disponible ici. Pour résumer, un serveur HTTP peut ne renvoyer que quelques parties d'un fichier sur demande d'un client à l'aide de l'entête "Range".
Cet outil d'attaque, killapache.pl, envoie une première requête afin de s'assurer que le serveur distant accepte d'envoyer des morceaux de fichiers (des "Range") et si oui l'attaque est lancée [Attention, cette vérification n'est pas fiable, c'est à dire qu'un serveur marqué non vulnérable peut l'être..]. L'outil analyse le code retour de la première requête en cherchant le mot "Partial".

J'ai utilisé socat afin de voir l'attaque fonctionner 'in vivo'. Depuis un xterm je lance donc:
kevin@slackware:~$ socat - TCP-LISTEN:8080,reuseaddr,fork


D'un autre xterm je lance l'attaque (après avoir modifié le script pour qu'il tape le port 8080, constante PeerPort):
kevin@slackware:~$ perl kill_apache.pl 127.0.0.1 

Il suffit d'observer l'attaque après avoir renvoyé "Partial" (une réponse non RFC mais suffisante pour que l'attaque soit lancée):
[je coupe un peu, c'est long.  snip--- snip--- snip--- vous comprenez l'idée de cette ligne d'en-tête. ]
Et les requêtes s'enchaînent.

L'attaque devient évidente. En réponse à ces requêtes, le serveur va donc prendre la page d'accueil du site web attaqué, la zipper 1300 fois puis découper ces 1300 fichiers zippés afin de renvoyer les bonnes parties de celui-ci au client.
Finesse supplémentaire de l'attaque, ce n'est pas un GET, mais un HEAD qui est demandé. Donc le serveur va calculer une très grosse quantité de données et n'en renvoyer que le début ! Nous sommes donc en présence d'un DoS de belle facture où le client avec quelques requêtes va provoquer énormément de travail sur un serveur sans être lui-même impacté.

2/ Mitigations
Un ensemble de bons conseils ont été donnés sur la mailing list apache. Il n'existe pas de solution unique, je décris les idées émises.

Nous avons vu que l'en-tête Range est utile pour n'envoyer qu'une partie des fichiers. Cet en-tête est donc particulièrement employé pour des sites pourvoyeurs de gros pdfs (genre e-readers) ou de videos. En dehors de ces cas ou autre emploi similaire (Webdav?), la désactivation de cet en-tête est la solution la plus simple à mettre en oeuvre:
  RequestHeader unset Range

Une deuxième solution propose de limiter la longueur des en-têtes. Les images ci-dessus montrent que l'en-tête Range: ne fait qu'une seule ligne. La directive de configuration:

        LimitRequestFieldSize 200
permet de bloquer effectivement cette attaque. Deux points sont à considérer. Tout d'abord certains autres en-têtes peuvent légitimement avoir besoin d'une taille supérieure ce qui provoquera un blocage du service se servant de cette en-tête. C'est donc à adapter au cas par cas. Ensuite, cette attaque est appelée à évoluer et il apparaît comme crédible qu'elle fonctionnera avec un en-tête plus petit.

Une troisième solution préconise de limiter le nombre de champ Range dans la même requête au nombre de 5 (limite arbitraire, à adapter, des cas légitimes d'usages existent). Ceci se fait via un module apache développé pour l'occasion, ou des directives de configuration (expliquées dans le mail apache).

Enfin, la dernière solution consiste à attendre :-) Les développeurs apache ont promis une solution dans les 48 heures.

Pour l'historique, L'en tête Range: a déjà souffert d'une faille légèrement similaire en requêtant plusieurs fois le même morceau de fichier: CVE-2007-0086. Mon conseil serait donc de désactiver cet en-tête à moins que le site web en fasse un usage vital. Deux CVE sur un même en-tête HTTP risquent de donner des idées à des attaquants qui chercheront à affiner/modifier cette attaque pour qu'elle soit la plus efficace possible en étant moins bruyante.

3/conclusion
C'est effectivement un attaque fructueuse, certains messages sur des mailings listes indiquent que la machine s'est mise à swapper de manière démesurée jusqu'à provoquer un blocage complet. Les méthodes de mitigation sont très effectives et clairement exposées dans le mail apache. Une proposition d'évolution de la norme HTTP RFC 2616 est faite suite à discussion sur une ML apache.
Ceci dit, je suis surpris qu'on ne parle pas de IIS ou nginx, alors que ceux-ci savent utiliser Range et la compression. Peut-être un autre CVE, je n'ai pas de IIS ou nginx pour tester. Quelqu'un? :-)

EDIT: Le correctif apache, http://www.apache.org/dist/httpd/Announcement2.2.html Edit (bis): il ne s'agit pas du correctif attendu, merci à "Anonyme" de l'avoir signalé. Edit (ter): le lien est correct, la mise à jour est annoncée, c'est bien le 2.2.20 qui corrige ce CVE.
EDIT secondaire: testé rapidement sur un lighttpd et un nginx, conf par défaut après un apt-get debian. Les deux semblent non vulnérables, j'ai plus de CPU consommé par le script killapache.pl que par le webserver :-)

jeudi 11 août 2011

Old school ping of death still alive?

Le dernier patch tuesday de microsoft a été bien fourni (19 références). L'une d'elle (CVE-2011-1871) a ravivé quelques souvenirs en me rappelant la fameuse ligne de commande suivante:
C:\> ping -l 65510 A.B.C.D
Pour mémoire, il s'agit du ping of death qui a du faire enrager plus d'un internaute \o/ C'était l'époque des chans IRC, du Smurf et des DDOS sur ligne modem 28800 :-)

Le CVE-2011-1871 indique en effet qu'il est possible de crasher une machine windows à l'aide de messages ICMP. Microsoft ajoute: "aucun facteur atténuant pour cette vulnérabilité" (aller en milieu de page et dérouler le CVE-2011-1871). Ce qui ressemble très fortement au ping of death: de manière distante et avec de l'ICMP il est possible de faire tomber une machine.
Aucun détail technique n'est connu, il est seulement fait mention d'une succession de messages ICMP (et non pas un unique paquet). Peu de risques de voir ces paquets sur internet, la menace a été remontée de manière "responsable" selon les termes de microsoft, c'est à dire qu'il faut comprendre que la faille n'a pas été publiée publiquement quelque part sur internet. Néanmoins et même si aucune vulnérabilité n'est connue, il est conseillé de mettre à jour (comme toujours).

[ D'ailleurs, si quelqu'un a des détails techniques sur cette faille ou un PoC, mon e-mail est valide ]