Ataque de dicionário — Operação abrangente

Documento de referência do projeto Time2Crack
Destinatários: desenvolvedores, pesquisadores de segurança, usuários avançados

Índice

  • Visão geral
  • Formação histórica e académica
  • Fundamentos conceituais: por que os dicionários trabalham
  • Arquitetura de um moderno ataque dicionário
  • O corpus de senhas reais
  • K-Anonymity HIBP verificação: um ataque em tempo real
  • Listas de Palavras de Idioma Time2Crack
  • Detecção do Dicionário no Tempo2Crack: isDictWord()
  • Desleetificação: como o atacante descodifica substituições
  • Cálculo do tempo de fissuração: addDictionaryAttacks()
  • Calibração de alta fidelidade: applyHighFidelityCalibration()
  • Probabilidade de aplicabilidade e escore de confiança
  • Bloom filter RockYou : detecção local de senhas generalizadas
  • Comparação com ataques derivados
  • Limitações do dicionário de ataque
  • Defesas eficazes
  • Referências

  • Resumo

    O ataque do dicionário é o mais antigo método de quebra de senha, o mais simples conceitualmente, e estatisticamente mais eficaz na maioria das senhas humanas reais. Seu princípio é testar, em ordem decrescente de probabilidade, uma lista pré-compilada de candidatos — o "dicionário" — em vez de enumerar exaustivamente todas as combinações possíveis como a força bruta faz.

    Porque é terrivelmente eficaz Os humanos não escolhem suas senhas aleatoriamente. Décadas de vazamentos de dados revelam que a distribuição real de senhas está extremamente concentrada: as 1.000 senhas mais comuns representam cerca de 5 a 10% de todas as contas online. Os 1 milhão mais comuns cobrem 40 a 60%. Um ataque de dicionário bem construído irá testar esses candidatos em milissegundos a segundos — onde a força bruta levaria milhões de anos.

    No Time2Crack, o dicionário ataca dois mecanismos distintos, mas complementares:

  • Verificação HIBP (Teve sido pwned): Confronto da senha com as credenciais exclusivas de ~14 bilhões de vazamentos de dados históricos. Se a senha estiver lá, um atacante a descobrirá em uma fração de segundo.
  • Detecção da Lista de Palavras da Língua Uma palavra de linguagem comum — "sol" ou "sol" — é vulnerável mesmo que não esteja no HIBP.
  • Essas duas deteções são independentes e complementares: HiBP cobre as credenciais exatas de compromisso, a lista de palavras abrange as palavras comuns ainda não vazadas.


    2. Antecedentes históricos e acadêmicos

    2.1 Origens

    O ataque do dicionário precede a era moderna da segurança do computador. Os primeiros sistemas Unix guardaram senhas em linguagem simples em /etc/passwd, tornando qualquer ataque dicionário trivial assim que o arquivo foi acessível.

    Cronologia dos marcos : AnoEvento ---------------------- 1979Morris & Thompson: Primeiro artigo acadêmico sobre segurança de senhas do Unix. Veja se 1/3 das senhas escolhem palavras em inglês comuns 1988Morris Worm: propaga-se parcialmente através de um dicionário de 432 palavras + host /usr/share/dict/words 1993Crack 5.0 (Alec Muffett): Primeira ferramenta pública de ataque de dicionário no Unix, inclui regras de mutação 2000John the Ripper: populariza wordlists combinadas com regras de hashcat (wordlist + modo regras) 2009RockYou vazamento: 14,3 milhões de senhas claras revelam a distribuição real das escolhas humanas 2012Eu fui Pwned (Troy Hunt): primeiro serviço de auditoria pública para credenciais comprometidas 2013Adobe quebra: 153 milhões de contas — senhas de topo tornam-se identificáveis por análise de frequência mesmo em haxixes não saldados 2016Hashcat open source v3.0: otimização maciça de ataques de lista de palavras em GPU (MD5: 2 TH/s em 8 GPU cluster) 2019Coleção #1–5: 2,7 bilhões de pares de login/senha compilados, distribuídos publicamente 2024HIBP v8: ~14 bilhões de senhas únicas indexadas

    2.2 Fuga de fundação

    Alguns vazamentos transformaram a paisagem do ataque pelo dicionário revelando a distribuição real das senhas humanas:

    RockYou (2009) Um desenvolvedor tinha armazenado 14,3 milhões de senhas em linguagem simples.
  • As primeiras 10 senhas cobriram ~5% das contas
  • Primeiro 1.000: ~20% das contas
  • A distribuição segue uma lei de poder — confirmando que os humanos "pensam o mesmo"
  • LinkedIn (2012) — 6,5 milhões de SHA-1 não salgados. Adobe (2013) — 153 milhões de contas. Fui enganado (2013–presente) - Agregação progressiva de fugas públicas, permitindo que Troy Hunt crie uma base de referência usada em todo o mundo.

    2.3 Benchmarks de referência para o ataque do dicionário

    Uma lista de 200.000 entradas testadas à velocidade de um RTX 4090:

    AlgoritmoVelocidadeTempo para 200k candidatos ---------------------------------------- MD5168,9 GH/s~1,2 nanosegundo SHA-150,86 GH/s~3,9 nanossegundos SHA-25622.68 GH/s~8,8 nanossegundos NTLM288,5 GH/s~ 0,7 nanosegundo bcrypt (custo 5)184 kH/s~ 1,09 segundo Argon2id~67 H/s~50 minutos

    O ataque do dicionário é, portanto, quase instantâneo para MD5, SHA-1 e NTLM — e permanece muito rápido mesmo para bcrypt em pequenas listas.


    3. Fundamentos conceituais: por que os dicionários trabalham

    3.1 A Lei do Poder das Senhas Humanas

    Todos os estudos empíricos convergem para a mesma observação: a distribuição de senhas humanas não é uniforme — segue-se a lei do poder Algumas senhas concentram uma fração desproporcionada de escolhas.

    Formalmente : se todas as senhas são classificadas por frequência decrescente, a frequência da senha de classificação r é proporcional a r^(-α) com α 1,5 a 2 De acordo com o corpus.

    Consequência directa: 10 senhas mais comuns Um atacante que testa apenas 10 candidatos já tem uma chance em 20 de ter sucesso — estatisticamente, é enorme para a quantidade de ruído gerado.

    3.2 Bias Cognitivas na Criação de Senhas

    Os humanos não escolhem ao acaso. Eles sistematicamente aplicam heurísticas que tornam suas senhas previsíveis:

  • Bias de memória : as palavras fáceis de lembrar (nomes comuns, nomes próprios, termos da cultura popular) são sobre-representadas
  • Bias de Disponibilidade A senha reflete o ambiente imediato (nome do animal doméstico, equipe esportiva, caráter serial)
  • Vieses de substituição previsíveis : "e" → "3", "a" → "@", "o" → "0" — o usuário acredita que a senha seja forte, mas essas substituições são exatamente as primeiras que o atacante tenta fazer
  • Bia completa : adição de um número ou símbolo no final de uma palavra (senha 1, sol!)
  • Vieses culturais As senhas comuns estão ligadas ao idioma e cultura do usuário ("Soleil123" na França, "Sommer123" na Alemanha)
  • 3.3 O conceito de "senha já nas listas"

    Uma senha pode estar em uma lista de ataque por duas razões diferentes:

    Razão 1 — Ele está no HIBP A credencial exata foi comprometida em um vazamento passado. O atacante não precisa adivinhar — testa as credenciais conhecidas uma a uma, por ordem de frequência. Se o servidor alvo aceitar a credencial, ela estará terminada. Razão 2 — Está numa lista linguística A senha é uma palavra comum do vocabulário comum. Mesmo que nunca tenha fugido, está em todas as listas de palavras de ataque porque é um candidato óbvio. "Paillon" pode não estar no HiBP, mas está na lista de palavras francesa de qualquer ferramenta de craqueamento grave.

    Estes dois casos correspondem a ataques de natureza diferente, com velocidades diferentes — e isto é precisamente o que modelos Time2Crack.


    4. Arquitetura de um moderno ataque dicionário

    4.1 Oleoduto geral

    Um moderno ataque dicionário ocorre em várias 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: Pré-processamento da Lista de Palavras - Ordenar por frequência (o mais provável primeiro) - Deduplicação (não duas vezes o mesmo candidato) - Filtragem de comprimento (comprimento alvo + ±2) - Normalização (inferior, Unicode NFC)

    Fase 3: Cálculo dos hashs candidatos Para cada candidato w na lista de palavras: • hashcandidato = hashAlgo(w) Promocional se hashcandidato == hashAlvo: Encontrado - Velocidade: 168 GH/s para MD5 em RTX 4090

    Fase 4: Análise dos resultados Relatório de senhas rachadas, estatísticas de cobertura

    4.2 Otimização de hardware

    Os ataques de dicionário modernos são massivamente paralelos na GPU:

  • Hashcat (ferramenta de referência): explora os núcleos CUDA da GPU para paralelizar bilhões de computação simultânea de hash
  • Pipeline Vector : em um RTX 4090, uma única instrução SIMD calcula 8 a 16 hashs MD5 em paralelo
  • Cache de GPU : a lista de palavras é carregada em VRAM para minimizar a latência da memória
  • Batting : os candidatos são enviados para a GPU em lotes de milhões para maximizar o fluxo
  • Para uma lista de palavras de 14 bilhões de entradas (tamanho HIBP) em 12× RTX 4090:

  • MD5 : 14e9 / (168,9e9 × 12) 6.9 segundos
  • custo de bcrypt 5 : 14e9 / (184000 × 12) 6.337 anos
  • Esta diferença de ~9 ordens de magnitude entre MD5 e bcrypt explica porque a escolha do algoritmo de hash é crítica.

    4.3 Ordem de ensaio dos candidatos

    A lista de palavras não é testada em ordem alfabética — é ordenado por probabilidade decrescente :

  • As senhas de escape mais comuns (RockYou top 100)
  • Senhas comuns multi-fault (lista de prioridades HIBP)
  • Palavras comuns da língua alvo
  • Nomes próprios (primeiros nomes, cidades, celebridades)
  • Termos temáticos relacionados com o objectivo
  • Variações e conjugação
  • Este tipo garante que se a senha for "baixa", ela será encontrada nos primeiros milissegundos — seja qual for a velocidade do hash.


    5. O corpus de senhas reais

    5. 1 Fui enganado (HIBP)

    Tamanho ~14 bilhões de senhas únicas (2024) Origem : agregação de vazamentos públicos desde 2013 Formato : SHA-1 ordenado por frequência de aparência Acesso público : k- anonimato API, hash download completo disponível para defensores

    HiBP é a referência global porque:

  • Abrange quase todas as principais fugas públicas
  • Os hashs são ordenados por frequência — as senhas mais comuns são testadas primeiro
  • É mantido ativamente (novos vazamentos adicionados continuamente)
  • Um atacante com a descarga completa HIBP pode primeiro testar os ~14 bilhões de candidatos em ordem decrescente de frequência. Para algoritmos não saldados (MD5, SHA-1), esta lista cobre a ordem de 50-70% de todas as senhas online reais.

    5.2 RockYou (2009) — Corpo fundador

    Tamanho : 14,3 milhões de senhas claras Características-chave : PosiçãoSenhaOcorrências% de corpus ---------------------------------------------------- 1123456290 7312,03% 21234579 0780,55% 312345678976 7900,54% 4senha59 4620,42% 5Adoro-te.49 9520,35% Top 10—~650.000~4,5% Top 100—~1 200 000~ 8,4% Top 1000—~2 500 000~17,5% Top 10.000—~4 500 000~31,5% Educação Teste apenas 10.000 candidatos (100 μs velocidade MD5) compromete ~31% de uma base de dados de contas protegidas MD5.

    5.3 Colecções de listas de palavras especializadas

    SecListas (Daniel Miessler): coleção de código aberto de ~ 4 GB wordlists cobrindo:
  • Senhas (RockYou, senhas de topo várias fugas)
  • Utilização actual
  • Senhas ordenadas por idioma
  • Termos técnicos, nomes de produtos, celebridades
  • Kaonashi : 1.3 bilhões de entradas wordlist compilado desde vazamentos públicos Crackstation : 1.5 bilhões de entradas, incluindo palavras de todos os dicionários da Wikipédia em vários idiomas Fracopass : agregação de ~8 bilhões de entradas de senha reais

    Esses corpus podem ser baixados publicamente — sua existência é um fato estabelecido de segurança ofensiva.


    6. K-Anonymity verificação HIBP: Um ataque em tempo real

    6.1 Protocolo k- anonimato

    Time2Crack incorpora uma verificação HIBP em tempo real que reproduz exatamente o que um atacante faria com o banco de dados HIBP — mas nunca transmite a senha em linguagem simples ou seu hash completo.

    O protocolo k-anonymity funciona da seguinte forma:

    1. Calculer SHA-1(password)      → par exemple "CBFDAC6008F9CAB4083784CBD1874F76618D2A97"
    
  • Envie apenas os primeiros 5 caracteres para a API HIBP: "CBFDA"
  • A API retorna TODOS os sufixos SHA-1 começando com "CBFDA" (aproximadamente 400-600 hashes)
  • Procure localmente se o resto do hash ("C6008F9CAB4083784CBD1874F7618D2A97") está na lista
  • Se encontrado: senha foi comprometida (HIBP também retorna o número de vazamentos)
  • Garantia da confidencialidade O servidor HIBP nunca vê o hash completo (por isso não consegue identificar a senha), muito menos a senha clara. O cálculo final é feito localmente. O que isto significa para o ataque : se o HIBP retorna uma correspondência com uma contagem elevada (por exemplo, 9.547.236 aparições para "123456"), isso significa que um atacante com o banco de dados do HIBP testando esta credencial iria encontrá-lo em uma posição muito alta em sua lista ordenada por frequência - em uma fração de nanossegundos.

    6.2 Implementação no Time2Crack (app.js)

    A verificação HIBP é assíncrona e não bloqueada. A senha é imediatamente analisada por métodos locais, e a verificação HIBP completa o 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
    

    resposta const = aguarde buscar( https://api.pwnedpasswords.com/range/${prefix} ); linhas const = aguarde response.text();

    para (linha contínua de linhas. split('\n')) { const [hashSufixo, contagem] = line.split(':'); se (hashSuffix.toLowerCase() = suffix.toLowerCase() { retornar parseInt( contagem); // número de vazamentos } } retorno 0; // não encontrado }

    Dados de desempenho HIBP :
  • Latência típica da API: 50–200 ms (rede)
  • Volume de sufixos retornados: ~400–600 por consulta
  • Falso positivo: 0 (SHA-1 é determinístico)
  • Falso negativo: 0 (se no HiBP, sempre devolvido)
  • 6.3 Interpretação da contagem HIBP

    A contagem retornada pelo HiBP indica o número de vezes que esta senha exata apareceu em vazamentos indexados:

    ContagemInterpretaçãoTempo de fissuração (MD5, 12× RTX 4090) ----------------------------------------------------------------------------- > 1 000 000Top 100 Mundo< 1 nanosegundo 10.000–1.000.000Muito frequentes< 10 nanossegundos 1 000–10 000Frequentes< 100 nanossegundos 100–1.000Pouco frequentes, mas conhecidos< 1 microssegundo 1–100Raros mas comprometidos< 10 microssegundos

    Mesmo uma contagem de 1 (a senha apareceu apenas uma vez em um vazamento) indica uma vulnerabilidade: se um atacante ataca esta conta especificamente e tem a lista de credenciais do vazamento em questão, ele vai encontrá-lo.


    7. Time2Crack Language Wordlists

    7.1 Por que as listas de palavras linguísticas para além do HIBP

    O HiBP cobre as credenciais exatas de compromisso — mas não as palavras comuns nunca fogem ainda. Um usuário francófono que escolhe "efémero" como uma senha pode não estar no HiBP (a palavra é improvável em credenciais anglophone), mas está na lista de palavras francesa de qualquer atacante que se desloque em um sistema francófono.

    Os wordlists da linguagem Time2Crack cobrem esta lacuna:

    LínguaOrigemTamanho estimado ---------------------------------- InglêsSecListas Wikipedia PT~200,000 entradas Francês (fr)SecListas Wikipedia PT~150,000 entradas EspanholSecListas Wikipedia ES~150,000 entradas Português (pt)SecListas Wikipedia PT~ 120 000 entradas AlemãoSeclistas Wikipedia DE~ 180.000 entradas Turco (tr)SecListas Wikipédia TR~100,000 entradas Italiano (i)kkrypt0nn~100,000 entradas Polaco (pl)kkrypt0nn~80 000 entradas Países Baixos (nl)kkrypt0nn~80 000 entradas Filtragem aplicada Apenas palavras com ≥ 4 caracteres são retidas (os 1-3 caracteres são muito curtos para ser uma senha realista, e sua inclusão iria inflar a lista sem valor acrescentado).

    7.2 Carregamento preguiçoso

    Listas de palavras não estão incluídas no código – são carregadas a pedido ao mudar de idioma, para atender ao orçamento da rede:

    // app.js - loadDictionary()
    async function loadDictionary(lang) {
      if (DICTlang & DICTWORDS) return;  // Déjà chargé
      if (DICTLUGAR) {
    DICTPENDINGLANG = lang; // Arquivo de espera
    Retorno;
    }
    DICTLOADING = true;
    

    const res = aguarde a busca(data/wordlists/${lang}.txt); const text = aguarde res.text();

    // Converter para Set<string> para pesquisa O(1) DICTMENÇÃO = novo conjunto ( text.split("\n") .map( w => w.normalize("NFC").trim().toLowerCase() .filtro(w => w.comprimento >= 4) ); DICTLANG = Lang; DICTCARGAMENTO = falso; }

    Porquê? Set ? Estrutura Set JavaScript garante O(1) buscas — independentemente do tamanho do dicionário (50.000 ou 200.000 entradas), verificação DICTWORDS.has(word) leva o mesmo tempo constante. Array Seria necessário O(n) por exame, ou seja, até 200.000 comparações por verificação.

    Carregando fila

    A DICTPEDIDOSLANG evita as condições raciais durante as rápidas alterações linguísticas:

    Scénario : l'utilisateur switche rapidement EN → FR → DE
    ├── EN demandé : DICTCARGA = false → start of the fetch PT
    FR solicitado durante a recolha PT : DICTLOADING = true → DICTPEDIDOSLANG = "fr"
    ├── DE demandé pendant fetch EN : DICTCARGO = true → DICTPENDINGLANG = "de" (crash "fr")
    - Buscar Terminas: DICTLANG = "en", puis lance loadDictionary("de")
    └── Résultat : seule la dernière langue demandée est chargée

    Este comportamento é intencional: o idioma mais recentemente solicitado é carregado, não todas as línguas intermediárias.


    8. Dictionary Detection in Time2Crack: isDictWord()

    8.1. Operação de detecção

    A função isDictWord(pw) determina se uma senha é ou é derivada de uma palavra do dicionário atual:

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

    // Normalização: NFC + Minúsculas const l = pw. normalize ("NFC").toLowerCase();

    // Verificação direta se (DICT)

    WORDS.has(l) || DICTWORDS.has(deLeet(pw)) retorna true;

    // Variações morfológicas const deleetWord = deLeet( pw); variações const = getMorphVariations(deletWord);

    (variação constante das variações) { se (DICT)

    WORDS.has(variation)) return true; }

    Retorno falso; }

    Linha de detecção de 3 camadas :
  • Correspondente directa : A senha padrão está no dicionário?
  • "sol" → hit directo
  • "SOLEIL" → padrão em "sol" → hit
  • Correspondência pós-saída : A senha contém padrão deixar substituições?
  • "s0l3il" → deLeet → "sol" → hit
  • "p@ssw0rd" → deLeet → "senha" → hit
  • Variações morfológicas : é a senha uma variante morfológica conhecida?
  • "sol" → variação plural de "sol" → hit
  • "senhas" → variação de "senha" → bater
  • 8.2 Normalização Unicode (NFC)

    Normalização normalize("NFC") assegura que os caracteres acentuados sejam tratados de forma consistente:

  • "e" pode ser representado no Unicode como um código de ponto único (U+00E9) ou como "e" + acento de combinação (U+0065 + U+0301)
  • Sem padronização, "café" e "café" (codificações diferentes) não corresponderiam
  • Essa padronização é aplicada tanto na criação do dicionário quanto na verificação – garantindo correspondência correta para linguagens de sotaque (FR, ES, DE, PT, etc.).

    8.3 Impacto na vulnerabilidade detectada

    Quando isDictWord() Para trás. trueSão aplicáveis vários ataques:

  • Ataque do dicionário auto: pontuação de confiança 0,85 (vs 0 se ausente)
  • Ataque híbrido : hybridVuln = true → 1000 mutações testadas com base em dicionário
  • Ataque PCFG : aumento da pontuação de confiança (base lexical detectada)
  • Ataque morfológico : alta prioridade se variante morfológica detectada

  • 9. Desleetificação: como o atacante decodifica substituições

    9.1 Leetspeak e suas limitações como proteção

    O leetspeak é uma prática de substituir letras por números ou símbolos visualmente semelhantes: a→@, e→3, i→1 ou !, o→0, s→$. Usuários usam-no para "fortalecer" palavras comuns.

    Exemplo : "senha" → "p@$$w0rd"

    A realidade: estas substituições são as primeiras regras aplicadas em qualquer ataque de dicionário com regras de mutação. Eles não constituem uma defesa real contra um atacante competente.

    9.2 Execução deLeet() no tempo2Crack

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

    função deLeetWith( pw, oneMap) { deixe 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; }

    função deLeet(pw) { // Ambiguidade: "1" pode ser "i" ou "l" const withI = deLeetWith(pw, { i: "1!", l: "" }); const withL = deLeetWith(pw, { l: "1, i: "!" });

    // Se o dicionário for carregado, prefira a variante que corresponde se (DICT)MENÇÃO se (DICT)WORDS. tem (com L) retorno com L; se (DICT)WORDS. tem(comI) retorno comI; }

    // Caso contrário: prefira a variante com os números menos restantes const digestsI = (comI.match(/\d/g) const digestsL = (comL.match(/\d/g) dígito de retorno L <= dígito I ? comL: comI; }

    9.3 Gestão da ambiguidade "1" → "i" ou "l"

    A substituição "1" é ambígua: "1" pode representar "i" (como em "1nfo" → "info") ou "l" (como em "p1ayer" → "player").

  • Testando ambas as variantes ("comI" e "comL")
  • Se o dicionário for carregado, preferindo a variante que dá uma correspondência de dicionário
  • Sem um dicionário, preferindo a variante que deixa o menor número residual (assunção: a desleetificação completa é mais provável)
  • Exemplo :
  • "b1ue" → comI = "biue" (não em dict), comL = "blue" (em dict) → retorna "blue"
  • "f1le" → comI = "file" (em dict), comL = "flle" (não em dict) → retorna "file"
  • 9.4 Substituições não abrangidas (intencionalmente)

    Time2Crack não cobre substituições raras ou ambíguas para além dos padrões LEETBASE. É uma escolha de design: cobrir muitos casos aumentaria os falsos positivos (detectando uma senha como uma "palavra atual" enquanto não é). Os padrões incluídos cobrem > 95% das leetificações reais observadas no corpus.


    10. Cálculo do tempo de fissuração: addDictionaryAttacks()

    Lógica de cálculo

    // 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
    

    const note = ? t("nWeakPassword") : comum ? t("nInLeaks") : dictWord ? t(nDictHit) : t(nAbsentLeaks);

    rows.push({ atk: t("aDict"), hash: a.name, baço: a.rate, sec, nota, cat: "dict" }); } }

    10.2 Três níveis de vulnerabilidade

    Nível 1 — Ultrafraco (weak = true) : ~100 / baço A senha está no Top 100 do mundo ("senha", "123456", "qwerty"...). Um atacante testando estes 100 candidatos prioritários encontra-o na primeira passagem. Para MD5: 100 / 168.9e9 0,6 nanossegundo. Nível 2 — Comum (common = true) : ~10 000 / baço A senha está na lista de referência HIBP das senhas ~10.000 mais frequentes. Estes candidatos são testados nos primeiros microssegundos. Para MD5: 10.000 / 168,9e9 59 nanossegundos. Nível 3 — DictWord (dictWord = true) : ~200.000 / baço A senha é uma palavra do dicionário de idiomas atual (lista de palavras local ~50k–200k entradas). Uma verificação completa da lista de palavras é quase instantânea para algoritmos rápidos. Para MD5: 200 000 / 168,9e9 1.18 microsegundo. Nível 4 — Não aplicável (sec = null) : a senha não é nem ultra-fraca, nem comum, nem uma palavra do dicionário atual. O ataque do dicionário sozinho não é aplicável — outros ataques (força bruta, Markov, PCFG) tornar-se a principal ameaça.

    10.3 Por que estes números (100, 10.000, 200.000)?

    Estes valores são calibrados para dados reais:

  • 100 As primeiras senhas 100 RockYou representam ~10% do corpus. Todas as ferramentas sérias as testam como prioridade.
  • 10 000 : HiBP classifica seus ~14 bilhões de entradas por frequência. Os 10 mil tops cobrem cerca de 30–40% das senhas reais em uso. Qualquer atacante competente começa com este subconjunto.
  • 200 000 : tamanho típico de uma lista de palavras completa da linguagem após a filtragem. Isto é suficiente para cobrir o vocabulário atual de uma língua sem exceder a capacidade de carga razoável na memória.
  • Referência Weir et al. (2009) mostram que palavras de dicionário são encontradas nas primeiras 200.000 tentativas de ataque bem ordenado. Ur et al. (2012) confirmam que senhas comuns são encontradas nas primeiras 10.000 tentativas.

    10.4 Exemplo numérico completo

    Para a senha "sol" (palavra francesa atual, detectada como dictWord) :

    AlgoritmoVelocidade (12× RTX 4090)FórmulaTempo ------------------------------------------------------- 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 segundos SHA-256272 GH/s200 000 / 272e9735 picosegundos bcrypt (custo 5)2.2 MH/s200 000 / 2 200 00090,9 milissegundos Argon2id800 H/s200 000 / 800250 segundos

    Mesmo para Argon2id, 250 segundos são menos de 5 minutos — para uma simples palavra do dicionário francês.


    11. Calibração de alta fidelidade: applyHighFidelityCalibration()

    11.1 Por que a calibração adicional?

    O cálculo bruto addDictionaryAttacks() dá uma estimativa do "pior caso" — como se o atacante estivesse testando toda a lista de palavras uniformemente. ordenado por probabilidade : as senhas mais comuns chegam primeiro.

    Calibração de alta fidelidade aplica um multiplicador corretivo baseado em observações 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 = contexto.comum ? 0.15: contexto.dictWord ? 0.5: 1.0;
    Quebrar;
    Multiplicador common (0.15) : se a senha está na lista de prioridades comuns, ela é encontrada em média no percentil 15 da lista — ou seja, ~1.500 testes dos 10.000 listados. O tempo é multiplicado por 0,15 → 6,7× mais rápido do que o exame uniforme. Multiplicador dictWord (0,5) : uma palavra comum dicionário é encontrado em média meio-termo de uma lista bem ordenada. Multiplicador 0.5 → 2× mais rápido do que o exame uniforme.

    11.2 Fontes Acadêmicas de Calibração

  • Ur et al. (2012) — Como se mede sua senha? (USENIX Security): análise da distribuição de senhas no corpus real. Palavras comuns: encontradas nos primeiros 10.000 ensaios para 95% dos casos.
  • Weir et al. (2009) — Quebra de senhas usando Gramática Probabilística Livre de Contexto (IEEE S&P): Palavras de dicionário puras são encontradas nas primeiras 200.000 tentativas de um ataque ordenado.

  • 12. Probabilidade de aplicabilidade e escore de confiança

    12.1 Sistema de pontuação

    Time2Crack não apenas calcula um tempo — ele também avalia a probabilidade de que o ataque do dicionário seja realmente o ataque mais rápido, através de um sistema de pontuação multifator:

    // Score d'applicabilité (0-1)
    case "dict":
      return context.common ? 0.99 : context.dictWord ? 0.85 : 0;
  • 0, 99 se common A senha está no HIBP → o ataque do dicionário aplica-se com máxima confiança.
  • 0,85 se dictWord Apenas: alta probabilidade. Uma palavra do dicionário é vulnerável, mas um atacante deve ter a lista de palavras linguísticas correta.
  • 0 Caso contrário: o ataque do dicionário não se aplica (nenhuma vulnerabilidade lexical detectada).
  • 12.2 Escore de evidência

    Paralelamente ao escore de aplicabilidade, um escore de "prova" registra os sinais observados:

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

    Uma pontuação de evidência de 2 (palavra tanto no HIBP quanto no dicionário linguístico) aumenta a confiança final de 0,08 (2 × 0,04).

    12.3 Pontuação de Confiança Final

    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(aplicabilidade, base) + evidênciaBoost - específicaPenalidade ));

    Para uma senha common com dictWord também 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
  • Máxima confiança: O ataque do dicionário é o ataque primário sem ambiguidades.


    13. Bloom filter RockYou: detecção local de senhas generalizadas

    13.1 Contexto

    Para além da verificação HIBP (que requer uma chamada de rede), a Time2Crack incorpora uma filtro de flores Um filtro de flores é uma estrutura de dados probabilística que permite testar pertencendo a um conjunto com uma probabilidade de falsos positivos (~1%), sem armazenar os próprios elementos.

    13.2 Benefícios do filtro de flores

    CritériosHIBP k- anonimatoFiltro Bloom local -------------------------------------------------------------- Cobertura~14 bilhões~ 14 milhões (RockYou) Latência50–200 ms (rede)< 1 ms (local) Confidencialidadek- anonimato (5 tanques SHA-1)100% local, nada transmitido Falso positivo0%~1% TamanhoAPI~2–5 MB (binário do filtro de brilho)

    13.3 Operação de dupla apreensão

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

    // Dupla-hashing: h1 e h2 são duas funções de hash independentes const h1 = fnv1a32(w, 2166136261); // FNV1a com sementes padrão const h2 = fnv1a32(w, 0x811c9dc5); // FNV1a com sementes alternativas

    para (vamos i = 0; i < k; i++) { const pos = (h1 + (i) (h2) >> (0)) % m; // k posições no array de bits const byteIdx = Math.floor(pos / 8); const bitIdx = pos % 8;

    // Se um pouco for 0: a palavra está definitivamente ausente se ((bitArray[byteIdx] & (1 < < bitIdx)) = 0) retornar false; } // Todos os bits estão em 1 : a palavra está provavelmente presente (com 1% de FP) Retorno verdadeiro; }

    O duplo hashing FNV1a garante uma distribuição uniforme de posições na matriz de bits, minimizando colisões e mantendo a taxa de falsos positivos perto de 1%.

    13.4 Carregamento e formato binário

    O filtro flor é armazenado em data/rockyou.bloom — um ficheiro binário com:

  • Cabeçalho (20 bytes): número mágico (0x424c4f4f = "BLOO"), versão, m (tamanho do array de bits), k (número de funções de hash), n (número de elementos)
  • Carga útil : bit array (m/8 bytes)
  • A carga é acionada manualmente pelo usuário (botão na UI), não automaticamente no carregamento da página — para preservar o desempenho inicial.


    14. Comparação com ataques derivados

    O ataque do dicionário "puro" é o primeiro de uma família de ataques que todos compartilham uma raiz comum: uma lista de palavras lexicais. Time2Crack implementa 7 modelos de cracking offline (força bruta, dicionário, híbrido, máscara, PCFG, Markov, combinador), cada um atacando a senha de um ângulo diferente.

    14,1 Dicionário vs Híbrido

    CritériosDicionárioHíbrido (dict+regras) ------------------------------------------------ CandidatosPalavras do dicionário comoPalavras + ~1000 mutações por palavra Espaço de teclas200.000 candidatos~200 milhões de candidatos Exemplos triturados"senha", "sol""P@ssw0rd!", "s0l3il2024" Velocidade relativa1000× mais rápidoCobertura muito mais ampla Aplicável sepalavra exata na listaSenha derivada de uma palavra dita

    O ataque híbrido começa onde o dicionário puro pára: leva cada palavra da lista de palavras e aplica regras sistemáticas de mutação (hashcat "melhor64.rule" em mente).

    14,2 Dicionário vs PCFG

    CritériosDicionárioPCFG --------------------------------- ModeloLista fixa dos candidatosGramática da estrutura probabilística ForçarPalavras precisasEstruturas Word+Digits, Cap+lower+sym Exemplo"senha" → 文"Password123" → 文 (detetado na estrutura) Coberturavocabulário conhecidoEstruturas humanas genéricas

    Uma senha como "Password123" pode passar despercebida em um dicionário (a palavra exata "Password123" pode não estar listada), mas será rachada muito rapidamente pelo PCFG que reconhece a estrutura [Majuscule][minuscules][digites].

    14.3 Dicionário vs Markov

    CritériosDicionárioMarkov ----------------------------------- CandidatosLista pré-compiladaMosca gerada por modelo estatístico Coberturavocabulário conhecidoQualquer provável sequência "humana" VantagemMuito rápido em palavras exatasCobre palavras de vocabulário desconhecidas Exemplo"Sunshine" → 文"sunsh1ne" potencialmente

    Markov cobre casos em que a senha parece uma palavra humana sem estar em nenhuma lista.

    14.4 Dicionário vs Recheio Credencial

    CritériosDicionárioRecheio Credencial ----------------------------------------------- ObjectivoQuebrando um haxixeTestar uma autenticação específica MecanismoComputação local do HashTentativas de ligação remota OrigemLista de Palavras GenéricasEmparelhar as fugas de login/senha DefesaAlgoritmo de hash forteLimitação de taxa, MFA, bloqueio de IP

    O recheio credencial não ataca um hash — ele tenta diretamente pares de login/password em serviços remotos. É conceitualmente diferente de cracking, mas compartilha a mesma fonte de dados (HIBP/fail).


    15. Limitações do dicionário de ataque

    15.1 Limites intrínsecos

    1. Apenas vocabulário conhecido Uma senha inventada que não se assemelha a nenhuma palavra existente e que não está no HiBP é impermeável ao ataque de dicionário puro. "Xqz7mK9pL" nunca estará em nenhuma lista de palavras. 2. Cobertura linguística Um atacante atacando um usuário de língua francesa sem uma lista de palavras francesa perderá palavras como "efémero", "grenouille" ou "bricolagem" que não estão em listas de palavras em inglês padrão. 3. Novas senhas Uma credencial que acabou de ser criada e nunca fugiu não estará no HiBP — mesmo que seja muito comum, terá de esperar até o próximo vazamento para encontrá-lo. 4. Senhas muito longas Uma senha composta por uma frase inventada há muito tempo ("MaGrandeAventure2024SousLesEtoiles") não estará em nenhuma lista de palavras — mesmo que cada palavra tomada separadamente seja trivial. Esta é a ideia por trás das frases-passe, tratada por outros ataques (Combinador, PRINCE).

    15.2 Qual o Cálculo do Time2Crack Não Modelo

    Lista de Palavras de Contexto O Time2Crack usa wordlists genéricos. Listas de palavras de força bruta combinadas : Ferramentas como CeWL (Custom Word List Generator) podem extrair termos do site alvo para construir uma lista de palavras personalizada. Este nível de segmentação não é modelado. Vazamentos recentes ainda não no HIBP entre o momento em que ocorre um vazamento e sua integração no HIBP, as credenciais comprometidas circulam em fóruns privados sem serem acessíveis via API pública. Algoritmos de hash não abrangidos Os algoritmos Time2Crack 6 (MD5, SHA-1, SHA-256, NTLM, bcrypt, Argon2id). Algoritmos como SHA-512, scrypt ou PBKDF2 têm perfis diferentes.

    16. Defesas eficazes

    16.1 O que protege contra ataques de dicionário

    Algoritmo de hash moderno (bcrypt, Argon2id) Esta é a defesa mais eficaz do lado do servidor.
  • MD5: rachadura em ~ 1 microsegundo
  • bcrypt custo 12 : crack in 35 horas
  • Argon2id (parâmetros recomendados): crack in anos
  • A diferença de 10+ ordens de magnitude entre MD5 e Argon2id torna a senha do dicionário "sol" imune na prática se protegida por Argon2id — mesmo que o atacante saiba que é uma palavra francesa.

    Sal único por conta Um sal impede ataques pré- calculados na tabela e obriga o atacante a recalcular individualmente para cada conta. Ele não protege ataques de lista de palavras direcionados (o atacante ainda pode testar as 200.000 palavras com o sal), mas invalida as tabelas do arco-íris e torna impraticáveis ataques maciços em grandes bases de dados. Comprimento da senha Uma senha de uma única palavra do dicionário (8-10 caracteres) é vulnerável. Uma frase-passe de 4-5 palavras ("cheval-lumière-forest-voyage") é resistente ao ataque do dicionário puro, mas não ao ataque Combinator — daí a importância do comprimento E da aleatoriedade. Senhas geradas aleatoriamente A solução real: use um gerenciador de senhas que gera senhas aleatórias longas (20+ caracteres de todos os tipos). Estas senhas nunca estarão em nenhum dicionário. Autenticação multifatorial (MFA) O MFA não impede o crack offline (o atacante recupera hashs e cracks offline), mas protege contra o recheio credencial (use credenciais rachadas para conectar). Taxa que limita e detecta anomalias Protege contra ataques on-line (tentativas diretas de conexão), não contra rachadura offline de haxixes roubados.

    16.2 O que não protege

    Substituições de leet simples : "senha" → "p@ssw0rd" — ver secção 9. Números adicionados no final : "password" → "password1" — entre as primeiras regras testadas. Pagamento inicial : "senha" → "senha" — regra padrão de capitalização. Figuras e símbolos se a palavra permanecer reconhecível "Sunshine!" está em qualquer lista de palavras que inclui "Sunshine" com regras básicas. Complexidade imposta sem comprimento "P@s1w" atende aos critérios de complexidade (maj, min, número, símbolo) mas é mais curto e previsível do que "correcthorsebaterystaple".

    16.3 Recomendações práticas

  • Usar um gerenciador de senhas (Bitwarden, 1Password, KeePass) — gera senhas aleatórias, você só precisa lembrar a senha mestre.
  • Activar o MFA em todo o lado — mesmo que a senha esteja comprometida, o atacante não pode se conectar.
  • Verificar o HIBP regularmente — se o seu e-mail está em fugas conhecidas.
  • Nunca reutilize uma senha — o recheio de credenciais explora a reutilização de serviços cruzados.
  • Para senhas memorizáveis : 5+ palavras frase-passe aleatório (não "cavalo-correcto-bateria-agrafe-violeta", mas palavras realmente desenhadas por sorteio).

  • 17. Referências

    Fontes primárias (estudos académicos)

    Morris, R., & Thompson, K. (1979). Segurança da senha: Um histórico de casos. Comunicação da ACM, 22(11), 594-597.
  • Primeira análise acadêmica da distribuição de senhas Unix
  • Reconhece que as senhas ~1/3 são palavras comuns em inglês
  • Klein, D.V. (1990).
    Falindo o cracker: Uma pesquisa e melhorias na segurança de senha. Procedimentos de Simpósio de Segurança UNIX, 5-14.
  • 15.000 quebra senha Unix: 25% rachado em poucas horas
  • Documentar as primeiras listas de palavras e as regras de mutação
  • Weir, M., Aggarwal, S., de Medeiros, B., & Glodek, B. (2009).
    Quebra de senha usando gramáticas probabilísticas livres de contexto. Simpósio IEE sobre Segurança e Privacidade.
  • Referência básica no ataque PCFG e comparação com ataque dicionário puro
  • Determina que palavras de dicionário são encontradas nas primeiras 200.000 tentativas de um ataque ordenado
  • Citado em Time2Crack para a calibração HF do ataque do dicionário (multiplicador 0.5)
  • Ur, B., Kelley, P. G., Komanduri, S., Lee, J., Maase, M., Shay, R., Vaniea, K., Bauer, L., & Cranor, L. F. (2012).
    Como sua senha mede? O efeito dos medidores de força na escolha do usuário da senha. 21o Simpósio de Segurança USENIX.
  • Análise da distribuição das palavras comuns no corpus real
  • Palavras comuns encontradas nas primeiras 100-10 000 tentativas
  • Citado em Time2Crack para calibração de HF common ? 0.15 (nível superior 10k)
  • Bonneau, J (2012).
    A ciência do canto: Analisando um corpus anônimo de 70 milhões de senhas. Simpósio IEE sobre Segurança e Privacidade.
  • Estudo de 70 milhões de senhas do Yahoo anonimizadas
  • Quantifica a distribuição real de senhas, confirma a lei do poder
  • Medindo a eficácia do recheio credencial (2–5% taxa de sucesso em contas reais)
  • Ma, J., Yang, W., Luo, M., & Li, N. (2014).
    Um estudo de modelos probabilísticos de senha. Simpósio IEE sobre Segurança e Privacidade.
  • Comparação de modelos probabilísticos (dicionário, Markov, PCFG) no corpus real
  • Best64.rule priorizado → ~40% redução no tempo médio para palavras de dicionário
  • Citado em Time2Crack para calibração HF de ataque híbrido
  • Wheeler, D.L. (2016).
    zxcvbn: estimativa da força de senha de baixo orçamento. 25o Simpósio de Segurança USENIX, 157-173.
  • Forçar o sistema de estimação usando listas de palavras e padrões
  • Análise de vieses cognitivos na criação de senhas
  • Medir a eficácia das listas de palavras em relação à força bruta
  • Pasquini, D., Cianfriglia, M., Ateniese, G., & Bernaschi, M. (2021).
    Redução do viés em modelar a força de senha do mundo real através de aprendizagem profunda e dicionários dinâmicos. 30o Simpósio de Segurança USENIX.
  • Avaliação de modelos de estimativa para ataques reais
  • Confirma que os dicionários continuam a ser a ferramenta mais eficaz para senhas humanas comuns
  • Fontes industriais

    Fui enganado. (2024).
    Senhas digitadas. https://hapibeenpwned.com/Passwords
  • Base de ~14 bilhões de senhas únicas de vazamentos documentados
  • API k- anonimato usada pela Time2Crack para verificação em tempo real
  • Sistemas Colmeias. (2025).
    Tabela de senha de sistemas Hive 2025.
  • Benchmarks 12× RTX 4090: MD5 2,027 GH/s, NTLM 3,462 GH/s, custo de bcrypt 5 : 2,2 MH/s
  • Fonte principal de taxas de hash utilizadas no Time2Crack
  • Hashcat. (2025).
    Hashcat — Recuperação avançada de senhas.
  • Ferramenta de referência para benchmarks GPU
  • Documentação das regras de mutação (melhor64.regra, UmaRegraParaRegraTodos)
  • Gosney, J (2012).
    Estribos sobre Lee et al. e quebra de senha probabilística. Procedimento de senhascon.
  • Primeiros benchmarks multi-GPU documentados publicamente
  • Referência para calibração de ataques baseados em regras
  • Miessler, D. (2024).
    SecLists — Uma coleção de vários tipos de listas utilizadas durante as avaliações de segurança. GitHub.
  • Fonte das listas de palavras da Wikipédia usadas no Time2Crack
  • Listas de palavras em inglês, francês, espanhol, português, alemão, turco
  • Fontes secundárias (contexto)

    Troy Hunt. (2013).
    Introdução 306 Million Freely Downloadable Pwned Passwords. troyhunt.com.
  • Estabelecimento inicial do serviço HIBP e explicação do protocolo k-anonymity
  • Thomas, K., et al. (2019).
    Proteger contas de recheio credencial com alerta de quebra de senha. 28o Simpósio de Segurança USENIX.
  • Estudo Google/Stanford sobre proteção de credenciais comprometidas
  • Confirma a eficácia do k-anonymity como mecanismo de privacidade
  • Wang, D., Cheng, H., Wang, P., Huang, X., & Jian, G. (2016).
    A lei do Zipf em senhas. Transacções IEEE sobre a Forense e a Segurança da Informação, 12(11), 2776–2791.
  • Formalização matemática da lei de poder na distribuição de senhas
  • Confirma que a distribuição do Zipf mantém todo o grande corpus conhecido
  • Fontes da Web citadas no aplicativo Time2Crack

    IEEE Xplore (referência dictional). https://ieexplore.ieee.org/document/6234435
  • Fonte relacionada em descDict (app.js) para a ordem de cobertura dos principais dicionários.
  • Intervalo de API HIBP (k- anonimato). https://api.pwnedpasswords.com/range/
  • Endpoint usado pelo Time2Crack para verificação do k-anonymity (pedido de prefixo sha1).
  • Padrão de chamadas HIBP em código. https://api.pwnedpasswords.com/range/${prefix}
  • A forma exata da URL chamada nos exemplos de código do documento (prefixo SHA-1 interpolado).

  • Documento gerado para o projeto Time2Crack — Versão 1.0 — 2026-04-01 Código- fonte: app.js (funções addDictionaryAttacks, isDictWord, deLeet, loadDictionary, applyHighFidelityCalibration, bloomHas)*