PHP代码审计实战之MetInfo CMS

这次主要白盒审计MetInfo CMS的一个变量覆盖漏洞。

先查看\include\common.inc.php文件,因为其中是通过$_request来获取用户请求的信息:

PHP代码审计实战之MetInfo CMS

这里是遍历初始化变量,很可能会出现变量覆盖,判断了key的第一个字符是不是“_”来避免覆盖系统全局变量,以及使用自定义函数daddslashes()对变量值进行处理。


接着查看daddslashes()函数的定义:

PHP代码审计实战之MetInfo CMS

可以看到,该函数先判断有没有开启magic_quotes_gpc即魔法引号,若没有则调用addslashes()函数对通过POST方法提交的内容进行转义过滤。也就是说,并没有对GET方法提交的内容进行过滤。


接着来看/about/页面的信息,查看\about\index.php文件,这里存在两个比较可疑的变量、一个是fmodule变量、另一个是module变量,其中还有require_once()函数,可能存在文件包含漏洞:

PHP代码审计实战之MetInfo CMS


先来输出一下看看$module变量的值是什么:

PHP代码审计实战之MetInfo CMS

PHP代码审计实战之MetInfo CMS

可以看到是一个show.php 文件。


然后尝试一下能不能将$module变量的值覆盖掉:

PHP代码审计实战之MetInfo CMS

查看得到并没有覆盖掉。


下面接着看包含进来的文件/include/module.php:

PHP代码审计实战之MetInfo CMS

可以看到包含了common.inc.php文件。


也就是说\about\index.php文件中的$fmodule变量可以通过包含/include/module.php>包含common.inc.php>然后接收$_request来接受GET方法传递过来的新的fmodule值来导致原fmodule变量的值被覆盖,输出尝试一下:

PHP代码审计实战之MetInfo CMS

PHP代码审计实战之MetInfo CMS

可以看到fmodule被覆盖掉了。


因为需要利用到require_once()函数来实现文件包含漏洞的利用,接着找fmodule变量和module变量之间的关系,回到module.php来跟踪module变量,可以看到在最后的判断语句中存在该变量:

PHP代码审计实战之MetInfo CMS


先在结尾输出一下看看能不能进行覆盖:

PHP代码审计实战之MetInfo CMS


当fmodule不为7时,不覆盖;fmodule为7时,覆盖:

PHP代码审计实战之MetInfo CMS

PHP代码审计实战之MetInfo CMS

即存在变量覆盖漏洞,可以进行文件包含漏洞的利用。


下面就是利用的示例,包含上传的小马文件xiaoma.txt:

PHP代码审计实战之MetInfo CMS

只要将该文件包含即可进行PHP解析而不是看该文件后缀名,降低了攻击成本。接下来的利用就是按部就班了。


防御方法:

最简单的防御实现就是,直接在\about\index.php中判断module变量的值是否等于“show.php”,若是则包含指定的文件,否则不进行任何操作:

PHP代码审计实战之MetInfo CMS


再次访问一样的URL已经不生效了(返回空白页面):

PHP代码审计实战之MetInfo CMS


这里提一下PHP文件包含漏洞正常的防御方法:

1、严格判断包含中的参数是否外部可控。

2、路径限制,限制被包含的文件只能在某一个文件夹内,特别是一定要禁止目录跳转字符,如:“../”。

3、基于白名单的包含文件验证,验证被包含的文件是否在白名单中。

4、尽量不要使用动态包含,可以在需要包含的页面固定写好,如:“include("head.php")”。

5、可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。