L’auteur a choisi que le Electronic Frontier Foundation Inc recevrait une donation dans le cadre du programme Write for Donations.
Les menaces de sécurité sont de plus en plus sophistiquées, de sorte que les développeurs et les administrateurs de systèmes doivent adopter une approche proactive pour défendre et tester la sécurité de leurs apps.
L’une des méthodes courantes pour tester la sécurité des apps client ou des services réseau est le fuzzing, qui consiste à envoyer de manière répétée des données non valides ou mal formées à l’application et à analyser sa réponse. C’est utile pour tester la résistance et la robustesse de l’application à des entrées inattendues, qui peuvent inclure des données corrompues ou des attaques réelles.
Radamsa est un outil de fuzzing open-source qui peut générer des cas de test basés sur des données d’entrée spécifiées par l’utilisateur. Radamsa est entièrement scriptable, et a jusqu’à présent réussi à trouver des vulnérabilités dans des apps du monde réel, comme Gzip.
Dans ce tutoriel, vous allez installer et utiliser Radamsa pour tester des apps en ligne de commande et en réseau en utilisant vos propres scénarios de test.
Attention : Radamsa est un outil de test de pénétration qui peut vous permettre d’identifier les vulnérabilités ou les faiblesses de certains systèmes ou apps. Vous ne devez pas utiliser les vulnérabilités trouvées avec Radamsa pour toute forme de comportement imprudent ou préjudiciable ou d’exploitation malveillante. Les vulnérabilités doivent être signalées de manière éthique au responsable de l’application concernée, et ne doivent pas être divulguées publiquement sans autorisation explicite.
Avant de commencer ce guide, vous aurez besoin des éléments suivants :
Attention : Radamsa peut entraîner un fonctionnement instable ou un plantage des apps ou des systèmes. N’exécutez Radamsa que dans un environnement où vous êtes préparé à cela, par exemple sur un serveur dédié. Veuillez également vous assurer que vous avez l’autorisation écrite explicite du propriétaire d’un système avant de procéder à des tests de fuzzing sur celui-ci.
Une fois que tout est prêt, connectez-vous à votre serveur en tant qu’utilisateur non root pour commencer.
Tout d’abord, vous allez télécharger et compiler Radamsa afin de commencer à l’utiliser sur votre système. Le code source de Radamsa est disponible dans le dépôt officiel sur GitLab.
Commencez par mettre à jour l’index local des paquets pour refléter tout nouveau changement en amont :
- sudo apt update
Puis, installez les packages gcc
, git
, make
, et wget
nécessaires pour compiler le code source en un binaire exécutable :
- sudo apt install gcc git make wget
Après avoir confirmé l’installation, apt
téléchargera et installera les paquets spécifiés et toutes leurs dépendances requises.
Ensuite, vous téléchargerez une copie du code source de Radamsa en le clonant à partir du dépôt hébergé sur GitLab :
- git clone https://gitlab.com/akihe/radamsa.git
Cette opération créera un répertoire appelé radamsa
, contenant le code source de l’application. Déplacez-vous dans le répertoire pour commencer à compiler le code :
- cd radamsa
Ensuite, vous pouvez lancer le processus de compilation en utilisant make
:
- make
Enfin, vous pouvez installer le binaire Radamsa compilé sur votre $PATH
:
- sudo make install
Une fois cette opération terminée, vous pouvez vérifier la version installée pour vous assurer que tout fonctionne :
- radamsa --version
Votre sortie ressemblera à ce qui suit :
OutputRadamsa 0.6
SI vous voyez une erreur radamsa: command not found
, vérifiez que toutes les dépendances requises ont été installées et qu’il n’y a pas eu d’erreurs lors de la compilation.
Maintenant que vous avez installé Radamsa, vous pouvez commencer à générer quelques exemples de scénarios de tests pour comprendre comment Radamsa fonctionne et à quoi il peut servir.
Maintenant que Radamsa a été installé, vous pouvez l’utiliser pour générer quelques scénarios de tests de fuzzing.
Un scénario de test est une donnée qui sera utilisée comme entrée dans le programme que vous testez. Par exemple, si vous testez un programme d’archivage tel que Gzip, un scénario de test peut être une archive de fichiers que vous essayez de décompresser.
Remarque : Radamsa manipulera les données d’entrée d’une grande variété de manières inattendues, y compris la répétition extrême, les inversions de bits, l’injection de caractères de contrôle, etc. Cela peut entraîner une interruption ou une instabilité de votre session terminale. Il faut donc en être conscient avant de poursuivre.
Tout d’abord, transmettez un texte simple à Radamsa pour voir ce qui se passe :
- echo "Hello, world!" | radamsa
Cela permettra de manipuler (ou de “fuzz”) les données saisies et de produire un scénario de test, par exemple :
OutputHello,, world!
Dans ce cas, Radamsa a ajouté une virgule supplémentaire entre Hello
et world
. Cela peut ne pas sembler être un changement significatif, mais dans certaines apps, cela peut entraîner une interprétation incorrecte des données.
Essayons à nouveau en exécutant la même commande. Vous verrez une sortie différente :
OutputHello, '''''''wor'd!
Cette fois, plusieurs guillemets simples ('
) ont été insérés dans la chaîne, dont un qui a écrasé le l
de world
. Ce cas particulier est plus susceptible d’entraîner des problèmes pour une application, car des guillemets simples/doubles sont souvent utilisés pour séparer différents éléments de données dans une liste.
Essayons encore une fois :
OutputHello, $+$PATH\u0000`xcalc`world!
Dans ce cas, Radamsa a inséré une chaîne d’injection shell, qui sera utile pour tester les vulnérabilités de l’injection de commandes dans l’application que vous testez.
Vous avez utilisé Radamsa pour fuzz une chaîne d’entrée et produire une série de scénarios de tests. Ensuite, vous utiliserez Radamsa pour fuzz une application en ligne de commande.
Dans cette étape, vous utiliserez Radamsa pour fuzz une application de ligne de commande et signaler tout crash qui se produit.
La technique exacte pour fuzz chaque programme varie énormément, et différentes méthodes seront plus efficaces pour différents programmes. Cependant, dans ce tutoriel, nous utiliserons l’exemple de jq
, qui est un programme de ligne de commande utilisé pour traiter les données JSON.
Vous pouvez utiliser tout autre programme similaire, à condition qu’il suive le principe général consistant à prendre une certaine forme de données structurées ou non structurées, à en faire quelque chose, puis à produire un résultat. Par exemple, cet exemple fonctionnerait également avec Gzip, Grep, bc, tr, etc.
Si vous n’avez pas déjà installé jq
, vous pouvez l’installer en utilisant apt
:
- sudo apt install jq
jq
va maintenant être installé.
Pour commencer le fuzzing, créez un exemple de fichier JSON que vous utiliserez comme entrée dans Radamsa :
- nano test.json
Ensuite, ajoutez au fichier l’échantillon de données JSON suivant :
{
"test": "test",
"array": [
"item1: foo",
"item2: bar"
]
}
Vous pouvez analyser ce fichier en utilisant jq
si vous souhaitez vérifier que la syntaxe JSON est valide :
- jq . test.json
Si le JSON est valide, jq
produira le fichier. Dans le cas contraire, il affichera une erreur, que vous pourrez utiliser pour corriger la syntaxe si nécessaire.
Ensuite, effectuez un test fuzzing du fichier JSON à l’aide de Radamsa et transmettez-le à jq
. Cela forcera jq
à lire le scénario de test manipulé plutôt que les données JSON valides d’origine :
- radamsa test.json | jq
Si Radamsa fuzz les données JSON de façon à ce qu’elles soient toujours valides d’un point de vue syntaxique, jq
produira les données mais avec les modifications que Radamsa y aura apportées.
Si, au contraire, Radamsa rend les données JSON invalides, jq
produira un message d’erreur. Par exemple :
Outputparse error: Expected separator between values at line 5, column 16
L’autre résultat serait que jq
soit incapable de traiter correctement les données manipulées, ce qui entraînerait un crash ou un mauvais comportement. C’est ce que vous recherchez vraiment avec le fuzzing, car cela peut indiquer une vulnérabilité de sécurité telle qu’un débordement de tampon ou une injection de commande.
Afin de tester plus efficacement les vulnérabilités de ce type, un script Bash peut être utilisé pour automatiser le processus de fuzzing, y compris la génération de scénarios de test, leur transmission au programme cible et la capture de tout résultat pertinent.
Créez un fichier nommé jq-fuzz.sh
:
- nano jq-fuzz.sh
Le contenu exact du script variera en fonction du type de programme que vous manipulez et des données d’entrée, mais dans le cas de jq
et d’autres programmes similaires, le script suivant suffit.
Copiez le script dans votre fichier jq-fuzz.sh
:
#!/bin/bash
while true; do
radamsa test.json > input.txt
jq . input.txt > /dev/null 2>&1
if [ $? -gt 127 ]; then
cp input.txt crash-`date +s%.%N`.txt
echo "Crash found!"
fi
done
Le script contient un while
pour que le contenu se répète en boucle. À chaque fois que le script se répète, Radamsa génère un scénario de test basé sur test.json
et le sauvegarde dans input.txt
.
Le scénario de test input.txt
est alors exécuté via jq
, et toutes les sorties standard et les erreurs dirigées vers /dev/null
pour éviter de remplir l’écran du terminal.
Enfin, la valeur de sortie de jq
est vérifiée. Si la valeur de sortie est supérieure à 127
, cela indique une interruption fatale (un crash), puis les données d’entrée sont sauvegardées pour examen à une date ultérieure dans un fichier nommé crash-
suivies de la date actuelle en secondes et nanosecondes Unix.
Marquez le script comme exécutable et exécutez-le afin de commencer automatiquement le test fuzzing de jq
.
- chmod +x jq-fuzz.sh
- ./jq-fuzz.sh
Vous pouvez émettre CTRL+C
à tout moment pour terminer le script. Vous pouvez ensuite vérifier si des crashs ont été trouvés en utilisant ls
pour afficher la liste des répertoires contenant les fichiers de plantage qui ont été créés.
Vous souhaiterez peut-être améliorer vos données d’entrée JSON, car l’utilisation d’un fichier d’entrée plus complexe est susceptible d’améliorer la qualité de vos résultats de fuzzing. Évitez d’utiliser un gros fichier ou un fichier qui contient beaucoup de données répétées - un fichier d’entrée idéal est un fichier de petite taille, mais qui contient quand même autant d’éléments “complexes” que possible. Par exemple, un bon fichier d’entrée contiendra des échantillons de données stockées dans tous les formats, y compris des chaînes de caractères, des entiers, des booléens, des listes et des objets, ainsi que des données imbriquées si possible.
Vous avez utilisé Radamsa pour effectuer un fuzzing sur une application en ligne de commande. Maintenant, vous allez utiliser Radamsa pour effectuer un fuzzing sur les demandes adressées aux services du réseau.
Radamsa peut également être utilisé pour manipuler les services de réseau, soit en tant que client de réseau, soit en tant que serveur de réseau. Dans cette étape, vous utiliserez Radamsa pour manipuler un service réseau, Radamsa agissant en tant que client.
L’objectif de la manipulation des services réseau est de tester la résilience d’un service réseau particulier aux clients qui lui envoient des données mal formées et/ou malveillantes. De nombreux services réseau tels que les serveurs web ou les serveurs DNS sont généralement exposés à internet, ce qui signifie qu’ils constituent une cible courante pour les attaquants. Un service réseau qui n’est pas suffisamment résistant à la réception de données mal formées peut tomber en panne, ou pire encore, tomber en panne à l’état ouvert, permettant aux attaquants de lire des données sensibles telles que les clés de cryptage ou les données des utilisateurs.
La technique spécifique de manipulation des services réseau varie énormément selon le service réseau en question, mais dans cet exemple, nous utiliserons Radamsa pour manipuler un serveur web de base servant du contenu HTML statique.
Tout d’abord, vous devez configurer le serveur web à utiliser pour les tests. Vous pouvez le faire en utilisant le serveur de développement intégré qui est fourni avec le package php-cli
. Vous aurez également besoin de curl
pour tester votre serveur web.
Si vous n’avez pas php-cli
et/ou curl
, vous pouvez les installer en utilisant apt
:
- sudo apt install php-cli curl
Ensuite, créez un répertoire pour y stocker les fichiers de votre serveur web et déplacez-vous dans celui-ci :
- mkdir ~/www
- cd ~/www
Puis, créez un fichier HTML contenant un exemple de texte :
- nano index.html
Ajoutez le code suivant au fichier :
<h1>Hello, world!</h1>
Vous pouvez maintenant exécuter votre serveur web PHP. Vous devrez pouvoir consulter le journal du serveur web tout en utilisant une autre session de terminal. Pour ce faire, ouvrez une autre session de terminal et une connexion SSH à votre serveur :
- cd ~/www
- php -S localhost:8080
Il en résultera quelque chose de similaire à ce qui suit :
OutputPHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Wed Jan 1 16:06:41 2020
Listening on http://localhost:8080
Document root is /home/user/www
Press Ctrl-C to quit.
Vous pouvez maintenant revenir à votre session de terminal d’origine et vérifier que le serveur web fonctionne en utilisant curl
:
- curl localhost:8080
Il en résultera la production du fichier d’échantillon index.html
que vous avez créé plus tôt :
Output<h1>Hello, world!</h1>
Votre serveur web ne doit être accessible que localement, vous ne devez donc ouvrir aucun port sur votre pare-feu pour lui.
Maintenant que vous avez configuré votre serveur web de test, vous pouvez commencer à le tester en utilisant Radamsa.
Tout d’abord, vous devez créer un exemple de requête HTTP à utiliser comme données d’entrée pour Radamsa. Créez un nouveau fichier pour le stocker :
- nano http-request.txt
Ensuite, copiez l’exemple de requête HTTP suivant dans le fichier :
GET / HTTP/1.1
Host: localhost:8080
User-Agent: test
Accept: */*
Maintenant, vous pouvez utiliser Radamsa pour soumettre cette requête HTTP à votre serveur web local. Pour ce faire, vous devrez utiliser Radamsa comme client TCP, ce qui peut être fait en spécifiant une adresse IP et un port de connexion :
- radamsa -o 127.0.0.1:8080 http-request.txt
Remarque : sachez que l’utilisation de Radamsa comme client TCP peut entraîner la transmission de données mal formées/malveillantes sur le réseau. Cela peut causer des dégâts, alors faites très attention à n’accéder qu’aux réseaux que vous êtes autorisé à tester, ou de préférence, tenez-vous en à l’adresse de l’hôte local (127.0.0.1
).
Enfin, si vous consultez les journaux de votre serveur web local, vous verrez qu’il a reçu les demandes, mais qu’il ne les a probablement pas traitées car elles étaient invalides/mal formées.
Les journaux produits seront visibles dans la deuxième fenêtre de votre terminal :
Output[Wed Jan 1 16:26:49 2020] 127.0.0.1:49334 Invalid request (Unexpected EOF)
[Wed Jan 1 16:28:04 2020] 127.0.0.1:49336 Invalid request (Malformed HTTP request)
[Wed Jan 1 16:28:05 2020] 127.0.0.1:49338 Invalid request (Malformed HTTP request)
[Wed Jan 1 16:28:07 2020] 127.0.0.1:49340 Invalid request (Unexpected EOF)
[Wed Jan 1 16:28:08 2020] 127.0.0.1:49342 Invalid request (Malformed HTTP request)
Pour obtenir des résultats optimaux et garantir l’enregistrement des crashs, vous pouvez écrire un script d’automatisation similaire à celui utilisé à l’Étape 3. Vous devriez également envisager d’utiliser un fichier d’entrée plus complexe, qui peut contenir des ajouts tels que des en-têtes HTTP supplémentaires.
Vous avez effectué le fuzzing d’un service réseau en utilisant Radamsa comme client TCP. Ensuite, vous allez effectuer le fuzzing d’un client réseau avec Radamsa agissant en tant que serveur.
Dans cette étape, vous utiliserez Radamsa pour tester par fuzzing une application client réseau. Cette opération est réalisée en interceptant les réponses d’un service réseau et en effectuant un fuzzing avant qu’elles ne soient reçues par le client.
L’objectif de ce type de fuzzing est de tester la résistance des apps clientes du réseau à la réception de données mal formées ou malveillantes provenant des services réseau. Par exemple, tester un navigateur web (client) recevant du HTML mal formé d’un serveur web (service réseau), ou tester un client DNS recevant des réponses DNS mal formées d’un serveur DNS.
Comme dans le cas des apps de ligne de commande ou des services réseau, la technique exacte utilisée pour effectuer le fuzzing de chaque application client de réseau varie considérablement, mais dans cet exemple, vous utiliserez whois
, qui est une simple application d’envoi/réception basée sur TCP.
L’application whois
est utilisée pour faire des demandes aux serveurs WHOIS et recevoir des enregistrements WHOIS en réponse. WHIOS fonctionne sur le port TCP 43
en texte en clair, ce qui en fait un bon candidat pour les tests fuzzing en réseau.
Si vous n’avez pas déjà whois
à votre disposition, vous pouvez l’installer en utilisant apt
:
- sudo apt install whois
Tout d’abord, vous devrez acquérir un exemple de réponse whois
pour l’utiliser comme donnée d’entrée. Vous pouvez le faire en effectuant une requête whois
et en enregistrant la sortie dans un fichier. Vous pouvez utiliser le domaine que vous souhaitez tant que vous testez le programme whois
localement en utilisant des données de test :
- whois example.com > whois.txt
Ensuite, vous devrez configurer Radamsa comme un serveur qui sert des versions fuzzées de cette réponse whois
. Vous devrez pouvoir continuer à utiliser votre terminal une fois que Radamsa fonctionnera en mode serveur. Il est donc recommandé d’ouvrir une autre session de terminal et une connexion SSH à votre serveur pour cela :
- radamsa -o :4343 whois.txt -n inf
Radamsa fonctionnera désormais en mode serveur TCP, et servira une version fuzzée de whois.txt
à chaque fois qu’une connexion sera établie avec le serveur, quelles que soient les données de requête reçues.
Vous pouvez maintenant tester l’application client whois
. Vous aurez besoin d’une requête whois
normale pour le domaine de votre choix (il n’est pas nécessaire que ce soit le même que celui pour lequel les données de l’échantillon ont été recueillies), mais avec whois
pointé vers votre serveur Radamsa local :
- whois -h localhost:4343 example.com
La réponse sera votre échantillon de données, mais fuzzé par Radamsa. Vous pouvez continuer à effectuer des requêtes vers le serveur local tant que Radamsa fonctionne, et il servira une réponse fuzzée différente à chaque fois.
Comme pour le fuzzing des services réseau, pour améliorer l’efficacité de ce test de fuzzing du client réseau et s’assurer que tout crash est capturé, vous pouvez écrire un script d’automatisation similaire à celui utilisé à l’Étape 3.
Dans cette dernière étape, vous avez utilisé Radamsa pour effectuer un test de fuzzing sur une application client réseau.
Dans cet article, vous avez implémenté Radamsa et l’avez utilisé pour fuzz une application en ligne de commande, un service réseau et un client réseau. Vous disposez maintenant des connaissances de base nécessaires pour tester vos propres apps, avec pour résultat, espérons-le, d’améliorer leur robustesse et leur résistance aux attaques.
Si vous souhaitez explorer davantage Radamsa, vous pouvez consulter le fichier README
de Radamsa en détail, car il contient des informations techniques supplémentaires et des exemples d’utilisation de l’outil :
Vous pouvez également consulter d’autres outils de fuzzing tels que l’American Fuzzy Lop (AFL), qui est un outil de fuzzing avancé conçu pour tester des apps binaires à une vitesse et une précision extrêmement élevées :
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!