Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitLabGitLab/pfg666/dtls-fuzzer
FuzzingSegurança de Rede
GitLabpfg666/dtls-fuzzer

dtls-fuzzer

dtls-fuzzer é um fuzzer de estado de protocolo para implementações de servidor DTLS.

Ver Repositório
49há 5 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

dtls-fuzzer é uma ferramenta Java que realiza fuzzing de estado de protocolo de servidores DTLS. Mais concretamente, suporta as seguintes funcionalidades:

  1. dado um alfabeto, pode gerar automaticamente um modelo de uma implementação de servidor DTLS local;
  2. dado um teste (sequência de entradas) e um alfabeto, pode executar o teste numa implementação de servidor DTLS;
  3. pode executar uma tarefa de aprendizagem em lote, envolvendo múltiplas execuções de aprendizagem.

dtls-fuzzer utiliza TLS-Attacker para gerar/analisar mensagens DTLS, bem como para manter o estado. Para esse fim, TLS-Attacker foi estendido com suporte para DTLS. dtls-fuzzer depende da versão 3.0b do TLS-Attacker, uma versão que implementa a melhoria DTLS.

Conteúdo do artefato

O artefato contém:

  1. uma descrição da estrutura de ficheiros do dtls-fuzzer, incluindo código-fonte e dados experimentais consistentes com os apresentados no artigo;
  2. um guia passo a passo para avaliar o dtls-fuzzer numa SUT (System Under Test)/ implementação de servidor DTLS escolhida.

Estrutura de ficheiros do dtls-fuzzer

As pastas mais importantes no diretório raiz do dtls-fuzzer são:

  1. 'src', diretório que contém o código-fonte Java do dtls-fuzzer;
  2. 'examples', diretório que contém exemplos de alfabetos, testes, especificações (ou seja, modelos) e ficheiros de argumentos que podem ser fornecidos ao dtls-fuzzer para lançar experiências de aprendizagem. Os ficheiros neste diretório são usados como entradas para experiências de aprendizagem;
  3. 'experiments', diretório que contém dados relativos a experiências. Alguns destes dados também servem como entrada para experiências de aprendizagem. As pastas mais notáveis são:
    1. 'suts', com binários para SUTs Java. Estas SUTs são programas de servidor DTLS feitos à medida cujo código-fonte está disponível publicamente;
    2. 'patches', patches que foram aplicados a algumas SUTs (particularmente a utilitários) antes do código-fonte ser compilado. O objetivo principal destes patches foi prevenir comportamentos induzidos por temporização durante a aprendizagem, ativar/desativar funcionalidades na SUT e configurar parâmetros como a chave pré-partilhada;
    3. 'keystore', material de chave (por exemplo, pares de chaves pública-privada, Java keystores) usado durante a aprendizagem;
    4. 'results', resultados experimentais.

Resultados experimentais

'experiments/results' contém resultados experimentais, que são o principal resultado do trabalho. Em particular

  • 'all_ciphers' contém pastas de saída para todas as experiências executadas;
    • 'mapper' contém resultados experimentais que ajudam a justificar algumas das decisões do mapper (ver Secção 5.2)
  • 'included' contém pastas de saída para experiências convergentes (convergente significa que a aprendizagem gera com sucesso um modelo).
    • note que nem todas as experiências em 'all_ciphers' foram bem-sucedidas/terminaram com um modelo final (dizemos nesses casos que a aprendizagem não convergiu)

Pastas de saída

As pastas de saída são nomeadas com base na configuração da experiência, ou seja:

  • a SUT/implementação testada;
  • o alfabeto usado, em termos de algoritmos de troca de chaves cobertos, onde 'all' indica que todos os 4 algoritmos de troca de chaves foram usados;
  • quando aplicável, se a certificação do cliente era obrigatória (req), opcional (nreq) ou desativada (none);
  • o algoritmo de teste: random walk (rwalk) ou uma adaptação do mesmo (stests);
    • experiências que usam a adaptação não foram incluídas no artigo
  • opcionalmente, se as retransmissões foram incluídas/excluídas das saídas (incl ou excl).
    • retransmissões foram incluídas por defeito

