0x00
先自动审计,找到有eval函数的地方,根据结果可以看到eval函数集中在/inc/coomon/template.php
根据经验,这个文件应该是用于模板渲染的。Eval函数集中出现在ifex和runphp两个函数当中:之后应该要找到触发这两个函数的方法,可以全局搜索ifex函数(runphp触发失败),查看有哪些地方调用:这里主要是用到index.php当中的调用。
0x01 关于模板调用的过程分析:
要挖掘到这个漏洞首先要了解一下整个模板的调用过程:
程序首先拆分m参数,然后根据不同类型加载不同模板:
当我们进行一次搜索时,请求是这个亚子的:
然后参数被分为vod和search两部分,之后加载/inc/module/vod.php文件根据method参数为search找到如下代码:我们可以看到我们查询的参数传递到$tpl对象的P属性中,之后继续跟踪代码,其实就是利用正则表达式对模板文件进行替换:可以看到在第181行加载模板文件 我们先来看一下模板文件啥样:其中的page:key会被替换成我们输入的关键字。而且继续跟踪代码,发现它调用了mark方法进行一些正则替换:因为这个方法当中可以调用了runphp函数,所以尝试在这个地方尝试触发RCE,结果失败了。先跳出这个函数,之后又调用pageshow函数进行处理除了经过上面两个方法,之后还要进过一部分的正则替换整个模板才算处理完成这个时候我们可以看一下模板文件被处理后的样子:
可以发现这个时候虽然模板文件内容被替换了一部分,但是还不是前台显示的样子,所以其实解析内容还没有完全结束。而且根据之前的调试我们也发现还没有进行过eval处理,将变量填充到模板文件中,所以之后肯定还有一步处理过程。
根据index.php内容,在加载了模板文件之后,要调用ifex方法,这个方法才是进行变量解释的部分:
到这整个模板加载的流程已经全部了解了。
在这里我们可以发现整个模板解析过程分为两部分,ifex之前的部分本质就是解析模板本身的内容,将模板内要填充变量的地方填充成变量解析的格式,然后第二部分调用ifex进行变量解析。在第一部分进行替换的过程其实替换的是模板本身的内容,只要模板本身没有出错就不会产生漏洞。所以我们要想利用ifex解析变量过程执行恶意代码,就必须破坏第一部分解析,在第一步解析完成之后模板内容当中必须包含我们自定义的恶意代码,这样在ifex解析时就会把我们的恶意代码一起渲染解释。那么我们首要便是找到可交互位置,只有我们输入的内容,前台也进行输出,才说明我们的输入被添加进入模板文件了。
0x02
这里选择搜索框当作漏洞触发点。
根据之前的跟踪我们发现ifex解析之前,模板的内容是有自己的固定格式的,而且通过分析ifex函数也可以看出来:
可以看到ifex通过一个正则表达式来识别这种固定格式,然后将识别内容全部存入数组$iar当中。关于这个正则表达式,我们来具体看一下:
他会匹配如上的一个格式,然后keyword位置的内容会被存入$iar[2]数组,之后赋值给$strif,因为这个变量会拼接到eval当中,所以要特别关注。
接下来我们通过debug方式来看一下之前的分析是否正确:在搜索框输入上面的字符串
经过第一部分替换之后:
进入ifex进行解析时:可以看到我们之前的分析没有错,而且可以看出我们输入的恶意已经确实已经改变了模板的结构,之后继续debug看如何触发eval执行自定义代码:可以看到在第904行输入的keyword被传递到eval函数当中:通过echo输出eval执行的字符串:可以尝试自己拼接php代码执行任意代码。不过要注意的是存在危险字符过滤,所以构造php代码时要注意:放出最后写shell的payload:利用base64编码绕过单双引号限制,利用file_put_contents写入文件。成功写入一句话木马:在下载的另外一个版本中发现了修复方案: