Denial of service PHP sur toutes les versions inférieures à 5.3.1

Un advisory concernant les releases PHP antérieures à la version 5.3.1 a été publié ce vendredi. En effet, la 5.3.1 contient un patch pour un DoS ayant été reporté le 27 Octobre 2009. Le problème concerne le support de la RFC 1867 dans PHP (Formulaire d’upload HTML).

Concept

Lorsque l’on envoie une requête POST à un script PHP avec le content-type “multipart/form-data” et que l’on inclut une liste de fichiers dans cette requête, PHP crée un fichier temporaire pour chaque fichier de la requête. PHP crée ces fichiers sans même regarder si le script supporte l’upload de fichiers. Après l’exécution du script, les fichiers temporaires sont normalement effacés. Le problème vient donc du fait que si vous incluez un très grand nombre de fichiers dans la requête, PHP a besoin de créer ces fichiers avant l’exécution du script et donc la suppression qui devrait en découler. Le denial of service apparait lorsque l’on crée bons nombres de requêtes (ca rappelle vaguement la faille wordpress, et la plupart des DoS bien entendu), et que chaque requête contient beaucoup de fichiers à traiter (+15000). Lorsque vous envoyez cette requête au serveur web, il s’écroule et cesse de répondre car il doit processer un énorme nombre de fichiers (création / suppression) dans un très court délai. N’importe quel site tournant sous PHP et où l’upload de fichier est activé (configuration par défaut) est vulnérable. Il n’est pas nécessaire d’avoir un formulaire d’upload pour exécuter l’exploit. Cette faille est donc critique. J’ai d’ailleurs lu dans mes RSS d’hier qu’OVH organisait une patch party cette nuit, je suppose que c’est pour protéger ses mutualisés de cette faille.

PHP intègre deux paramètres de configuration qui ont attrait à l’upload:

Cependant, ces deux paramètres ne sont pas suffisants pour enrayer ce DoS.

Notions d’enrayement

Trois workarounds sont proposés concernant cette faille:

  • Désactiver l’upload de fichier
    Si vous n’avez pas besoin d’uploader des fichiers sur votre dédié, vous pouvez donc désactiver cette fonctionnalité.
    file_uploads = Off dans le php.ini
  • Installer PHP 5.3.1
    Si vous ne pouvez pas désactiver l’upload de fichiers, alors il convient d’upgrader PHP à la version 5.3.1.Cette nouvelle version intègre un patch pour la faille:
    En effet; max_file_uploads a été ajouté et permet de définir le nombre maximum de fichiers à processer à la fois (limité à 20 par défaut) afin d’enrayer les possibilités de DoS par trop grand nombre de fichiers temporaires.
  • Installer Suhosin PHP Extension /!\
    L’extension Suhosin possède une option nommée “suhosin.upload.max_uploads”. Cette option définit le nombre maximum de fichiers qui peuvent être uploadés par requête, définit par défaut à 25.
    /!\Suhoshin PHP extension ne doit pas être confondu avec Suhosin patch qui ne protège pas de cette attaque mais est assez largement déployé sur les serveurs de productions.

Tests dans des environnements de production

  • PHP on Linux (Ubuntu 8.10) / PHP Version 5.2.6-2ubuntu4.3

Vérification du nombre de fichiers temporaires:

Création d’un fichier pour compter le nombre de fichiers crées:

Donc une heure après, le serveur ne répond toujours pas et 2.419.649 fichiers temporaires ont été crées. Si l’on redémarre le serveur, ces fichiers ne sont pas effacés.

  • PHP on FreeBSD 7.2 / PHP Version 5.2.9

Même chose lorsque l’on tente de compter les fichiers temporaires:

Donc nous avons 117490 fichiers temporaires sur le serveur.

  • PHP on Windows: XAMPP / XAMPP for Windows setup filename: xampp-win32-1.7.2.exe / PHP Version 5.3.0

En quelques secondes, le serveur ne répond plus, 65535 fichiers temporaires sont crés et aucun autre ne peut être crée.

