CMS Made Simple Cache Poisoning

CMS Made Simple est un système de gestion de contenu (CMS) conçu pour être simple d’utilisation et léger dans le fonctionnement et son impact sur le serveur.

Je m’y suis un peu penché pour réaliser un audit de sécurité en boîte blanche dans mon temps libre et de veille sécurité afin de m’entraîner dans la recherche de vulnérabilités. C’est un bon compromis entre WordPress, sur lequel je me serais probablement cassé les dents, et des CMS complètement obscurs (je me suis basé sur les statistiques de Wappalyzer pour faire mon choix). Allons-y !

Des défauts de sécurité

Un défaut de salage dans le stockage des mots de passe

Si les mots de passe sont bien salés, ceux-ci le sont avec le même sel dans une même installation. Ceci implique qu’un attaquant ayant obtenu l’ensemble de la base et connaissant le sel utilisé (ce qui est plus complexe étant donné que celui-ci est stocké dans le fichier de configuration) peut obtenir l’ensemble des mots de passe d’un calcul (ce qui n’est pas le cas d’une base avec un sel différent pour chaque mot de passe).

Le code de salage du mot de passe :

$this->password = md5(get_site_preference('sitemask','').$password);

On notera par ailleurs que l’utilisation de l’algorithme de hashage MD5 n’est pas recommandé pour ces utilisations, l’algorithme présentant des défauts dans sa résistance aux collisions.

Le risque concret le plus probable est la reconnaissance par un attaquant de 2 utilisateurs ayant des mots de passe identiques car ceux-ci auront le même hash. Un peu de social engineering pourrait alors permettre de l’obtenir après l’avoir identifié.

Même mot de passe en base CMS Made Simple

Récupération du mot de passe d’un utilisateur

Le mécanisme d’authentification et de récupération de mot de passe présente plusieurs défauts.

Tout d’abord, il constitue une divulgation des noms d’utilisateurs existants par force brute. En effet, un message différencié permet de “deviner” les noms d’utilisateurs existants afin de les attaquer par force brute ensuite.

Divulgation de comptes utilisateurs dans CMS Made Simple

Si le compte utilisateur existant obtenu est utilisé pour réaliser une récupération du mot de passe, un e-mail contenant un hash permettant de le réinitialiser avec un mot de passe de son choix est envoyé :

$url = $config['admin_url'] . '/login.php?recoverme=' . md5(md5($config['root_path'] . '--' . $user->username . md5($user->password)));

Comme on peut le constater dans le code ci-dessus, extrait de l’application (admin/login.php ligne 52), le lien de récupération n’est dépendant que du mot de passe et ne varie a priori pas par ailleurs. Il est ainsi possible de le rejouer s’il a été obtenu une première fois et que le mot de passe de l’utilisateur n’a pas été modifié dans ce laps de temps. Ainsi si l’utilisateur décide d’ignorer ce lien (et de ne pas réinitialiser son mot de passe), un attaquant ayant obtenu par la suite ce hash est susceptible de l’utiliser.

Un autre problème se présente avec ce système. Ce mode de création du hash permet de ne pas stocker en base de données des hashs de récupération de mot de passe et CMS Made Simple en profite. C’est à dire que lors de la récupération du mot de passe, le hash renseigné en paramètre de l’url est comparé à une série de hashs générés à partir des informations de la base de données.

Une vulnérabilité de type empoisonnement de cache serveur

Il est possible d’insérer du contenu malveillant et même du code client dans les pages du serveur en exploitant le paramètre de la requête HTTP Host. Si le système de cache est activé, ce contenu est inséré dans les pages pour tous les utilisateurs du site. Ceci peut mener à des attaques de type phishing en détournant les liens vers un site extérieur. Il est aussi potentiellement possible d’exécuter du code client dans le navigateur des utilisateurs mais ceci n’a pas encore été prouvé.

Le code vulnérable se trouve aux lignes 372 à 376 :

$prefix = 'http://';
if( CmsApp::get_instance()->is_https_request() ) 
	$prefix = 'https://';
$str = $prefix.$_SERVER['HTTP_HOST'].$path;
$this->_cache[$key] = $str;
return $str;

Mais il y a dans ce processus un contrôle basique des entrées qui est cependant insuffisant (include.php aux lignes 98 à 105) :

{
$sanitize = function(&$value,$key) {
	$value = preg_replace('/\<\/?script[^\>]*\>/i', '', $value);
    $value = str_ireplace('script:', '', $value);
  };
array_walk_recursive($_GET,$sanitize);
array_walk_recursive($_SERVER,$sanitize);
}

Mais ce code n’est pas suffisant pour plusieurs raisons :

  • Les fonctions preg_replace et str_ireplace ne sont pas récursives (<sc<script>ript> sera filtré en <script>),
  • Ceci exclut l’inclusion d’IFrame et d’Object.

Au final on peut donc exploiter cette vulnérabilité avec la requête suivante pour remplacer tout les liens (à envoyer lors du renouvellement du cache) :

GET / HTTP/1.1
Host: www.malicious.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:42.0) Gecko/20100101,  Firefox/42.0
Accept: */*
Accept-Encoding: gzip, deflate
Connection: close

Ou insérer du code :

GET / HTTP/1.1
Host: ' javasscript:cript:alert(Xss)
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:42.0) Gecko/20100101,  Firefox/42.0
Accept: */*
Accept-Encoding: gzip, deflate
Connection: close

L’exploitation de cette vulnérabilité est quand même dépendante de plusieurs choses :

  • Il n’y a pas de VHost sur le serveur cible (i.e. il ne repose pas sur le header Host pour router les requêtes sur le bon serveur),
  • Le système de cache Smarty est activé (ce n’est pas le comportement par défaut) sur l’installation CMS Made Simple.

Conclusion

L’éditeur de CMS Made Simple a corrigé la vulnérabilité de Cache Poisoning après que je l’ai contacté. Les nouvelles versions non vulnérables sont sorties pour leurs branches supportées.

Parallèlement, la vulnérabilité a été identifiée comme CVE-2016-2784 et est référencée sur les sites et mailing lists les plus courants dans les milieux de la sécurité. Par ailleurs l’exploit est également disponible sur ce site.

Site officiel de CMS Made Simple : http://www.cmsmadesimple.org/

Exploit : http://www.kilawyn.fr/exploits/CMSMadeSimpleCachePoisoning.txt