# LFI2RCE a través de la espera eterna
Aprende hacking en AWS de cero a héroe conhtARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
* Si quieres ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Información Básica
Por defecto, cuando se sube un archivo a PHP (incluso si no lo está esperando), generará un archivo temporal en `/tmp` con un nombre como **`php[a-zA-Z0-9]{6}`**, aunque he visto algunas imágenes de docker donde los archivos generados no contienen dígitos.
En una inclusión de archivo local, **si logras incluir ese archivo subido, conseguirás RCE**.
Ten en cuenta que por defecto **PHP solo permite subir 20 archivos en una sola petición** (configurado en `/etc/php//apache2/php.ini`):
```
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
```
También, el **número de nombres de archivos potenciales es 62\*62\*62\*62\*62\*62 = 56800235584**
### Otras técnicas
Otras técnicas se basan en atacar protocolos de PHP (no podrás si solo controlas la última parte de la ruta), revelando la ruta del archivo, abusando de archivos esperados, o **haciendo que PHP sufra una falla de segmentación para que los archivos temporales subidos no se eliminen**.\
Esta técnica es **muy similar a la última pero sin necesidad de encontrar un zero day**.
### Técnica de espera eterna
En esta técnica **solo necesitamos controlar una ruta relativa**. Si logramos subir archivos y hacer que el **LFI nunca termine**, tendremos "suficiente tiempo" para **fuerza bruta en archivos subidos** y **encontrar** cualquiera de los que se hayan subido.
**Pros de esta técnica**:
* Solo necesitas controlar una ruta relativa dentro de un include
* No requiere nginx ni un nivel de acceso inesperado a archivos de registro
* No requiere un 0 day para causar una falla de segmentación
* No requiere revelación de ruta
Los **problemas principales** de esta técnica son:
* Necesidad de que esté presente un archivo específico(s) (podría haber más)
* La cantidad **insana** de nombres de archivos potenciales: **56800235584**
* Si el servidor **no utiliza dígitos** la cantidad total potencial es: **19770609664**
* Por defecto **solo se pueden subir 20 archivos** en una **sola solicitud**.
* El **número máximo de trabajadores paralelos** del servidor utilizado.
* Este límite con los anteriores puede hacer que este ataque dure demasiado
* **Tiempo de espera para una solicitud de PHP**. Idealmente, esto debería ser eterno o debería matar el proceso de PHP sin eliminar los archivos temporales subidos, si no, esto también será un problema
Entonces, ¿cómo puedes **hacer que un include de PHP nunca termine**? Simplemente incluyendo el archivo **`/sys/kernel/security/apparmor/revision`** (**lamentablemente no disponible en contenedores Docker**).
Pruébalo llamando:
```bash
php -a # open php cli
include("/sys/kernel/security/apparmor/revision");
```
## Apache2
Por defecto, Apache soporta **150 conexiones concurrentes**, siguiendo [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) es posible aumentar este número hasta 8000. Sigue esto para usar PHP con ese módulo: [https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04).
Por defecto, (como puedo ver en mis pruebas), un **proceso PHP puede durar eternamente**.
Hagamos algunos cálculos:
* Podemos usar **149 conexiones** para generar **149 \* 20 = 2980 archivos temporales** con nuestro webshell.
* Luego, usar la **última conexión** para **fuerza bruta** de archivos potenciales.
* A una velocidad de **10 solicitudes/s** los tiempos son:
* 56800235584 / 2980 / 10 / 3600 \~= **530 horas** (50% de probabilidad en 265h)
* (sin dígitos) 19770609664 / 2980 / 10 / 3600 \~= 185h (50% de probabilidad en 93h)
{% hint style="warning" %}
¡Nota que en el ejemplo anterior estamos **DoSing completamente a otros clientes**!
{% endhint %}
Si el servidor Apache está mejorado y pudiéramos abusar de **4000 conexiones** (a mitad de camino hacia el máximo). Podríamos crear `3999*20 = 79980` **archivos** y el **número** se **reduciría** a alrededor de **19.7h** o **6.9h** (10h, 3.5h con 50% de probabilidad).
## PHP-FMP
Si en lugar de usar el módulo php regular para apache para ejecutar scripts PHP, la **página web está usando** **PHP-FMP** (esto mejora la eficiencia de la página web, por lo que es común encontrarlo), hay algo más que se puede hacer para mejorar la técnica.
PHP-FMP permite **configurar** el **parámetro** **`request_terminate_timeout`** en **`/etc/php//fpm/pool.d/www.conf`**.\
Este parámetro indica la cantidad máxima de segundos **cuando** **la solicitud a PHP debe terminar** (infinito por defecto, pero **30s si el parámetro está descomentado**). Cuando una solicitud está siendo procesada por PHP el número indicado de segundos, es **terminada**. Esto significa, que si la solicitud estaba subiendo archivos temporales, debido a que el **procesamiento de php fue detenido**, esos **archivos no van a ser eliminados**. Por lo tanto, si puedes hacer que una solicitud dure ese tiempo, puedes **generar miles de archivos temporales** que no serán eliminados, lo que **acelerará el proceso de encontrarlos** y reduce la probabilidad de un DoS a la plataforma al consumir todas las conexiones.
Entonces, para **evitar DoS** supongamos que un **atacante estará usando solo 100 conexiones** al mismo tiempo y el tiempo máximo de procesamiento de php por **php-fmp** (`request_terminate_timeout`**) es **30s**. Por lo tanto, el número de **archivos temporales** que se pueden generar **por segundo** es `100*20/30 = 66.67`.
Luego, para generar **10000 archivos** un atacante necesitaría: **`10000/66.67 = 150s`** (para generar **100000 archivos** el tiempo sería **25min**).
Luego, el atacante podría usar esas **100 conexiones** para realizar una **búsqueda por fuerza bruta**. \*\*\*\* Suponiendo una velocidad de 300 req/s el tiempo necesario para explotar esto es el siguiente:
* 56800235584 / 10000 / 300 / 3600 \~= **5.25 horas** (50% de probabilidad en 2.63h)
* (con 100000 archivos) 56800235584 / 100000 / 300 / 3600 \~= **0.525 horas** (50% de probabilidad en 0.263h)
Sí, es posible generar 100000 archivos temporales en una instancia EC2 de tamaño medio:
{% hint style="warning" %}
Nota que para activar el tiempo de espera sería **suficiente incluir la página LFI vulnerable**, para que entre en un bucle de inclusión eterno.
{% endhint %}
## Nginx
Parece que por defecto Nginx soporta **512 conexiones paralelas** al mismo tiempo (y este número puede ser mejorado).
Aprende hacking en AWS de cero a héroe conhtARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).