Ataque del Diccionario - Operación Integral

Documento de referencia del proyecto Time2Crack
Recipientes: desarrolladores, investigadores de seguridad, usuarios avanzados

Índice

  • Sinopsis
  • Antecedentes históricos y académicos
  • Fundaciones conceptuales: por qué los diccionarios trabajan
  • Arquitectura de un ataque de diccionario moderno
  • El corpus de contraseñas reales
  • K-Anonymity HIBP verification: a real-time attack
  • Time2Crack Language Listas de palabras
  • Detección de Diccionario en Time2Crack: isDictWord()
  • De-leetification: how the attacker decodes substitutions
  • Cálculo del tiempo de grieta: addDictionaryAttacks()
  • Calibración de alta fidelidad: applyHighFidelityCalibration()
  • La probabilidad de aplicabilidad y puntaje de confianza
  • Bloom filter RockYou : detección local de contraseñas generalizadas
  • Comparación con los ataques derivados
  • Limitaciones del diccionario de ataque
  • Defensas eficaces
  • Referencias

  • 1. Sinopsis

    El ataque al diccionario es el método de grieta de contraseña más antiguo, el más simple conceptualmente y estadísticamente más eficaz en la mayoría de las contraseñas humanas reales. Su principio es probar, en orden descendente de probabilidad, una lista precompilada de candidatos — el "diccionario"— en lugar de enumerar exhaustivamente todas las combinaciones posibles como lo hace la fuerza prima.

    Por qué es terriblemente eficaz Los humanos no eligen sus contraseñas aleatoriamente. Decenios de las filtraciones de datos revelan que la distribución real de las contraseñas está muy concentrada: las más comunes 1.000 contraseñas representan alrededor de 5 a 10% de todas las cuentas en línea. Los más comunes 1 millón cubren 40 a 60%. Un ataque de diccionario bien construido pondrá a prueba a estos candidatos en milisegundos a segundos, donde la fuerza bruta tomaría millones de años.

    En Time2Crack, el diccionario atacan dos mecanismos distintos pero complementarios:

  • Verificación de HIBP (He estado Pwned): Confrontación de la contraseña a los ~14 mil millones de credenciales únicas de las filtraciones históricas de datos. Si la contraseña está allí, un atacante lo descubriría en una fracción de segundo.
  • Detección de Wordlist Language Una palabra de lenguaje común — "sun" o "sunshine"— es vulnerable incluso si no está en HIBP.
  • Estas dos detecciones son independientes y complementarias: HiBP cubre las credenciales exactas de compromiso, la lista de palabras cubre las palabras comunes que aún no se han filtrado.


    2. Antecedentes históricos y académicos

    2.1 Origen

    El ataque del diccionario precede a la era moderna de seguridad informática. Los primeros sistemas Unix almacenan contraseñas en lenguaje simple en /etc/passwd, haciendo cualquier ataque de diccionario trivial tan pronto como el archivo era accesible.

    Cronología de los hitos : AñoEvento ----------------- 1979Morris & Thompson: Primer artículo académico sobre seguridad de contraseñas Unix. Vea que 1/3 de contraseñas eligen palabras comunes en inglés 1988Morris Worm: se propaga parcialmente a través de un diccionario de palabras 432 + host /usr/share/dict/words 1993Crack 5.0 (Alec Muffett): Primera herramienta de ataque del diccionario público en Unix, incluye reglas de mutación 2000John the Ripper: populariza las listas de palabras combinadas con reglas hashcat (modo de palabras + reglas) 2009RockYou fuga: 14.3 millones de contraseñas claras revelan la distribución real de las opciones humanas 2012He estado Pwned (Troy Hunt): primer servicio de auditoría pública para credenciales comprometidas 2013Adobe break: 153 millones de cuentas — las contraseñas superiores se identifican por análisis de frecuencia incluso en hashs no saldados 2016Hashcat open source v3.0: massive optimization of wordlist attacks on GPU (MD5: 2 TH/s on 8 GPU cluster) 2019Colección #1–5: 2.700 millones de pares de inicio de sesión/password compilados, distribuidos públicamente 2024HIBP v8: ~14 mil millones de contraseñas únicas indexadas

    2.2 Pérdidas de fundación

    Algunas filtraciones han transformado el paisaje del ataque por diccionario revelando la distribución real de contraseñas humanas:

    RockYou (2009) Un desarrollador había almacenado 14.3 millones de contraseñas en lenguaje simple.
  • Las primeras 10 contraseñas cubrieron ~5% de las cuentas
  • Primero 1.000: ~20% de las cuentas
  • La distribución sigue una ley de poder, confirmando que los humanos "piensan lo mismo"
  • LinkedIn (2012) - 6,5 millones de SHA-1 no saldadas. Adobe (2013) - 153 millones de cuentas. He sido Pwned (2013–presente) - La agregación progresiva de fugas públicas, permitiendo a Troy Hunt crear una base de referencia utilizada en todo el mundo.

    2.3 Puntos de referencia para el ataque al diccionario

    Una lista de 200.000 entradas probadas a la velocidad de un RTX 4090:

    AlgoritmSpeedTiempo para 200k candidatos ---------------------------- MD5168,9 GH/s~1,2 nanosegundo SHA-150.86 GH/s~3.9 nanoseconds SHA-25622.68 GH/s~8.8 nanosegundos NTLM288,5 GH/s~0,7 nanosegundo bcrypt (cost 5)184 kH/s~1.09 segundo Argon2id~67 H/s~50 minutos

    Por lo tanto, el ataque del diccionario es casi instantáneo para MD5, SHA-1 y NTLM — y sigue siendo muy rápido incluso para la cripta en pequeñas listas.


    3. Fundaciones conceptuales: por qué los diccionarios trabajan

    3.1 The Power Law of Human Passwords

    Todos los estudios empíricos convergen hacia la misma observación: la distribución de contraseñas humanas no es uniforme — sigue a derecho del poder (Zipf). Algunas contraseñas concentran una fracción desproporcionada de opciones.

    Formally : si todas las contraseñas se clasifican disminuyendo la frecuencia, la frecuencia de la contraseña de rango r es proporcional a r^(-α) con α 1,5 a 2 Según el cuerpo.

    Consecuencia directa: 10 contraseñas más comunes Un atacante que prueba sólo 10 candidatos ya tiene una oportunidad en 20 para tener éxito — estadísticamente, es enorme para la cantidad de ruido generado.

    3.2 Bias cognitivas en la creación de contraseña

    Los humanos no eligen al azar. Aplican sistemáticamente heurísticas que hacen predecibles sus contraseñas:

  • Bias de memoria : las palabras fáciles de recordar (nombres comunes, nombres, términos de cultura popular) están sobrerepresentadas
  • Disponibilidad Bias La contraseña refleja el entorno inmediato (nombre animal doméstico, equipo deportivo, carácter serial)
  • Sesgos de sustitución predictibles : "e" → "3", "a" → "@", "o" → "0" — el usuario cree que la contraseña es fuerte, pero estas sustituciones son exactamente la primera que el atacante intenta hacer
  • Bias completas : adición de un número o símbolo al final de una palabra (password1, sol!)
  • Sesgo cultural Las contraseñas comunes están vinculadas al lenguaje y la cultura del usuario ("Soleil123" en Francia, "Sommer123" en Alemania)
  • 3.3 El concepto de "palabra ya en las listas"

    Una contraseña puede estar en una lista de ataque por dos razones diferentes:

    Razón 1 - Está en HIBP La credencial exacta ha sido comprometida en una fuga pasada. El atacante no necesita adivinar — prueba las credenciales conocidas uno por uno, en orden de frecuencia. Si el servidor de destino acepta la credencial, se termina. Razón 2 - Está en una lista de palabras lingüística La contraseña es una palabra ordinaria de vocabulario común. Incluso si nunca ha huido, es en todos los wordlists de ataque porque es un candidato obvio. "Paillon" puede no estar en HiBP, pero está en la lista de palabras francesa de cualquier herramienta de grieta seria.

    Estos dos casos corresponden a ataques de naturaleza diferente, con diferentes velocidades, y esto es precisamente lo que los modelos Time2Crack.


    4. Arquitectura de un ataque de diccionario moderno

    4.1 Gasoducto general

    Un ataque de diccionario moderno tiene lugar en varias fases:

    Phase 1 : Constitution de la wordlist
        ├── Mots de passe fuités (HIBP, RockYou, Collections)
        ├── Wordlists linguistiques (dictionnaires, prénoms, lieux)
        ├── Wordlists thématiques (sport, pop culture, tech, religion)
        └── Wordlists contextuelles (domaine de l'entreprise cible, noms d'employés)
    

    Fase 2: Preprocesamiento de la lista de palabras - Ordenar por frecuencia (probablemente primero) - Deduplicación (no el doble del mismo candidato) - Filtración de la longitud (longitud del objetivo + ±2) - Normalización (bajo, Unicode NFC)

    Fase 3: Cálculo de Hashs Candidato Para cada candidato w en la lista de palabras: , hashcandidato = hahalgo(w) Promocional si hashcandidato= hashMeta: finalizada - Velocidad: 168 GH/s para MD5 en RTX 4090

    Fase 4: Análisis de los resultados Report of cracked passwords, coverage statistics

    4.2 Optimizaciones de hardware

    Los ataques de diccionario modernos son masivamente paralelos a la GPU:

  • Hashcat (herramienta de referencia): explota los núcleos de CUDA de la GPU para paralelizar miles de millones de computaciones simultáneas precipitadas
  • Vector Pipeline : en un RTX 4090, una sola instrucción SIMD calcula 8 a 16 hashs MD5 en paralelo
  • Caché de GPU : la lista de palabras se carga en VRAM para minimizar la latencia de memoria
  • Batching : los candidatos son enviados a la GPU en lotes de millones para maximizar el flujo
  • Para una lista de palabras de 14 mil millones de entradas (tamaño HIP) en 12× RTX 4090:

  • MD5 : 14e9 / (168.9e9 × 12) 6.9 segundos
  • bcrypt cost 5 : 14e9 / (184000 × 12) 6.337 años
  • Esta diferencia de ~9 órdenes de magnitud entre MD5 y bcrypt explica por qué la elección del algoritmo hash es crítica.

    4.3 Orden de prueba de candidatos

    La lista de palabras no se prueba en orden alfabético — es ordenados por la disminución de la probabilidad :

  • Las contraseñas de escape más comunes (RockYou top 100)
  • contraseñas comunes de múltiples fallas (lista de prioridades de la IPBP)
  • Palabras comunes del idioma objetivo
  • Los nombres propios (primeros nombres, ciudades, celebridades)
  • Mandatos temáticos relacionados con objetivos
  • Variaciones y conjugaciones
  • Este tipo asegura que si la contraseña es "bajo", se encontrará en los primeros milisegundos, sea cual sea la velocidad de precipitación.


    5. El corpus de contraseñas reales

    5.1 He estado Pwned (HIBP)

    Tamaño ~14 mil millones de contraseñas únicas (2024) Fuente : agregación de fugas públicas desde 2013 Formato : SHA-1 ordenados por frecuencia de apariencia Acceso público : k- anonymity API, descarga completa de hash disponible para los defensores

    HiBP es la referencia global porque:

  • Cubre casi todas las principales filtraciones públicas
  • Los hashs están ordenados por frecuencia — las contraseñas más comunes se prueban primero
  • Se mantiene activamente (nuevas fugas agregadas continuamente)
  • Un atacante con el vertedero completo HIBP puede probar los ~14 mil millones de candidatos en orden descendente de frecuencia. Para algoritmos no saltados (MD5, SHA-1), esta lista cubre en el orden de 50-70% de todas las contraseñas en línea reales.

    5.2 RockYou (2009) — Funding corpus

    Tamaño : 14.3 millones de contraseñas claras Características clave : RankContraseñaOccurrences% del corpus --------------------------------------------------- 1123456290 7312.03% 21234579 0780,55% 312345678976 7900,54% 4contraseña59 4620,42% 5Te amo.49 9520,35% Top 10—~650.000~4.5% Top 100—~1 200 000~8.4% Top 1 000—~2 500 000~17,5% Top 10.000—~4 500 000-31,5% Educación Prueba sólo 10.000 candidatos (100 μs MD5 velocidad) compromisos ~31% de una base de datos de cuentas protegidas MD5.

    5.3 Colecciones de listas de palabras especializadas

    SecLists (Daniel Miessler): colección de código abierto de ~4 GB listas de palabras que cubren:
  • Contraseñas (RockYou, contraseñas principales varias fugas)
  • Usos actuales
  • Contraseñas clasificadas por idioma
  • Términos técnicos, nombres de productos, celebridades
  • Kaonashi : 1.3 mil millones de entradas de redacción compiladas desde las filtraciones públicas Crackstation : 1.500 millones de entradas incluyendo palabras de todos los diccionarios de Wikipedia en varios idiomas Weakpass : agregación de ~8 mil millones de entradas de contraseña real

    Estos cuerpos son descargables públicamente — su existencia es un hecho establecido de seguridad ofensiva.


    6. K-Anonymity Verification HIBP: A Real-Time Attack

    6.1 Protocolo k-Anonimato

    Time2Crack incorpora un cheque HIBP en tiempo real que reproduce exactamente lo que un atacante haría con la base de datos HIBP, pero nunca transmite la contraseña en lenguaje llano o su hash completo.

    El protocolo k-anonymity funciona como sigue:

    1. Calculer SHA-1(password)      → par exemple "CBFDAC6008F9CAB4083784CBD1874F76618D2A97"
    
  • Enviar sólo los primeros 5 caracteres a la API HIBP: "CBFDA"
  • La API devuelve TODOS los sufijos SHA-1 comenzando con "CBFDA" (aproximadamente 400-600 hashes)
  • Buscar localmente si el resto del hash ("C6008F9CAB4083784CBD1874F76618D2A97") está en la lista
  • Si se encuentra: la contraseña se ha comprometido (HIBP también devuelve el número de fugas)
  • Garantía de confidencialidad El servidor HIBP nunca ve el hash completo (por lo que no puede identificar la contraseña), ni mucho menos la contraseña clara. El cálculo final se hace localmente. Lo que esto significa para el ataque : si HIBP devuelve una coincidencia con un alto recuento (p. ej. 9,547,236 apariciones para "123456"), esto significa que un atacante con la base de datos HIBP probar este credencial lo encontraría en una posición muy alta en su lista clasificada por frecuencia, en una fracción de nanosegundos.

    6.2 Aplicación en Time2Crack (app.js)

    El cheque HIBP es asincrónico y no bloqueo. La contraseña es analizada inmediatamente por métodos locales, y el cheque HIBP completa el resultado:

    // Pseudo-code simplifié
    async function checkHIBP(password) {
      const sha1 = await sha1Hash(password);
      const prefix = sha1.substring(0, 5);   // 5 premiers chars
      const suffix = sha1.substring(5);       // reste du hash
    

    const response = await fetch( https://api.pwnedpasswords.com/range/${prefix} ); const lines = await response.text();

    para (línea contigua de líneas.split('\n') { const [hashSuffix, count] = line.split(':'); si (hashSuffix.toLowerCase() = suffix.toLowerCase() {) parseInt(count); // número de fugas } } retorno 0; // no encontrado }

    Datos sobre el desempeño de la Oficina :
  • Latencia típica de API: 50–200 ms (network)
  • Volumen de sufijos devueltos: ~400–600 por consulta
  • Falso positivo: 0 (SHA-1 es determinista)
  • Falso negativo: 0 (si en HiBP, siempre devuelto)
  • 6.3 Interpretación del Conde HIBP

    El recuento devuelto por HiBP indica el número de veces que esta contraseña exacta apareció en las filtraciones indexadas:

    CondeInterpretaciónTiempo de cuna (MD5, 12× RTX 4090) ---.--- 1 000 000Top 100 World1 nanosegundo 10.000 a 1.000.000Muy común10 nanosegundos 1 000-10 000Común100 nanosegundos 100 a 11.000Infrecuente pero conocido1 microsegundo 1–100Rara pero comprometida10 microsegundos

    Incluso un recuento de 1 (la contraseña apareció sólo una vez en una fuga) indica una vulnerabilidad: si un atacante se dirige específicamente a esta cuenta y tiene la lista de credenciales de la fuga en cuestión, lo encontrará.


    7. Time2Crack Language Wordlists

    7.1 ¿Por qué los wordlists de idiomas además de HIBP

    HiBP cubre las credenciales de compromiso exactas, pero no las palabras comunes nunca se agotan todavía. Un usuario de habla francesa que elige "ephemeral" como una contraseña puede no estar en HiBP (la palabra es poco probable en credenciales de aglofono), pero está en la lista de palabras francesa de cualquier atacante dirigido a un sistema de habla francesa.

    Las listas de palabras de Time2Crack cubren esta brecha:

    IdiomaFuenteTamaño estimado ------. InglésSecLists Wikipedia EN~ 200.000 entradas Francés (fr)SecLists Wikipedia EN~150.000 entradas EspañolSecLists Wikipedia ES~150.000 entradas Portugués (pt)SecLists Wikipedia PT~ 120.000 entradas AlemánSecLists Wikipedia DE~180.000 entradas Turco (tr)SecLists Wikipedia TR~100.000 entradas Italiano (it)kkrypt0nn~100.000 entradas Polaco (pl)kkrypt0nn~80 000 entries Países Bajos nl)kkrypt0nn~80 000 entries Filtro aplicado Sólo se mantienen palabras de ≥ 4 caracteres (los 1–3 caracteres son demasiado cortos para ser una contraseña realista, y su inclusión inflará la lista sin valor añadido).

    7.2 Carga perezosa

    Las listas de palabras no están incluidas en el código — se cargan bajo petición al cambiar el idioma, para cubrir el presupuesto de la red:

    // app.js - loadDictionary()
    async function loadDictionary(lang) {
      if (DICTlang " DICT "WORDS) return;  // Déjà chargé
      if (DICTLOADING) {
    DICTPENDINGLANG = lang; // Archivo de espera
    retorno;
    }
    DICTLOADING = true;
    

    const res = await fetch(data/wordlists/${lang}.txt); const text = await res.text();

    // Convertir en Establecer referencias clave para la búsqueda O(1) DICTWORDS = nuevo Set( texto.split("\n") .map(w = título w.normalize("NFC").trim().toLowerCase()) .filter(w = título w.length ); DICTLANG = Lang; DICTLOADING = false; }

    ¿Por qué? Set ? Estructura Set JavaScript garantiza las revisiones O(1), independientemente del tamaño del diccionario (50.000 o 200.000 entradas), verificación DICTWORDS.has(word) toma el mismo tiempo constante. Array requeriría O(n) por consulta, es decir, hasta 200.000 comparaciones por cheque.

    Carga de cola

    El DICTFINLANG evita las condiciones de raza durante los cambios rápidos en el idioma:

    Scénario : l'utilisateur switche rapidement EN → FR → DE
    ├── EN demandé : DICTLOADING = false → inicio de la fiesta EN
    FR solicitada durante la captura EN : DICTLOADING = true → DICTFINLANG = "fr"
    ├── DE demandé pendant fetch EN : DICTLOADING = verdadero → DICTPENDINGLANG = "de" (crash "fr")
    - Fin de la venta: DICTLANG = "en", puis lance loadDictionary("de")
    └── Résultat : seule la dernière langue demandée est chargée

    Este comportamiento es intencional: se carga el idioma más solicitado recientemente, no todos los idiomas intermedios.


    8. Detección de Diccionario en Time2Crack: isDictWord()

    8.1. Operación de detección

    La función isDictWord(pw) determina si una contraseña es o se deriva de una palabra de diccionario actual:

    // app.js - ligne 2181
    function isDictWord(pw) {
      if (!DICT(WORDS) devolver falso;
    

    // Normalización: NFC + maleta inferior const l = pw.normalize("NFC").toLowerCase();

    // Verificación directa si

    WORDS.has(l) || DICTWORDS.has (deLeet(pw))) devolver verdadero;

    // Variaciones morfológicas const deleetWord = deLeet(pw); const variaciones = getMorphVariations(deleetWord);

    para (continuación de variaciones) { si

    WORDS.has(variation)) return true; }

    devolver falso; }

    3 capas de detección :
  • Corrección directa : ¿Es la contraseña estándar en el diccionario como está?
  • "sun" → golpe directo
  • "SOLEIL" → estándar en "sun" → hit
  • Correspondencia de selección posterior : ¿Contiene la contraseña estándar las sustituciones?
  • "s0l3il" → deLeet → "sun" → hit
  • "p@ssw0rd" → deLeet → "password" → hit
  • Variaciones morfológicas : ¿La contraseña es una variante morfológica conocida?
  • "sun" → Variación plural de "sun" → hit
  • "passwords" → variación de "password" → hit
  • 8.2 Normalización Unicode (NFC)

    Normalización normalize("NFC") garantiza que los caracteres acentuados sean tratados consistentemente:

  • "e" se puede representar en Unicode como un solo código de puntos (U+00E9) o como "e" + combinación de acento (U+0065 + U+0301)
  • Sin estandarización, "coffee" y "coffee" (diferentes codificaciones) no coincidiría con
  • Esta estandarización se aplica tanto al crear el diccionario como al revisarlo, asegurando la correspondencia correcta para los lenguajes de acento (FR, ES, DE, PT, etc.).

    8.3 Impacto en la vulnerabilidad detectada

    Cuando isDictWord() Vuelve. truevarios ataques se aplican:

  • Ataque del diccionario auto: puntaje de confianza 0.85 (vs 0 si ausente)
  • Ataque híbrido : hybridVuln = true → 1000 mutaciones probadas en el diccionario
  • Ataque PCFG : mayor puntaje de confianza (base electrónico detectado)
  • Ataque morfológico : alta prioridad si se detecta la variante morfológica

  • 9. De-leetificación: cómo el atacante descifra las sustituciones

    9.1 Leetspeak y sus limitaciones como protección

    El leetspeak (o "1337 discurso") es una práctica de reemplazar letras con números o símbolos visualmente similares: a→@, e→3, i→1 o !, o→0, s→$. Los usuarios lo usan para "fortalecer" palabras comunes.

    Ejemplo : "password" → "p@$w0rd"

    La realidad: estas sustituciones son las primeras normas aplicadas no constituyen una defensa real contra un atacante competente.

    9.2 Aplicación deLeet() en Time2Crack

    // app.js - ligne 3622
    const LEETBASE = {}
    a: ["@", "4"],
    e: ["3"],
    ["0"],
    s: ["$", "5"],
    t: ["+", "7"],
    ["#"],
    ["9"],
    };
    

    función deLeetWith(pw, oneMap) { let r = pw.normalize("NFC").toLowerCase(); para (const [ch, reps] de Object.entries(LEET)

    BASE)) for (const c of reps) r = r.split(c).join(ch); // Appliquer la résolution ambiguë (i ou l) en dernier for (const [ch, reps] of Object.entries(oneMap)) for (const c of reps) r = r.split(c).join(ch); return r; }

    función de Leet(pw) { // Ambigüedad: "1" puede ser "i" o "l" const withI = deLeetWith(pw, { i: "1!", l: "" }); const withL = deLeetCon(pw, { l: "1", i: "!" });

    // Si el diccionario está cargado, prefiera la variante que coincida siWORDS { siWORDS.has(withL)) retorno conL; siWORDS.has(conI) return withI; }

    // De lo contrario: prefiere la variante con los números menos restantes const digestsI = (con I.match(/\d/g) const digestsL = (con L.match(/\d/g) dígito de retorno L = dígito I? withL: withI; }

    9.3 Gestión de la ambigüedad "1" → "i" o "l"

    La sustitución "1" es ambiguo: "1" puede representar "i" (como en "1nfo" → "info") o "l" (como en "p1ayer" → "jugador"). Time2Crack resuelve esta ambigüedad por:

  • Probando ambas variantes ("con I" y "con L")
  • Si el diccionario está cargado, prefiriendo la variante que da un partido del diccionario
  • Sin un diccionario, prefiriendo la variante que deja los números residuales más pocos (asunción: la eliminación completa es más probable)
  • Ejemplo :
  • "b1ue" → conI = "biue" (no en dict), conL = "blue" (en dict) → devuelve "blue"
  • "f1le" → conI = "file" (en dict), conL = "flle" (no en dict) → devuelve "file"
  • 9.4 Sustituciones no cubiertas (intencionadamente)

    Time2Crack no cubre sustituciones raras o ambiguas más allá de los patrones de LEETBASE. Es una opción de diseño: cubrir demasiados casos aumentaría los falsos positivos (detectar una contraseña como una "palabra corriente" mientras que no lo es).Los patrones incluidos cubren √95% de las leetificaciones reales observadas en el corpus.


    10. Cálculo del tiempo de grieta: addDictionaryAttacks()

    Cálculo lógico

    // app.js - ligne 3848
    function addDictionaryAttacks(rows, common, weak, dictWord) {
      for (const a of ALGOS) {
        let sec;
        if (weak)     sec = 100 / a.rate;     // Top ~100 entrées
        else if (common) sec = 10000 / a.rate; // HIBP priority list ~10k
        else if (dictWord) sec = 200000 / a.rate; // Scan wordlist complète ~200k mots
        else sec = null;                        // Non applicable
    

    nota const = débil ? t("nWeakPassword") : común ? t("nInLeaks") : dictWord ? t(nDictHit) t(nAbsentLeaks);

    rows.push({ atk: t("aDict"), hash: a.name, spleen: a.rate, sec, note, cat: "dict" }); } }

    10.2 Tres niveles de vulnerabilidad

    Nivel 1 - Ultra-mojado (G)weak = true) : ~100 / bazo La contraseña está en el Top 100 del mundo ("password", "123456", "qwerty"...). Un atacante que prueba a estos 100 candidatos prioritarios lo encuentra en el primer paso. 0.6 nanosegundo. Nivel 2 - Común (G)common = true-10 000 / bazo La contraseña está en la lista de referencia HIBP de las ~10.000 contraseñas más frecuentes. Estos candidatos se prueban en los primeros microsegundos. Para MD5: 10,000 / 168,9e9 59 nanoseconds. Nivel 3 - DictWord (G)dictWord = true~200,000 / bazo La contraseña es una palabra del diccionario de idioma actual (lista de palabras locales ~50k–200k entries). Un análisis completo de la lista de palabras es casi instantáneo para algoritmos rápidos. Para MD5: 200 000 / 168,9e9 1.18 microsecond. Nivel 4 - No aplicable (G)sec = null) : la contraseña no es ni ultra-mojo, ni común, ni una palabra del diccionario actual. El ataque del diccionario solo no es aplicable - otros ataques (fuerza bruta, Markov, PCFG) se convierten en la principal amenaza.

    10.3 ¿Por qué estos números (100, 10.000, 200.000)?

    Estos valores se calibran a datos reales:

  • 100 Las primeras contraseñas de 100 RockYou representan ~10% del cuerpo. Todas las herramientas serias las prueban como una prioridad.
  • 10 000 : HiBP clasifica sus ~14 mil millones de entradas por frecuencia. Los 10.000 cubren alrededor del 30-40% de las contraseñas reales en uso. Cualquier atacante competente comienza con este subconjunto.
  • 200 000 : tamaño típico de una lista completa de idiomas después de filtrar. Esto es suficiente para cubrir el vocabulario actual de un idioma sin exceder la capacidad de carga razonable en la memoria.
  • Referencia Weir et al. (2009) muestran que las palabras del diccionario se encuentran en los primeros 200.000 intentos de un ataque bien ordenado. Ur et al. (2012) confirman que las contraseñas comunes se encuentran en los primeros 10.000 intentos.

    10.4 Ejemplo numérico completo

    Para la contraseña "sun" (actual palabra francesa, detectada como dictWord)

    AlgoritmVelocidad (12× RTX 4090)FormulaHora ----------------------------- NTLM3.462 GH/s200 000 / 3 462e957.8 picosegundos MD52 027 GH/s200 000 / 2 027e998.7 picosegundos SHA-1610 GH/s200 000 / 610e9327,9 picosegundos SHA-256272 GH/s200 000 / 272e9735 picos segundos bcrypt (cost 5)2.2 MH/s200 000 / 2 200 00090,9 milisegundos Argon2id800 H/s200 000 / 800250 segundos

    Incluso para Argon2id, 250 segundos es menos de 5 minutos, para una simple palabra del diccionario francés.


    11. Calibración de alta fidelidad: applyHighFidelityCalibration()

    11.1 ¿Por qué la calibración adicional?

    El cálculo bruto addDictionaryAttacks() da una estimación del "caso peor" — como si el atacante estuviera probando uniformemente toda la lista de palabras. ordenado por probabilidad : las contraseñas más comunes llegan primero.

    La calibración de alta fidelidad aplica un multiplicador correctivo basado en observaciones empíricas:

    // app.js - ligne 4442
    case "dict":
      // Ur et al. 2012 : mots communs trouvés dans les 100-10k premiers essais
      // Weir 2009 : mots dict trouvés dans les 200k premiers essais (scan ordonné)
      m = context.common? 0.15: context.dictWord ? 0.5: 1.0;
    Break;
    Multiplicador common (0.15) : si la contraseña está en la lista de prioridades comunes, se encuentra en promedio en el percentil 15 de la lista - que es ~1,500 pruebas de los 10.000 listados. El tiempo se multiplica por 0.15 → 6.7× más rápido que el análisis uniforme. Multiplicador dictWord (0.5) : una palabra de diccionario común se encuentra en medio término medio promedio de una lista bien ordenada. Multiplier 0.5 → 2× más rápido que el escaneo uniforme.

    Fuentes académicas de calibración

  • Ur et al. (2012) - ¿Cómo se asegura su contraseña? (USENIX Security): análisis de la distribución de contraseñas en corpus real. Palabras comunes: encontradas en los primeros 10.000 ensayos para el 95% de los casos.
  • Weir et al. (2009) — Recuperar contraseña Usando gramáticas libres de contextos probabilísticos Las palabras del diccionario puro se encuentran en los primeros 200.000 ensayos de un ataque ordenado.

  • 12. probabilidad de aplicabilidad y puntaje de confianza

    12.1 Sistema de cableado

    Time2Crack no solo calcula un tiempo — también evalúa la probabilidad de que el ataque del diccionario sea en realidad el ataque más rápido, a través de un sistema de puntuación multifactorial:

    // Score d'applicabilité (0-1)
    case "dict":
      return context.common ? 0.99 : context.dictWord ? 0.85 : 0;
  • 0.99 si common La contraseña está en HIBP → el ataque del diccionario se aplica con máxima confianza.
  • 0.85 si dictWord Sólo: alta probabilidad. Una palabra de diccionario es vulnerable, pero un atacante debe tener la lista lingüística correcta.
  • 0 De lo contrario: el ataque del diccionario no se aplica (no se detecta ninguna vulnerabilidad lexical).
  • 12.2 Puntuación de la prueba

    En paralelo con la puntuación de aplicabilidad, un marcador "prueba" registra las señales observadas:

    case "dict":
      return Number(!!context.common) + Number(!!context.dictWord);
      // 0 : aucun signal
      // 1 : un signal (common OU dictWord)
      // 2 : deux signaux (common ET dictWord)

    Una puntuación de evidencia de 2 (palabra en HIBP y diccionario lingüístico) aumenta la confianza final de 0.08 (2 × 0.04).

    12.3 Puntuación final de la confianza

    const base = confidenceBase["dict"] || 0.6;  // confiance de base
    const evidenceBoost = Math.min(0.12, row.evidenceScore  0.04);
    const speculativePenalty = speculativeCats.has("dict") ? 0.08 : 0;  // dict n'est pas spéculatif
    

    row.confidence = Math.max(0, Math.min(1, Math.max(aplicabilidad, base) + evidenciaBoost - específicoPenalty ));

    Para una contraseña common con dictWord también detectado:

  • applicability = 0.99
  • evidenceBoost = min(0.12, 2 × 0.04) = 0.08
  • confidence = min(1, max(0.99, 0.6) + 0.08) = min(1, 1.07) = 1.0
  • Confianza máxima: El ataque del diccionario es el ataque primario sin ambigüedad.


    13. Bloom filter RockYou: detección local de contraseñas generalizadas

    13.1 Antecedentes

    Además de la verificación HIBP (que requiere una llamada de red), Time2Crack incorpora una filtro Un filtro de floración es una estructura probabilística de datos que le permite probar pertenecer a un conjunto con una probabilidad de falsos positivos (~1%), sin almacenar los mismos elementos.

    13.2 Beneficios del filtro de floración

    CriteriosHIBP k- anónimoFiltro de Bloom local --------.--- Cobertura~14 mil millones~14 millones (RockYou) Latency50–200 ms (redes)1 ms (local) Confidencialidadk- anonimato (5 tanques SHA-1)100% local, nada transmitido Falso positivo0%~1% TamañoAPI~2-5 MB (bloom filter binario)

    13.3 Operación de doble escoria

    // app.js - ligne 1962
    function bloomHas(filter, word) {
      if (!filter) return false;
      const { bitArray, m, k } = filter;
      const w = word.toLowerCase();
    

    // Doble-hashing: h1 y h2 son dos funciones de hash independientes const h1 = fnv1a32(w, 2166136261); // FNV1a con semilla estándar const h2 = fnv1a32(w, 0x811c9dc5); // FNV1a con semilla alternativa

    para (let i = 0; i) const pos = (h1 + i (h2) нелиныминых (0)) % m; // k posiciones en la matriz de bits const byteIdx = Math.floor(pos / 8); const bitIdx = pos % 8;

    // Si un poco es 0: la palabra está ausente si ((bitArray[byteIdx] " (1 Identificado bitIdx)) = 0) devuelve falso; } // Todos los bits son a 1 : la palabra es PROBABLY presente (con 1% de FP) retorno verdadero; }

    El FNV1a doble-hashing garantiza una distribución uniforme de posiciones en la matriz de bits, minimizando las colisiones y manteniendo la tasa de falsos positivos cerca del 1%.

    13.4 Carga y formato binario

    El filtro de floración se almacena en data/rockyou.bloom — un archivo binario con:

  • Header (20 bytes): número mágico (0x424c4f4f = "BLOO"), versión, m (tamaño de array de bits), k (número de funciones de hash), n (número de elementos)
  • Carga : bit array (m/8 bytes)
  • La carga es activada manualmente por el usuario (botón en la interfaz de usuario), no automáticamente en la carga de la página, para preservar el rendimiento inicial.


    14. Comparación con los ataques derivados

    El ataque del diccionario "puro" es el primero de una familia de ataques que todos comparten una raíz común: una lista de palabras lexical. Time2Crack implementa 7 modelos de grieta offline (fuerza de grieta, diccionario, híbrido, máscara, PCFG, Markov, combinador), cada uno atacando la contraseña desde un ángulo diferente.

    14.1 Diccionario vs híbrido

    CriteriosDiccionarioHybrid (dict+rules) ---------------------------- CandidatosDiccionario Palabras comoPalabras + ~1000 mutaciones por palabra Keyspace200.000 candidatos~200 millones de candidatos Ejemplos desgarrados"password", "sun""¡P@ssw0rd!", "s0l3il2024" Velocidad relativa1000× más rápidoGran cobertura Aplicable sipalabra exacta en la listaContraseña derivada de una palabra dict

    El ataque híbrido comienza donde el diccionario puro se detiene: toma cada palabra de la lista de palabras y aplica reglas de mutación sistemática (hashcat "best64.rule" en mente).

    14.2 Diccionario vs PCFG

    CriteriosDiccionarioPCFG --------------------------- ModeloLista fija de candidatosGramática de estructura probabilística FuerzaPalabras precisasEstructuras Word+Digits, Cap+lower+sym Ejemplo"password" → ✓"Password123" → ✓ (estructura detectada) Coberturavocabulario conocidoEstructuras humanas genéticas

    Una contraseña como "Password123" puede pasar desapercibida en un diccionario (la palabra exacta "Password123" no puede ser listada) pero se romperá muy rápidamente por PCFG que reconoce la estructura [Majuscule][minuscules][digits].

    14.3 Diccionario vs Markov

    CriteriosDiccionarioMarkov --------------------------- CandidatosLista precompiladaFly-generated by statistical model Coberturavocabulario conocidoCualquier secuencia "humana" probable VentajasMuy rápido en palabras exactasCubre palabras de vocabulario desconocidas Ejemplo"sunshine" → ✓"sunsh1ne" potencialmente ✓

    Markov cubre casos donde la contraseña parece una palabra humana sin estar en ninguna lista.

    14.4 Dictionary vs Credential Stuffing

    CriteriosDiccionarioCrédential Stuffing --------------------------- ObjetivoCracking a hashPruebe un login específico MecanismoComputación local de HashPruebas de conexión remota FuenteGenérico WordlistPareja de inicio de sesión / filtraciones de contraseña Defensaalgoritmo de hash fuerteLimitación de tarifas, MFA, bloqueo IP

    El relleno de credencial no ataca un hash – intenta directamente conectarse/password pares en servicios remotos. Es conceptualmente diferente de la grieta, pero comparte la misma fuente de datos (HIBP/fail).


    15. Limitaciones del diccionario de ataque

    15.1 Límites intrínsecos

    1. El vocabulario conocido sólo Una contraseña inventada que no se asemeja a ninguna palabra existente y no está en HiBP es impermeable al ataque de diccionario puro. "Xqz7mK9pL" nunca estará en ninguna lista de palabras. 2. Cobertura lingüística Un atacante dirigido a un usuario de habla francesa sin una lista de palabras francesa perderá palabras como "ephemeral", "grenouille", o "bricolage" que no están en las listas de palabras inglesas estándar. 3. Nuevas contraseñas Una credencial que acaba de crearse y nunca ha huido no estará en HiBP, aunque sea muy común, tendrá que esperar hasta la próxima fuga para encontrarla. 4. contraseñas muy largas Una contraseña que consiste en una frase inventada largamente ("MaGrandeAventure2024SousLesEtoiles") no estará en ninguna lista de palabras, incluso si cada palabra tomada por separado es trivial. Esta es la idea detrás de las contraseñas, tratada por otros ataques (Combinador, PRINCE).

    15.2 ¿Qué cálculo de Time2Crack no modela

    Context Wordlists : un atacante dirigido a un sector específico construirá listas de palabras adaptadas (condiciones médicas para hospitales, videojuegos slang para plataformas de juego). Listas de palabras de fuerza bruta combinadas : Herramientas como CeWL (Custom Word List Generator) pueden extraer términos del sitio web objetivo para construir una lista de palabras personalizada. Este nivel de selección no se modela. Residuos recientes aún no en HIBP entre el momento en que se produce una fuga y su integración en HIBP, las credenciales comprometidas circulan en foros privados sin ser accesibles a través de la API pública. algoritmos de Hash no cubiertos Time2Crack modelos 6 algoritmos (MD5, SHA-1, SHA-256, NTLM, bcrypt, Argon2id). Los algoritmos como SHA-512, scrypt o PBKDF2 tienen diferentes perfiles.

    16. Defensas eficaces

    16.1 Lo que protege contra el ataque del diccionario

    algoritmo moderno de hash (bcrypt, Argon2id) Esta es la defensa más efectiva en el lado servidor.
  • MD5: crack in ~1 microsecond
  • bcrypt cost 12 : crack in 35 horas
  • Argon2id (parámetros recomendados): crack in años
  • La diferencia de 10+ órdenes de magnitud entre MD5 y Argon2id hace que la contraseña del diccionario "sun" inmune en la práctica si está protegida por Argon2id, incluso si el atacante sabe que es una palabra francesa.

    Sal única por cuenta Una sal evita los ataques de mesa precalculados y obliga al atacante a recalcular individualmente para cada cuenta. No protege los ataques selectivos de las listas de palabras (el atacante todavía puede probar las 200.000 palabras con la sal), pero invalida las tablas de arco iris y hace que los ataques masivos en grandes bases de datos sean impracticables. Duración de la contraseña Una contraseña de una sola palabra de diccionario (8-10 caracteres) es vulnerable. Un passphrase de 4-5 palabras ("cheval-lumière-forest-voyage") es resistente al ataque del diccionario puro pero no al ataque del Combinador, por lo tanto la importancia de la longitud Y la aleatoriedad. contraseñas generadas aleatoriamente La solución real: use un gestor de contraseñas que genere contraseñas aleatorias largas (20+ caracteres de todo tipo). Estas contraseñas nunca estarán en ningún diccionario. autenticación multifactorial (MFA) El MFA no evita el crack fuera de línea (el atacante recupera los hashs y cracks fuera de línea), pero protege contra el relleno credencial (usar credenciales cracked para conectar). Tasa de limitación y detección de anomalías Protege contra ataques en línea (intentes de conexión directa), no contra el cracking fuera de línea de hashs robados.

    16.2 Lo que no protege

    Sustituciones de hoja simple : "password" → "p@ssw0rd" — ver la sección 9. Números añadidos al final : "password" → "password1" — entre las primeras reglas probadas. Pago inicial : "password" → "Password" — regla de capitalización estándar. Figuras y símbolos si la palabra permanece reconocible "sunshine!" está en cualquier lista de palabras que incluye "sunshine" con reglas básicas. Complejidad impuesta sin longitud "P@s1w" cumple con los criterios de complejidad (maj, min, número, símbolo) pero es más corto y más predecible que "horsebaterystaple".

    16.3 Recomendaciones prácticas

  • Utilice un administrador de contraseñas (Bitwarden, 1Password, KeePass) — genera contraseñas aleatorias, sólo tiene que recordar la contraseña principal.
  • Habilitar MFA en todas partes — incluso si la contraseña está comprometida, el atacante no puede conectarse.
  • Compruebe HIBP regularmente - si su correo electrónico está en fugas conocidas.
  • Nunca reutilizar una contraseña — el relleno credencial explota los servicios cruzados reutiliza.
  • Para contraseñas mensurables : 5+ palabras passphrases al azar (no "horse-correct-battery-agrafe-violet", sino palabras realmente dibujadas por sorteo).

  • 17. Referencias

    Fuentes primarias (estudios académicos)

    Morris, R., " Thompson, K. (1979). Seguridad de contraseña: historial de casos. Comunicaciones de la ACM, 22(11), 594-597.
  • Primer análisis académico de la distribución de contraseñas Unix
  • Reconoce que ~1/3 contraseñas son palabras comunes en inglés
  • Klein, D.V. (1990).
    Foiling the cracker: Una encuesta de seguridad de contraseñas y mejoras. Procesos de Simposio de Seguridad UNIX, 5-14.
  • 15,000 Unix contraseña crack: 25% crackeado en unas pocas horas
  • Document first wordlists and mutation rules
  • Weir, M., Aggarwal, S., de Medeiros, B., " Glodek, B. (2009).
    grieta de contraseña usando gramáticas libres de contexto probabilístico. Simposio IEEE sobre Seguridad y Privacidad.
  • Referencia básica sobre ataque PCFG y comparación con ataque de diccionario puro
  • Determina que las palabras del diccionario se encuentran en los primeros 200.000 intentos de un ataque ordenado
  • Citado en Time2Crack para la calibración HF del ataque del diccionario (multiplier 0.5)
  • Ur, B., Kelley, P. G., Komanduri, S., Lee, J., Maase, M., Shay, R., Vaniea, K., Bauer, L., " Cranor, L. F. (2012).
    ¿Cómo se mide su contraseña? El efecto de los medidores de fuerza en la opción contraseña-usuario. 21o Simposio de Seguridad USENIX.
  • Análisis de la distribución de palabras comunes en cuerpo real
  • Palabras comunes encontradas en los primeros 100-10 000 intentos
  • Citado en Time2Crack para la calibración HF common ? 0.15 (nivel superior a 10k)
  • Bonneau, J (2012).
    La ciencia del canto: Analizar un corpus anónimo de 70 millones de contraseñas. Simposio IEEE sobre Seguridad y Privacidad.
  • Estudio de 70 millones de contraseñas anónimos de Yahoo
  • Cuantifica la distribución efectiva de contraseñas, confirma la ley de poder
  • Medición de la eficacia del relleno credencial (2–5% de velocidad en cuentas reales)
  • Ma, J., Yang, W., Luo, M., " Li, N. (2014).
    Estudio de modelos probabilísticos de contraseña. Simposio IEEE sobre Seguridad y Privacidad.
  • Comparación de modelos probabilísticos (diccionario, Markov, PCFG) sobre corpus real
  • Best64.rule priord → ~40% reducción en tiempo promedio para palabras de diccionario
  • Citado en Time2Crack para la calibración de HF de ataque híbrido
  • Wheeler, D.L. (2016).
    zxcvbn: estimación de la fuerza de contraseña de bajo presupuesto. 25o Simposio de Seguridad, 157-173.
  • Sistema de estimación de la fuerza utilizando listas y patrones
  • Análisis de sesgos cognitivos en la creación de contraseña
  • Medir la eficacia de las listas de palabras en relación con la fuerza bruta
  • Pasquini, D., Cianfriglia, M., Ateniese, G., " Bernaschi, M. (2021).
    Reducción del sesgo en modelar la fuerza de la contraseña del mundo real a través del aprendizaje profundo y los diccionarios dinámicos. 30o Simposio de Seguridad USENIX.
  • Assessment of estimation models for actual attacks
  • Confirma que los diccionarios siguen siendo la herramienta más eficaz para contraseñas humanas comunes
  • Fuentes industriales

    ¿He sido Pwned. (2024).
    contraseñas desgarradas. https://haveibeenpwned.com/Passwords
  • Basis de ~14 mil millones de contraseñas únicas de filtraciones documentadas
  • k-Anónimo API utilizado por Time2Crack para la verificación en tiempo real
  • Hive Systems. (2025).
    2025 Hive Systems Password Table.
  • Parámetros 12× RTX 4090: MD5 2,027 GH/s, NTLM 3,462 GH/s, bcrypt cost 5 : 2,2 MH/s
  • Fuente principal de las tasas de hash utilizadas en Time2Crack
  • Hashcat. (2025).
    Hashcat — Recuperación avanzada de contraseña.
  • Herramienta de referencia para parámetros GPU
  • Documentación de reglas de mutación (best64.rule, OneRuleToRuleThemAll)
  • Gosney, J (2012).
    Criaturas de Lee et al. y contraseña probabilística. Procedimientos de contraseña.
  • Primeros parámetros de referencia multi-GPU documentados públicamente
  • Referencia para la calibración de los ataques basados en normas
  • Miessler, D. (2024).
    SecLists — Una colección de múltiples tipos de listas utilizadas durante las evaluaciones de seguridad. GitHub.
  • Fuente de los Wordlists de Wikipedia utilizados en Time2Crack
  • Listas de palabras en inglés, francés, español, portugués, alemán, turco
  • Fuentes secundarias (contexto)

    Troy Hunt. (2013).
    Introducción 306 Millones de contraseñas desplegadas gratuitamente. troyhunt.com.
  • Establecimiento inicial del servicio HIBP y explicación del protocolo k-anonymity
  • Thomas, K., et al. (2019).
    Proteger cuentas de relleno credencial con alerta de rotura de contraseñas. 28o Simposio de Seguridad USENIX.
  • Estudio Google/Stanford sobre la protección de credenciales comprometidas
  • Confirma la eficacia del anonimato k como mecanismo de privacidad
  • Wang, D., Cheng, H., Wang, P., Huang, X., " Jian, G. (2016).
    La ley de Zipf en contraseñas. Transacciones de IEEE sobre Forenses de Información y Seguridad, 12(11), 2776–2791.
  • formalización matemática de la ley de poder en la distribución de contraseñas
  • Confirma que la distribución de Zipf tiene en todo el cuerpo grande conocido
  • Fuentes web citadas en la aplicación Time2Crack

    IEEE Xplore (referencia diccionario). https://ieeexplore.ieee.org/document/6234435
  • Fuentes relacionadas en descDict (app.js) para el orden de cobertura de los diccionarios superiores.
  • HIBP API range (k- anonymity). https://api.pwnedpasswords.com/range/
  • Endpoint efectivamente utilizado por Time2Crack para la verificación del anonimato k (sha1 solicitud de prefijo).
  • El patrón de llamadas HIBP en código. https://api.pwnedpasswords.com/range/${prefix}
  • La forma exacta de la URL llamada en los ejemplos de código de documento (prefijo SHA-1 interpolado).

  • Documento generado para el Proyecto Time2Crack — Versión 1.0 — 2026-04-01 Código fuente: app.js (funciones addDictionaryAttacks, isDictWord, deLeet, loadDictionary, applyHighFidelityCalibration, bloomHas)*