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
isDictWord()addDictionaryAttacks()applyHighFidelityCalibration()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:
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.
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.- Senha #1 ("123456") representou 290.731 contas (2%)
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 minutosO 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:
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:
Para uma lista de palavras de 14 bilhões de entradas (tamanho HIBP) em 12× RTX 4090:
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 :
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 defensoresHiBP é a referência global porque:
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: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 :
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 microssegundosMesmo 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 :
8.2 Normalização Unicode (NFC)
Normalização normalize("NFC") assegura que os caracteres acentuados sejam tratados de forma consistente:
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:
hybridVuln = true → 1000 mutações testadas com base em dicionário9. 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.
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").
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:
10.4 Exemplo numérico completo
Para a senha "sol" (palavra francesa atual, detectada como dictWord) :
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
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;
common A senha está no HIBP → o ataque do dicionário aplica-se com máxima confiança.dictWord Apenas: alta probabilidade. Uma palavra do dicionário é vulnerável, mas um atacante deve ter a lista de palavras linguísticas correta.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.99evidenceBoost = min(0.12, 2 × 0.04) = 0.08confidence = min(1, max(0.99, 0.6) + 0.08) = min(1, 1.07) = 1.0Má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:
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 ditaO 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éricasUma 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" potencialmenteMarkov 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 IPO 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.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
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.common ? 0.15 (nível superior 10k)Fontes industriais
Fui enganado. (2024). Senhas digitadas. https://hapibeenpwned.com/PasswordsFontes secundárias (contexto)
Troy Hunt. (2013). Introdução 306 Million Freely Downloadable Pwned Passwords. troyhunt.com.Fontes da Web citadas no aplicativo Time2Crack
IEEE Xplore (referência dictional). https://ieexplore.ieee.org/document/6234435descDict (app.js) para a ordem de cobertura dos principais dicionários.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)*