# LFI2RCE via Espera Eterna
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras maneiras de apoiar o HackTricks: * Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
## Informação Básica Por padrão, quando um arquivo é enviado para o PHP (mesmo que não esteja esperando), ele irá gerar um arquivo temporário em `/tmp` com um nome como **`php[a-zA-Z0-9]{6}`**, embora eu tenha visto algumas imagens do docker onde os arquivos gerados não contêm dígitos. Em uma inclusão de arquivo local, **se você conseguir incluir esse arquivo enviado, obterá RCE**. Observe que por padrão **o PHP permite apenas o envio de 20 arquivos em uma única solicitação** (definido em `/etc/php//apache2/php.ini`): ``` ; Maximum number of files that can be uploaded via a single request max_file_uploads = 20 ``` Também, o **número de nomes de arquivo potenciais são 62\*62\*62\*62\*62\*62 = 56800235584** ### Outras técnicas Outras técnicas dependem de atacar os protocolos PHP (você não será capaz se controlar apenas a última parte do caminho), revelar o caminho do arquivo, abusar de arquivos esperados, ou **fazer o PHP sofrer uma falha de segmentação para que os arquivos temporários enviados não sejam excluídos**.\ Essa técnica é **muito semelhante à última, mas sem a necessidade de encontrar uma vulnerabilidade zero day**. ### Técnica de espera eterna Nesta técnica **só precisamos controlar um caminho relativo**. Se conseguirmos enviar arquivos e fazer o **LFI nunca terminar**, teremos "tempo suficiente" para **forçar bruta os arquivos enviados** e **encontrar** qualquer um dos arquivos enviados. **Prós desta técnica**: * Você só precisa controlar um caminho relativo dentro de um include * Não requer nginx ou um nível inesperado de acesso aos arquivos de log * Não requer uma vulnerabilidade zero day para causar uma falha de segmentação * Não requer uma revelação de caminho Os **principais problemas** desta técnica são: * Necessidade de um arquivo(s) específico(s) estar presente (pode haver mais) * A **quantidade insana** de nomes de arquivo potenciais: **56800235584** * Se o servidor **não estiver usando dígitos**, o total potencial é: **19770609664** * Por padrão, **apenas 20 arquivos** podem ser enviados em uma **única solicitação**. * O **número máximo de trabalhadores paralelos** do servidor utilizado. * Esse limite junto com os anteriores pode fazer com que esse ataque dure muito tempo * **Tempo limite para uma solicitação PHP**. Idealmente, isso deveria ser eterno ou deveria encerrar o processo PHP sem excluir os arquivos temporários enviados, caso contrário, isso também será um problema Então, como você pode **fazer um include PHP nunca terminar**? Apenas incluindo o arquivo **`/sys/kernel/security/apparmor/revision`** (**não disponível em contêineres Docker** infelizmente...). Tente apenas chamando: ```bash php -a # open php cli include("/sys/kernel/security/apparmor/revision"); ``` ## Apache2 Por padrão, o Apache suporta **150 conexões simultâneas**, seguindo [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) é possível aumentar esse número para 8000. Siga este tutorial para usar o PHP com esse 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 padrão, (como pude ver nos meus testes), um **processo PHP pode durar eternamente**. Vamos fazer alguns cálculos: * Podemos usar **149 conexões** para gerar **149 \* 20 = 2980 arquivos temporários** com nossa webshell. * Em seguida, usar a **última conexão** para **forçar** possíveis arquivos. * A uma velocidade de **10 solicitações/s** os tempos são: * 56800235584 / 2980 / 10 / 3600 \~= **530 horas** (50% de chance em 265h) * (sem dígitos) 19770609664 / 2980 / 10 / 3600 \~= 185h (50% de chance em 93h) {% hint style="warning" %} Note que no exemplo anterior estamos **completamente DoSando outros clientes**! {% endhint %} Se o servidor Apache for melhorado e pudermos abusar de **4000 conexões** (metade do caminho para o número máximo). Poderíamos criar `3999*20 = 79980` **arquivos** e o **número** seria **reduzido** para cerca de **19.7h** ou **6.9h** (10h, 3.5h 50% de chance). ## PHP-FMP Se em vez de usar o módulo php regular para o apache executar scripts PHP a **página da web estiver usando** **PHP-FMP** (isso melhora a eficiência da página da web, então é comum encontrá-lo), há algo mais que pode ser feito para melhorar a técnica. O PHP-FMP permite **configurar** o **parâmetro** **`request_terminate_timeout`** em **`/etc/php//fpm/pool.d/www.conf`**.\ Este parâmetro indica a quantidade máxima de segundos **quando** a **solicitação ao PHP deve ser encerrada** (infinito por padrão, mas **30s se o parâmetro for descomentado**). Quando uma solicitação está sendo processada pelo PHP pelo número indicado de segundos, ela é **encerrada**. Isso significa que se a solicitação estava enviando arquivos temporários, porque o **processamento php foi interrompido**, esses **arquivos não serão excluídos**. Portanto, se você puder fazer uma solicitação durar esse tempo, você pode **gerar milhares de arquivos temporários** que não serão excluídos, o que **acelerará o processo de encontrá-los** e reduzirá a probabilidade de um DoS na plataforma ao consumir todas as conexões. Então, para **evitar DoS** vamos supor que um **atacante estará usando apenas 100 conexões** ao mesmo tempo e o tempo máximo de processamento do php pelo **php-fmp** (`request_terminate_timeout`**)** é **30s**. Portanto, o número de **arquivos temporários** que podem ser gerados **por segundo** é `100*20/30 = 66.67`. Então, para gerar **10000 arquivos** um atacante precisaria de: **`10000/66.67 = 150s`** (para gerar **100000 arquivos** o tempo seria de **25min**). Então, o atacante poderia usar essas **100 conexões** para realizar uma **busca de força bruta**. Supondo uma velocidade de 300 req/s, o tempo necessário para explorar isso é o seguinte: * 56800235584 / 10000 / 300 / 3600 \~= **5.25 horas** (50% de chance em 2.63h) * (com 100000 arquivos) 56800235584 / 100000 / 300 / 3600 \~= **0.525 horas** (50% de chance em 0.263h) Sim, é possível gerar 100000 arquivos temporários em uma instância de tamanho médio do EC2:
{% hint style="warning" %} Note que para acionar o tempo limite seria **suficiente incluir a página LFI vulnerável**, para que entre em um loop de inclusão eterno. {% endhint %} ## Nginx Parece que por padrão o Nginx suporta **512 conexões paralelas** ao mesmo tempo (e esse número pode ser melhorado).