Alcune configurazioni di mod_proxy su Apache HTTP Server dalla versione 2.4.0 alla 2.4.55 consentono attacchi HTTP Request Smuggling (tecnica di attacco che interferisce con il processo con cui il sito web gestisce le sequenze di richieste HTTP ricevute da uno o più utenti).
Queste configurazioni risultano vulnerabili quando mod_proxy è abilitato insieme ad alcune forme di RewireRule o ProxyPassMatch, in cui un attaccante remoto può sfruttare la vulnerabilità per aggirare le misure di controllo degli accessi sul server proxy, autorizzando così URL indesiderati verso il server di origine.
Questa vulnerabilità consente a un attaccante di prendere di mira e accedere alle applicazioni interne nascoste dal proxy, con possibile accesso non autorizzato, perdita di dati o ulteriore compromissione del sistema.
Sperimentazione di CVE-2023-25690
Utilizzo di una macchina Windows come macchina attaccante.
Il backend-server e il proxy-server sono implementati tramite Docker su una macchina Kali Linux.
Struttura dei file del lab:
Modello di sperimentazione
Indirizzo IP della macchina Windows 10: 192.168.1.177
Indirizzo IP della macchina Kali Linux: 192.168.27.139
Indirizzo IP del Backend-Server: 172.18.0.2
Indirizzo IP del Proxy-Server: 172.18.0.3
Quando la macchina Windows 10 accede all'Apache HTTP Server ospitato sulla macchina Kali sulla porta 80, il traffico viene inoltrato alla porta 80 del Proxy-Server e quindi al Backend-Server attraverso la porta 8080.
Requisiti di sistema
Macchina attaccante:
Sistema operativo Windows 10
Strumenti installati: Pycharm, BurpSuite, VScode
Utilizzare il browser FireFox e installare l'estensione FoxyProxy per configurare il proxy
Macchina vittima:
Installare strumenti e servizi: Docker, Tcpdum
Configurare il Docker File (vedi appendice)
Obiettivo dell'attacco: sfruttare la vulnerabilità HTTP Request Smuggling per aggirare le restrizioni del server proxy e accedere alla funzione nascosta nella pagina admin.php
Implementazione della sperimentazione:
Utilizzare BurpSuite Community configurato come proxy per intercettare e modificare le richieste.
Nel browser, installare l'estensione FoxyProxy e aggiungere le informazioni sul proxy:
Attivare FoxyProxy nella barra degli strumenti (nella sezione estensioni del browser) passando da Turn Off a BurpSuite Commu:
In BurpSuite, impostare Intercept su on per intercettare i pacchetti:
Sulla macchina Kali, usare il comando cd per spostarsi nella cartella del lab contenente il file docker-composer.yml ed eseguire docker composer con il comando: docker-composer up --build
Verifica dell'iniezione CRLF:
Innanzitutto, inviamo una richiesta contenente i caratteri di controllo (CRLF) al sistema come segue: HTTP/1.1\r\nFoo:
baarr\r\r\n\n e codifichiamo l'URL come: %20HTTP/1.1%0d%0aFoo:%20baarr
=> Si può notare che, quando inseriamo i caratteri CRLF (%0d%0a), il server elabora la nostra richiesta senza restituire alcun errore o limitazione, il che dimostra che possiamo inserire i caratteri CRLF.
Verifica dell'HTTP Request Smuggling:
Successivamente, abbiamo un URI come il seguente:
/categories/1 HTTP/1.1\r\nHost: Localhost\r\n\r\nGET /SMUGGLED, e codificando l'URL otteniamo: /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED/
Dopo aver applicato la RewriteRule, si può notare che l'URL viene analizzato e la richiesta inviata, dopo essere passata attraverso il proxy, viene trasformata nel seguente formato:
Si può notare che, con una singola richiesta inviata, il server riceve e restituisce ben 2 risposte: una per GET /categories e una per GET /SMUGGLED.
Sfruttamento dell'HTTP Request Smuggling:
Supponiamo che nel file httpd.conf configuriamo il Proxy-Server per bloccare l'accesso alla pagina /admin/.
Possiamo sfruttare l'HTTP Request Smuggling per aggirare il meccanismo di controllo di apache-proxy con la richiesta:
Controllando i log, notiamo che siamo riusciti a bypassare apache-proxy, inviare con successo la richiesta a /admin e il backend ha restituito lo status code 200 per GET /admin.
Supponiamo che nel file admin.php ci sia una funzione che esegue il comando di sistema nslookup per interrogare un dominio qualsiasi come segue; il nostro obiettivo è aggirare il meccanismo del proxy e accedere a questa funzione nascosta per inviare una query DNS
a un dominio qualsiasi; qui interroghiamo la stessa macchina Kali.
Abbiamo il codice di sfruttamento (file CVE-2023-25690.py) e il file pre.txt (contenente la richiesta contrabbandata che vogliamo far bypassare al Proxy-Server per inviare la richiesta al sistema, in questo caso /admin.php). Questo codice crea una richiesta smuggling con la richiesta che vogliamo contenuta nel file pre.txt e la invia al server. Inoltre, salva i risultati della richiesta e della risposta nei rispettivi file req.txt e res.txt.
Contemporaneamente, sulla macchina Kali usiamo TCPDUMP per catturare i pacchetti DNS sulla porta 53.
Si può notare che la richiesta inviata è riuscita a superare il proxy: il proxy la considera una richiesta valida. Tuttavia, sul backend-server la richiesta viene analizzata includendo i caratteri di controllo, quindi da una singola richiesta il backend-server l'ha suddivisa in 3 richieste: una GET /categories.php?id=1, una GET /admin.php?secret=192.168.1.194 e infine una GET /abc.
Appendice
Configurazione del file DockerFile nella cartella Backend
Questo file di configurazione specifica che il Backend-Server utilizza l'immagine PHP 7.4-apache, un'immagine che contiene PHP 7.4 insieme al Web Server Apache.
Il secondo comando copia tutto il contenuto dalla cartella src/ nella cartella /var/www/html - questa è la directory predefinita che Apache usa per servire i contenuti web, nota anche come web root.
Il terzo comando usa sed per sostituire tutte le occorrenze di 80 con 8080. Questo consente di cambiare la porta predefinita di Apache sul Backend-Server dalla 80 alla 8080.
L'ultimo comando viene eseguito quando il container viene avviato: è il comando che usa apache per avviare Apache Web Server.
Configurazione del file DockerFile nella cartella Frontend
Questo file copia il file httpd.conf dalla cartella Frontend in /tmp/httd.conf e infine inserisce il contenuto di quel file httpd.conf nel file /usr/local/apache2/conf/httpd.conf.
Il file httpd.conf è il file di configurazione principale del server HTTP Apache; questo file definisce le impostazioni di configurazione o le operazioni del server - in questo caso il Proxy-Server.
Il file httpd.conf è normalmente installato nel percorso /usr/local/apache2/conf/httpd.conf, quindi dobbiamo inserire il contenuto nel percorso /usr/local/apache2/conf/httpd.conf; creiamo invece un file httpd.conf nella cartella Frontend per poter configurare Apache in modo più flessibile (senza dover eseguire cd fino a quel percorso per riscrivere il file httpd.conf).
Configurazione del file docker-compose.yml:
Qui vengono definiti i servizi, le reti, ecc. necessari per eseguire l'applicazione.
Qui dichiariamo 2 servizi principali: apache-proxy e backend-server:
Apache-Proxy: viene costruito usando il file ./frontend/DockerFile e la rete backend-network (bridge); inoltre ha la configurazione depends_on: backend-server per specificare che Apache-Proxy può essere avviato solo dopo l'avvio del Backend-Server. Infine, ports: "80:80" specifica il port forwarding: il traffico diretto alla porta 80 sulla macchina host viene inoltrato alla porta 80 del container.
Backend-Server: viene costruito usando il file ./backend/DockerFile con la rete backend-network insieme al Proxy per consentire la comunicazione tra loro; la configurazione expose apre la porta 8080 così che Apache-Proxy inoltri il traffico al Backend-Server attraverso questa porta; infine, include alcune funzionalità di sicurezza come il divieto per l'utente di creare nuovi privilegi (aggiungere, modificare o eliminare file, aggiungere permessi su processi o reti, ecc.) e il filtraggio delle system call eseguite da un programma.
Configurazione del file httpd.conf
Prima di tutto, la configurazione salva i log in due percorsi: /use/local/apache2/logs/error.log e /use/local/apache2/logs/access.log.
Successivamente, vengono caricati i moduli necessari per poter applicare la Rewrite Rule (regola di riscrittura).
Successivamente viene specificato il DocumentRoot, la direttiva nel file di configurazione di Apache che determina dove si trovano i file dati del server.
Poi viene applicata la regola di riscrittura per i percorsi verso /categories/ e /admin/.
E infine, blocca l'invio di richieste a /admin/ -> lo scopo è permetterci di eseguire il lab di bypass del proxy e accedere a questa pagina.
Così abbiamo inviato con successo una richiesta a /admin.php, dove il proxy non ci consentiva di inviare richieste.
=> Controllando TCPDUMP vediamo che ha catturato i pacchetti DNS inviati -> esecuzione riuscita della funzione nascosta in /admin.php.