Jump to content

En el caso de que tratemos con archivos PHP, existe un concepto que son los llamados PHP Wrappers. Un wrapper es una especie de envoltura que le dice al Stream (secuencia, petición, entrada/salida de datos) como actuar.

Esta característica de PHP es muy útil en ataques como el LFI y el XXE, gracias a esto, podemos obtener alguna que otra ventaja que de otra forma no tendríamos.

El concepto de wrapper quedará más claro cuando lo veamos ahora.

Índice:

  • php://filter
  • zip://
  • data://
  • php://input
  • expect://
  • Referencias

php://filter

El Wrapper filter nos permite encodear el archivo que le especifiquemos, esto es muy útil, ya que nos permite poder leer archivos PHP que en otro caso, el navegador simplemente interpretaría directamente.

Por ejemplo, tenemos el siguiente archivo:

image 116

Como vemos, tiene una contraseña en un comentario. Pero si nosotros accedemos al archivo desde la web:

image 117

Solo vemos la salida del código interpretado 😥. Sin embargo, usando el wrapper filter, seremos capaces de leer el archivo PHP al completo.

Para probar el wrapper, he creado un LFI en un archivo index.php. Por lo que, en este LFI, el payload que introduciremos para hacer uso del wrapper y leer el archivo secret.php, será el siguiente:

  • php://filter/convert.base64-encode/resource=<archivo>
image 118

De esta forma, estamos leyendo el archivo secret.php pero en base64, por lo que si decodeamos esta salida:

image 119

Obtenemos el archivo al completo. Un detalle curioso sobre los wrappers es que podemos concatenar varios a través del uso de un pipe | o un slash /. Ejemplo:

image 120
image 121

Y obtenemos exactamente el mismo resultado.

Además de poder encodear en base64, podemos aplicar ROT13 con la siguiente cadena:

  • php://filter/read=string.rot13/resource=<archivo>

Aunque este en concreto no sirve para leer archivos PHP:

image 265

Pero si aplica para otro tipo de archivos:

image 266

En conclusión, referente a este wrapper, tenemos los dos siguientes payloads:

  • php://filter/convert.base64-encode/resource=<archivo>
  • php://filter/read=string.rot13/resource=<archivo>

zip://

El wrapper zip nos permite ejecutar un php que hayamos metido dentro de un archivo zip. Incluso no hace falta que el archivo zip tenga como extensión zip, sino que puede tener cualquiera.

Este wrapper no está instalado por defecto, pero se puede instalar con el siguiente comando:

  • sudo apt install phpX.Y-zip

Donde X e Y, es la versión PHP que tengamos instalada o a la que queramos instalarle esta característica.

Ejemplo de ejecución de webshell a través de este wrapper:

image 267

Payload:

  • zip://<archivo zip>%23<archivo php>

En <archivo zip>, si no se encontrase en el directorio actual, se le especificaría el directorio donde se encontrase el archivo y listo.

Nota: en caso de que el archivo PHP fuese una webshell o esperase algún parámetro, se le agregaría con un ampersand como vemos en la siguiente imagen.

image 268

E incluso cambiando la extensión del zip, seguirá funcionando:

image 269
image 270

data://

El wrapper data nos permite incluir datos externos, incluido código PHP. Este wrapper solo funciona si la opción allow_url_include está activada en la configuración de PHP (la opción equivalente a un Remote File Inclusion).

Ejecutar código PHP con este wrapper es bastante sencillo, podemos hacerlo de dos formas:

  • En texto plano
  • En base 64

En texto plano, simplemente tendríamos que usar el siguiente payload:

  • data:text/plain,<código PHP>

Ejemplo:

image

De cara a hacerlo usando base64, simplemente tendríamos que encodear el código PHP:

image 264

Y colocarlo en el wrapper tal que:

  • data://text/plain;base64,<código PHP en base64>
  • data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NtZF0pOyA/Pgo=

De esta forma, como estamos definiendo un parámetro para ejecutar comandos, el payload para por ejemplo ejecutar el comando id sería:

  • data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NtZF0pOyA/Pgo=&cmd=id

Ejemplo:

image 263

php://input

Este wrapper es parecido al de arriba (data). Se puede usar para incluir código PHP. Su requisito al igual que el wrapper data es que la opción allow_url_include de la configuración de PHP debe de estar habilitada.

Con esto hecho, se podría ejecutar comandos mandando el código PHP en los datos de una petición POST. Ejemplo:

  • curl -s -X POST -d ‘<código PHP>’ ‘http://example.com/index.php?file=php://input’
image 262

En este caso, la salida del comando la podemos ver en la respuesta.

expect://

El wrapper expect no está instalado por defecto, pero en el caso de que lo esté, permite ejecutar directamente comandos de la siguiente forma:

  • expect://<comando>

Esto ocurre porque este wrapper da acceso a una PTY (pseudo-teletype), que en UNIX básicamente se refiere a una terminal. Da acceso tanto al STDIN, STDOUT como STDERR.

Conclusión PHP Wrappers

Como hemos podido ver, esta característica de PHP es muy útil en muchas ocasiones, ya que nos puede ayudar conseguir acciones que de una u otra forma no podríamos. Es bastante útil hacer uso de ellas cuando estamos ante vulnerabilidades como el Local File Inclusion (LFI) o el XML External Entity (XXE), o realmente en cualquier caso donde veamos que tenemos la capacidad de usarlas.

Referencias

  • What do pty and tty mean?
  • expect://
  • File Inclusion / Directory Traversal – HackTheBox Academy

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...