Sur XAMPP pour Windows, PHP crée les fichiers temporaires dans C:\xampp\tmp (si votre installation est dans C:\xampp\)
Les fichiers sont appelés phpXXXX.tmp (Où X’s charset est ‘a’-‘z’, ‘A’-‘Z’, ‘0′-’9’).

Deux heures plus tard l’utilisation du CPU n’est pas revenue à la normale. Cependant le serveur web répond à nouveau. Après un redémarrage du serveur, l’utilisation du CPU redevient normale. Cependant les 65535 fichiers temporaires ne sont pas effacés.

  • PHP on OpenBSD 4.6 / PHP Version 5.2.10

Le système est revenu à la normale.

OpenBSD absorbe très bien ce type d’attaque, les effets n’ont duré que quelques minutes.
Pourquoi cela ? Grace à Suhosin PHP extension. OpenBSD a cette extension activée par défaut.

Exploitation

Dans certains cas, cette attaque peut se transformer une inclusion locale et donc en exécution de code distant. La plupart des OS n’effacent pas les fichiers temporaires crée, même après redémarrage du serveur web. De fait un grand nombre de fichiers temporaires sont laissés dans le répertoire temporaire (habituellement /tmp sur les systèmes unix). On peut donc tenter de deviner le nom de l’un de ces fichiers et de l’inclure. Pour que cela fonctionne, tous les fichiers uploadés doivent contenir le code php suivant:

Sur les système tournant sous Windows, seulement quatre caractères sont utilisés pour générer les fichiers temporaires (phpXXXX.tmp). Une fois que le serveur répond à nouveau, il y a 65 535 fichiers dans le repertoire temporaire. Il est donc possible de deviner facilement le nom de l’un de ces fichiers et de l’inclure.

Sur unix, 6 caractères sont utilisés pour gérer les fichiers temporaires, il est donc impossible de deviner le nom de ceux-ci. Ou alors, cela prendra beaucoup de temps. L’auteur a tenté cette méthode sur un serveur ayant généré 800 000 fichiers temporaires. Après cinq minutes de tentative, il a réussi à deviner le nom d’un fichier et à exécuter du PHP.

Le script python permettant de générer l’attaque n’a pas été publié. Enfin, pas par l’auteur en tout cas. Cela se comprend aisément, du fait des conditions réunis: PHP largement déployé, pas besoin de formulaire d’upload, upload activé par défaut, seulement la dernière version corrige la faille, extension Suhosin non déployée par défaut sauf sur OpenBSD, de quoi faire tomber 70% des serveurs de la planète.

Mettez rapidement à jour vos serveurs. Un script doit déjà assez largement être distribué.

Références

L’équipe d’Acunetix essentiellement connue pour son scanner de failles web; devenu d’ailleurs entre temps un scanner de port, un soft d’exploitation d’injection SQL, un forgeur de packet HTTP et j’en passe; a averti l’équipe PHP le 27 octobre. L’auteur de cette découverte est bogdan de l’équipe Acunetix. On notera d’ailleurs avec intérêt qu’Acunetix n’a pas sorti l’adviso trois jours après avoir contacté le vendor; suivez mon regard :-)

Correction rapide

On vient de patcher quelques serveurs, la version 5.3.1 a pas été poussée dans les dépots officiels, on a donc installé suhosin qui lui y est:
apt-get install php5-suhosin (http://packages.debian.org/lenny/php5-suhosin)
La configuration se passe dans /etc/php5/apache2/conf.d

Partagez cet article !

    3 thoughts on “Denial of service PHP sur toutes les versions inférieures à 5.3.1

    1. […] John, fidèle lecteur de Korben.info qui m’a alerté de cette faille touchant toutes les versions […]

    2. Mr Xhark dit :

      Qu’en est-il sur l’infra des pagespersos de Free ?

    3. Jansky dit :

      I am really impressed with your writing skills and also with the structure in your weblog.
      Anyway keep up the excellent high quality writing, it is uncommon to peer a great blog like this one nowadays..

    Laisser un commentaire

    Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *