这次主要白盒审计MetInfo CMS的一个变量覆盖漏洞。
先查看\include\common.inc.php文件,因为其中是通过$_request来获取用户请求的信息:
这里是遍历初始化变量,很可能会出现变量覆盖,判断了key的第一个字符是不是“_”来避免覆盖系统全局变量,以及使用自定义函数daddslashes()对变量值进行处理。
接着查看daddslashes()函数的定义:
可以看到,该函数先判断有没有开启magic_quotes_gpc即魔法引号,若没有则调用addslashes()函数对通过POST方法提交的内容进行转义过滤。也就是说,并没有对GET方法提交的内容进行过滤。
接着来看/about/页面的信息,查看\about\index.php文件,这里存在两个比较可疑的变量、一个是fmodule变量、另一个是module变量,其中还有require_once()函数,可能存在文件包含漏洞:
先来输出一下看看$module变量的值是什么:
可以看到是一个show.php 文件。
然后尝试一下能不能将$module变量的值覆盖掉:
查看得到并没有覆盖掉。
下面接着看包含进来的文件/include/module.php:
可以看到包含了common.inc.php文件。
也就是说\about\index.php文件中的$fmodule变量可以通过包含/include/module.php>包含common.inc.php>然后接收$_request来接受GET方法传递过来的新的fmodule值来导致原fmodule变量的值被覆盖,输出尝试一下:
可以看到fmodule被覆盖掉了。
因为需要利用到require_once()函数来实现文件包含漏洞的利用,接着找fmodule变量和module变量之间的关系,回到module.php来跟踪module变量,可以看到在最后的判断语句中存在该变量:
先在结尾输出一下看看能不能进行覆盖:
当fmodule不为7时,不覆盖;fmodule为7时,覆盖:
即存在变量覆盖漏洞,可以进行文件包含漏洞的利用。
下面就是利用的示例,包含上传的小马文件xiaoma.txt:
只要将该文件包含即可进行PHP解析而不是看该文件后缀名,降低了攻击成本。接下来的利用就是按部就班了。
防御方法:
最简单的防御实现就是,直接在\about\index.php中判断module变量的值是否等于“show.php”,若是则包含指定的文件,否则不进行任何操作:
再次访问一样的URL已经不生效了(返回空白页面):
这里提一下PHP文件包含漏洞正常的防御方法:
1、严格判断包含中的参数是否外部可控。
2、路径限制,限制被包含的文件只能在某一个文件夹内,特别是一定要禁止目录跳转字符,如:“../”。
3、基于白名单的包含文件验证,验证被包含的文件是否在白名单中。
4、尽量不要使用动态包含,可以在需要包含的页面固定写好,如:“include("head.php")”。
5、可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。