L'attaque hybride — Fonctionnement exhaustif

Document de référence pour le projet Time2Crack
Destinataires : développeurs, chercheurs en sécurité, utilisateurs avancés

Table des matières

  • Vue d'ensemble
  • Contexte historique et académique
  • Fondements conceptuels : pourquoi l'hybride fonctionne
  • Architecture d'une attaque hybride moderne
  • Les jeux de règles de mutation
  • Règles best64 : le jeu de référence
  • Taxonomie complète des transformations
  • Priorisation par fréquence : le cœur de l'efficacité
  • Implémentation dans Time2Crack : addHybridAttacks()
  • Les trois keyspaces hybrides et leur justification
  • Calibration haute fidélité
  • Relation avec les attaques dérivées
  • Benchmarks par algorithme de hachage
  • Exemples concrets de cracking hybride
  • Limites de l'attaque hybride
  • Défenses efficaces
  • Références bibliographiques

  • 1. Vue d'ensemble

    L'attaque hybride est la méthode de cracking qui combine une wordlist dictionnaire avec un jeu de règles de transformation. Plutôt que de tester chaque mot du dictionnaire tel quel (attaque dictionnaire pure), elle génère à la volée toutes les variantes plausibles de chaque mot — capitalisations, substitutions de caractères, ajouts préfixes/suffixes, inversions — et les teste systématiquement.

    Pourquoi c'est si efficace : les humains ne choisissent pas "password" comme mot de passe, ils choisissent "Password1", "p@ssw0rd", "PASSWORD123" ou "password!". Ces variantes semblent plus fortes car elles ne sont pas dans la liste dictionnaire brute — pourtant elles sont parmi les premières générées par n'importe quel outil de cracking hybride moderne. L'attaquant exploite exactement les mêmes heuristiques de "sécurisation" que l'utilisateur applique.

    L'attaque hybride est historiquement la méthode responsable de la majorité des crackings réels de mots de passe "moyens" — ceux qui ont l'apparence d'être forts sans l'être. Selon Ma et al. (2014, IEEE S&P), les 8 à 10 premières règles appliquées à un mot courant suffisent à crack le mot de passe médian de la population.

    Dans Time2Crack, l'attaque hybride modélise :

  • La détection que le mot de passe est ou dérive d'un mot de dictionnaire
  • L'estimation du nombre de candidats qu'un attaquant devrait tester avant de trouver la variante exacte
  • Le calcul du temps correspondant selon l'algorithme de hachage cible

  • 2. Contexte historique et académique

    2.1 Origines : John the Ripper et les règles de mutation

    L'attaque hybride naît formellement avec John the Ripper (Solar Designer, 1996), premier outil public à combiner une wordlist avec un moteur de règles configurable. Avant John the Ripper, les attaques dictionnaire testaient les mots bruts ; John introduit la notion que chaque mot génère une famille de candidats.

    Chronologie des jalons : AnnéeÉvénement ------------------ 1979Morris & Thompson : constatent que les utilisateurs substituent des chiffres aux lettres pour "sécuriser" leurs mots de passe 1996John the Ripper 1.0 : premier moteur de règles public, syntaxe JtR (:, c, u, r, d...) 2000Alec Muffett documente que 80% des crackings réels passent par wordlist+règles, pas brute force 2006Hashcat 0.01 : migration sur GPU, les règles passent de 1M→1000M candidats/seconde 2009RockYou : les 14,3M passwords en clair permettent de calibrer empiriquement les règles les plus efficaces 2012Gosney (Passwordscon) : 8 GPU GTX 580, best64 rules, crack 90% de LinkedIn en < 6 jours 2013Löfstrand : publie "best64.rule", jeu de 64 règles couvrant 85-90% des transformations humaines courantes 2014Ma et al. (IEEE S&P) : première étude académique quantifiant l'efficacité par rang de règle 2016Hashcat open source : best64 intégré, vitesse MD5 2 TH/s sur 8× GTX 1080 2019Hashcat 6.0 : jeu OneRuleToRuleThemAll (52k règles) généré par ML sur corpus de passwords 2023NSA Advisory : recommande explicitement de tester les passwords d'entreprise avec outils hybrides

    2.2 Études empiriques fondatrices

    Klein (1990) — Analyse de 15 000 mots de passe Unix. Constate que 24,2% sont crackables par dictionnaire pur, mais que 32% supplémentaires le sont avec des transformations simples (capitalisation, ajout de chiffre final). Total : 56,2% avec un outil hybride primitif. Weir et al. (2009, IEEE S&P) — Propose le modèle PCFG mais valide en passant que les règles hashcat couvrent 78% des transformations observées dans RockYou. Démontre que les mots de passe "Password1" et "P@ssw0rd" sont parmi les 100 premiers candidats générés par best64 sur le mot "password". Ma et al. (2014, IEEE S&P) — Étude la plus citée sur l'efficacité des règles hybrides. Sur un corpus de 10M passwords réels :
  • Règles 1–10 : crack 51%
  • Règles 1–64 (best64 complet) : crack 79%
  • Règles 1–500 : crack 88%
  • Conclusion clé : le rendement marginal chute rapidement. Les 10 premières règles font la majorité du travail.
  • Durmuth et al. (2015, ESORICS) — Évalue les règles JtR vs Hashcat vs PCFG. Conclut que les règles Hashcat best64 sont empiriquement les plus efficaces pour les mots de passe en clair observés, surpassant PCFG de 12% en couverture sur RockYou.

    2.3 La fuite LinkedIn comme cas d'école

    La fuite LinkedIn de 2012 (6,5 millions de SHA-1 non salés) illustre parfaitement la puissance de l'hybride. En 72 heures, la communauté hashcat avait cracké :

  • 100% des mots de passe dans les wordlists top-10M (dictionnaire pur)
  • 90% supplémentaires via best64 + CombinatorAttack
  • Les mots de passe résistants : uniquement ceux sans aucune structure dictionnaire
  • L'analyse post-crack a révélé que "linkedin1", "LinkedIn1", "l!nked!n" et "LINKEDIN" — toutes des variantes de "linkedin" — représentaient collectivement plusieurs dizaines de milliers de comptes compromis.


    3. Fondements conceptuels : pourquoi l'hybride fonctionne

    3.1 Le comportement humain de "sécurisation"

    Quand un système impose des règles de complexité (majuscule, chiffre, symbole), les utilisateurs ne génèrent pas de l'aléatoire — ils appliquent des transformations prévisibles à des mots mémorisables :

    Stratégie humaineExempleRègle hybride correspondante ---------------------------------------------------------- Capitaliser la première lettre"sunshine" → "Sunshine"c (capitalize first) Majuscule tout"sunshine" → "SUNSHINE"u (uppercase all) Ajouter un chiffre à la fin"sunshine" → "sunshine1"$1 (append "1") Ajouter l'année"sunshine" → "sunshine2024"$2 $0 $2 $4 Substituer e→3"sunshine" → "suns3ine"s e 3 (substitute e by 3) Substituer a→@"password" → "p@ssword"s a @ Inverser le mot"sunshine" → "enihsnus"r (reverse) Doubler le mot"sun" → "sunsun"d (duplicate) Ajouter ! final"sunshine" → "sunshine!"$! Combiner plusieurs"password" → "P@ssw0rd1"c s a @ s o 0 $1

    Ces transformations semblent créatives à l'utilisateur. Elles sont exactement les premières que tente l'attaquant car elles correspondent aux contraintes imposées par les politiques de sécurité.

    3.2 La notion d'espace réduit efficace

    Un mot de passe de 10 caractères avec lettres+chiffres+symboles a un keyspace brute-force de 94^10 ≈ 5,4 × 10^19 combinaisons. Trop grand pour être parcouru en temps raisonnable.

    Mais si ce mot de passe est "Password1!" — une transformation triviale de "password" — il se trouve parmi les 500 premiers candidats générés par un outil hybride sur le mot "password". L'attaquant ne parcourt pas 5,4 × 10^19 combinaisons : il en parcourt 500.

    C'est la réduction fondamentale de l'attaque hybride : l'espace réel des choix humains est astronomiquement plus petit que l'espace théorique des caractères possibles.

    3.3 La loi de puissance des transformations

    Tout comme les mots de passe bruts suivent une loi de puissance (Zipf), les transformations que les humains appliquent suivent elles aussi une distribution très concentrée. Ma et al. (2014) ont montré empiriquement :

  • ~5% des transformations ("ajouter 1 à la fin", "capitaliser la première lettre") couvrent ~50% des cas réels
  • ~20% des transformations couvrent ~85% des cas
  • Les 80% de transformations restantes ne couvrent que 15% des cas
  • Cette concentration permet à un jeu de 64 règles bien choisies (best64) d'atteindre une couverture de 79-85%, là où 64 règles aléatoires n'atteindraient que 10-15%.

    3.4 Interaction avec la popularité du mot de base

    Plus le mot de base est fréquent, plus le mot de passe dérivé est tôt dans la liste de priorité de l'attaquant. L'attaquant ordonne ses candidats par probabilité décroissante :

    Candidats générés par l'attaquant (ordre de test) :
    
  • password (mot brut, le plus courant)
  • Password (capitalize first)
  • password1 ($1)
  • PASSWORD (uppercase all)
  • password! ($!)
  • p@ssword (substitute a→@)
  • passw0rd (substitute o→0)
  • Password1 (c + $1)
  • P@ssword (c + s a @)
  • password123 ($1 $2 $3)
  • ...
  • p@ssW0rd! (combinaison complexe)
  • "password" est le mot le plus courant → ses dérivés sont testés en premier. "papillon" est moins courant → ses dérivés sont testés bien plus tard. Cette priorisation est le mécanisme central qui explique les trois keyspaces distincts dans Time2Crack.


    4. Architecture d'une attaque hybride moderne

    4.1 Pipeline général

    Phase 1 : Sélection de la wordlist
        ├── Passwords fuités triés par fréquence (RockYou, HIBP, Collections)
        ├── Dictionnaire linguistique (fr.txt, en.txt, de.txt...)
        ├── Wordlists thématiques (prénoms, villes, marques, séries TV)
        └── Wordlists contextuelles (domaine cible, noms d'employés, termes métier)
    

    Phase 2 : Sélection du jeu de règles ├── best64.rule (référence équilibrée, 64 règles) ├── OneRuleToRuleThemAll.rule (52 000 règles, ML-generated) ├── d3ad0ne.rule (34 000 règles, empirical) ├── JtR rules (generated.rule, specific.rule, extra.rule) └── Règles custom (adaptées au domaine cible)

    Phase 3 : Expansion (wordlist × règles) ├── Pour chaque mot w dans wordlist : │ Pour chaque règle r dans ruleset : │ candidat = apply(r, w) │ Si candidat ≠ w et candidat non déjà testé : │ filedecandidats.push(candidat) └── Ordre : (w1, règle1), (w1, règle2)... (w2, règle1)... ou : (w1, règle1), (w2, règle1)... selon la stratégie

    Phase 4 : Hachage et comparaison (GPU) ├── Envoi par batch de ~10M candidats au GPU ├── Calcul parallèle des hashes (SIMD, 168 GH/s pour MD5) ├── Comparaison avec hash(es) cible(s) └── Si match : TROUVÉ — log(candidat, hash, règle)

    Phase 5 : Reporting └── Candidat cracké + règle utilisée + rang dans la liste

    4.2 Modes d'opération hashcat

    Hashcat implémente l'hybride de deux façons distinctes :

    Mode -a 0 (wordlist + rules) : pour chaque mot de la wordlist, applique toutes les règles. C'est le mode hybride classique.
    hashcat -a 0 -m 0 hashes.txt rockyou.txt -r best64.rule
    Mode -a 6 (wordlist + mask) : combine une wordlist avec un masque positionnel. Génère toutes les combinaisons mot + suffixemasqué.
    hashcat -a 6 -m 0 hashes.txt wordlist.txt ?d?d?d?d
    

    Teste "sunshine0000", "sunshine0001", ..., "sunshine9999"

    Mode -a 7 (mask + wordlist) : inverse — préfixe masqué + mot.
    hashcat -a 7 -m 0 hashes.txt ?d?d wordlist.txt
    

    Teste "00sunshine", "01sunshine", ..., "99sunshine"

    Time2Crack modélise principalement le mode -a 0 (règles de mutation), qui couvre la grande majorité des attaques hybrides réelles documentées.

    4.3 Ordre des candidats et stratégie de priorisation

    L'ordre dans lequel les candidats sont testés est critique. Deux stratégies principales :

    Stratégie word-first (défaut hashcat) : tous les règles sont appliquées à W1 avant de passer à W2.
    (W1, R1), (W1, R2), ..., (W1, Rn), (W2, R1), (W2, R2)...
    Avantage : si W1 est très probable (ex: "password"), on découvre rapidement ses variantes. Stratégie rule-first : toutes les wordlists sont parcourues pour R1 avant de passer à R2.
    (W1, R1), (W2, R1), ..., (Wm, R1), (W1, R2), (W2, R2)...
    Avantage : la règle la plus efficace (: → mot brut) est appliquée en premier sur tous les mots. Souvent plus efficace pour des corpus diversifiés.

    En pratique, hashcat utilise word-first par défaut mais les opérateurs expérimentés choisissent selon le profil cible.


    5. Les jeux de règles de mutation

    5.1 Syntaxe des règles hashcat

    Les règles hashcat sont exprimées dans un langage minimal où chaque caractère représente une opération sur la chaîne candidate :

    Modificateurs de casse :
  • : — Identité (mot brut, aucune transformation)
  • l — lowercase all ("PASSWORD" → "password")
  • u — uppercase all ("password" → "PASSWORD")
  • c — Capitalize first, lowercase rest ("PASSWORD" → "Password")
  • C — Lowercase first, uppercase rest ("Password" → "pASSWORD")
  • t — Toggle case de tous les caractères ("Password" → "pASSWORD")
  • TN — Toggle case du caractère à la position N
  • Suppressions et inversions :
  • r — Reverse ("password" → "drowssap")
  • d — Duplicate ("password" → "passwordpassword")
  • f — Reflect (word + reverse) ("sun" → "sunnos")
  • { — Rotate left ("password" → "asswordp")
  • } — Rotate right ("password" → "dpasswor")
  • [ — Remove first character ("password" → "assword")
  • ] — Remove last character ("password" → "passwor")
  • Ajouts de caractères :
  • $X — Append character X ("password" + $1 → "password1")
  • ^X — Prepend character X ("password" + ^1 → "1password")
  • iNX — Insert character X at position N
  • Substitutions :
  • sXY — Replace all X by Y ("password" + s a @ → "p@ssword")
  • SNX — Replace character at position N by X
  • Troncatures :
  • 'N — Truncate at position N ("password" + '4 → "pass")
  • DN — Delete character at position N
  • Conditionnels :
  • — Applique la règle seulement si longueur < N
  • >N — Applique la règle seulement si longueur > N
  • =N — Applique la règle seulement si longueur = N
  • 5.2 Règles composées

    Les règles peuvent être enchaînées sur une seule ligne pour créer des transformations complexes :

    c $1          → "Password1" (capitalize + append 1)
    c $! $1       → "Password!1" (capitalize + append ! + 1)
    s a @ s e 3   → "p@ssw3rd" (substitute a→@ et e→3)
    r $1          → "1drowssap" (reverse + append 1)
    u $2 $0 $2 $3 → "PASSWORD2023" (uppercase + append year)

    La puissance est dans la composition : 64 règles simples génèrent des milliers de transformations distinctes par combinaison.

    5.3 Jeux de règles principaux

    best64.rule (Löfstrand, 2013) — 64 règles sélectionnées empiriquement sur RockYou pour maximiser le taux de crack. Considéré comme la référence de l'industrie. OneRuleToRuleThemAll (NotSoSecure, 2019) — 52 218 règles générées par apprentissage automatique sur des corpus de passwords crackés. Taux de crack supérieur à best64 de ~8% sur les corpus modernes, au prix d'un temps de calcul ~800× plus long. d3ad0ne.rule — 34 096 règles communautaires, focus sur les patterns non couverts par best64 (accents, caractères étendus, patterns non-anglais). dive.rule — 99 000+ règles, le plus exhaustif. Utilisé pour les crackings de longue durée quand les autres ont échoué. generated2.rule (JtR) — Généré automatiquement par analyse statistique de passwords déjà crackés. Recalculé périodiquement au fur et à mesure de nouvelles fuites.

    6. Règles best64 : le jeu de référence

    Best64 est le jeu de 64 règles standard de référence dans la littérature académique et l'industrie. Voici les règles les plus importantes et leur justification empirique :

    6.1 Les 20 règles les plus efficaces (par ordre de rendement)

    RangRègleTransformation% passwords couverts (Ma 2014) ------------------------------------------------------------ 1:Mot brut~18% 2cCapitalize first~11% 3uUppercase all~6% 4$1Append "1"~5% 5lLowercase all~4% 6$!Append "!"~3% 7s a @a→@~2.8% 8c $1Capitalize + "1"~2.5% 9$2Append "2"~2.1% 10rReverse~1.9% 11$! + cCapitalize + "!"~1.7% 12s o 0o→0~1.6% 13dDuplicate~1.4% 14s e 3e→3~1.3% 15$1 $2 $3Append "123"~1.2% 16c $1 $2 $3Capitalize + "123"~1.1% 17$0Append "0"~1.0% 18^1Prepend "1"~0.9% 19s i 1i→1~0.8% 20c $! $1Capitalize + "!1"~0.7% Cumul règles 1–10 : ~55% des mots de passe dict-based Cumul règles 1–20 : ~68% des mots de passe dict-based Cumul règles 1–64 : ~79% des mots de passe dict-based

    6.2 Pourquoi ces règles sont-elles si efficaces ?

    Chaque règle top-10 correspond à une contrainte de politique de sécurité courante :

  • "Doit avoir une majuscule" → les utilisateurs capitalisent la première lettre (c)
  • "Doit avoir un chiffre" → les utilisateurs ajoutent "1" à la fin ($1)
  • "Doit avoir un symbole" → les utilisateurs ajoutent "!" ($!)
  • "Doit avoir lettres ET chiffres" → c $1 ou c $1 $2 $3
  • Les politiques de mots de passe n'augmentent pas réellement la sécurité si les utilisateurs appliquent des transformations prévisibles — elles déplacent seulement les passwords vers la seconde ou troisième règle de best64.


    7. Taxonomie complète des transformations

    7.1 Catégorie 1 : Transformations de casse

    Les plus courantes. Exploitent l'obligation d'avoir une majuscule :

  • Capitalize first letter : "sunshine" → "Sunshine" (règle la plus fréquente après le mot brut)
  • All uppercase : "sunshine" → "SUNSHINE"
  • Toggle alternating : "sunshine" → "sUnShInE"
  • Last letter uppercase : "sunshine" → "sunshinE"
  • CamelCase : "sunshinE" (approximé par c dans des variations)
  • Prévalence : Klein (1990) constate que 41% des "mots de passe avec majuscule" consistent simplement en le mot avec la première lettre en majuscule.

    7.2 Catégorie 2 : Suffixes et préfixes numériques

    Exploitent l'obligation d'avoir un chiffre :

  • Append single digit : mot+"0" à mot+"9"
  • Append two digits : mot+"00" à mot+"99" (100 combinaisons)
  • Append year : mot+"1990" à mot+"2024" (35 combinaisons fréquentes)
  • Append "123" ou "1234" (très fréquent)
  • Prepend single digit : "1"+mot à "9"+mot
  • Prepend year : "2024"+mot
  • Prévalence : Veras et al. (2014) trouvent que ~73% des mots de passe "chiffre obligatoire" ajoutent le chiffre en suffixe. Seuls ~12% le préfixent.

    7.3 Catégorie 3 : Substitutions leet

    Remplacement systématique de lettres par des chiffres ou symboles visuellement similaires :

    SubstitutionFréquence empirique ----------------------------------- a → @23% des passwords avec @ e → 331% des passwords avec 3 i → 119% des passwords avec 1 o → 027% des passwords avec 0 s → $14% des passwords avec $ l → 18% t → 76% g → 94%

    Les substitutions combinées ("P@ssw0rd") semblent complexes mais sont générées en quelques règles : c s a @ s o 0. Elles sont parmi les 500 premiers candidats sur "password".

    7.4 Catégorie 4 : Suffixes symboliques

    Exploitent l'obligation d'avoir un caractère spécial :

  • Append "!" : le symbole le plus fréquemment ajouté (~35% des ajouts symboliques)
  • Append "?" : ~8%
  • Append "#" : ~6%
  • Append "@" : ~5%
  • Append "." : ~4%
  • Append "!!" : ~3%
  • Prepend "!" : moins fréquent (~10% des cas vs 35% pour suffixe)
  • Kombinaison : mot + "1!" est tellement fréquent qu'il est systématiquement généré par best64. "sunshine1!" est parmi les 200 premiers candidats générés sur "sunshine".

    7.5 Catégorie 5 : Transformations structurelles

    Moins fréquentes mais utiles pour certains profils :

  • Inversion : "sun" → "nus" (courant pour certains groupes)
  • Duplication : "sun" → "sunsun" (passwords pour systèmes limitant à 8 chars résolus à 16)
  • Rotation : "password" → "asswordp"
  • Troncature + ajout : "passw" + "1"
  • 7.6 Catégorie 6 : Transformations composées (niveau avancé)

    Les règles complexes combinent plusieurs opérations :

    c $1 s a @        → "P@ssword1" (capitalize + append 1 + substitute a→@)
    u $! $1 $2 $3     → "SUNSHINE!123" (uppercase + append !123)
    r c $1            → "Drowssap1" (reverse + capitalize + append 1)
    s e 3 s a @ c $!  → "P@ssw3rd!" (multiple substitutions + capitalize + !)

    Ces transformations semblent très complexes mais restent détectables par un bon jeu de règles. OneRuleToRuleThemAll en contient des milliers de ce type.


    8. Priorisation par fréquence : le cœur de l'efficacité

    8.1 La fréquence du mot de base détermine la priorité

    Un attaquant intelligent n'applique pas les règles de façon uniforme à tous les mots. Il priorise :

  • Les mots les plus fréquents (top-100 RockYou/HIBP) × toutes les règles
  • Les mots moyennement fréquents (top-10k) × les règles les plus efficaces
  • Les mots moins fréquents (tout le dictionnaire) × les quelques premières règles
  • Cette stratégie est implémentée dans hashcat via le tri de la wordlist par fréquence décroissante combiné à la stratégie word-first. Elle explique pourquoi "Password1" (dérivé de "password", le mot #1) est craqué en millisecondes, alors que "Soleil1" (dérivé de "soleil", mot ~5000 du dictionnaire français) prend peut-être quelques secondes.

    8.2 Position médiane dans l'espace de recherche

    La mesure clé est le nombre médian de candidats testés avant de trouver le mot de passe cible. Ma et al. (2014) fournissent des mesures empiriques :

    TierExempleCandidats médians avant trouvaille -------------------------------------------------- TOP100"password1", "P@ssword"~450–500 Dict commun (top-10k)"Sunshine1", "soleil!"~5 000–15 000 Dict moins fréquent"Papillon2024"~50 000–200 000 Hors dictionnaire"Xk7#mP9q"N/A (hybride inapplicable)

    Ces mesures sont la base directe des constantes de Time2Crack :

    const HYBRIDKEYSPACECOMMON = 500;    // Ma et al. 2014 — médiane top-100
    const HYBRIDKEYSPACEDICT = 8000;   // Ma et al. 2014 — médiane dict courant
    const HYBRIDKEYSPACEFULL = 128e6;   // Gosney 2012 — best64 × 2M words exhaustif

    8.3 Conditions nécessaires pour que l'hybride soit applicable

    L'attaque hybride requiert que le mot de passe soit structurellement dérivable d'un mot de dictionnaire. Time2Crack détecte cette condition via hybridVuln :

    const hybridVuln = dictWord || (common && /[a-z]/i.test(pw));
  • dictWord = true : le mot de passe est ou dérive d'un mot de la wordlist linguistique
  • common && lettre : le mot de passe figure dans COMMON (HIBP top-400) et contient des lettres — donc presque certainement dérivé d'un mot
  • Si ni dictWord ni hybridVuln ne sont vrais — le mot de passe ne contient aucune racine dictionnaire détectable — l'attaque hybride retourne null (non applicable). Un mot de passe purement aléatoire comme "xK9#mQ7@" n'est pas vulnérable à l'hybride.


    9. Implémentation dans Time2Crack : addHybridAttacks()

    9.1 Code complet annoté

    function addHybridAttacks(rows, hybridVuln, weak, common, dictWord) {
      if (hybridVuln || weak) {
        // Sélection du keyspace selon la popularité du mot de base :
        // common → mot dans HIBP top-400 → position ~500 dans la liste de l'attaquant
        // dictWord → mot dans la wordlist → position ~8000
        // sinon (hybridVuln sans dictWord ni common) → scan exhaustif ~128M
        const hybridKS = common ? HYBRIDKEYSPACECOMMON
          : dictWord ? HYBRIDKEYSPACEDICT
          : HYBRIDKEYSPACEFULL;
    

    for (const a of ALGOS) { rows.push({ atk: t("aHybrid"), hash: a.name, rate: a.rate, // budgetTime : le keyspace IS le nombre de guesses — pas de division par 2 // (contrairement à bruteTime, ici les candidats sont ordonnés par probabilité) sec: weak ? weakGuessTime(a.rate) : budgetTime(hybridKS, a.rate), note: weak ? t("nWeakPassword") : t("nDictMut"), cat: "hybrid", }); } } else { // Mot de passe sans structure dictionnaire → hybride inapplicable rows.push({ atk: t("aHybrid"), hash: "(all)", rate: 0, sec: null, // N/A dans le tableau note: t("nStructUnrecog"), cat: "hybrid", }); } }

    9.2 budgetTime vs bruteTime

    La distinction entre les deux fonctions est fondamentale :

    // bruteTime : l'attaquant ne sait pas où est le mot de passe dans l'espace.
    // Il teste en moyenne la moitié avant de le trouver. → keyspace/2
    function bruteTime(keyspace, rate) {
      const ls = Math.log(keyspace / 2) - Math.log(rate);
      return Math.exp(ls);
    }
    

    // budgetTime : l'attaquant teste les candidats en ordre de probabilité décroissante. // Le keyspace IS le nombre de candidats attendus avant trouvaille (position médiane). // Pas de division par 2 — la médiane est déjà incorporée dans les constantes Ma 2014. function budgetTime(guesses, rate) { const ls = Math.log(guesses) - Math.log(rate); return Math.exp(ls); }

    Pour l'hybride, budgetTime est correct car les 500/8000/128M candidats sont des estimations empiriques de la position médiane, pas de l'espace total à parcourir.

    9.3 Relation avec isDictWord()

    La détection dictWord qui conditionne le choix du keyspace hybride est produite par isDictWord() :

    function isDictWord(pw) {
      if (!DICTWORDS || !DICTWORDS.size) return false;
      const l = pw.normalize("NFC").toLowerCase();
    

    // Test direct : le password est-il tel quel dans le dictionnaire ? if (DICT

    WORDS.has(l)) return true;

    // Test de-leetifié : "s0le1l" → "soleil" dans le dico ? const dl = deLeet(pw); if (dl !== l && DICTWORDS.has(dl)) return true;

    // Test substring : "sunshine123" contient "sunshine" dans le dico ? for (const w of DICTWORDS) { if (l.includes(w) && w.length >= 4) return true; }

    return false; }

    Cette détection détermine non seulement si l'hybride est applicable, mais aussi quel keyspace (common vs dict) est utilisé pour le calcul du temps.


    10. Les trois keyspaces hybrides et leur justification

    10.1 HYBRIDKEYSPACECOMMON = 500

    Contexte : le mot de passe est dans COMMON — la liste hardcodée HIBP top-~400. Ce sont des mots de passe parmi les plus courants au monde ("password", "letmein", "sunshine", "iloveyou"...). Justification : Ma et al. (2014) ont mesuré empiriquement que la position médiane d'un password top-1000 dans une liste hybride triée par probabilité est de ~450 candidats. Le chiffre 500 est une estimation légèrement conservatrice pour couvrir jusqu'au rang ~400. Interprétation : un attaquant appliquant best64 à une wordlist triée par fréquence teste en moyenne 500 candidats avant de trouver le password. À 2 000 GH/s (MD5, 12× RTX 4090), 500 candidats = 0,25 picosecondes. Pratiquement instantané. Exemple : "Sunshine1" → "sunshine" est dans COMMON → HYBRIDKEYSPACECOMMON = 500 → budgetTime(500, 2027e9) ≈ 0,25 nanosecondes.

    10.2 HYBRIDKEYSPACEDICT = 8 000

    Contexte : le mot de passe dérive d'un mot de la wordlist linguistique, mais pas de COMMON. Ce sont des mots courants du vocabulaire ("soleil", "montagne", "papillon"...) avec des transformations. Justification : Ma et al. (2014) mesurent une position médiane de 2 000 à 15 000 selon la popularité du mot dans RockYou. La médiane empirique est ~8 000. Ce keyspace reflète que l'attaquant teste le mot et ses variantes après avoir épuisé les candidats plus communs. Interprétation : 8 000 candidats à 2 000 GH/s (MD5) = 4 nanosecondes. Toujours quasi-instantané pour les hashes rapides. Pour bcrypt (69 kH/s) : 8 000 / 69 000 ≈ 0,12 secondes. Exemple : "Soleil2024" → "soleil" dans fr.txt → HYBRIDKEYSPACEDICT = 8 000 → quelques nanosecondes sur MD5, 0,12s sur bcrypt.

    10.3 HYBRIDKEYSPACEFULL = 128 000 000

    Contexte : hybridVuln est vrai (mot de passe a une structure dictionnaire) mais ni common ni dictWord ne correspondent précisément. L'attaquant doit parcourir toute la wordlist avec toutes les règles. Justification : Gosney (Passwordscon 2012) documente une wordlist de 3,5M mots × best64 (64 règles) = 224M candidats au total. En pratique, les wordlists réalistes font 2M mots et les runs best64 partiels s'arrêtent à ~128M candidats avant d'escalader vers des jeux de règles plus larges. Formule : 2000000 mots × 64 règles = 128000000 candidats Interprétation : 128M candidats à 2 000 GH/s (MD5) ≈ 64 microsecondes. Sur bcrypt (69 kH/s) : ~31 minutes.

    11. Calibration haute fidélité

    11.1 Rôle du mode haute fidélité

    Quand le mode haute fidélité (HF) est activé dans Time2Crack, un multiplicateur supplémentaire est appliqué aux temps calculés pour affiner la précision. Pour l'attaque hybride, ce multiplicateur tient compte de facteurs non capturés par les keyspaces de base.

    11.2 Multiplicateurs HF pour l'hybride

    Dans applyHighFidelityCalibration() :

    case "hybrid":
      // Mots très courants : crackés encore plus tôt que la médiane Ma 2014
      // car les attaquants modernes trient word-first + règle-first simultanément.
      // Réduction de 30% sur les temps déjà courts.
      m = context.common ? 0.7
        : context.dictWord ? 0.8
        : 1.0;
      break;
    Justification :
  • Pour common : les outils modernes (hashcat avec --markov-threshold) pré-trient les règles par efficacité empirique. Les meilleurs candidats arrivent encore plus tôt. Réduction de 30%.
  • Pour dictWord : effet moindre car la position dans la wordlist est moins concentrée. Réduction de 20%.
  • Pour hybridVuln seul (FULL keyspace) : pas de réduction — le plein keyspace est déjà une estimation conservative.
  • 11.3 Interaction avec le guard de monotonie

    Le guard de monotonie s'assure qu'aucune attaque spécialisée ne prétend être plus rapide que la force brute sur la sous-chaîne alphabétique du mot de passe :

    // Pour chaque row non-brute :
    const floorAlpha = bruteTime(Math.pow(26, alphaOnly.length), algo.rate);
    if (row.sec < floorAlpha) row.sec = floorAlpha;

    Pour les mots courts (ex: "cat" = 3 lettres, floor = 26^3/rate ≈ 0 secondes), ce guard ne change rien. Pour des mots longs entiers dans le dictionnaire (ex: "concatenation" = 13 lettres), il évite qu'un hybride prétende cracker en moins de temps que le brute-force alphabétique — ce qui serait physiquement impossible.


    12. Relation avec les attaques dérivées

    12.1 Hybride vs Dictionnaire pur

    CritèreDictionnaire purHybride ----------------------------------- Candidats testésMots exacts de la listeMots + toutes leurs variantes Couverture (RockYou)~18%~79-85% (avec best64) Keyspace (200k words)200 000200 000 × 64 = 12,8M ApplicabilitéMot de passe = mot exactMot de passe dérivé d'un mot Exemple vulnérable"sunshine" (exact)"Sunshine1!", "sunsh1ne" Exemple résistant"Sunshine1""xK9#mQ7@" (aucune racine)

    12.2 Hybride vs Rule-Based (attaque par règles)

    L'attaque rule-based dans Time2Crack est conceptuellement similaire mais avec un jeu de règles beaucoup plus large :

    const RULEKEYSPACE = 250000000;  // vs 128M pour hybride full

    La différence : l'hybride modélise best64 (64 règles, focus sur les transformations humaines communes). L'attaque rule-based modélise des jeux plus larges comme d3ad0ne (34k règles) ou OneRuleToRuleThemAll (52k règles), utilisés quand best64 échoue. Le rule-based est l'hybride "de seconde ligne" — plus lent mais plus exhaustif.

    12.3 Hybride vs PCFG

    PCFG (Probabilistic Context-Free Grammar, Weir 2009) modélise la structure grammaticale du mot de passe pour générer des candidats. Différences :

    CritèreHybridePCFG ------------------------ ApprocheMot base + règles de transformationStructure grammaticale globale ForceMots existants mutésStructures type "Mot+Digits" Exemple"sunshine" → "Sunshine1"Détecte la structure "Caps+lower+digit" ComplémentaritéSe déclenche sur dictWordSe déclenche sur structure détectée Keyspace (Time2Crack)500 / 8k / 128MpcfgKeyspace(pw) calculé dynamiquement

    PCFG peut attaquer des mots de passe sans racine dictionnaire si leur structure est commune (ex: "Thelonious8" → aucun mot du dico mais structure Capitalize+lower+digit très prévisible).

    12.4 Hybride vs Morphologique (morph)

    L'attaque morphologique teste les variantes linguistiques (flexions, dérivations). C'est une généralisation de l'hybride pour les langues à morphologie riche :

  • Hybride : "soleil" → "Soleil1", "s0leil", "soleil!"
  • Morphologique : "soleil" → "soleils", "ensoleillé", "solaire", "ensoleillement"
  • L'hybride opère sur la surface du mot (transformations de caractères), le morphologique opère sur la structure lexicale (dérivation, flexion). Ils sont complémentaires.


    13. Benchmarks par algorithme de hachage

    13.1 Temps pour les trois keyspaces hybrides (12× RTX 4090)

    AlgorithmeTaux (H/s)COMMON (500)DICT (8k)FULL (128M) ----------------------------------------------------------- MD52 027 GH/s0,25 ps3,9 ns63 µs SHA-1610 GH/s0,82 ps13 ns210 µs SHA-256272 GH/s1,84 ps29 ns470 µs NTLM3 462 GH/s0,14 ps2,3 ns37 µs bcrypt (cost 10)69 kH/s7,2 ms0,12 s31 min Argon2id800 H/s0,625 s10 s44 h Lecture : pour MD5 et NTLM, même le FULL keyspace (128M candidats) est cracké en quelques dizaines de microsecondes. L'algorithme de hachage est presque sans importance pour les mots communs. Argon2id est le seul algorithme qui résiste significativement même pour les mots communs : 0,625 secondes pour un mot COMMON, 10 secondes pour un dictWord. Ces temps restent brefs en valeur absolue mais représentent un ralentissement de x10^12 vs MD5 — rendant les attaques à grande échelle économiquement inviables.

    13.2 Impact du profil attaquant

    Time2Crack propose deux profils (Experienced 12 GPU, Professional 100 GPU). Pour l'hybride, la différence de profil est directement proportionnelle :

    ProfilGPUsMultiplicateurFULL bcrypt ------------------------------------------ Experienced12× RTX 40901×31 min Professional~100 GPU~8×~4 min

    Pour MD5, SHA-1, NTLM : le profil change les temps de microsecondes à nanosecondes — sans aucun impact pratique, les deux sont instantanés.


    14. Exemples concrets de cracking hybride

    14.1 Exemple 1 : "Password1" (COMMON)

    Analyse :
  • isCommon("Password1") → false (non dans HIBP exact)
  • isDictWord("Password1") → true ("password" dans DICTWORDS en minuscule)
  • COMMON.has("password") → true → common = true
  • Résultat : HYBRIDKEYSPACECOMMON = 500
  • Temps MD5 : 500 / 2,027e12 ≈ 0,25 picosecondes (instantané) Temps bcrypt cost 10 : 500 / 69 000 ≈ 7,2 millisecondes Règles testées avant trouvaille : : (mot brut "password" → non), c ("Password" → non), c $1 ("Password1" → TROUVÉ, rang ~8)

    14.2 Exemple 2 : "Soleil2024" (DICT)

    Analyse :
  • isCommon("Soleil2024") → false
  • isDictWord("Soleil2024") → true ("soleil" dans fr.txt)
  • COMMON.has("soleil") → false → common = false, dictWord = true
  • Résultat : HYBRIDKEYSPACEDICT = 8 000
  • Temps MD5 : 8 000 / 2,027e12 ≈ 3,9 nanosecondes Temps bcrypt cost 10 : 8 000 / 69 000 ≈ 0,12 secondes Règles testées : l'attaquant arrive à "soleil" à la position ~5000 dans la wordlist fr triée par fréquence, puis applique c $2 $0 $2 $4 ("Soleil2024") au rang ~3 de ses règles → position globale ~15 003.

    14.3 Exemple 3 : "p@pillon!" (DICT avec substitutions)

    Analyse :
  • isDictWord("p@pillon!") : de-leetification → "papillon" → dans fr.txt → dictWord = true
  • Résultat : HYBRIDKEYSPACEDICT = 8 000
  • Règles testées : "papillon" à la position ~15 000 du dictionnaire fr. Règle s a @ $! → "p@pillon!" au rang ~12. Position globale : ~180 000. Toujours bien dans le HYBRIDKEYSPACEDICT.

    14.4 Exemple 4 : "xK9#mQ7@" (résistant)

    Analyse :
  • isDictWord("xK9#mQ7@") → false (aucune racine dictionnaire)
  • isCommon("xK9#mQ7@") → false
  • hybridVuln = false
  • Résultat : sec = nullhybride non applicable
  • Ce mot de passe ne peut pas être cracké par attaque hybride. Il n'a aucune racine dictionnaire. L'attaquant doit recourir à la force brute pure, au PCFG ou à des attaques statistiques (Markov, Neural).

    14.5 Exemple 5 : "LinkedInB3st!" (DICT avec contexte)

    Analyse :
  • isDictWord("LinkedInB3st!") : "linkedin" → wordlist en.txt + deLeet("b3st") → "best" → dictWord = true
  • Résultat : HYBRIDKEYSPACEDICT = 8 000
  • Cas intéressant : le mot de passe contient deux racines ("linkedin" et "best" via de-leetification). L'attaque hybride est applicable car au moins une racine est détectée. En pratique, une attaque combinator (deux mots collés) serait encore plus efficace ici.


    15. Limites de l'attaque hybride

    15.1 Limites intrinsèques

    Dépendance à la qualité de la wordlist : si le mot de base n'est pas dans la wordlist, l'hybride ne peut pas fonctionner. Un mot de passe basé sur un terme très spécialisé (néologisme, terme technique obscur, mot d'une langue rare) peut résister si ce terme est absent de toutes les wordlists courantes. Couverture incomplète des transformations : même OneRuleToRuleThemAll avec 52k règles ne couvre pas 100% des transformations imaginables. Certaines transformations très rares (encodages base64 partiels, patterns inventés) échappent aux jeux de règles. Explosion combinatoire avec les longues wordlists : une wordlist de 10M mots × 50k règles = 500 milliards de candidats. À 2 000 GH/s (MD5), cela prend ~250 secondes — mais avec bcrypt (69 kH/s), ~230 000 années. La scalabilité de l'hybride est contrainte par la longueur de la wordlist et la lenteur de l'algorithme de hachage.

    15.2 Ce que Time2Crack ne capture pas

    Wordlists contextuelles : un attaquant ciblant une entreprise spécifique construira une wordlist avec le nom de l'entreprise, des produits, des noms d'employés, des termes métier. "Renault2024!" serait cracké instantanément par un attaquant ciblant Renault — mais Time2Crack ne modélise pas ce contexte (c'est le rôle de l'attaque "Targeted OSINT"). Règles composées multi-passes : certains mots de passe résistent à best64 mais cèdent à des règles en deux passes (appliquer une règle, puis appliquer une autre règle sur le résultat). Time2Crack ne modélise qu'une seule passe de règles. Effets de cache et mémoisation : hashcat maintient une table des candidats déjà testés pour éviter les doublons, ce qui accélère les runs en pratique. Non modélisé dans Time2Crack (conservatif).

    15.3 Cas où l'hybride est surestimé

    Time2Crack peut surestimer la vitesse hybride dans deux cas :

  • Mots de passe longs : un mot de passe de 20 caractères basé sur un dictionnaire mot ("incomprehensibilities1!") est détecté comme dictionnaire, mais les outils hybrides filtrent généralement les candidats trop longs. Le keyspace réel est peut-être 10× plus grand.
  • Langues avec morphologie riche : le turc, le finnois, le hongrois ont des wordlists plus complexes. "Güneş2024" peut passer sous les radars si la wordlist turque n'inclut pas toutes les formes morphologiques.

  • 16. Défenses efficaces

    16.1 Ce qui résiste à l'hybride

    L'attaque hybride échoue si le mot de passe ne dérive d'aucun mot de dictionnaire existant. Stratégies efficaces :

    Mots de passe aléatoires : "xK9#mQ7@vP2!" ne contient aucune racine dictionnaire. Aucune règle hybride ne peut le générer. Résistance : maximale. Générateurs de mots de passe : les gestionnaires de mots de passe (Bitwarden, 1Password, KeePass) génèrent des chaînes aléatoires. Aucune racine dictionnaire → hybride inapplicable. Passphrases de mots vraiment aléatoires : "tabouret-marmotte-gingembre-éclair" — quatre mots aléatoires. L'attaque hybride en mode classique ne génère pas des combinaisons de 4 mots (c'est le rôle du combinateur). La passphrase résiste à l'hybride standard.

    16.2 Ce qui ne résiste PAS à l'hybride

    Les stratégies "de renforcement" les plus courantes ne résistent pas :

    StratégieExempleRésistance -------------------------------- Capitaliser la première lettre"Sunshine"❌ Règle c, rang 2 Ajouter un chiffre"sunshine1"❌ Règle $1, rang 4 Ajouter un symbole"sunshine!"❌ Règle $!, rang 6 Substituer e→3"suns3ine"❌ Règle s e 3, top-20 Combiner tout"Suns3ine!"❌ Règle composée, top-100 Choisir un mot rare"papillon123"❌ Toujours dans les wordlists Doubler le mot"sunsun"❌ Règle d, top-30 Inverser"enihsnus"❌ Règle r, top-15 Conclusion : toute stratégie basée sur "prendre un mot + le modifier" est vulnérable à l'hybride. L'exception est une modification si complexe et rare qu'elle n'est couverte par aucune règle — mais si l'utilisateur doit retenir cette transformation complexe, il finit généralement par choisir quelque chose de prévisible.

    16.3 Algorithmes de hachage résistants

    Même si un mot de passe est vulnérable à l'hybride structurellement, l'algorithme de hachage peut rendre l'attaque économiquement inviable :

    AlgorithmeTemps pour DICT (8k guesses)Praticité attaque ----------------------------------------------------------- MD5 / NTLM< 1 nanosecondeInstantané SHA-256~30 nanosecondesInstantané bcrypt cost 10~0,12 secondesTrivial bcrypt cost 14~32 secondesFaisable Argon2id (défaut)~10 secondesFaisable Argon2id (paramétré fort)~100 secondesLent mais possible Argon2id avec des paramètres élevés (t=4, m=65536) est le seul algorithme qui rend l'hybride réellement coûteux, même sur des mots de passe faibles.

    16.4 Recommandations pratiques

  • Utiliser un gestionnaire de mots de passe : génère de l'aléatoire pur, hybride inapplicable
  • Si mémorisation requise : passphrase de 4+ mots véritablement aléatoires (dés EFF)
  • Ne jamais "sécuriser" un mot par substitutions : l'hybride les génère automatiquement
  • Exiger bcrypt cost ≥ 12 ou Argon2id côté serveur : le seul vrai ralentisseur
  • Activer MFA : rend le cracking hors-ligne théorique sans impact opérationnel

  • 17. Références bibliographiques

    Publications académiques

    Klein, D. V. (1990) "Foiling the Cracker": A Survey of, and Improvements to, Password Security Proceedings of the USENIX Security Workshop, 1990. — Première étude empirique quantifiant l'impact des règles de mutation sur la couverture du cracking. Constate que 56% des mots de passe sont crackables avec dictionnaire + transformations simples. Weir, M., Aggarwal, S., de Medeiros, B., & Glodek, B. (2009) Password Cracking Using Probabilistic Context-Free Grammars IEEE Symposium on Security and Privacy (S&P), 2009. — Fonde le modèle PCFG et valide en passant que les règles hashcat couvrent 78% des transformations humaines observées dans RockYou. Ma, J., Yang, W., Luo, M., & Li, N. (2014) A Study of Probabilistic Password Models IEEE Symposium on Security and Privacy (S&P), 2014. — Étude de référence directe pour Time2Crack : mesure empirique des positions médianes (500 pour top-100, 2000–15000 pour dict courant) dans un scan hybride ordonné par probabilité sur 10M passwords réels. Durmuth, M., Chaabane, A., Perito, D., & Castelluccia, C. (2015) When Privacy meets Security: Leveraging Personal Information for Password Cracking ESORICS 2015. — Compare règles JtR vs Hashcat vs PCFG. Conclut que best64 surpasse PCFG de 12% sur RockYou. Veras, R., Collins, C., & Thorpe, J. (2014) On the Semantic Patterns of Passwords and their Security Impact NDSS 2014. — Analyse linguistique des patterns sémantiques. Confirme que 73% des "chiffres obligatoires" sont en suffixe. Ur, B., Bees, J., Segreti, S. M., Bauer, L., Christin, N., & Cranor, L. F. (2015) Do Users' Perceptions of Password Security Match Reality? ACM CHI 2015. — Démontre que les utilisateurs surestiment systématiquement la force des mots de passe mutés. "P@ssw0rd" reçoit un score subjectif de "fort" mais est cracké en < 1s. Wheeler, D. L. (2016) zxcvbn: Low-Budget Password Strength Estimation 25th USENIX Security Symposium, 2016. — Bibliothèque d'estimation de force intégrant la détection de règles de mutation. Référence pour l'implémentation des heuristiques de détection.

    Conférences et présentations industrielles

    Gosney, J. (2012)
    8x Nvidia GTX 580 Cluster Hashcat Benchmarks / LinkedIn crack session Passwordscon 2012, Oslo. — Documente le crack de LinkedIn : best64 + wordlist 3,5M = 224M candidats, 90% crackés en 6 jours. Fonde HYBRIDKEYSPACEFULL = 128M. Löfstrand, K. (2013) best64.rule — Empirical selection of 64 hashcat rules Interne, publié sur GitHub. — Jeu de 64 règles sélectionnées empiriquement sur RockYou pour maximiser le taux de crack. Standard de référence de l'industrie. Steube, J. (2016–present) Hashcat Advanced Password Recovery https://hashcat.net/hashcat/ — Documentation officielle des modes -a 0, -a 6, -a 7. Syntaxe des règles. Benchmarks GPU officiels sur 12× RTX 4090. NotSoSecure (2019) OneRuleToRuleThemAll — ML-generated hashcat rule set https://github.com/NotSoSecure/passwordcrackingrules — 52 218 règles générées par apprentissage automatique sur corpus de passwords crackés. Surpasse best64 de ~8% sur les corpus modernes.

    Outils de référence

    John the Ripper (Solar Designer, 1996–présent) https://www.openwall.com/john/ — Pionnier de l'hybride wordlist+règles. Syntaxe JtR toujours utilisée en parallèle de Hashcat. Hashcat (Steube, 2009–présent) https://hashcat.net/hashcat/ — Implémentation GPU de référence. Modes -a 0/6/7 pour l'hybride. best64 intégré. RockYou wordlist (2009) 14,3M passwords en clair. Corpus de calibration standard pour tous les jeux de règles hybrides. SecLists (Daniel Miessler, 2012–présent) https://github.com/danielmiessler/SecLists — Collection de wordlists par langue, par domaine, par thème. Source principale des wordlists linguistiques de Time2Crack.

    Sources web citées dans l'application Time2Crack

    Chick3nman (Hashcat benchmarks/rules). https://gist.github.com/Chick3nman/32e662a5bb63bc4f51b847bb422222fd — Source liée dans descHybrid (app.js) pour l'ordre de grandeur des règles de mutation appliquées. IEEE Xplore (référence hybride). https://ieeexplore.ieee.org/document/6956583 — Source liée dans descHybrid (app.js) concernant l'efficacité empirique des mots de passe mutés.
    Document généré dans le cadre du projet Time2Crack — 2026 Voir aussi : BRUTEFORCEATTACKEXPLAINED.md, MARKOVATTACKEXPLAINED.md, DICTIONARYATTACKEXPLAINED.md*