miércoles, 30 de enero de 2013

LFI 2 RCE en Windows con archivos temporales

Esto lo leí hace algún tiempo y me pareció sencillamente genial. Se trata de una forma bastante ingeniosa de explotar un LFI mediante ficheros temporales de PHP en Windows. El paper es de marzo de 2011 y lo pueden encontrar en este link:

http://gynvael.coldwind.pl/download.php?f=PHP_LFI_rfc1867_temporary_files.pdf

Por mi parte trataré de explicarlo como lo entendí.


Uploading de ficheros en PHP

Al enviar un fichero por POST a un script PHP, como si de un uploader se tratara, PHP almacena el fichero como un temporal en cierto directorio del sistema configurado en la directiva "upload_tmp_dir" de "php.ini". En el caso de Windows este directorio suele ser "C:\\windows\temp\". El fichero temporal se mantiene mientras dura la ejecución del script PHP y se elimina al terminar su ejecución.

Entonces podemos aprovechar este comportamiento para almacenar código PHP malicioso en los ficheros temporales. Para esto solo tenemos que enviar nuestro código malicioso por POST como si tratáramos de subir un fichero y se creará un fichero temporal conteniendo dicho código. Nuestro único problema es que no conocemos el nombre del fichero temporal para poder llamarlo desde el LFI.

Sin embargo, en Windows, sabemos que el nombre del fichero temporal empieza con las letras "php". Luego le sigue un número en hexadecimal que se obtiene a partir de la hora del sistema (número de milisegundos) y finalmente la extención ".TMP".

Aún así la cantidad de posibles nombres de ficheros es demasiado grande como para tratar de adivinar uno en particular. Se hace necesario entonces encontrar otra forma de aprovechar los ficheros temporales.

Es aquí donde empieza lo interesante...

Usando wilcards en PHP

En enero de 2011 Vladimir Vorontsov y Arthur Gerkis publicaron un paper en el cual mostraban un curioso comportamiento de PHP al manejar ciertos caracteres en los nombres de ficheros en Windows. El paper se puede encontrar aquí:

http://onsec.ru/onsec.whitepaper-02.eng.pdf

Los investigadores descubrieron, mediante pruebas de fuzzing, que ciertos caracteres en los nombres de los ficheros que se pasaban como parametro a las funciones de PHP eran reemplazados por otros. Así por ejemplo el caracter ">" se sustituye por "?" y el caracter "<" por "*". Además encontraron que muchas de las funciones para manejo de ficheros en PHP terminan llamando a la función "FindFirstFile()" del API de Windows. Esta función admite wilcards o caracteres comodín: "?" para sustituir un carácter cualquiera y "*" para varios.

Y adivinen qué... entre las funciones afectadas están require, require_once, include e include_once.

Entonces imaginemos que en cierto directorio hay un archivo llamado "libreria.php" y es el unico cuyo nombre inicia con "lib". Daría lo mismo hacer esto:

require("cierto/directorio/libreria.php");

o esto:

require("cierto/directorio/lib<");

Puesto que el carácter "<" será reemplazado por el comodín "*".

A estas alturas seguro que ya sospechas como podemos aprovechar esto para explotar el LFI }:))

Explotando el LFI

Bien, ahora imaginemos que tenemos un script vulnerable a LFI llamado "lfi.php", la variable vulnerable es "file" y se envia por GET. Algo así:

http://example.com/lfi.php?file=../../../../../boot.ini

Para explotar este LFI usando ficheros temporales prepararemos un pequeño formulario de subida de ficheros como este:

<html>
<head></head>
<body>
 <form action="http://example.com/lfi.php?file=../../../../../windows/temp/php<<" enctype="multipart/form-data" method="post">
  <input name="payload" type="file">
  <input value="exploit!" type="submit">
 </form>
</body>
</html>

Ahora solo tenemos que escribir en un fichero de texto el código PHP que queremos ejecutar y enviarlo con este formulario.

Observe que la URL vulnerable va en el campo "action" del formulario y que la variable vulnerable pide el fichero "../../../../../windows/temp/php<<", es decir el primer fichero que empiece con "php" y esté en el directorio de los temporales ;) Es casi seguro que ese fichero será el que estamos enviando con el formulario.

Demo

Para terminar les dejo este vídeo donde se muestra todo el procedimiento. En este caso estoy usando XAMPP y viene con una configuración diferente para "upload_tmp_dir".



Un saludo.

6 comentarios:

  1. manya... cesar esa no la sabia... ejejje man y segun veo el paper tambien la funcionalidad va con linux ....
    felicitaciones buen video... y esa musika0'??

    ResponderEliminar
  2. Hola, es un buen truco a que sí? xD

    Cierto, en Linux también se crean temporales cuando subes un fichero con PHP. Por defecto se crean en /tmp y con nombres aleatorios que empiezan con "php".

    Sin embargo, lo que no funciona en Linux son los wilcards, osea no puedes pedir un /tmp/php*. Eso no va a funcionar en Linux.

    Pero hay una forma bastante rayada de aprovechar los temporales de PHP en Linux usando un "phpinfo". Te dejo el link:

    http://alguienenlafisi.blogspot.com/2011/12/lfi-with-phpinfo.html

    Nota: lo del phpinfo lo he probado en localhost y funciona bien. Sin embargo "in the real world" no es tan efectivo... al parecer como se trata de una condición de carrera se necesita de mucha rapidez.

    Un saludo.

    ResponderEliminar
  3. Ah... me olvidaba lo de la música xD Es "Bouncing Bellz" de "Jessie Chambers". (de las que te vienen en youtube xD)

    ResponderEliminar
  4. Bien ... buen dato vro. Muy buen post ... Espero nos sigas sorprendiendo con mas post de esta calidad... Buena vro.

    ResponderEliminar
  5. me olvidaba esta buena la musika... ejjeje ;)

    ResponderEliminar
  6. XAMPP EN Windows 8 me lanza como programa malicioso, y sigo el enlace de la web original. Una duda, yo tengo archivos como de 4 MB hasta 4 GB en mi Web Disk, con smylink puedo hacer un enlace simbolico (no duro), hacia otra ruta, pero la pregunta en si seria si se puede usar condicionantes asi como preg_match (.*?) o como wilcards (*?) pero en Host Linux? osea, como son varios ficheros, zip y algunos php, buscar entre ellos un sufijo o prefijo, se puede en linux utilizando symlink php?

    Mi correo: MegaBedder[Dot]HoTMaiL.com

    ResponderEliminar