Como exemplo, o nome da pasta 'jsse-12_rsa_cert_none_rwalk_incl' indica uma experiência na implementação JSSE 12 do DTLS, usando um alfabeto que inclui entradas para realizar handshakes RSA, a autenticação de certificado do cliente está desativada, o algoritmo de teste é random walk e as retransmissões estão incluídas.

Uma pasta de saída contém:

  • 'alphabet.xml', o alfabeto de entrada;
  • 'command.args', o ficheiro de argumentos usado que contém vários parâmetros da experiência, nomeadamente:
    • queries, o limite no número de testes random walk que precisam de passar para uma hipótese ser considerada final
    • equivalenceAlgorithms, algoritmos de teste baseados em modelo empregues
    • runWait e timeout, o timeout de início e de resposta respetivamente (abordamo-los mais tarde)
  • 'sul.config', configuração dependente da SUT para TLS-Attacker, a mesma configuração pode ser usada para executar traces de workflow na SUT usando apenas TLS-Attacker;
  • 'hyp[0-9]+.dot', hipóteses intermédias;
  • 'statistics.txt', estatísticas da experiência como o número total de testes, tempo de aprendizagem;
    • A Tabela 4 apresenta estes dados
  • 'nondet.log', registos de comportamento não determinístico encontrado;
  • 'learnedModel.dot', no caso de a aprendizagem ter convergido, o modelo aprendido (ou seja, hipótese final);
  • 'error.msg', uma mensagem de erro gerada no caso de a experiência ter falhado/a aprendizagem ter sido interrompida e, portanto, não convergir para um modelo final.
    • o principal culpado é o não determinismo relacionado com tempo (as mesmas entradas levam a resultados diferentes).

O avaliador pode verificar (por exemplo) que os resultados experimentais em 'included' correspondem aos apresentados na Tabela 4, ou que as configurações testadas na Tabela 2 também aparecem em 'all_ciphers'. Note que os modelos que aparecem no artigo foram o resultado de uma poda/trimagem significativa, enquanto que os modelos que aparecem nas pastas de saída não foram alterados.

Passos de avaliação do dtls-fuzzer

Para efeitos de avaliação do dtls-fuzzer é necessário realizar os seguintes passos:

  1. Garantir que os pré-requisitos são cumpridos
  2. Instalar o dtls-fuzzer
  3. Configurar a SUT
  4. Usar o dtls-fuzzer para gerar modelos para a SUT
  5. Analisar resultados

Esta secção de avaliação é seguida por um guia sobre como usar o dtls-fuzzer que introduz os seus principais casos de uso.

Garantir os pré-requisitos

dtls-fuzzer foi testado em distribuições Linux Ubuntu 18.04 e Debian 9. Deve funcionar em qualquer distribuição Linux recente. O suporte para outras plataformas não foi testado. Este guia assume que é utilizada uma distribuição baseada em Debian (que tem 'apt-get').

É necessária uma Máquina Virtual (VM) Java 8 JDK (Java Development Kit). A versão usada para executar experiências é a 1.8.0_222, embora versões posteriores do Java 8 também devam funcionar. Note que a ferramenta não compila em Java 9 ou posterior. Também dependemos do maven (o utilitário 'mvn') para gestão/implantação de dependências.

Recomendamos usar uma máquina suficientemente potente, caso contrário parâmetros de temporização sensíveis, como o tempo de espera de resposta, podem tornar-se demasiado baixos, causando saídas diferentes das obtidas no artigo. Pior ainda, podem fazer com que as experiências de aprendizagem falhem. As experiências originais foram executadas num servidor com muitos núcleos, no entanto, esperamos (embora não tenhamos testado exaustivamente) que a aprendizagem seja possível num desktop com processador i7. A aprendizagem também é possível em sistemas mais fracos se os parâmetros de temporização forem ajustados em conformidade. Finalmente, visualizar modelos .dot exportando-os para .pdf requer instalar a biblioteca graphviz. Assume-se que o utilitário 'dot' fornecido pelo graphviz está localizado no PATH do sistema.

