Mediante estos dos bugs localizados en el código fuente en C del motor PHP, seremos capaces de bypassear filtros anti LFI.
PATH TRUNCATION
0x01: Escenario:Código
<?php $file = "pagina/".$_GET['file'].".html"; include($file); ?>
además las magic quotes, están activas.
0x02: Limitaciones:
Con este planteamiento las opciones son limitadas, dado que no podemos usar el "null byte attack", podemos cargar cualquier html del sistema... pero qué archivos html contendrían informacion VITAL para la web? Realmente, opino que muy pocos, más aun sin poder lsitar archivos! (podemos hacer un full path disclosure ingresando un archivo no existente, pero suponemos que no nos devuelve información relevante!)
Bueno, lo que nos plantean los dos papers arriba mencionados, es que usando un bug del sistema podemos alcanzar CUALQUIER tipo de archivo, librándonos de la extensión impuesta ".html".
0x03: Conociendo el bug:
Las versiones mencionadas arriba de PHP poseen una especie de operador "neutro", por el que si se le añade a un archivo, éste, es removido antes de hacer un include (por ejemplo). Suponemos que el archivo a.php existe, si hiciesemos
Código
include("includes/a.php");
o
Código
include("includes/a.php/./././././");
El efecto sería exactamente igual, en algunas versiones que cuenten con el Suoshin patch, como operador neutro tambien es válido: / (0x2F), es decir, sin el punto!
Ahora bien, por si solo este operador neutro, de momento (luego veremos más cosas) no nos proporcion ningun gran avance... Pero pensemos en como se ejecuta nuestro include() a nivel de C, cuando se pasa un nombre de archivo a la funcion fopen, existe un tamaño máximo en la longitud del nombre pasado, este tamaño viene definido por el "MAXPATHLEN". De manera que si el tamaño es mayor, se trunca, y además silenciosamente, sin avisar de esta operacion. De este modo si nuestro archivo se llamase
Código:
aaaaaaaaaaaaaaaaaa(... 100000 vecse más xD)aaaaa
Esto SI es una gran ventaja, puesto que si pudiesemos hacer que el nombre pasado a la variable mediante GET superase ese límite, la extensión predefinida, se truncaría, quedando así nuestra extensión deseada. Pero... como hacer que exista un archivo con ese nombre tan tremendamente largo? Usando el operador normalizado!
Así, si el include recibiese un nombre de esta forma...:
Código:
pagina/asdf/../../../../../../boot.ini/././././././(un puñao de veces más xD)/././.html
en algun momento de la secuencia de puntos y contrabarras el MAXPATHLEN entraría en juego, truncando el final y dejando fuera de juego a la extensión .html!
0x04: Explotandolo:
Por razones que se esacpan a esta explicacion ( se detallan muy bien en los papers linkados arriba ) en windows el modo a explotar es acabando la cadena en "/" y en linux en "/."
Además se ha de empezar con una barra inclinada "/". De la siguiente manera
www.web.com/includeFAIL.php?pagina=/../../../../boot.ini/./././././././././././././
www.web.com/includeFAIL.php?pagina=/../../../../etc/passwd/././././././././././.
el primero para windows y el segundo para *nix (obviametne...)
PATH NORMALIZATION
Aunque debería haber empezado por aquí, he preferido hacerlo a la inversa, ya que la mayoría lo que buscan es resultados rápidos, y no comprender el problema por dentro... ( lo que considero un fallo enorme de planteamiento ). De cualquier manera, el concepto de normalización ya está explicado, si quereis más información a cerca del código en C responsable de elimiar todas esas barras y puntos () ya sabeis donde encontrar la información.
0x11: Escenario:
Supongams que tenemos un código como el siguiente y que, de nuevo, magic_quotes on.
Código
$file = $_GET['file']; include("/includes".$file); }else{ }
0x12: Limitaciones:
Dado este código a priori solo nos restringiria incluir txt, si por ejemplo, somos capaces de subir, un txt al sistema, supongamos que es una web... de yo que se, poemas, y nos dejan subir poemas en formato txt, un formato muy... inocente! XD mediante este código se nos restringiría el incluir esos txt mediante php.
0x13: Explotación:
facilmente se nos ocurre que una petición del estilo
www.web.com/includeFAIL.php?pagina=poemaMaligno.txt/.
dado el bug de la normalización bypassearía la condición de quew no termine en ".txt" pero el sistema, internamente cargaría un ".txt".
El ejemplo de los txt en sí, es muy malo, pero se puede extender a cualquier tipo de comprobación de extensión, supongamos un uploader, la funcion "fopen" y "move_uploaded_file" tambien adolecen de este problema. (Se describe en la segunda parte del paper mencionado ). De esta manera, si al comprobar la extensión se nos vigilase que no se subiesen ".php" podríamos subir un ".php/."
Ala a ser malignos pero bajo vuestra propia responsabilidad! Espero que a esta aportación se le haga un poco más de caso que me e tirado un ratico escribiendola ¬¬