ThinkPHP3.2.3代码审计

写在前面

  刚好CTFSHOW做到ThinkPHP代码审计的部分了,以前也没尝试审计过这种完整的框架,只会照着成品Payload瞎打,这里就审计下ThinkPHP3.2.3的那些利用点,总结一下。

审计


分析

ThinkPHP3.2.3代码审计

 show方法在ThinkPHP/Library/Think/Controller.class.php中被定义

ThinkPHP3.2.3代码审计

 此处参数$content可控即可使得show方法实现代码执行。

跟进display方法。

ThinkPHP3.2.3代码审计

 跟进display方法中的72行,在此参数$content会被解析。

ThinkPHP3.2.3代码审计

 在117-127行参数$content被具体处理,根据配置TMPL_ENGINE_TYPE的不同会使用不同的引擎,最终在129获取到解析后结果,在133行被返回输出。

先看ctfshow题目中对应的TMPL_ENGINE_TYPE='php'配置的情况。

ThinkPHP3.2.3代码审计

 以参数$content值为hello为例,122行处eval对应输出为

ThinkPHP3.2.3代码审计

所以构造参数$content值为<?php Payload_Code?>样式的代码即可实现show方法导致的命令执行。

再看TMPL_ENGINE_TYPE为其他值的情况(实际上划分为了think和第三方两种)。

ThinkPHP3.2.3代码审计

 参数$content被组合进数组$params,并在126行进行进一步处理。

ThinkPHP3.2.3代码审计

 跟进,注意到在在89行数组params被调用。

ThinkPHP3.2.3代码审计

 119行处数组params被进一步调用,跟进。

ThinkPHP3.2.3代码审计

 引擎在这里被进一步细分为think和第三方两种,这里不讨论第三方。

根据缓存的是否有效分别会加载缓存或模板文件,而缓存是否有效与show方法传入的参数$content的值有关,第一次传入时因为不存在对应缓存(缓存无效)会加载模板并生成对应的缓存接着再加载,在第二次传入时由于已存在对应缓存便会直接加载缓存。

从结果上来看两者是等效的,两种情况最终会调用28行的load方法(不代表传入的参数的情况完全如28行中所示)来加载缓存文件。

ThinkPHP3.2.3代码审计

令show方法传入参数$content的值为<?php phpinfo();?>为例并进入缓存无效的情况,审计生成缓存过程中涉及传入内容处理的相关代码。

ThinkPHP3.2.3代码审计

 直接跟进到解析的部分,此处的$tmplContent即为传入的内容,126行-134行简略来说对传入内容进行了PHP代码优化、Lirertal标签替换等,但不影响PHP代码解析(但是会增加可解析的形式,这一点会在给出的Payload中体现)。

最终解析完成并在load方法中include的内容如下(通常来说并不会触发exit)。

ThinkPHP3.2.3代码审计

Payload

TMPL_ENGINE_TYPE=Think/php

<?php Payload_Code ?>
<?= Payload_Code ?>

TMPL_ENGINE_TYPE=Think

<php>Payload_Code</php>
<php>Payload_Code<php>

未完待续

上一篇:Google Earth Engine——GEE中的Explorer如何使用,简单轻松的找到数据集长什么样子?


下一篇:不愧是阿里大佬,docker升级homeassistant