Em suma, os pré-requisitos aconselhados são:

  • distribuição Linux recente, de preferência baseada em Debian
  • máquina desktop/servidor para reprodução de experiências/aprendizagem fiável
  • (>=) 4 GB de RAM
  • Java 8 JDK
  • maven
  • graphviz

Configurar o ambiente

Java 8 JDK

dtls-fuzzer requer Java 8 JDK (Java Development Kit). Se o Java não estiver instalado, instalamos a implementação OpenJDK (via 'apt-get' no Ubuntu), e podemos saltar o resto desta subsecção.

root@kitploit:~
> sudo apt-get install openjdk-8-jdk

Se uma versão do java estiver instalada, podemos verificar qual a versão executando:

root@kitploit:~
> java -version

O código de versão deve começar com 1.8 (por exemplo, 1.8.0_242), e a Máquina Virtual deve ser "Server VM" (indicando que o JDK completo está instalado, e não apenas o ambiente de execução). Se for o caso, terminámos com o Java. Se não for, podemos verificar se o Java 8 JDK está instalado na nossa plataforma mas não está selecionado atualmente, listando as VMs Java instaladas através de:

root@kitploit:~
> update-java-alternatives --list

Se o Java 8 JDK aparecer, podemos usar o mesmo comando para configurar o Java 8 JDK como implementação Java padrão.

root@kitploit:~
> sudo update-java-alternatives --set java-1.8.0-openjdk-amd64

Caso contrário, precisamos de realizar a instalação completa como mostrado no início. Infelizmente, 'update-java-alternatives' às vezes não é bem-sucedido, indicado por mensagens "error". Se tal caso surgir, podemos usar 'update-alternives' para configurar interativamente qual VM Java é selecionada por 'java' (interpretador) e 'javac' (compilador).

root@kitploit:~
> sudo update-alternatives --config java
> sudo update-alternatives --config javac

Outros

Com o Java 8 configurado, procedemos à instalação das outras dependências, maven, graphviz mais algumas dependências comuns da SUT. Em seguida, clonamos o repositório do dtls-fuzzer para uma pasta à escolha, fazendo checkout do branch artifact. Para terminar, tornamos essa pasta o nosso diretório atual.

root@kitploit:~
> sudo apt-get install maven graphviz autotools-dev automake libtool
> git clone  -b usenix20-artifact https://github.com/assist-project/dtls-fuzzer.git ~/dtls-fuzzer
> cd ~/dtls-fuzzer

Instalar o dtls-fuzzer

Primeiro executamos o script 'prepare.sh' que instala bibliotecas das quais dtls-fuzzer depende, nomeadamente dois .jars locais e TLS-Attacker 3.0b. Em seguida, instalamos a própria ferramenta. Os comandos resultantes num sistema POSIX serão:

root@kitploit:~
> bash prepare.sh
> mvn clean install

Após estes passos, um diretório chamado 'target' deve ter sido construído contendo 'dtls-fuzzer.jar'. Esta é a nossa biblioteca executável. A partir deste ponto assume-se que os comandos são executados a partir do diretório raiz do dtls-fuzzer.

Execução rápida

Suponha que queremos gerar um modelo para OpenSSL 1.1.1b usando apenas PSK (Pre-Shared Keys). Uma execução rápida do dtls-fuzzer é feita da seguinte forma.

Primeiro configuramos a SUT, o que é feito automaticamente por um script 'setup_sut.sh'.

root@kitploit:~
> bash setup_sut.sh openssl-1.1.1b

Em seguida, selecionamos um ficheiro de argumentos da pasta 'args/openssl-1.1.1b'. Notamos que existem vários ficheiros de argumentos para escolher, nomeadamente:

root@kitploit:~
learn_openssl-1.1.1b_all_cert_none_rwalk_incl  
learn_openssl-1.1.1b_all_cert_nreq_rwalk_incl  
learn_openssl-1.1.1b_all_cert_req_rwalk_incl  
learn_openssl-1.1.1b_psk_rwalk_incl

