
PACK (Kit de Análise e Quebra de Senhas)
PACK (Password Analysis and Cracking Toolkit) é uma coleção de utilitários desenvolvidos para auxiliar na análise de listas de senhas, a fim de aprimorar a quebra de senhas por meio da detecção de padrões de máscaras, regras, conjuntos de caracteres e outras características de senhas. O kit gera arquivos de entrada válidos para a família de quebradores de senhas Hashcat.
OBSERVAÇÃO: O kit em si não é capaz de quebrar senhas, mas foi projetado para tornar a operação de quebradores de senhas mais eficiente.
Antes de começarmos a usar o kit, devemos estabelecer um critério de seleção de listas de senhas. Como estamos procurando analisar a maneira como as pessoas criam suas senhas, devemos obter a maior amostra possível de senhas vazadas. Uma excelente lista é baseada na violação do RockYou.com. Esta lista fornece uma coleção grande e diversificada que oferece bons resultados para senhas comuns usadas em sites semelhantes (por exemplo, redes sociais). A análise obtida desta lista pode não funcionar para organizações com políticas de senhas específicas. Portanto, selecionar uma amostra de entrada deve ser o mais próximo possível do seu alvo. Além disso, tente evitar obter listas baseadas em senhas já quebradas, pois isso gerará viés estatístico em relação às regras e máscaras usadas pelo(s) indivíduo(s) que quebraram a lista, e não pelos usuários reais.
A análise mais básica que você pode realizar é simplesmente obter o comprimento, conjunto de caracteres e outras características mais comuns das senhas na lista fornecida. No exemplo abaixo, usaremos 'rockyou.txt' contendo aproximadamente 14 milhões de senhas. Execute statsgen.py com a seguinte linha de comando:
$ python statsgen.py rockyou.txt
Abaixo está a saída do comando acima:
_
StatsGen #.#.# | |
_ __ __ _ ___| | _
| '_ \ / _` |/ __| |/ /
| |_) | (_| | (__| <
| .__/ \__,_|\___|_|\_\
| |
|_| [email protected]
[*] Analisando senhas em [rockyou.txt]
[+] Analisando 100% (14344390/14344390) das senhas
OBSERVAÇÃO: As estatísticas abaixo são relativas ao número de senhas analisadas, não ao número total de senhas
[*] Comprimento:
[+] 8: 20% (2966037)
[+] 7: 17% (2506271)
[+] 9: 15% (2191039)
[+] 10: 14% (2013695)
[+] 6: 13% (1947798)
...
[*] Conjunto de caracteres:
[+] loweralphanum: 42% (6074867)
[+] loweralpha: 25% (3726129)
[+] numeric: 16% (2346744)
[+] loweralphaspecialnum: 02% (426353)
[+] upperalphanum: 02% (407431)
...
[*] Complexidade da senha:
[+] digit: min(0) max(255)
[+] lower: min(0) max(255)
[+] upper: min(0) max(187)
[+] special: min(0) max(255)
[*] Máscaras Simples:
[+] stringdigit: 37% (5339556)
[+] string: 28% (4115314)
[+] digit: 16% (2346744)
[+] digitstring: 04% (663951)
[+] othermask: 04% (576324)
...
[*] Máscaras Avançadas:
[+] ?l?l?l?l?l?l?l?l: 04% (687991)
[+] ?l?l?l?l?l?l: 04% (601152)
[+] ?l?l?l?l?l?l?l: 04% (585013)
[+] ?l?l?l?l?l?l?l?l?l: 03% (516830)
[+] ?d?d?d?d?d?d?d: 03% (487429)
...
OBSERVAÇÃO: Você pode reduzir o número de outliers exibidos incluindo a flag --hiderare, que não mostrará nenhum item com ocorrência inferior a 1%.
Aqui está o que podemos aprender imediatamente com a lista acima:
A última seção, "Máscaras Avançadas", contém as máscaras mais frequentes usando o formato Hashcat. Símbolos individuais podem ser interpretados da seguinte forma:
?l - um único caractere minúsculo
?u - um único caractere maiúsculo
?d - um único dígito
?s - um único caractere especial
Por exemplo, a primeira máscara, "?l?l?l?l?l?l?l?l", corresponderá a todas as senhas alfanuméricas minúsculas. Dado o tamanho da amostra, você conseguirá quebrar aproximadamente 4% das senhas. No entanto, após gerar a saída inicial, você pode estar interessado em usar filtros para restringir os dados de senha.
Vamos ver como os usuários do RockYou tendem a selecionar suas senhas usando a máscara simples "stringdigit" (uma string seguida por números):
$ python statsgen.py ../PACK-0.0.3/archive/rockyou.txt --simplemask stringdigit -q --hiderare
[*] Analisando senhas em [rockyou.txt]
[+] Analisando 37% (5339556/14344390) das senhas
OBSERVAÇÃO: As estatísticas abaixo são relativas ao número de senhas analisadas, não ao número total de senhas
[*] Comprimento:
[+] 8: 23% (1267260)
[+] 7: 18% (981432)
[+] 9: 17% (939971)
[+] 10: 14% (750938)
[+] 6: 11% (618983)
[+] 11: 05% (294869)
[+] 12: 03% (175875)
[+] 13: 01% (103047)
[+] 14: 01% (65958)
[*] Conjunto de caracteres:
[+] loweralphanum: 88% (4720184)
[+] upperalphanum: 06% (325941)
[+] mixedalphanum: 05% (293431)
[*] Complexidade da senha:
[+] digit: min(1) max(252)
[+] lower: min(0) max(46)
[+] upper: min(0) max(31)
[+] special: min(0) max(0)
[*] Máscaras Simples:
[+] stringdigit: 100% (5339556)
[*] Máscaras Avançadas:
[+] ?l?l?l?l?l?l?d?d: 07% (420318)
[+] ?l?l?l?l?l?d?d: 05% (292306)
[+] ?l?l?l?l?l?l?l?d?d: 05% (273624)
[+] ?l?l?l?l?d?d?d?d: 04% (235360)
[+] ?l?l?l?l?d?d: 04% (215074)
...
O topo da saída especifica a porcentagem do total de senhas analisadas. Neste caso, quebrando apenas senhas que correspondem à máscara "stringdigit", é possível recuperar apenas cerca de 37% do conjunto total, conforme exibido na saída original. Em seguida, parece que apenas 11% deste tipo de senha usam algo diferente de minúsculas. Portanto, seria inteligente concentrar-se apenas em strings minúsculas que correspondam a esta máscara. Por fim, na seção "Máscaras Avançadas", podemos ver que a maioria das senhas "stringdigit" consiste em uma string com dois ou quatro dígitos após ela. Com as informações obtidas da saída acima, podemos começar a criar uma imagem mental dos padrões de geração de senhas dos usuários alvo.
Existem alguns outros filtros disponíveis para comprimento da senha, máscara e conjuntos de caracteres:
Comprimento: --minlength e/ou --maxlength
Máscara Simples: --simplemask [numeric, loweralpha, upperalpha, mixedalpha, loweralphanum, etc.]
Conjuntos de caracteres: --charset [digit, string, stringdigit, digitstring, digitstringdigit, etc.]
OBSERVAÇÃO: Mais de um filtro da mesma classe pode ser especificado como uma lista separada por vírgulas:
--simplemask="stringdigit,digitstring"
Embora a seção "Máscaras Avançadas" exiba apenas padrões que correspondem a mais de 1% de todas as senhas, você pode obter e salvar uma lista completa de máscaras de senhas correspondentes a um dicionário específico usando o seguinte comando:
$ python statsgen.py rockyou.txt -o rockyou.masks
Todas as máscaras de senha e suas frequências serão salvas no arquivo especificado no formato CSV. Naturalmente, você pode fornecer filtros para gerar apenas arquivos de máscaras que correspondam aos parâmetros especificados. O arquivo de saída pode ser usado como entrada para a ferramenta MaskGen abordada na próxima seção.
O MaskGen permite criar ataques de máscara baseados em padrões para entrada na família de quebradores de senhas Hashcat. A ferramenta usa a saída produzida pelo statsgen acima com a flag '-o' para produzir o ataque de máscara mais otimizado, classificado por complexidade da máscara, ocorrência da máscara ou a razão entre os dois (índice ótimo).
Vamos executar o MaskGen apenas com a saída do StatGen como argumento:
$ python maskgen.py rockyou.masks
_
MaskGen #.#.# | |
_ __ __ _ ___| | _
| '_ \ / _` |/ __| |/ /
| |_) | (_| | (__| <
| .__/ \__,_|\___|_|\_\
| |
|_| [email protected]
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por seu [optindex].
[*] Geração de máscaras concluída:
Máscaras geradas: 146578
Cobertura das máscaras: 100% (14344390/14344390)
Tempo de execução das máscaras: >1 ano
Existem várias informações que você deve observar:
Como você geralmente tem tempo limitado para executar e criar ataques, o maskgen permite especificar quanto tempo você tem para realizar ataques de máscara e gerará a coleção mais otimizada de máscaras com base no modo de ordenação. Vamos brincar um pouco com diferentes modos de ordenação e tempos alvo:
$ python maskgen.py rockyou.masks --targettime 600 --optindex -q
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por seu [optindex].
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 779
Cobertura das máscaras: 56% (8116195/14344390)
Tempo de execução das máscaras: 0:11:36
$ python maskgen.py rockyou.masks --targettime 600 --complexity -q
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por sua [complexity].
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 5163
Cobertura das máscaras: 31% (4572346/14344390)
Tempo de execução das máscaras: 0:10:01
$ python maskgen.py rockyou.masks --targettime 600 --occurrence -q
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por sua [occurrence].
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 4
Cobertura das máscaras: 16% (2390986/14344390)
Tempo de execução das máscaras: 1:34:05
Todas as execuções acima têm tempo alvo de 600 segundos (ou 10 minutos) com diferentes modos de ordenação. Com base em nossos experimentos, as máscaras geradas usando o modo de ordenação OptIndex podem quebrar 56% das senhas do RockYou em cerca de 10 minutos. Ao mesmo tempo, as máscaras geradas usando o modo de ordenação Occurrence não só têm uma cobertura bastante fraca de apenas 16%, mas também excederam o tempo alvo especificado em mais de uma hora.
OBSERVAÇÃO: As máscaras ordenadas por complexidade podem ser muito eficazes ao atacar listas baseadas em políticas.
Vamos ver algumas das máscaras geradas pelo maskgen no modo optindex usando a flag --showmasks:
$ python maskgen.py rockyou.masks --targettime 43200 --optindex -q --showmasks
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por seu [optindex].
[L:] Máscara: [ Ocorr: ] [ Tempo: ]
...
[ 7] ?l?d?s?l?l?d?d [6 ] [ 0:00:00]
[ 8] ?s?l?l?l?l?l?l?s [3480 ] [ 0:05:36]
[ 9] ?l?l?l?l?d?d?d?d?s [1553 ] [ 0:02:30]
[ 8] ?d?l?d?d?d?l?l?l [47 ] [ 0:00:04]
[ 8] ?d?l?l?d?l?d?d?l [47 ] [ 0:00:04]
[ 8] ?d?l?l?d?d?l?d?l [47 ] [ 0:00:04]
[ 8] ?d?l?d?l?d?d?l?l [47 ] [ 0:00:04]
[ 8] ?d?d?l?l?d?l?d?l [47 ] [ 0:00:04]
[ 8] ?d?l?d?d?l?l?l?l [122 ] [ 0:00:11]
[ 8] ?u?u?d?u?d?d?d?d [18 ] [ 0:00:01]
[ 6] ?d?s?s?s?s?s [4 ] [ 0:00:00]
[10] ?l?l?l?l?l?l?l?l?d?d [213109 ] [ 5:48:02]
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 3970
Cobertura das máscaras: 74% (10620959/14344390)
Tempo de execução das máscaras: 16:10:38
As máscaras exibidas seguem um formato bastante intuitivo:
[ 9] ?l?l?l?l?d?d?d?d?s [1553 ] [ 0:02:30]
\ \ \
\ _ máscara gerada \ _ tempo de execução da máscara
\
_ comprimento da máscara _ ocorrência da máscara
No exemplo acima, você pode ver parte da lógica que entra na geração de máscaras. Por exemplo, embora a máscara '?s?l?l?l?l?l?l?s' tenha um dos tempos de execução mais longos na amostra (5 minutos), ela ainda tem prioridade mais alta devido à sua ocorrência relativamente maior em comparação com '?l?l?l?l?d?d?d?d?s'. Ao mesmo tempo, embora '?l?d?s?l?l?d?d' tenha uma cobertura bastante baixa, ela ainda obtém uma prioridade mais alta do que outras máscaras porque, sendo uma máscara de apenas seis caracteres, executa muito rapidamente.
Você pode otimizar ainda mais seus ataques de máscara gerados usando filtros. Por exemplo, você pode ter hardware suficientemente poderoso onde pode simplesmente forçar por bruto todas as senhas de até 8 caracteres. Nesse caso, você pode gerar máscaras apenas maiores que 8 caracteres usando a flag --minlength da seguinte forma:
$ python maskgen.py rockyou.masks --targettime 43200 --optindex -q --minlength 8
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por seu [optindex].
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 585
Cobertura das máscaras: 41% (5905182/14344390)
Tempo de execução das máscaras: 15:50:36
Naturalmente, a cobertura das máscaras geradas foi reduzida, mas esses filtros se tornam úteis ao preparar uma coleção de máscaras para atacar listas de senhas diferentes daquelas usadas para gerá-las.
A lista abaixo mostra filtros adicionais que você pode usar:
Opções de Filtro de Máscara Individual:
--minlength=8 Comprimento mínimo da senha
--maxlength=8 Comprimento máximo da senha
--mintime=3600 Tempo mínimo de execução da máscara (segundos)
--maxtime=3600 Tempo máximo de execução da máscara (segundos)
--mincomplexity=1 Complexidade mínima
--maxcomplexity=100
Complexidade máxima
--minoccurrence=1 Ocorrência mínima
--maxoccurrence=100
Ocorrência máxima
As flags de ocorrência e complexidade podem ser particularmente poderosas para ajustar as máscaras geradas usando diferentes modos de ordenação.
Depois de satisfeito com as máscaras geradas acima, você pode salvá-las usando a flag -o:
$ python maskgen.py rockyou.masks --targettime 43200 --optindex -q -o rockyou.hcmask
[*] Analisando máscaras em [rockyou.masks]
[*] Salvando máscaras geradas em [rockyou.hcmask]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por seu [optindex].
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 3970
Cobertura das máscaras: 74% (10620959/14344390)
Tempo de execução das máscaras: 16:10:38
Isso produzirá o arquivo 'rockyou.hcmask', que pode ser usado diretamente pelo conjunto de ferramentas Hashcat ou como parte de um script personalizado que itera sobre eles.
Muitas vezes é útil ver quão bem as máscaras geradas se saem contra listas já quebradas. O Maskgen pode comparar uma coleção de máscaras com outras para ver quão bem elas se sairiam se máscaras de uma lista de senhas fossem tentadas contra outra. Vamos comparar quão bem as máscaras geradas da lista RockYou se sairão contra outra lista comprometida, como Gawker:
$ python statsgen.py ../PACK-0.0.3/archive/gawker.dic -o gawker.masks
$ python maskgen.py gawker.masks --checkmasksfile rockyou.hcmask -q
[*] Analisando máscaras em [gawker.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Verificando cobertura das máscaras em [rockyou.hcmask]
[*] Correspondência de máscaras concluída:
Máscaras correspondidas: 1775
Cobertura das máscaras: 96% (1048889/1084394)
Tempo de execução das máscaras: 16:25:44
Usando o parâmetro '--checkmasksfile', tentamos executar as máscaras dentro do arquivo 'rockyou.hcmask' gerado anteriormente contra as máscaras de uma lista vazada de amostra 'gawker.masks'. Isso resulta em uma boa cobertura de 96%, onde 1775 das 3970 máscaras geradas totais baseadas no RockYou corresponderam a máscaras na lista Gawker.
Também é possível ver a cobertura de uma ou mais máscaras especificando-as diretamente na linha de comando da seguinte forma:
$ python maskgen.py gawker.masks --checkmasks="?u?l?l?l?l?l?d,?l?l?l?l?l?d?d" -q
[*] Analisando máscaras em [gawker.masks]
[*] Usando 1.000.000.000 chaves/seg para cálculos.
[*] Verificando cobertura destas máscaras [?u?l?l?l?l?l?d, ?l?l?l?l?l?d?d]
[*] Correspondência de máscaras concluída:
Máscaras correspondidas: 2
Cobertura das máscaras: 1% (18144/1084394)
Tempo de execução das máscaras: 0:00:04
Ambas as máscaras especificadas corresponderam com apenas 1% de cobertura.
Dependendo das especificações exatas do seu hardware e do hash alvo, você pode querer aumentar ou diminuir a velocidade de chaves/seg usada durante os cálculos usando o parâmetro '--pps':
$ python maskgen.py rockyou.masks --targettime 43200 --pps 50000000 -q
[*] Analisando máscaras em [rockyou.masks]
[*] Usando 50.000.000 chaves/seg para cálculos.
[*] Ordenando máscaras por seu [optindex].
[!] Tempo alvo excedido.
[*] Geração de máscaras concluída:
Máscaras geradas: 1192
Cobertura das máscaras: 61% (8754548/14344390)
Tempo de execução das máscaras: 12:17:31
Usar o parâmetro '--pps' para corresponder ao seu desempenho real torna o tempo alvo mais significativo.
Muitos ataques de máscara e dicionário falharão no ambiente corporativo com requisitos mínimos de complexidade de senha. Em vez de recorrer a um ataque de força bruta puro, podemos alavancar regras de complexidade de senha conhecidas ou adivinhadas para evitar tentar candidatos a senha que não estejam em conformidade com a política ou, inversamente, auditar apenas senhas não conformes. Usando o PolicyGen, você poderá gerar uma coleção de máscaras seguindo a complexidade da senha, a fim de reduzir significativamente o tempo de quebra.
Abaixo está uma sessão de exemplo onde geramos todas as máscaras de senha válidas para um ambiente que exige pelo menos um dígito, uma maiúscula e um caractere especial.
$ python policygen.py --minlength 8 --maxlength 8 --minlower 1 --minupper 1 --mindigit 1 --minspecial 1 -o complexity.hcmask
_
PolicyGen #.#.# | |
_ __ __ _ ___| | _
| '_ \ / _` |/ __| |/ /
| |_) | (_| | (__| <
| .__/ \__,_|\___|_|\_\
| |
|_| [email protected][*] Saving generated masks to [complexity.hcmask]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Password policy:
Pass Lengths: min:8 max:8
Min strength: l:1 u:1 d:1 s:1
Max strength: l:None u:None d:None s:None
[*] Generating [compliant] masks.
[*] Generating 8 character password masks.
[*] Total Masks: 65536 Time: 76 days, 18:50:04
[*] Policy Masks: 40824 Time: 35 days, 0:33:09
A partir da saída acima, podemos ver que geramos 40824 máscaras que correspondem à complexidade especificada e levarão cerca de 35 dias para serem executadas a uma velocidade de 1.000.000.000 de chaves/segundo.
Caso você esteja simplesmente realizando uma auditoria de senhas e tenha a tarefa de descobrir apenas senhas não conformes, pode usar a flag --noncompliant para inverter as máscaras geradas:
$ python policygen.py --minlength 8 --maxlength 8 --minlower 1 --minupper 1 --mindigit 1 --minspecial 1 -o noncompliant.hcmask -q --noncompliant
[*] Saving generated masks to [noncompliant.hcmask]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Password policy:
Pass Lengths: min:8 max:8
Min strength: l:1 u:1 d:1 s:1
Max strength: l:None u:None d:None s:None
[*] Generating [non-compliant] masks.
[*] Generating 8 character password masks.
[*] Total Masks: 65536 Time: 76 days, 18:50:04
[*] Policy Masks: 24712 Time: 41 days, 18:16:55
Vamos ver algumas das máscaras não conformes geradas acima usando a flag --showmasks:
$ python policygen.py --minlength 8 --maxlength 8 --minlower 1 --minupper 1 --mindigit 1 --minspecial 1 -o noncompliant.hcmask -q --noncompliant --showmasks
[*] Saving generated masks to [noncompliant.hcmask]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Password policy:
Pass Lengths: min:8 max:8
Min strength: l:1 u:1 d:1 s:1
Max strength: l:None u:None d:None s:None
[*] Generating [non-compliant] masks.
[*] Generating 8 character password masks.
[ 8] ?d?d?d?d?d?d?d?d [l: 0 u: 0 d: 8 s: 0] [ 0:00:00]
[ 8] ?d?d?d?d?d?d?d?l [l: 1 u: 0 d: 7 s: 0] [ 0:00:00]
[ 8] ?d?d?d?d?d?d?d?u [l: 0 u: 1 d: 7 s: 0] [ 0:00:00]
[ 8] ?d?d?d?d?d?d?d?s [l: 0 u: 0 d: 7 s: 1] [ 0:00:00]
...
[ 8] ?s?s?s?s?s?s?s?d [l: 0 u: 0 d: 1 s: 7] [ 0:07:06]
[ 8] ?s?s?s?s?s?s?s?l [l: 1 u: 0 d: 0 s: 7] [ 0:18:28]
[ 8] ?s?s?s?s?s?s?s?u [l: 0 u: 1 d: 0 s: 7] [ 0:18:28]
[ 8] ?s?s?s?s?s?s?s?s [l: 0 u: 0 d: 0 s: 8] [ 0:23:26]
[*] Total Masks: 65536 Time: 76 days, 18:50:04
[*] Policy Masks: 24712 Time: 41 days, 18:16:55
Como você pode ver, todas as máscaras têm pelo menos um requisito de complexidade de senha ausente. Curiosamente, com menos máscaras geradas, leva mais tempo para atacar por causa de máscaras de longa duração como ?s?s?s?s?s?s?s?s.
Também é possível especificar a complexidade máxima da senha usando as flags --maxlower, --maxupper, --maxdigit e --maxspecial para ajustar seu ataque. Por exemplo, abaixo está um site de exemplo que impõe uma política de senhas, mas não permite caracteres especiais:
$ python policygen.py --minlength 8 --maxlength 8 --minlower 1 --minupper 1 --mindigit 1 --maxspecial 0 -o maxcomplexity.hcmask -q
[*] Saving generated masks to [maxcomplexity.hcmask]
[*] Using 1,000,000,000 keys/sec for calculations.
[*] Password policy:
Pass Lengths: min:8 max:8
Min strength: l:1 u:1 d:1 s:None
Max strength: l:None u:None d:None s:0
[*] Generating [compliant] masks.
[*] Generating 8 character password masks.
[*] Total Masks: 65536 Time: 76 days, 18:50:04
[*] Policy Masks: 5796 Time: 1 day, 20:20:55
rulegen.py implementa análise de senhas e geração de regras para o quebrador de senhas Hashcat, conforme descrito no artigo Automatic Password Rule Analysis and Generation. Por favor, revise este documento para uma discussão detalhada sobre a teoria da análise e geração de regras.
Reverter palavras-fonte e regras de modificação de palavras a partir de senhas já quebradas pode ser muito eficaz na realização de ataques contra hashes ainda criptografados. Ao reciclar/expandir continuamente as regras e palavras geradas, você pode conseguir quebrar um número maior de senhas.
Existem vários pré-requisitos para o uso eficaz do rulegen.py. A ferramenta utiliza a biblioteca de verificação ortográfica Enchant para interfacear com vários mecanismos de verificação ortográfica, como Aspell, MySpell, etc. Você deve instalar essas ferramentas antes do uso. Também é fundamental instalar dicionários para o mecanismo de verificação ortográfica que você escolher (alternativamente, é possível usar uma wordlist personalizada). Por último, incluí o PyEnchant por conveniência, que deve interfacear diretamente com as bibliotecas compartilhadas do Enchant; no entanto, se houver problemas, basta remover o diretório 'enchant' incluído e instalar o PyEnchant para sua distribuição.
Para detalhes adicionais sobre a sintaxe específica de regras do Hashcat, veja Hashcat Rule Based Attack.
O uso mais básico do rulegen.py envolve a análise de uma única senha para detectar automaticamente regras. Vamos detectar regras e a possível palavra-fonte usada para gerar uma senha de exemplo P@55w0rd123:
$ python rulegen.py --verbose --password P@55w0rd123
_
RuleGen #.#.# | |
_ __ __ _ ___| | _
| '_ \ / _` |/ __| |/ /
| |_) | (_| | (__| <
| .__/ \__,_|\___|_|\_\
| |
|_| [email protected]
[*] Using Enchant 'aspell' module. For best results please install
'aspell' module language dictionaries.
[*] Analyzing password: P@55w0rd123
[-] Pas sword => {edit distance suboptimal: 8 (7)} => P@55w0rd123
[+] Password => sa@ ss5 so0 $1 $2 $3 => P@55w0rd123
[+] Passwords => sa@ ss5 so0 o81 $2 $3 => P@55w0rd123
[+] Passwords => sa@ ss5 so0 i81 o92 $3 => P@55w0rd123
[+] Passwords => sa@ ss5 so0 i81 i92 oA3 => P@55w0rd123
[+] Password's => sa@ ss5 so0 o81 o92 $3 => P@55w0rd123
[+] Password's => sa@ ss5 so0 o81 i92 oA3 => P@55w0rd123
[+] Password's => sa@ ss5 so0 i81 o92 oA3 => P@55w0rd123
Existem várias flags que usamos neste exemplo:
O processamento de arquivos de senhas é abordado em uma seção abaixo; no entanto, vamos primeiro discutir algumas das opções de ajuste fino disponíveis usando uma única senha como exemplo.
Observe que estamos usando o módulo Enchant aspell para detecção de palavras-fonte. O mecanismo de verificação ortográfica exato pode ser alterado usando a flag --provider da seguinte forma:
$ python rulegen.py --verbose --provider myspell --password P@55w0rd123 -q
[*] Using Enchant 'myspell' module. For best results please install
'myspell' module language dictionaries.
...
NOTA: A prioridade do mecanismo do provedor pode ser especificada usando uma lista separada por vírgulas (por exemplo, --provider aspell,myspell).
O uso do mecanismo de detecção de palavras-fonte pode ser completamente desabilitado especificando uma palavra-fonte com a flag --word:
$ python rulegen.py -q --verbose --word word --password P@55w0rd123
[*] Analyzing password: P@55w0rd123
[+] word => ^5 ^5 ^@ ^P so0 $1 $2 $3 => P@55w0rd123
Ao especificar diferentes palavras-fonte, você pode se divertir experimentando com o mecanismo de geração de regras.
Inevitavelmente, você chegará a um ponto em que gerar regras usando a wordlist padrão do mecanismo de verificação ortográfica não é mais suficiente. Você pode especificar uma wordlist personalizada usando a flag --wordlist. Isso é particularmente útil ao reutilizar palavras-fonte de uma sessão de análise anterior:
$ python rulegen.py -q --verbose --wordlist rockyou.txt --password 1pa55w0rd1
[*] Using Enchant 'Personal Wordlist' module. For best results please install
'Personal Wordlist' module language dictionaries.
[*] Analyzing password: 1pa55w0rd1
[+] password => ^1 ss5 so0 $1 => 1pa55w0rd1
A wordlist personalizada pode ser particularmente útil ao usar palavras que não são comumente encontradas, como gírias, bem como senhas já quebradas.
Embora o rulegen.py tente gerar e registrar apenas as melhores palavras-fonte e regras, pode haver casos em que você está interessado em mais resultados. Use as flags --morewords e --morerules para gerar palavras e regras que podem exceder a distância de edição ótima:
$ python rulegen.py -q --verbose --password '$m0n3y$' --morerules --morewords
[*] Using Enchant 'aspell' module. For best results please install
'aspell' module language dictionaries.
[*] Analyzing password: $m0n3y$
[+] money => ^$ so0 se3 $$ => $m0n3y$
[+] moneys => ^$ so0 se3 o6$ => $m0n3y$
[+] mingy => ^$ si0 sg3 $$ => $m0n3y$
[+] many => ^$ sa0 i43 $$ => $m0n3y$
[+] Mooney => sM$ o1m so0 se3 $$ => $m0n3y$
É possível expandir ainda mais as palavras geradas usando as flags --maxworddist e --maxwords. Da mesma forma, você pode produzir mais regras usando as flags --maxrulelen e --maxrules.
O rulegen.py inclui vários mecanismos avançados para gerar palavras e regras de melhor qualidade. É possível desabilitá-los para observar a diferença (ou se estiverem causando problemas) usando as flags --simplewords e --simplerules. Vamos observar como as palavras-fonte e as regras mudam com essas flags ativadas:
$ python rulegen.py -q --verbose --password '$m0n3y$' --simplewords --simplerules
[*] Using Enchant 'aspell' module. For best results please install
'aspell' module language dictionaries.
[*] Analyzing password: $m0n3y$
[-] Meany => {edit distance suboptimal: 5 (4)} => $m0n3y$
[+] many => i0$ o20 i43 i6$ => $m0n3y$
[+] mingy => i0$ o20 o43 i6$ => $m0n3y$
[+] money => i0$ o20 o43 i6$ => $m0n3y$
[+] mangy => i0$ o20 o43 i6$ => $m0n3y$
[+] manky => i0$ o20 o43 i6$ => $m0n3y$
Observe que a qualidade das palavras e regras geradas foi significativamente reduzida, com palavras como 'manky' tendo menos relação com a palavra-fonte real 'money'. Ao mesmo tempo, as regras geradas foram reduzidas a inserções, exclusões e substituições simples.
Agora que você domina todas as diferentes flags e chaves, podemos tentar gerar palavras e regras para uma coleção de senhas. Vamos gerar um arquivo de texto korelogic.txt contendo as seguintes senhas de teste bastante complexas:
&~defcon
'#(4)\
August19681
'&a123456
10-D'Ann
~|Bailey
Krist0f3r
f@cebOOK
Nuclear$(
zxcvbn2010!
13Hark's
NjB3qqm
Sydney93?
antalya%]
Annl05de
;-Fluffy
Agora vamos observar a análise do rulegen.py simplesmente especificando o arquivo de senhas como primeiro argumento:
$ python rulegen.py korelogic.txt -q
[*] Using Enchant 'aspell' module. For best results please install
'aspell' module language dictionaries.
[*] Analyzing passwords file: korelogic.txt:
[*] Press Ctrl-C to end execution and generate statistical analysis.
[*] Saving rules to analysis.rule
[*] Saving words to analysis.word
[*] Finished processing 16 passwords in 1.00 seconds at the rate of 15.94 p/sec
[*] Generating statistics for [analysis] rules and words.
[-] Skipped 0 all numeric passwords (0.00%)
[-] Skipped 2 passwords with less than 25% alpha characters (12.50%)
[-] Skipped 0 passwords with non ascii characters (0.00%)
[*] Top 10 rules
[+] ^3 ^1 o4r - 3 (2.00%)
[+] i61 i79 i86 i98 oA1 - 2 (1.00%)
[+] ^- ^0 ^1 i4' o5A - 2 (1.00%)
[+] sS1 i13 T2 - 1 (0.00%)
[+] i61 se9 i86 i98 oA1 - 1 (0.00%)
[+] o61 i79 i86 i98 oA1 - 1 (0.00%)
[+] ^- ^0 ^1 so' i5A - 1 (0.00%)
[+] D3 si0 i55 $e - 1 (0.00%)
[+] i61 i79 se6 i98 oA1 - 1 (0.00%)
[+] i3a o5y o6a i7% o8] - 1 (0.00%)
[*] Top 10 words
[+] Analyze - 1 (0.00%)
[+] defcon - 1 (0.00%)
[+] Kristen - 1 (0.00%)
[+] Bailey - 1 (0.00%)
[+] Augusts - 1 (0.00%)
[+] Annelid - 1 (0.00%)
[+] Hack's - 1 (0.00%)
[+] antlers - 1 (0.00%)
[+] antelope - 1 (0.00%)
[+] xxxv - 1 (0.00%)
Usando todas as configurações padrão, conseguimos produzir várias regras de alta qualidade. O aplicativo exibe algumas estatísticas básicas das 10 principais regras e palavras. Todas as regras e palavras geradas são salvas usando o nome base 'analysis' por padrão:
Observe que várias senhas como #(4)\ e '&a123456 foram puladas porque não possuem características suficientes para serem processadas. Além da contagem de caracteres alfa, o programa pulará senhas totalmente numéricas e senhas contendo caracteres não ASCII. Este último deve-se a um bug no mecanismo Enchant que espero corrigir no futuro, permitindo o processamento de palavras em muitos idiomas.
Como mencionado anteriormente, o rulegen.py salva os arquivos de saída usando o nome base 'analysis' por padrão. Você pode alterar o nome base do arquivo com a flag --basename ou -b da seguinte forma:
$ python rulegen.py korelogic.txt -q -b korelogic
[*] Using Enchant 'aspell' module. For best results please install
'aspell' module language dictionaries.
[*] Analyzing passwords file: korelogic.txt:
[*] Press Ctrl-C to end execution and generate statistical analysis.
[*] Saving rules to korelogic.rule
[*] Saving words to korelogic.word
Pode haver situações em que você enfrente problemas ao gerar regras para o quebrador de senhas Hashcat. O rulegen.py inclui a flag --hashcat para validar palavras e regras geradas usando o próprio hashcat em modo --stdout. Para que este modo funcione corretamente, você deve baixar a versão mais recente do hashcat-cli e editar a variável HASHCAT_PATH no código-fonte. Por exemplo, no momento em que este artigo foi escrito, coloquei a pasta hashcat-0.## no diretório PACK e defini HASHCAT_PATH como 'hashcat-0.##/'.
Você também pode observar o funcionamento interno do mecanismo de geração de regras com a flag --debug. Não se preocupe com mensagens de certas falhas de regras; isso é resultado do solucionador do problema da parada tentando encontrar uma solução ótima e válida.
Embora este guia introduza uma série de métodos para analisar senhas, reverter regras e gerar máscaras, existem vários outros truques que estão esperando para serem descobertos. Ficaria entusiasmado se você me contasse sobre algum uso incomum ou sugestões para qualquer uma das ferramentas abordadas.
Boas quebras!
-Peter