Une des astuces lorsque l’on audite des mots de passe, consiste à utiliser un dictionnaire contextuel de l’entité que vous auditez. Par exemple la société “Big Corp Example” a un des “access point” Wi-Fi et on veut tester la dureté de la PSK. On va se constituer un petit dictionnaire en utilisant des mots clé liés à la société en question :

  • avec le SSID de l’AP (prenons par exemple d’un SSID = “meetingroom” ) :
  • Une liste de gens connus dans l’entreprise (Jean-Kevin Michu)
  • Une liste de mots-clés en fonction du contexte de l’entreprise (Fabrication coton tige pour dauphin)
    corp
    example
    meeting
    room
    jean
    kevin
    michu
    fabrication
    coton
    tige
    dauphin

Ensuite on fait le pari que l’entité ne va utiliser plus de N mots ensemble (par exemple de 1 à 3 maximum), et on va utiliser des variantes du type :

  • Tout en minuscule
  • Tout en majuscule
  • Majuscule sur la première lettre et le reste en minuscule
  • Séparé ou pas avec des espaces
  • Et en option : suffixé par des chiffres (de 1 à 4 en général ça fait 10000 [0000->9999] + 1000 [000->999] + 100 [00->99] + 10 [0->9] + 1 sans rien, soit 11111 combinaisons pour chaque permutations )

On peut bien sûr ajouter d’autres options, comme préfixer ou suffixer tous les mots de passe par une chaîne constante, aller jusqu’à 6 chiffres (ça englobe aussi les dates de naissance) mais ça fait beaucoup de mot de passe à tester.

exemple de code en Ruby en ce limitant uniquement à deux chiffres en suffixe, on obtient 975024 combinaisons en tout :

candidates = [  "big", "corp", "example", "meeting", "room", "jean", 
                "kevin", "michu", "fabrication", "coton", "tige", 
                "dauphin" ]

result = 1.upto(3).map do |nb|
        candidates.permutation(nb).map do |perm|
            [ " ", "" ].each.map do |a_join|
                [
                    perm.join(a_join) , 
                    perm.map {|keyword| keyword.upcase}.join(a_join) , 
                    perm.map {|keyword| 
                                keyword[0].upcase+keyword[1..-1]
                            }.join(a_join) 
                ].map do |pure_text|
                    [
                        pure_text,
                        10.times.map {|i| pure_text+i.to_s},
                        100.times.map {|i| pure_text+ "%02d" % [i]} #,
                        #1000.times.map {|i| pure_text+ "%03d" % [i]},
                        #10000.times.map {|i| pure_text+ "%04d" % [i]},
                    ]
                end
            end
    end 
end.flatten

result.each {|password| puts password}

Voici un exemple pour comprendre comment fonctionne la méthode permutation. Si j’ai trois éléments et que je veux toutes les combinaisons de deux éléments :

a = [ 1 , 2 , 3 ]

a.permutation(2) {|perm| puts perm.join(',') }
############## Execution ##############
1,2
1,3
2,1
2,3
3,1
3,2

Si je veux toutes les combinaisons possibles, il faut prendre les combinaisons de 1 à N éléments (N étant le nombre d’éléments en tout) :

a = [ 1 , 2 , 3 ]

1.upto(a.length).map do |nb|
    a.permutation(nb) {|perm| puts perm.join(',') }
end
############## Execution ##############
1
2
3
1,2
1,3
2,1
2,3
3,1
3,2
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1