O ficheiro de argumentos de interesse é 'learn_openssl-1.1.1b_psk_rwalk_incl', pois o seu nome indica PSK. Assim, selecionamo-lo e executamos o fuzzer nele. Adicionalmente, limitamos o número de testes a 200, para encurtar o tempo de aprendizagem. Finalmente, para o OpenSSL, LD_LIBRARY_PATH tem de ser definido para o diretório da implementação ('suts/openssl-1.1.1b/'). Antes de executar a aprendizagem, podemos querer executar um teste simples para verificar se a nossa configuração está a funcionar. Um bom teste é simplesmente completar um handshake. Fornecemos o ficheiro de argumentos, juntamente com um teste correspondente de 'examples/tests' como parâmetro. Obtemos:

root@kitploit:~
>  LD_LIBRARY_PATH=suts/openssl-1.1.1b/ java -jar target/dtls-fuzzer.jar @args/openssl-1.1.1b/learn_openssl-1.1.1b_psk_rwalk_incl -test examples/tests/psk

Se tudo correr bem, o servidor deve ter imprimido "This is a hello message", uma mensagem que enviamos após completar o handshake. Sabendo que a nossa configuração funciona, podemos agora iniciar a aprendizagem executando:

root@kitploit:~
> LD_LIBRARY_PATH=suts/openssl-1.1.1b/ java -jar target/dtls-fuzzer.jar @args/openssl-1.1.1b/learn_openssl-1.1.1b_psk_rwalk_incl -queries 200

Notamos que foi criado um diretório de saída, 'output/openssl-1.1.1b_psk_rwalk_incl/' para a experiência. Podemos fazer 'ls' a este diretório para verificar o estado atual da experiência (o número de hipóteses geradas...).

root@kitploit:~
> ls output/openssl-1.1.1b_psk_rwalk_incl/

Quando as coisas correm bem

Se tudo correr bem, após 20-30 minutos, o diretório de saída deve conter um ficheiro 'learnedModel.dot'. Podemos visualizar o ficheiro usando o utilitário 'dot' do graphviz, exportando para .pdf e abrindo o .pdf com o nosso visualizador de .pdf favorito.

root@kitploit:~
> dot -Tpdf output/openssl-1.1.1b_psk_rwalk_incl/learnedModel.dot > output/openssl-1.1.1b_psk_rwalk_incl/learnedModel.pdf
> evince output/openssl-1.1.1b_psk_rwalk_incl/learnedModel.pdf

Finalmente, podemos usar 'trim_model.sh' para gerar uma versão melhor/mais simplificada do modelo. Isto pode ser feito da seguinte forma:

root@kitploit:~
> bash trim_model.sh --output output/openssl-1.1.1b_psk_rwalk_incl/nicerLearnedModel.dot output/openssl-1.1.1b_psk_rwalk_incl/learnedModel.dot 
> dot -Tpdf output/openssl-1.1.1b_psk_rwalk_incl/nicerLearnedModel.dot > output/openssl-1.1.1b_psk_rwalk_incl/nicerLearnedModel.pdf
> evince output/openssl-1.1.1b_psk_rwalk_incl/nicerLearnedModel.pdf

Podemos agora determinar a conformidade do sistema verificando o modelo em relação à especificação...

Quando as coisas correm mal

Ao fazer 'ls' do diretório de saída podemos encontrar 'error.msg'. Isso é um sinal de que a experiência falhou e a aprendizagem terminou abruptamente. Nesses casos, exibir o conteúdo revela a razão por detrás da falha.

root@kitploit:~
> cat output/openssl-1.1.1b_psk_rwalk_incl/error.msg

Note que a verificação de conformidade ainda pode ser realizada na última hipótese gerada, desde que as descobertas potenciais sejam validadas contra o sistema (como devem ser de qualquer forma).

Configurar a SUT

Fornecemos um script para configurar a SUT. Este script descarrega os ficheiros de origem, instala algumas dependências (jvm) e compila a SUT. Para ver as SUTs para as quais é fornecida configuração automática, execute:

