Les hash des mots de passe sont stockés dans la table wp_users sous cette forme :
user_login user_password
admin $P$BXox1.zpleKOuW4jFS6/Fmg4iaiK.B/
Décomposition du hash: $P$BXox1.zpleKOuW4jFS6/Fmg4iaiK.B/
- $P : algorithme
- $B : nombre d’ itération
- Xox1.zpl : sel aléatoire – longueur huit caractères
- eKOuW4jFS6/Fmg4iaiK.B/ hash composé de 22 caractères
remarque : il n’ y a pas de séparateur entre le sel et le hash wordpress. Les longueurs sont fixes.
Le nom de l’ utilisateur n’ est pas utilisé dans le calcul du hash wordpress
Type de hash et itérations
B: détermine le nombre d’itération
Pour connaître le nombre d’ itération , on cherche dans un premier temps, la position du caractère dans la chaine suivante.
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Dans notre exemple, il s’ agit de B. B est en 13ieme position dans la chaine (l’index commence à 0).
la position de B défini l’ exposant.
2^13 = 8192
Algorithme de génération du hash
1ere phase : initialisation de la variable « hash »
hash = md5(salt | password)
concaténation du sel et du password puis hashage en md5
2eme phase : Réalisation de 8192 itérations (methode pour lutter contre le brute force)
Pour i de 0 à 8191
hash = md5(hash | password)
Fin Pour
Le nombre d’ itérations s’élève à 8192 . A chaque itération le hash est le hash de la précédente itération.
3eme phase: traitement pour rendre lisible le hash wordpress. Application d’ une fonction de type « base64 »
Je vais m’ étendre sur cette 3ieme phase
encode64(hash)
Principe :
Le base64 est un codage de l’information utilisant 64 caractères.
On procède de gauche à droite, en concaténant 3 octets pour créer un seul groupement de 24 bits (8 bits par octet). Ils sont alors séparés en 4 nombres de seulement 6 bits (qui en binaire ne permettent que 64 combinaisons). Chacune des 4 valeurs est enfin représentée (codée) par un caractère simple et prédéfini de l’alphabet retenu. (Table ci-dessous.)
1 2 3 4 5 6
0123456789012345678901234567890123456789012345678901234567890123
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Les deux premières lignes : indice de 0 à 63
la ligne suivante : les caractères
Le hash wordpress sera donc composé exclusivement de minuscules , de majuscules , de chiffre , du point et du slash.
Principe de codage :
Un hash md5 à une longueur de 16 octets. On découpe par groupe de 3 octets, ce qui nous fait 5 groupes. il reste 1 octets. nous verrons que ce dernier octet est traité un peu différemment.
traitement des groupes:
1er octet en bit : AAaa bbbb
2ieme octet en bit : cccc dddd
3ième octet en bit : eeee FFff
On concatène les 3 octets :
AAaa bbbb cccc dddd eeee FFff
Découpage par groupe de 6 bits selon le schémas suivant :
AAaa bbbb cccc dddd eeee FFff
1er groupe : aabbbb
2ieme groupe : ddddAA
3ieme groupe : ffcccc
4ieme groupe : eeeeFF
On traite les 4 autres groupes de 3 octets de la même manière.
Cas particulier : le dernier octet
Dernier octet : GGgg hhhh
Découpage par groupe de 6 bits selon le schémas suivant :
On concatène 4 bits à 0000 à GGgghhhh (0000GGgghhhh) de façon à avoir 2 x 6 bits.
0000GGgghhhh
1er groupe : gghhhh
2ieme groupe 0000GG
Le dernier octet est donc découpé en 2 caractères
Démonstration :
Éléments nécessaires pour la démonstration :
- hash en string hexa obtenu apres les 8192 itérations
aaa5e9a2f1461e1244326bb8a66b014d hash wordpress
eKOuW4jFS6/Fmg4iaiK.B/- Découpage des 3 premiers octets :
a a a 5 e 9
10101010 10100101 11101001
AAaa bbbb cccc dddd eeee FFff
1 aabbbb = 101010 = 42d = « e »»
2 ddddAA = 010110 = 22d = « K »
3 ffcccc = 011010 = 26d = « O »
4 eeeeFF = 111010 = 58d = « u »
Les 4 premiers caractères sont : eKOU ce qui correspond au 4 premiers caractère du hash wordpress de notre exemple. (eKOuW4jFS6/Fmg4iaiK.B/
Pour le dernier caractère :
Découpage
4 d
01001101
On ajoute 4 bits à 0 devant
000001 001101
0000GG gghhhh
1 gghhhh = 001101 = 13d = « B »
2 0000GG = 000001 = 1d = « / »
les 2 derniers caractères sont : B/, ce qui correspond bien au 2 derniers caractère du hash wordpress de notre exemple. (eKOuW4jFS6/Fmg4iaiK.B/)
Brute force
Le programme hashcat peut être utilisé pour brute forcer les hash wordpress.
Dans hashcat, le commutateur -m permet de définir l’ algo à utilisé.
Définir -m400. Ce qui correspond selon la documentation à l’ algo utilisé par WordPress.
Programme python
Pour finir un programme en python qui calcule le hash wordpress.
Vous devez fournir le salt et le password. Lignes 47 et 48 .
# -*- coding: utf-8 -*-
import hashlib
import binascii
#
# fonctions
#
def _hash_encode64(hash, itoa64):
output=""
i=0
while True:
value = ord(hash[i]);
i+=1
output = output + str(itoa64[value & 63])
if (i<16):
value = value | ord(hash[i]) << 8
output = output + str(itoa64[(value >> 6) & 63])
i+=1
if (i >= 16):
print i
break
if (i < 16):
value = value | (ord(hash[i]) << 16)
output = output + str(itoa64[(value >> 12) & 63])
i+=1
if (i >= 16):
break;
output = output + str(itoa64[(value >> 18) & 63])
return output
# 1 2 3 4 5 6
# 0123456789012345678901234567890123456789012345678901234567890123
itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#arg01 : salt
#arg02 : pass
salt = "Xox1.zpl"
password = "password"
#resultat : $P$BXox1.zpleKOuW4jFS6/Fmg4iaiK.B/
hash = hashlib.md5(salt + password).hexdigest()
print hash
hash = hashlib.md5(salt + password).digest()
for i in range(0,8192) :
hash = hashlib.md5(hash + password).digest()
print binascii.hexlify(hash)
P= _hash_encode64(hash, itoa64)
print "$P$B" + salt + P + "\n"