|
|
 | |  |  | Retour sur la vulnérabilité CVE-2008-1930 dans Wordpress |  |
by Louis Nyffenegger (05/05/08)
-- [ Retour sur la vulnérabilité CVE-2008-1930 dans Wordpress ]----
Cet article traite de la vulnérabilité sur la protection des
cookies dans Wordpress 2.5 publiée le 25 avril 2008 par Steven J.
Murdoch.
--[ 1. Explication de la vulnérabilité ]---------------------------
La vulnérabilité présente dans la gestion des cookies de
wordpress est liée au fait que l'authentification d'un utilisateur
est réalisée en se basant sur une simple concaténation de
l'identifiant et d'une date d'expiration.
En effet, la fonction d'authentification réalise les actions
suivantes (wordpress-2.5/wp-includes/pluggable.php:470) :
- vérification de la présence d'un cookie :
if ( empty($cookie) ) {
if ( empty($_COOKIE[AUTH_COOKIE]) )
return false;
$cookie = $_COOKIE[AUTH_COOKIE];
}
- récupération des valeurs stockées (identifiant et date
d'expiration) :
list($username, $expiration, $hmac) = explode('|', $cookie);
$expired = $expiration;
- vérification de la validité du cookie :
if ( $expired < time() )
return false;
- vérification de l'intégrité du cookie :
$key = wp_hash($username . $expiration);
$hash = hash_hmac('md5', $username . $expiration, $key);
if ( $hmac != $hash )
return false;
- vérification de l'existence de l'utilisateur :
$user = get_userdatabylogin($username);
if ( ! $user ) return false;
return $user->ID;
La vérification de l'existence de l'utilisateur ainsi que la
vérification via la fonction hash_hmac oblige un intrus à créer
un compte sur le blog, sans quoi il n'est pas possible d'exploiter
cette vulnérabilité.
Cependant, même si une vérification à l'aide de la fonction
hash_hmac est réalisée, à l'aide d'une clé prédéfinie par le
propriétaire du blog, il est possible de passer à travers le
mécanisme d'authentification.
La vulnérabilité provient du fait que le hash_hmac est basé sur une
simple concaténation du nom d'utilisateur et d'une date
d'expiration, tous les 2 fournis par l'utilisateur :
hash_hmac('md5', $username . $expiration, $key);
Ainsi, les valeurs suivantes donneront la même signature :
user expiration -> hash_hmac
user 11211190309 -> e94cba8f1e2f6430e831c5ec242ff73d
user1 1211190309 -> e94cba8f1e2f6430e831c5ec242ff73d
Le code suivant permet de vérifier ce problème :
<?php
require_once( dirname(__FILE__) . '/wp-config.php');
$username=$_GET["user"];
$expired=$_GET["expiration"];
$key = wp_hash($username . $expired);
echo hash_hmac('md5', $username . $expired, $key);
?>
L'appel de ce script se fait simplement par accès à la page avec
en argument le nom d'utilisateur et une valeur d'expiration :
http://wordpress/wordpress-2.5/gen.php?user=user1&expiration=1211190309
--[ 2. Exploitation de la vulnérabilité ]--------------------------
L'exploitation de cette vulnérabilité est très simple à réaliser :
- Tout d'abord, il faut créer un utilisateur dont l'identifiant
commence par le nom de l'administrateur suivi du début d'une date
d'expiration : admin1 pour l'utilisateur admin par exemple.
Cette action se fait sur la page :
http://wordpress/wordpress-2.5/wp-login.php?action=register
La date d'expiration étant issue de time(), concaténer la valeur
1 semble le plus simple, mais il est aussi possible de créer des
utilisateurs admin12, admin121, admin1211, ... Bien sûr ce choix
est à faire en fonction de la date courante.
- Une fois l'utilisateur créé, il faut se connecter au blog en
tant qu'admin1. Il est ainsi possible de récupérer un cookie
valide :
admin1%7C1210158445%7C49718d2581bd399916b90a088a11ec84
Où %7C correspond au séparateur |, ce qui donne le triplet :
admin1 | 1210158445 | 49718d2581bd399916b90a088a11ec84
On a ainsi une valeur de hmac chiffrée avec la clé du blog.
- À partir de ces valeurs, il est possible de générer un cookie
valide pour le compte admin :
admin | 11210158445 | 49718d2581bd399916b90a088a11ec84
- Après édition du cookie, il suffit de recharger la page pour
être connecté en tant qu'administrateur.
De plus, ce cookie aura une date d'expiration bien plus lointaine
dans le temps que le cookie original de l'administrateur.
Ainsi les contrôles sur le contenu du cookie sont passés :
- un cookie est envoyé par le client ;
- la date d'expiration est supérieure à la date courante :
if ( $expired < time() )
return false;
- l'intégrité du cookie est respectée (malgré la falsification
du nom d'utilisateur) grâce à la collision :
$key = wp_hash($username . $expiration);
$hash = hash_hmac('md5', $username . $expiration, $key);
if ( $hmac != $hash )
return false;
- le compte admin existe :
$user = get_userdatabylogin($username);
if ( ! $user ) return false;
return $user->ID;
--[ 3. Correction de la vulnérabilité ]--------------------------
La vulnérabilité a tout simplement été corrigée en ajoutant un
caractère '|' entre l'identifiant et la date d'expiration :
% diff -Nup wordpress-2.5/wp-includes/pluggable.php wordpress-2.5.1/wp-includes/pluggable.php | less
[...]
- $key = wp_hash($username . $expiration);
- $hash = hash_hmac('md5', $username . $expiration, $key);
+ $key = wp_hash($username . '|' . $expiration);
+ $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
[...]
Cette protection fonctionne car celle-ci empêche de faire une
concaténation valide. En effet, même si un intrus crée un
utilisateur "admin|" (ce qui n'est pas possible par défaut), lors
du calcul du hmac, les valeurs suivantes seront utilisés :
user expiration user|expiration
admin| | 1210158445 -> admin||1210158445
admin|1 | 1210158445 -> admin|1|1210158445
Alors que le calcul correcte donne :
admin | 1210158445 -> admin|1210158445
Il n'est ainsi pas possible de créer un utilisateur permettant de
créer une valeur hmac valide.
--[ 4. Conclusion ]------------------------------------------------
Cette brève vous a présenté l'exploitation d'une vulnérabilité dans
Wordpress, et ainsi comment une simple concaténation peut amener
de gros problèmes de sécurité (comme souvent), même si au premier
abord tout semble correct. Il est ainsi important, lorsque l'on
utilise des fonctions cryptographiques, de s'assurer que leur
utilisation est correcte et que des collisions ne sont pas
trivialement réalisables.
-- Louis Nyffenegger <Louis.Nyffenegger@hsc.fr> --
--[ 5. Liens ]-----------------------------------------------------
- Le site de Wordpress :
http://wordpress.org/
- La version 2.5 de Wordpress :
http://wordpress.org/wordpress-2.5.tar.gz
- L'avis CVE :
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1930
- L'avis dans Full Disclosure :
http://archives.neohapsis.com/archives/fulldisclosure/2008-04/0696.html
|