root@kitploit:~
> bash setup_sut.sh

Para configurar, por exemplo, a implementação tinydtls do Contiki-NG, execute:

root@kitploit:~
> bash setup_sut.sh ctinydtls

O script irá gerar duas pastas no diretório raiz do dtls-fuzzer.

  • 'suts', onde os binários da SUT são implantados
  • 'modules', onde quaisquer dependências são implantadas

Infelizmente, automatizar a configuração da SUT é um processo complicado, por isso tomamos os seguintes atalhos. Para SUTs Java (JSSE, Scandium) não compilamos as implementações, em vez disso usamos os .jars compilados do diretório 'experiments/suts'. Note que o código-fonte destas SUTs Java (aplicações servidoras) está disponível publicamente online, veja Scandium e JSSE, o que também é o caso do PionDTLS. A instalação automática de dependências pode solicitar acesso 'sudo'. Isto acontece para o GnuTLS que depende de bibliotecas externas como nettle, e para o TinyDTLS da Eclipse, que depende de autoconf. Finalmente, não fornecemos configuração automática/ficheiros de argumentos para NSS e PionDTLS devido à complexidade da configuração destes sistemas.

Resolução de problemas

Se algo no processo de configuração parar de funcionar, eliminar a pasta 'suts' (ou a pasta 'suts/SUT' específica da SUT) e reexecutar o script de configuração pode resolver o problema. Além disso, em caso de falha na compilação, o código-fonte da implementação ainda deve ser descarregado para o diretório 'suts'. Uma solução alternativa é compilar a implementação manualmente. Desde que a implementação seja compilada, a nossa configuração deve funcionar.

Fornecemos aqui uma árvore incompleta de dependências que as várias SUTs têm. As que estão em itálico são dependências que 'setup_sut.sh' tenta instalar usando acesso 'sudo'.

  • GnuTLS:
    • m4
    • pkg-config
    • nettle
  • Eclipse's TinyDTLS
    • m4
    • autoconf
  • WolfSSL
    • m4
    • autoconf
    • libtool
  • nettle
    • m4
    • pkg-config
  • autoconf
    • aclocal
      • automake
      • autotools-dev

Aprender uma configuração de SUT

Estamos agora prontos para aprender uma configuração de SUT. Ficheiros de argumentos para várias configurações de SUT são fornecidos no diretório 'args' localizado no diretório base do dtls-fuzzer. Cada nome de ficheiro de argumentos descreve a configuração da experiência (SUT, alfabeto, autenticação) conforme descrito pelos nomes das pastas de saída em 'experiments/results/'. Para iniciar a aprendizagem para uma SUT usando um ficheiro de argumentos, execute:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/sut_name/arg_file

A pasta de saída será armazenada num diretório 'output' gerado.

Adaptações de parâmetros

Limite de testes

Comparado com as experiências no artigo, aumentámos o timeout de resposta para várias SUTs como adaptação a hardware menos potente. Para encurtar o tempo de aprendizagem, sugerimos diminuir o limite de testes do algoritmo random walk de 20000 para 5000. Isto pode ser feito com:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/sut_name/arg_file -queries 5000

Isto irá sobrescrever a definição de limite no ficheiro de argumentos. Exceto para GnuTLS, PionDTLS e JSSE, esperamos que a aprendizagem produza os mesmos modelos para este limite mais baixo.

Parâmetros de temporização

A temporização pode tornar-se um problema, causando não determinismo, seguido de terminação abrupta com um ficheiro 'error.msg' informativo. Nesses casos, existem dois parâmetros que podem ser ajustados:

  1. o response timeout (tempo esperado por cada resposta antes de concluir que o servidor está silencioso);
  2. o start timeout (tempo esperado para o servidor iniciar).

Estes parâmetros podem ser ajustados sobrescrevendo (provavelmente com um valor mais alto) as definições correspondentes no ficheiro de argumentos:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/sut_name/arg_file -timeout new_response_timeout -runWait new_start_timeout

