前言
maccms8.x命令执行漏洞分析现场…..
先放上POC
漏洞分析
根据POC,来到index.php
然后跟进be()
也就是说通过get请求发送$m
再将$m打散成$par
先看$par[0]
我们跟到vod.php然后这个’search’为method之一.看看wd在search中是怎么用的
然后这里的$wd可以通过任何形式的请求获得.
知道了$m的作用,然后我们回到index.php,看看这里是如何解析$wd
跟进到$tpl->ifex();
这里指定一个匹配规则:{if-([\s\S]?):([\s\S]+?)}([\s\S]?){endif-\1}
$this->H在vod.php中可以找到:
所以实际上,
1 | preg_match_all($labelRule,$this->H,$iar); |
这段代码是在匹配获得我们输入参数后的html页面的符合匹配规则的字符串放入$iar中.
这里的正则匹配如果看不懂了,建议debug动态调试一下,有助于理解
进入一个for循环
底下的代码可以看到一堆eval()
这个就是漏洞的触发点,要做的就是绕过限制,触发命令执行.
找到912行处,这里对eval的限制最少.
所以最终我们输入的wd参数带有{if-就可以绕过,因为最前面有这么一行代码:
1 | if (!strpos(",".$this->H,"{if-")) { return; } |
然后还要满足匹配规则:{if-([\s\S]?):([\s\S]+?)}([\s\S]?){endif-\1}
所以构造payload:
1 | {if-A:(phpinfo())}{endif-A} |
总结
这个漏洞不难,根据POC,也能很快的分析出来.
就是中间发现原来自己对preg_match_all()这个函数的用法一直没有理解通透.
学长和我说正则匹配出的数组中存储的信息,要看它正则表达式是怎么写的:
表达式:{if-([\s\S]?):([\s\S]+?)}([\s\S]?){endif-\1}
所以他匹配的结果就是一个二维数组$iar
以下是$iar[0]的内容:
这是根据正则规则,匹配出的所有字符串
以下是$iar[2]的内容:
发现没有$iar[2]的内容就是第二个[\s\S]的匹配内容
以下分别是$iar[1]和$iar[3]的内容