# LFI2RCE via Eternal waiting {{#include ../../banners/hacktricks-training.md}} ## 基本信息 默认情况下,当文件上传到 PHP(即使它不期望这样做)时,它将在 `/tmp` 中生成一个临时文件,名称类似于 **`php[a-zA-Z0-9]{6}`**,尽管我见过一些 docker 镜像生成的文件不包含数字。 在本地文件包含中,**如果你设法包含那个上传的文件,你将获得 RCE**。 请注意,默认情况下 **PHP 只允许在单个请求中上传 20 个文件**(在 `/etc/php//apache2/php.ini` 中设置): ``` ; Maximum number of files that can be uploaded via a single request max_file_uploads = 20 ``` 此外,**潜在文件名的数量为 62\*62\*62\*62\*62\*62 = 56800235584** ### 其他技术 其他技术依赖于攻击 PHP 协议(如果您只控制路径的最后部分,则无法进行攻击)、披露文件路径、滥用预期文件,或**使 PHP 遭受分段错误,以便上传的临时文件不会被删除**。\ 这种技术**与最后一种非常相似,但不需要找到零日漏洞**。 ### 永久等待技术 在这种技术中,**我们只需要控制一个相对路径**。如果我们设法上传文件并使**LFI 永远不会结束**,我们将有“足够的时间”来**暴力破解上传的文件**并**找到**任何已上传的文件。 **这种技术的优点**: - 您只需控制包含中的相对路径 - 不需要 nginx 或意外的访问日志文件的级别 - 不需要零日漏洞来导致分段错误 - 不需要路径披露 这种技术的**主要问题**是: - 需要特定的文件存在(可能还有更多) - **潜在文件名的数量惊人**:**56800235584** - 如果服务器**不使用数字**,则总潜在数量为:**19770609664** - 默认情况下,**每个请求只能上传 20 个文件**。 - 使用的服务器的**最大并行工作者数量**。 - 这个限制与之前的限制可能会使攻击持续太久 - **PHP 请求的超时**。理想情况下,这应该是永恒的,或者应该在不删除临时上传文件的情况下终止 PHP 进程,否则这也会很麻烦 那么,您如何**使 PHP 包含永远不会结束**?只需包含文件**`/sys/kernel/security/apparmor/revision`**(**在 Docker 容器中不可用**,不幸的是...)。 只需调用: ```bash php -a # open php cli include("/sys/kernel/security/apparmor/revision"); ``` ## Apache2 默认情况下,Apache 支持 **150 个并发连接**,根据 [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) 的信息,可以将这个数字提升到 8000。按照此方法使用 PHP 和该模块: [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)。 默认情况下,(根据我的测试)**PHP 进程可以永远存在**。 让我们做一些数学计算: - 我们可以使用 **149 个连接** 来生成 **149 \* 20 = 2980 个临时文件**,通过我们的 webshell。 - 然后,使用 **最后一个连接** 来 **暴力破解** 潜在文件。 - 以 **10 个请求/秒** 的速度,时间为: - 56800235584 / 2980 / 10 / 3600 \~= **530 小时**(265 小时有 50% 的机会) - (不带数字)19770609664 / 2980 / 10 / 3600 \~= 185 小时(93 小时有 50% 的机会) > [!WARNING] > 请注意,在前面的例子中,我们正在 **完全 DoS 其他客户端**! 如果 Apache 服务器得到改善,我们可以滥用 **4000 个连接**(达到最大数量的一半)。我们可以创建 `3999*20 = 79980` **个文件**,并且 **时间** 将 **减少** 到大约 **19.7 小时** 或 **6.9 小时**(10 小时,3.5 小时有 50% 的机会)。 ## PHP-FMP 如果不是使用常规的 php 模块来运行 PHP 脚本,而是 **网页使用** **PHP-FMP**(这提高了网页的效率,因此常见),还有其他方法可以改进该技术。 PHP-FMP 允许在 **`/etc/php//fpm/pool.d/www.conf`** 中 **配置** **参数** **`request_terminate_timeout`**。\ 该参数指示 **请求 PHP 时必须终止的最大秒数**(默认无限制,但 **如果参数未注释则为 30 秒**)。当 PHP 正在处理请求时,达到指定的秒数后,它会被 **终止**。这意味着,如果请求正在上传临时文件,因为 **PHP 处理被停止**,那些 **文件不会被删除**。因此,如果您能让请求持续那么长时间,就可以 **生成成千上万的临时文件**,这些文件不会被删除,这将 **加快查找它们的过程**,并减少通过消耗所有连接对平台造成 DoS 的可能性。 因此,为了 **避免 DoS**,假设 **攻击者将同时使用 100 个连接**,而 php-fmp 的最大处理时间 **(`request_terminate_timeout`**) 为 **30 秒**。因此,每秒可以生成的 **临时文件** 数量为 `100*20/30 = 66.67`。 然后,攻击者需要 **`10000/66.67 = 150s`** 来生成 **10000 个文件**(生成 **100000 个文件** 的时间为 **25 分钟**)。 然后,攻击者可以使用这 **100 个连接** 来执行 **暴力搜索**。假设速度为 300 req/s,利用此漏洞所需的时间如下: - 56800235584 / 10000 / 300 / 3600 \~= **5.25 小时**(2.63 小时有 50% 的机会) - (有 100000 个文件)56800235584 / 100000 / 300 / 3600 \~= **0.525 小时**(0.263 小时有 50% 的机会) 是的,可以在 EC2 中等大小的实例中生成 100000 个临时文件:
> [!WARNING] > 请注意,为了触发超时,**只需包含易受攻击的 LFI 页面**,使其进入一个永恒的包含循环。 ## Nginx 默认情况下,Nginx 似乎支持 **512 个并行连接**(这个数字可以提高)。 {{#include ../../banners/hacktricks-training.md}}