Para evitar problemas relacionados com temporização, sugerimos executar experiências numa máquina suficientemente potente. A principal causa de não determinismo é a SUT demorar muito tempo a iniciar ou a gerar uma resposta. Esta probabilidade diminui à medida que mais poder computacional é fornecido.

Tempo de aprendizagem

Podemos desejar terminar automaticamente as experiências após um certo período, particularmente experiências que não se espera que terminem. Definir este período é possível através do parâmetro time limit ao qual é atribuída a duração máxima que a experiência pode decorrer. Esta duração é fornecida no formato ISO 8601. Para limitar o tempo de execução de uma experiência a 60 minutos, executaríamos:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/sut_name/arg_file -timeLimit "PT60M"

Experiências concorrentes e colisões de portas

É possível executar múltiplas experiências ao mesmo tempo desde que os servidores estejam configurados para ouvir em portas diferentes. Podemos escolher lançar cada experiência num terminal separado. Alternativamente, podemos lançar experiências num único terminal usando o utilitário 'disown':

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/ctinydtls/learn_ctinydtls_psk_rwalk 1>/dev/null 2>&1 & disown

No entanto, executar mais do que algumas (>2) coloca uma carga adicional na máquina. Também aumenta a probabilidade de falha na aprendizagem devido a colisão acidental de portas. Na maioria das configurações, os servidores estão configurados para ouvir numa porta hard-coded através de localhost, as configurações fornecidas em 'args' usam portas hard-coded distintas. Para configurações JSSE e Scandium, a configuração é diferente. Em cada teste, a SUT lança um servidor a ouvir numa porta escolhida dinamicamente e comunica a porta através de sockets TCP para o dtls-fuzzer. Isto tem a vantagem de notificar o dtls-fuzzer quando o servidor está pronto para receber pacotes (sem isso, o dtls-fuzzer teria de esperar cegamente um período arbitrário de tempo para o servidor iniciar). A desvantagem é que a porta alocada pode ser a mesma que alguma porta hard-coded de uma experiência diferente, onde uma thread de servidor foi recentemente parada e uma nova thread ainda não foi iniciada (significando que a porta hard-coded poderia ser usada na alocação dinâmica). Para evitar esta forma de colisão, aconselhamos executar experiências Scandium e JSSE separadamente de todas as outras.

Configurações sugeridas

Sugerimos as seguintes configurações para as quais a compilação automática é fiável, a aprendizagem é mais rápida ou foram encontrados bugs interessantes. Certifique-se de que configura a SUT antes de executar o comando fornecido. Notará que nos concentramos em configurações PSK sempre que possível. Isso deve-se ao facto de PSK com palavras-passe pequenas exigir significativamente menos tempo de processamento do que qualquer outro mecanismo de encriptação.### OpenSSL 1.1.1b Qualquer configuração do openssl-1.1.1b (por exemplo 'args/openssl-1.1.1b/learn_openssl-1.1.1b_all_cert_req_rwalk_incl') pode ser experimentada. Os experimentos terminam rapidamente (menos de um dia), exercitando todos os algoritmos de troca de chaves. Comando para configuração que exige certificado do cliente usando todos os algoritmos de troca de chaves (PSK, RSA, ECDH, DH):

root@kitploit:~
> LD_LIBRARY_PATH=suts/openssl-1.1.1b/ java -jar target/dtls-fuzzer.jar @args/openssl-1.1.1b/learn_openssl-1.1.1b_all_cert_req_rwalk_incl -queries 5000

Nota: ao aprender o OpenSSL, é necessário apontar a variável LD_LIBRARY_PATH para o diretório de instalação.

MbedTLS 2.16.1

Qualquer configuração do mbedtls-2.16.1 pode ser usada pelas mesmas razões que o OpenSSL. Os experimentos levam mais tempo para concluir, pois o SUT é mais lento. Comando para configuração com autenticação de certificado do cliente desativada usando todos os algoritmos de troca de chaves:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/mbedtls-2.16.1/learn_mbedtls_all_cert_none_rwalk_incl -queries 5000

Contiki-NG TinyDTLS usando PSK

