lunes, 15 de junio de 2015

El viejo truco del symlink

Symlinks y PHP

En los sistemas unix/linux, un "symlink" o "enlace simbólico" es un tipo de fichero que hace referencia a otro fichero o directorio. Esto tiene cierta utilidad para mantener una estructura determinada en el árbol de directorios  sin duplicar la información puesto que los symlinks no son copias sino simples enlaces o referencias.

Desde la consola de linux se puede crear un symlink con el siguiente comando:

$ ln -s /ruta/al/fichero nombre_symlink

Y desde PHP, usando función "symlink". Así:

symlink("/ruta/al/fichero", "nombre_symlink");


PHP open_basedir

La directiva "open_basedir" de la configuración de PHP permite establecer un directorio base donde serán "enjaulados" los scripts PHP. De esta forma si un script intenta acceder a un recurso que esté fuera del directorio base se producirá un error y no se permitirá el acceso.

Esta directiva es configurada por algunos servidores de hosting y puede dar problemas luego de subir nuestra shell pues quedamos enjaulados y no podemos tener acceso al resto del árbol de directorios. Algunas formas simples de burlarlo son por ejemplo llamando a un programa externo con la función "system" (u otras similares) pues los programas externos no son afectados por la configuración de PHP. Otra forma sería usando un CGI en perl porque obviamente perl tampoco está afectado por el open_basedir.

Pero si las funciones para ejecutar programas externos están desactivadas y no es posible usar scripts en perl también hay otro truco sencillo usando symlinks.


El viejo truco del symlink

El truco consiste en crear un symlink que apunte a la raíz del árbol de directorios y luego usarlo para acceder al resto de ficheros.

Un primer intento sería ejecutar el siguiente código PHP:

symlink("../../../../../../", "root");

Pero va a fallar porque viola la restricción de open_basedir. Sin embargo, si lo hacemos como se muestra a continuación, no violaremos la restricción open_basedir y conseguiremos el mismo efecto:

symlink("x/x/x/x/x/x/", "foo");
symlink("foo/../../../../../../", "root");
unlink("foo");
symlink(".", "foo");

 
Expliquemos esto un poco. Primero se crea un symlink llamado "foo" que apunta seis directorios hacia "adelante" en el arbol de directorios. Esto no viola la restriccion open_basedir porque ésta es para directorios hacia atrás ;)

Luego se crea otro symlink, "root", que apunta hacia dentro del symlink "foo" y luego seis directorios hacia atrás ("foo/../../../../../../"). Esto no viola la restricción, pues al resolverse la secuencia de directorios veremos que "root" termina apuntando al directorio actual.

Luego borramos el symlink "foo" y creamos otro con el mismo nombre pero que ahora apunta al directorio actual (".") De esta manera conseguimos que ahora el symlink "root" apunte seis directorios hacia atrás del directorio actual. Suficiente para llegar a la raiz }:)) Jejeje

Finalmente accederíamos al resto de ficheros usando el symlink en la URL:

http://example.com/root/etc/passwd


Un saludo.


Actualización: Dejo una demo en vídeo.


4 comentarios:

  1. Un gran post! siempre entro acá con la intención de alimentarme de tu maravilloso blog, podés hacer un video explicando más sobre el tema? la verdad quedé con ganas de más, saludos desde colombia!

    ResponderEliminar
    Respuestas
    1. Hola, gracias por tu comentario. Actualicé el post con una demo en vídeo para que quede más claro.

      Un saludo desde Perú :D

      Eliminar
  2. La verdad desde hace mucho tiempo que ya no pirático intrusión, quiero decir que se parece a un ataque de LFI..

    ResponderEliminar
  3. Hola Alguien q tal soy de Peru kisiera q me ayudes con este mac q no encuentro creo q es falso pero no se cual seria la verdadera :F88C9F. ayudame amigo yo se q usted es un experto se lo agradesco mucho conosco todos los mac pero este se me hace un poco dificil. gracias .

    ResponderEliminar