Hola.
Quiero ver si consigo explotar un LFI en bibtexbrowser.
Directorio a explotar: /bibtexbrowser.php?frameset&bib=file.fib
Me puse a mirar el código de bibtexbrowser ( https://github.com/monperrus/bibtexbrowser/blob/master/bibtexbrowser.php ), y me encontré con esto:
foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) {
// get file extension to only allow .bib files
$ext = pathinfo($bib, PATHINFO_EXTENSION);
// this is a security protection
if (BIBTEXBROWSER_LOCAL_BIB_ONLY && (!file_exists($bib) || strcasecmp($ext, 'bib') != 0)) {
// to automate dectection of faulty links with tools such as webcheck
header('HTTP/1.1 404 Not found');
// escape $bib to prevent XSS
$escapedBib = htmlEntities($bib, ENT_QUOTES);
die('<b>the bib file '.$escapedBib.' does not exist !</b>');
}
} // end for each
Este código está un poco más actualizado que el que estoy explotando en otra página, porque la versión que esta cargada en la página donde estoy explotando la vulnerabilidad es vulnerable a XSS, cuando esta versión de bibtexbrowser no es vulnerable, se puede ver que no es vulnerable por esta línea:
// escape $bib to prevent XSS
$escapedBib = htmlEntities($bib, ENT_QUOTES);
Ahora volviendo al caso de LFI:
Baja la extensión del archivo así:
$ext = pathinfo($bib, PATHINFO_EXTENSION);
Buscando por Google, leí que se podía hacer un bypass de la función pathinfo utilizando null byte ( http://www.madirish.net/202 ).
Entonces para cargarme el index.php intenté algo como esto: index.php%00.bib , pero no parece funcionar.
¿Qué otras cosas podría intentar? o alguna explicación de porqué esto no funciona.
Saludos
El nullbyte no funciona porque a file_exists no le afectan nullbytes. Veras, en versiones anteriores de PHP, el nullbyte afectaba en string, lo que se traducía a que todas las funciones que trataban con ello, eran vulnerables. A partir de 5.3.4 si no me equivoco, eso cambió y ya no les afecta dado que nno admiten strings con nullbyte.
Sencilla demostración.
test.php<?php
if(isset($_GET['file'])){
$ext = pathinfo($_GET['file'], PATHINFO_EXTENSION);
$compare = (strcasecmp($ext, 'bib') != 0 ? false : true);
$exists = file_exists($_GET['file']);
echo '<strong>El archivo elegido es: </strong> ', var_dump($_GET['file']), '<br>';
echo '<strong>La extension del archivo es: </strong> ', var_dump($ext), '<br>';
echo '<strong>Segun strcasecmp, la extension es un bib ?:</strong> ', var_dump($compare), '<br>';
echo '<strong>El archivo elegido existe ?: </strong> ', var_dump((bool) $exists);
}
Si hago la esta consulta (y tengo creado el archivo .bib):
http://domain/test.php?file=hola.bib
Me devolvería:
El archivo elegido es: string(8) "hola.bib"
La extension del archivo es: string(3) "bib"
Segun strcasecmp, la extension es un bib ?: bool(true)
El archivo elegido existe ?: bool(true)
Pero si hago esto
http://domain/test.php?file=test.php%00.bib
Me devuelve:
El archivo elegido es: string(13) "test.php.bib"
La extension del archivo es: string(3) "bib"
Segun strcasecmp, la extension es un bib ?: bool(true)
El archivo elegido existe ?: bool(false)
Si te fijas, la función
strcasecmp si es vulnerable porque compara vía binaria pero el
file_exists no lo es (dice que el archivo no existe, a pesar de que existe) porque no procesa strings con NullBytes.
Puedes ver más info en el changelog de PHP para esa version.
http://php.net/releases/5_3_4.php
CitarPaths with NULL in them (foo\0bar.txt) are now considered as invalid (CVE-2006-7243).
Eso se aplica para todas la funciones que tratan con archivos (file_exists, file_get_contents, include, require etc..)
Saludos