Uma versão editada do modelo obtido para esta configuração aparece no apêndice. Podemos usar um limite baixo de testes de 2000, já que o alfabeto de entrada é pequeno, facilitando os testes.

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/ctinydtls/learn_ctinydtls_psk_rwalk -queries 2000

WolfSSL 4.0.0 usando PSK

Para o WolfSSL, fornecemos uma configuração PSK para a qual o aprendizado deve terminar relativamente rápido.

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/wolfssl-4.0.0/learn_wolfssl-4.0.0_psk_rwalk -queries 2000

GnuTLS 3.6.7 com autenticação do cliente desativada

A versão mais recente do GnuTLS que analisamos produziu modelos compactos e agradáveis. Infelizmente, ativar a autenticação do cliente levou a um aumento acentuado no número de testes necessários. Sugerimos uma configuração que a desative para reduzir o tempo de aprendizado:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/gnutls-3.6.7/learn_gnutls-3.6.7_all_cert_none_rwalk_incl -queries 2000

Scandium PSK (antes das correções de bugs)

Uma versão editada do modelo obtido para esta configuração aparece no artigo. O modelo expõe bugs importantes, infelizmente, o experimento é demorado. O experimento não deve ser executado em paralelo com experimentos que não envolvam Scandium ou JSSE. Comando:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/scandium-2.0.0/learn_scandium-2.0.0_psk_rwalk -queries 2000

JSSE 12.0.2 com autenticação exigida

Uma versão editada do modelo obtido para esta configuração aparece no artigo. O modelo expõe bugs importantes. O experimento não deve ser executado em paralelo com experimentos que não envolvam Scandium ou JSSE. Note que o aprendizado para JSSE não termina/converge, construindo hipóteses com cada vez mais estados. Portanto, configuramos os experimentos JSSE para terminar automaticamente após um dia (dois dias no artigo). Comando para troca de chaves RSA:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/jsse-12/learn_jsse-12_rsa_cert_req_rwalk_incl 

Em vez de um aprendizado árduo, podemos querer simplesmente testar se um handshake pode ser concluído neste cenário sem enviar nenhuma mensagem de certificado. Isso pode ser feito executando:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @args/jsse-12/learn_jsse-12_rsa_cert_req_rwalk_incl -test examples/tests/rsa

Analisando resultados

Uma vez que o aprendizado é concluído, as coisas a analisar no diretório de saída são:

  • 'statistics.txt', estatísticas do experimento, como número total de testes, tempo de aprendizado;
  • 'nondet.log', logs de comportamento não determinístico encontrado; se tudo correu bem, deve estar vazio;
  • 'learnedModel.dot', o modelo aprendido (ou hipótese final) gerado ao terminar com sucesso;
  • 'hyp[0-9]+.dot', hipóteses intermediárias;
  • 'error.msg', caso algo ruim tenha acontecido fazendo o aprendizado parar. Também gerado se o experimento de aprendizado expirar.

Visualizando o modelo

O modelo aprendido em .dot pode ser visualizado usando a biblioteca graphviz, convertendo para .pdf:

root@kitploit:~
> dot -Tpdf learnedModel.dot  > learnedModel.pdf

Infelizmente, à medida que os modelos crescem em tamanho, os .pdfs gerados por este método tornam-se cada vez mais difíceis de ler. Por isso, desenvolvemos/usamos/importamos scripts de poda que são acessados por 'trim_model.sh'. O script fornece informações de uso executando:

root@kitploit:~
> bash trim_model.sh

Recomendamos usar o script em sua forma mais básica, que é:

root@kitploit:~
> bash trim_model.sh learnedModel.dot 

O script:

  1. compactifica estados e rótulos de entrada/saída
  2. colore caminhos que levam à conclusão do handshake
    • o usuário deve então determinar se os handshakes são legais dada a configuração
  3. mescla grupos de 3 ou mais transições conectando os mesmos estados, e tendo as mesmas saídas mas entradas diferentes, sob a entrada 'Other'
  4. (opcionalmente) poda estados a partir dos quais um handshake não pode mais ser concluído (particularmente útil para JSSE)
  5. (opcionalmente) posiciona transições conectando os mesmos estados em uma única aresta

