
dtls-fuzzer es un fuzzer de estado de protocolo para implementaciones de servidores DTLS.
dtls-fuzzer es una herramienta Java que realiza pruebas de estado de protocolo mediante fuzzing en servidores DTLS. Más concretamente, soporta las siguientes funcionalidades:
dtls-fuzzer utiliza TLS-Attacker para generar/analizar mensajes DTLS, así como para mantener el estado. Con ese fin, TLS-Attacker ha sido extendido con soporte para DTLS. dtls-fuzzer se basa en la versión 3.0b de TLS-Attacker, una versión que implementa la mejora de DTLS.
El artefacto contiene:
Las carpetas más importantes en el directorio raíz de dtls-fuzzer son:
‘experiments/results’ contiene los resultados experimentales, que son la salida principal del trabajo. En particular:
Las carpetas de salida se nombran según la configuración del experimento, es decir:
Como ejemplo, el nombre de carpeta ‘jsse-12_rsa_cert_none_rwalk_incl’ indica un experimento en la implementación JSSE 12 de DTLS, utilizando un alfabeto que incluye entradas para realizar handshakes RSA, la autenticación de certificado del cliente está deshabilitada, el algoritmo de prueba es recorrido aleatorio y las retransmisiones están incluidas.
Una carpeta de salida contiene:
El evaluador puede verificar (por ejemplo) que los resultados experimentales en ‘included’ correspondan a los mostrados en la Tabla 4, o que las configuraciones probadas en la Tabla 2 también aparezcan en ‘all_ciphers’. Tenga en cuenta que los modelos que aparecen en el artículo fueron el resultado de una poda/recorte significativo, mientras que los modelos que aparecen en las carpetas de salida no están alterados.
Con el propósito de evaluar dtls-fuzzer es necesario realizar los siguientes pasos:
Esta sección de evaluación es seguida por una guía sobre el uso de dtls-fuzzer que introduce sus principales casos de uso.
dtls-fuzzer ha sido probado en Ubuntu 18.04 y Debian 9 distribuciones de Linux. Debería funcionar en cualquier distribución reciente de Linux. No se ha probado el soporte para otras plataformas. Esta guía asume que se utiliza una distribución basada en Debian (que tiene 'apt-get').
Se requiere una Máquina Virtual (VM) Java 8 JDK (Kit de Desarrollo Java). La versión utilizada para ejecutar experimentos es 1.8.0_222, aunque versiones posteriores de Java 8 también deberían funcionar. Tenga en cuenta que la herramienta no compila en Java 9 o posterior. También confiamos en maven (la utilidad 'mvn') para la gestión/implementación de dependencias.
Recomendamos usar una máquina suficientemente potente; de lo contrario, parámetros de temporización sensibles como el tiempo de espera de respuesta podrían volverse demasiado bajos, causando salidas diferentes a las obtenidas en el artículo. Peor aún, pueden causar que los experimentos de aprendizaje fallen. Los experimentos originales se ejecutaron en un servidor con muchos núcleos; sin embargo, esperamos (aunque no lo hemos probado a fondo) que el aprendizaje debería ser posible en un escritorio con un procesador i7. El aprendizaje también es posible en sistemas más débiles si los parámetros de temporización se ajustan en consecuencia. Finalmente, visualizar modelos .dot exportándolos a .pdf requiere instalar la biblioteca graphviz. Se asume que la utilidad 'dot' proporcionada por graphviz se encuentra en el PATH del sistema.
En resumen, los prerrequisitos recomendados son:
dtls-fuzzer requiere Java 8 JDK (Kit de Desarrollo Java). Si Java no está instalado, instalamos la implementación OpenJDK (a través de 'apt-get' en Ubuntu), y podemos saltarnos el resto de esta subsección.
> sudo apt-get install openjdk-8-jdk
Si una versión de Java está instalada, podemos verificar qué versión es ejecutando:
> java -version
El código de versión debe comenzar con 1.8 (por ejemplo, 1.8.0_242), y la Máquina Virtual debe ser "Server VM" (indicando que el JDK completo está instalado, en lugar de solo el entorno de ejecución). Si es así, hemos terminado con Java. Si no, podemos verificar si Java 8 JDK está instalado en nuestra plataforma pero no está seleccionado actualmente, listando las máquinas virtuales Java instaladas mediante:
> update-java-alternatives --list
Si Java 8 JDK aparece, podemos usar el mismo comando para configurar Java 8 JDK como la implementación Java predeterminada.
> sudo update-java-alternatives --set java-1.8.0-openjdk-amd64
De lo contrario, necesitamos realizar la instalación completa como se muestra al principio. Desafortunadamente, 'update-java-alternatives' a veces no tiene éxito, indicado por mensajes de "error". Si surge tal caso, podemos usar 'update-alternatives' para configurar interactivamente qué máquina virtual Java es seleccionada por 'java' (intérprete) y 'javac' (compilador).
> sudo update-alternatives --config java
> sudo update-alternatives --config javac
Con Java 8 configurado, procedemos a instalar las otras dependencias, maven, graphviz más algunas dependencias comunes del SUT. Luego clonamos el repositorio de dtls-fuzzer en una carpeta de nuestra elección, verificando la rama del artefacto. Para terminar, hacemos de esa carpeta nuestro directorio actual.
> 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
Primero ejecutamos el script 'prepare.sh' que instala las bibliotecas de las que depende dtls-fuzzer, a saber, dos .jars locales y TLS-Attacker 3.0b. Luego instalamos la herramienta en sí. Los comandos resultantes en un sistema POSIX serán:
> bash prepare.sh
> mvn clean install
Siguiendo estos pasos, se debería haber creado un directorio llamado 'target' que contiene 'dtls-fuzzer.jar'. Esta es nuestra biblioteca ejecutable. A partir de este punto se asume que los comandos se ejecutan desde el directorio raíz de dtls-fuzzer.
Supongamos que queremos generar un modelo para OpenSSL 1.1.1b usando solo PSK (Claves Precompartidas). Una ejecución rápida de dtls-fuzzer es la siguiente.
Primero configuramos el SUT, lo cual se hace automáticamente mediante un script 'setup_sut.sh'.
> bash setup_sut.sh openssl-1.1.1b
Luego seleccionamos un archivo de argumentos de la carpeta 'args/openssl-1.1.1b'. Observamos que hay varios archivos de argumentos para elegir, a saber:
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
El archivo de argumentos de interés es 'learn_openssl-1.1.1b_psk_rwalk_incl', ya que su nombre indica PSK. Por lo tanto, lo seleccionamos y ejecutamos el fuzzer sobre él. Además, limitamos el número de pruebas a 200, para acortar el tiempo de aprendizaje. Finalmente, para OpenSSL, LD_LIBRARY_PATH debe establecerse en el directorio de la implementación ('suts/openssl-1.1.1b/'). Antes de ejecutar el aprendizaje, quizás queramos ejecutar una prueba simple para verificar que nuestra configuración funciona. Una buena prueba es simplemente completar un handshake. Proporcionamos el archivo de argumentos, junto con una prueba correspondiente de 'examples/tests' como parámetro. Obtenemos:
> 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
Si todo va bien, el servidor debería haber impreso "This is a hello message", un mensaje que enviamos después de completar el handshake. Sabiendo que nuestra configuración funciona, ahora podemos iniciar el aprendizaje ejecutando:
> 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 se ha creado un directorio de salida, 'output/openssl-1.1.1b_psk_rwalk_incl/' para el experimento. Podemos hacer 'ls' en este directorio para verificar el estado actual del experimento (el número de hipótesis generadas...).
> ls output/openssl-1.1.1b_psk_rwalk_incl/
Si todo va bien, después de 20-30 minutos, el directorio de salida debería contener un archivo 'learnedModel.dot'. Podemos visualizar el archivo usando la utilidad 'dot' de graphviz, exportándolo a .pdf y abriendo el .pdf con nuestro visor de .pdf favorito.
> 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 generar una versión mejor/recortada del modelo. Esto se puede hacer de la siguiente manera:
> 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
Ahora podemos determinar la conformidad del sistema verificando el modelo contra la especificación...
Al hacer 'ls' en el directorio de salida, podríamos encontrar 'error.msg'. Eso es una señal de que el experimento falló y el aprendizaje terminó abruptamente. En tales casos, mostrar el contenido revela la razón detrás del fallo.
> cat output/openssl-1.1.1b_psk_rwalk_incl/error.msg
Tenga en cuenta que aún se puede verificar la conformidad en la última hipótesis generada, siempre que los hallazgos potenciales sean validados contra el sistema (como deberían ser de todos modos).
Proporcionamos un script para configurar el SUT. Este script descarga los archivos fuente, instala algunas dependencias (jvm) y construye el SUT. Para ver los SUTs para los cuales se proporciona configuración automática, ejecute:
> bash setup_sut.sh
Para configurar, por ejemplo, la implementación tinydtls de Contiki-NG, ejecute:
> bash setup_sut.sh ctinydtls
El script generará dos carpetas en el directorio raíz de dtls-fuzzer.
Desafortunadamente, automatizar la configuración del SUT es un proceso complicado, por lo que tomamos los siguientes atajos. Para SUTs Java (JSSE, Scandium) no construimos las implementaciones, en su lugar usamos los .jars compilados del directorio 'experimentos/suts'. Tenga en cuenta que el código fuente de estos SUTs Java (aplicaciones servidor) está disponible públicamente en línea, ver Scandium y JSSE, que también es el caso de PionDTLS. La instalación automática de dependencias puede solicitar acceso 'sudo'. Esto ocurre para GnuTLS, que depende de bibliotecas externas como nettle, y para TinyDTLS de Eclipse, que depende de autoconf. Finalmente, no proporcionamos configuración automática/archivos de argumentos para NSS y PionDTLS debido a lo complicado que es la configuración para estos sistemas.
Si las cosas en el proceso de configuración dejan de funcionar, eliminar la carpeta 'suts' (o la carpeta 'suts/SUT' específica del SUT) y volver a ejecutar el script de configuración puede resolver el problema. Además, en caso de fallo de construcción, el código fuente de la implementación aún debería estar descargado en el directorio 'suts'. Una solución alternativa es construir la implementación manualmente. Siempre que la implementación esté construida, nuestra configuración debería funcionar.
Por la presente damos un árbol incompleto de dependencias que tienen los diversos SUTs. Aquellas en cursiva son dependencias que 'setup_sut.sh' intenta instalar usando acceso 'sudo'.
Ahora estamos listos para aprender una configuración de SUT. Se proporcionan archivos de argumentos para varias configuraciones de SUT en el directorio 'args' ubicado en el directorio principal de dtls-fuzzer. Cada nombre de archivo de argumentos describe la configuración del experimento (SUT, alfabeto, autenticación) como se describe por los nombres de las carpetas de salida en 'experiments/results/'. Para iniciar el aprendizaje para un SUT usando un archivo de argumentos, ejecute:
> java -jar target/dtls-fuzzer.jar @args/nombre_sut/archivo_arg
La carpeta de salida se almacenará en un directorio 'output' generado.
En comparación con los experimentos del artículo, aumentamos el tiempo de espera de respuesta para varios SUTs como adaptación a hardware menos potente. Para acortar el tiempo de aprendizaje, sugerimos disminuir el límite de pruebas del algoritmo de recorrido aleatorio de 20000 a 5000. Esto se puede hacer mediante:
> java -jar target/dtls-fuzzer.jar @args/nombre_sut/archivo_arg -queries 5000
Esto sobrescribirá la configuración del límite en el archivo de argumentos. Excepto para GnuTLS, PionDTLS y JSSE, esperamos que el aprendizaje produzca los mismos modelos para este límite inferior.
El tiempo puede convertirse en un problema, causando no determinismo, seguido de una terminación abrupta con un archivo 'error.msg' informativo. En tales casos, hay dos parámetros que se pueden ajustar:
Estos parámetros se pueden ajustar sobrescribiendo (probablemente con un valor más alto) las configuraciones correspondientes en el archivo de argumentos:
> java -jar target/dtls-fuzzer.jar @args/nombre_sut/archivo_arg -timeout nuevo_tiempo_espera_respuesta -runWait nuevo_tiempo_espera_inicio
Para evitar problemas relacionados con la temporización, sugerimos ejecutar experimentos en una máquina suficientemente potente. La causa principal del no determinismo es que el SUT tarde demasiado en iniciar o generar una respuesta. Esta probabilidad disminuye a medida que se proporciona más potencia de cálculo.
Podemos desear terminar automáticamente los experimentos después de un cierto período, particularmente experimentos que no se espera que terminen nunca. Establecer este período es posible a través del parámetro límite de tiempo al que se le asigna la duración máxima que se permite que se ejecute el experimento. Esta duración se proporciona en formato ISO 8601. Para limitar el tiempo de ejecución de un experimento a 60 minutos, ejecutaríamos:
> java -jar target/dtls-fuzzer.jar @args/nombre_sut/archivo_arg -timeLimit "PT60M"
Es posible ejecutar múltiples experimentos a la vez siempre que los servidores estén configurados para escuchar en diferentes puertos. Podemos optar por lanzar cada experimento en una terminal separada. Alternativamente, podemos lanzar experimentos en una sola terminal usando la utilidad 'disown':
> java -jar target/dtls-fuzzer.jar @args/ctinydtls/learn_ctinydtls_psk_rwalk 1>/dev/null 2>&1 & disown
Sin embargo, ejecutar más de unos pocos (>2) pone una carga adicional en la máquina. También aumenta la probabilidad de fallo de aprendizaje debido a una colisión accidental de puertos. En la mayoría de las configuraciones, los servidores están configurados para escuchar en algún puerto fijo a través de localhost, las configuraciones proporcionadas en 'args' usan puertos fijos distintos. Para configuraciones JSSE y Scandium, la configuración es diferente. En cada prueba, el SUT lanza un servidor escuchando en un puerto elegido dinámicamente y comunica el puerto a través de sockets TCP a dtls-fuzzer. Esto tiene la ventaja de notificar a dtls-fuzzer cuando el servidor está listo para recibir paquetes (careciendo de esto, dtls-fuzzer tendría que esperar ciegamente una cantidad arbitraria de tiempo para que el servidor se inicie). La desventaja es que el puerto asignado podría ser el mismo que algún puerto fijo de un experimento diferente, en el que un hilo del servidor se ha detenido recientemente y no se ha iniciado un nuevo hilo aún (lo que significa que el puerto fijo podría ser utilizado en la asignación dinámica). Para evitar esta forma de colisión, recomendamos ejecutar experimentos de Scandium y JSSE por separado de todos los demás.
Sugerimos las siguientes configuraciones para las cuales la construcción automática es confiable, el aprendizaje es más rápido o se han encontrado errores interesantes. Asegúrese de configurar el SUT antes de ejecutar el comando proporcionado. Notará que nos centramos en configuraciones PSK cuando sea posible. Esto se debe a que PSK con contraseñas pequeñas requiere significativamente menos tiempo de procesamiento que cualquier otro mecanismo de cifrado.### OpenSSL 1.1.1b Cualquier configuración de openssl-1.1.1b (por ejemplo, 'args/openssl-1.1.1b/learn_openssl-1.1.1b_all_cert_req_rwalk_incl') puede probarse. Los experimentos terminan rápidamente (menos de un día), ejercitando todos los algoritmos de intercambio de claves. Comando para la configuración que requiere certificado de cliente usando todos los algoritmos de intercambio de claves (PSK, RSA, ECDH, DH):
> 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: al aprender OpenSSL es necesario apuntar la variable LD_LIBRARY_PATH al directorio de instalación.
Cualquier configuración de mbedtls-2.16.1 puede usarse por las mismas razones que OpenSSL. Los experimentos tardan más en completarse ya que el SUT es más lento. Comando para la configuración con autenticación de certificado de cliente deshabilitada usando todos los algoritmos de intercambio de claves:
> java -jar target/dtls-fuzzer.jar @args/mbedtls-2.16.1/learn_mbedtls_all_cert_none_rwalk_incl -queries 5000
En el apéndice aparece una versión editada del modelo obtenido para esta configuración. Podemos usar un límite de pruebas bajo de 2000 ya que el alfabeto de entrada es pequeño, facilitando las pruebas.
> java -jar target/dtls-fuzzer.jar @args/ctinydtls/learn_ctinydtls_psk_rwalk -queries 2000
Para WolfSSL proporcionamos una configuración PSK para la cual el aprendizaje debería terminar relativamente rápido.
> java -jar target/dtls-fuzzer.jar @args/wolfssl-4.0.0/learn_wolfssl-4.0.0_psk_rwalk -queries 2000
La versión más reciente de GnuTLS que analizamos produjo modelos compactos y agradables. Desafortunadamente, habilitar la autenticación de cliente provocó un fuerte aumento en el número de pruebas requeridas. Sugerimos una configuración que la deshabilite para acortar el tiempo de aprendizaje:
> java -jar target/dtls-fuzzer.jar @args/gnutls-3.6.7/learn_gnutls-3.6.7_all_cert_none_rwalk_incl -queries 2000
En el artículo aparece una versión editada del modelo obtenido para esta configuración. El modelo expone errores importantes; desafortunadamente, el experimento es largo. El experimento no debe ejecutarse en paralelo con experimentos que no involucren Scandium o JSSE. Comando:
> java -jar target/dtls-fuzzer.jar @args/scandium-2.0.0/learn_scandium-2.0.0_psk_rwalk -queries 2000
En el artículo aparece una versión editada del modelo obtenido para esta configuración. El modelo expone errores importantes. El experimento no debe ejecutarse en paralelo con experimentos que no involucren Scandium o JSSE. Tenga en cuenta que el aprendizaje para JSSE no finaliza/converge, construyendo hipótesis con cada vez más estados. Por lo tanto, configuramos los experimentos de JSSE para que terminen automáticamente después de un día (dos días en el artículo). Comando para intercambio de claves RSA:
> java -jar target/dtls-fuzzer.jar @args/jsse-12/learn_jsse-12_rsa_cert_req_rwalk_incl
En lugar de un aprendizaje arduo, es posible que simplemente queramos probar si se puede completar un handshake en esta configuración sin enviar ningún mensaje de certificado. Esto se puede hacer ejecutando:
> java -jar target/dtls-fuzzer.jar @args/jsse-12/learn_jsse-12_rsa_cert_req_rwalk_incl -test examples/tests/rsa
Una vez finalizado el aprendizaje, los elementos a analizar en el directorio de salida son:
El modelo aprendido en formato .dot se puede visualizar usando la biblioteca graphviz, mediante conversión a .pdf:
> dot -Tpdf learnedModel.dot > learnedModel.pdf
Desafortunadamente, a medida que los modelos crecen en tamaño, los .pdf generados con este método se vuelven cada vez más difíciles de leer. Por ello, desarrollamos/utilizamos/importamos scripts de poda a los que se accede mediante 'trim_model.sh'. El script proporciona información de uso ejecutando:
> bash trim_model.sh
Recomendamos usar el script en su forma más básica, que es:
> bash trim_model.sh learnedModel.dot
El script:
(5) requiere instalar la biblioteca personalizada mypydot Python 3 que se encuentra en 'experiments\scripts'. Todos los demás pasos usan 'sed' simple más la biblioteca Java dot-trimmer. Se incluye un .jar para esta biblioteca en 'experiments\scripts'.
Ejecute:
> java -jar target/dtls-fuzzer.jar -help
La cantidad de opciones puede ser abrumadora. Para aprender una implementación de servidor DTLS, solo es necesario especificar algunas opciones, a saber: "-connect ip_address:port", que es la dirección donde el servidor DTLS en ejecución está escuchando. Todas las demás opciones se establecen en valores predeterminados, incluido el alfabeto.
Para lanzar una ejecución de aprendizaje para una implementación de servidor local existente, por ejemplo, escuchando en el puerto 20000, ejecute:
> java -jar target/dtls-fuzzer.jar -connect localhost:20000
Probablemente habrá problemas con este tipo de aprendizaje. El aprendizaje requiere que sea posible reiniciar el servidor después de cada prueba. Algunos servidores mantendrán cierto estado de una prueba a otra. Esto puede provocar no determinismo durante el aprendizaje, por lo que un mejor enfoque es lanzar un nuevo hilo de servidor en cada prueba utilizando un comando proporcionado. El hilo del servidor se termina una vez que se ejecuta la prueba, asegurando un reinicio adecuado. Ejemplo para OpenSSL:
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -cmd "openssl s_server -accept 20000 -dtls1_2"
Con tantos parámetros, los comandos pueden volverse muy largos. dtls-fuzzer utiliza JCommander para analizar argumentos, que también puede leer parámetros de un archivo. Vaya a 'experiments/args' para ver ejemplos de argumentos. Para proporcionar un archivo de argumentos a dtls-fuzzer, indíquelo como parámetro precedido por "@". También puede agregar otros argumentos explícitos a los comandos (que sobrescribirán los del archivo de argumentos)
> java -jar target/dtls-fuzzer.jar @arg_file ...parámetros de sobrescritura...
Para lanzar un lote de ejecuciones de aprendizaje, se puede utilizar el script 'launcher.py' en 'experiments/scripts'. Proporcionado un directorio con archivos de argumentos, la herramienta lanzará un proceso de aprendizaje para cada archivo de argumentos.
> python3 experiments/scripts/launcher.py --jar target/dtls-fuzzer.jar --args args_folder
Antes de ejecutar experimentos de aprendizaje, ayuda verificar que los argumentos estén configurados correctamente, particularmente los parámetros de temporización. Con ese fin, dtls-fuzzer puede ejecutar un conjunto de pruebas personalizado (colección de pruebas) sobre el SUT y proporcionar un resumen de las salidas. Esta funcionalidad también se puede utilizar al diagnosticar experimentos de aprendizaje fallidos, es decir, averiguar qué salió mal.
Para ejecutar el conjunto de pruebas en un servidor usando el alfabeto predeterminado, puede ejecutar:
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -test test_file
Para ejemplos de archivos de prueba, vaya a 'examples/tests'. Un archivo de prueba comprende una lista de entradas separadas por nuevas líneas. Las pruebas están separadas por líneas nuevas vacías. El final de cada prueba es el final del archivo o una línea nueva vacía. "#" se usa para comentar una línea.
Si tiene un modelo/especificación, también puede ejecutar el conjunto de pruebas y comparar la salida con la de una especificación.
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -test test_file -specification model
El número de veces que se ejecutan las pruebas es configurable mediante el parámetro '-times', que por defecto es 1. Configurarlo a un número alto ayuda a detectar no determinismo en las configuraciones de aprendizaje, comparando la salida de cada prueba.
> java -jar target/dtls-fuzzer.jar -connect localhost:20000 -test test_file -times 10
Finalmente, si tiene el archivo de argumentos para un experimento de aprendizaje, puede usarlos para ejecutar pruebas en el SUT involucrado simplemente agregando los argumentos de prueba necesarios:
> java -jar target/dtls-fuzzer.jar @learning_arg_file -test test_file