(5) requer a instalação da biblioteca mypydot Python 3 personalizada encontrada em 'experiments\scripts'. Todos os outros passos usam 'sed' simples mais a biblioteca Java dot-trimmer. Um .jar para esta biblioteca está incluído em 'experiments\scripts'.

Guia geral do dtls-fuzzer

Exibindo página de ajuda

Execute:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar -help

Aprendendo implementações DTLS

O número de opções pode ser assustador. Para aprender uma implementação de servidor DTLS, você só precisa especificar algumas opções, a saber: "-connect ip_address:port" que é o endereço onde o servidor DTLS em execução está escutando. Todas as outras opções são definidas com valores padrão, incluindo o alfabeto.

Execução de aprendizado único

Para lançar uma execução de aprendizado para uma implementação de servidor local existente, digamos, escutando na porta 20000, execute:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar -connect localhost:20000

Provavelmente haverá problemas com este tipo de aprendizado. O aprendizado exige que seja possível reiniciar o servidor após cada teste. Alguns servidores carregarão algum estado de um teste para outro. Isso pode levar a não-determinismo durante o aprendizado, portanto, uma abordagem melhor é lançar uma nova thread do servidor em cada teste usando um comando fornecido. A thread do servidor é encerrada assim que o teste é executado, garantindo a reinicialização adequada. Exemplo para OpenSSL:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -cmd "openssl s_server -accept 20000 -dtls1_2"

Com tantos parâmetros, os comandos podem se tornar muito longos. dtls-fuzzer usa JCommander para analisar argumentos, que também pode ler parâmetros de um arquivo. Vá para 'experiments/args' para exemplos de argumentos. Para fornecer um arquivo de argumentos para dtls-fuzzer, forneça-o como parâmetro precedido por "@". Você também pode adicionar outros argumentos explícitos aos comandos (que sobrescreverão os do arquivo de argumentos)

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @arg_file ...parâmetros sobrescritos...

Aprendizado em lote

Para lançar um lote de execuções de aprendizado, pode-se usar o script 'launcher.py' em 'experiments/scripts'. Fornecido um diretório com arquivos de argumentos, a ferramenta lançará um processo de aprendizado para cada arquivo de argumento.

root@kitploit:~
> python3 experiments/scripts/launcher.py --jar target/dtls-fuzzer.jar --args args_folder

Executando um conjunto de testes

Antes de executar experimentos de aprendizado, é útil verificar se os argumentos estão configurados corretamente, especialmente os parâmetros de temporização. Para isso, dtls-fuzzerr pode executar um conjunto de testes personalizado (coleção de testes) no SUT e fornecer um resumo das saídas. Essa funcionalidade também pode ser usada ao diagnosticar experimentos de aprendizado com falha, ou seja, descobrir o que deu errado.

Para executar o conjunto de testes em um servidor usando o alfabeto padrão, execute:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -test test_file

Para exemplos de arquivos de teste, vá para 'examples/tests'. Um arquivo de teste consiste em uma lista de entradas separadas por nova linha. Os testes são separados por linhas novas vazias. O final de cada teste é o final do arquivo ou uma linha nova vazia. "#" é usado para comentar uma linha.

Se você tem um modelo/especificação, também pode executar o conjunto de testes e comparar a saída com a da especificação.

root@kitploit:~
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -test test_file -specification model

O número de vezes que os testes são executados é configurável pelo parâmetro '-times', que padrão é 1. Definir um número alto ajuda a detectar não-determinismo nas configurações de aprendizado, comparando a saída de cada teste.

root@kitploit:~
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -test test_file -times 10

Finalmente, se você tiver o arquivo de argumentos para um experimento de aprendizado, pode usá-los para executar testes no SUT envolvido apenas adicionando os argumentos de teste necessários:

root@kitploit:~
> java -jar target/dtls-fuzzer.jar @learning_arg_file -test test_file
Baixar ferramenta