欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

PbootCMS v1.3.2命令执行和SQL注入漏洞

来源: 作者: 时间:2019-02-24 19:29 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助

前几天看到个PbootCMS,然后打算审计一波,网上找了这个cms之前的漏洞,看到有表哥审计过这个文章了,https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=45649&page=1#pid506915,可能别的表哥也发现了这个漏洞,这里简单说下我的思路。
 
0x01 命令执行漏洞
这个漏洞目前找到5处,新版本和老版本不同的是新版本加了过滤,但是可以绕过,漏洞函数在ParserController.php里。在2330多行这里,parserIfLabel()方法中调用了eval函数。而且前面有过滤。先忽略过滤内容,一会回来看,看下哪里调用了parserfLabel方法。

找到了parserIfLabel()方法,而且从下面可以看到在ParserController.php中parserAfter()方法调用了parserIfLabel()方法。


再跟进下parserAfter()方法。根据注释和代码可以分析出这是这个模板在前端渲染的时候,解析标签步骤如下:解析框架标签,解析前置公共标签,解析当前位置标签,解析分类信息标签,解析内容标签,解析公共后置标签。问题出在最后一步“解析公共后置标签”这里,这里存在eval()函数调用。这个函数存在的地方其实可以用一句话表示:
只要存在把用户输入输出到前端的地方,就会有代码执行漏洞。

找到漏洞点,看下过滤。回到parserIfLabel()方法,可以看到“$pattern = ‘/{pboot:if(([^}]+))}([\s\S]*?){\/pboot:if}/’;”这个正则把标签 if 后面的内容取了出来,然后经过过滤并执行。这里主要看下最严重的过滤,在第2316-2331行这里。这里会用正则取出“(”前面的字符串(不包括特殊符号),也就是说@eval(‘phpinfo()’),会取出eval和phpinfo两个字符串,然后调用function_exists()函数,如果这两个方法存在,就不会进入eval()里面。
// 带有函数的条件语句进行安全校验
                if (preg_match_all('/([\w]+)([\s]+)?\(/i', $matches[1][$i], $matches2)) {
                    foreach ($matches2[1] as $value) {
                        if ((function_exists($value) || preg_match('/^eval$/i', $value)) && ! in_array($value, $white_fun)) {
                            $danger = true;
                            break;
                        }
                    }
                }
                // 如果有危险函数,则不解析该IF
                if ($danger) {
                    continue;
                } else {
                    $matches[1][$i] = decode_string($matches[1][$i]); // 解码条件字符串
                }


这个是新版本增加的过滤,这里有很多绕过方法,下面说三个:
1 使用空字节,在php中,phpinfo()可以用phpinfo%01()~phpinfo%19()代替,就可以使function_exists()方法返回False。这个绕过只有在留言的地方可以用,经过测试只有那里会进行url解码。

[1] [2]  下一页

前几天看到个PbootCMS,然后打算审计一波,网上找了这个cms之前的漏洞,看到有表哥审计过这个文章了,https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=45649&page=1#pid506915,可能别的表哥也发现了这个漏洞,这里简单说下我的思路。
 
0x01 命令执行漏洞
这个漏洞目前找到5处,新版本和老版本不同的是新版本加了过滤,但是可以绕过,漏洞函数在ParserController.php里。在2330多行这里,parserIfLabel()方法中调用了eval函数。而且前面有过滤。先忽略过滤内容,一会回来看,看下哪里调用了parserfLabel方法。

找到了parserIfLabel()方法,而且从下面可以看到在ParserController.php中parserAfter()方法调用了parserIfLabel()方法。

本文来自无奈人生安全网


再跟进下parserAfter()方法。根据注释和代码可以分析出这是这个模板在前端渲染的时候,解析标签步骤如下:解析框架标签,解析前置公共标签,解析当前位置标签,解析分类信息标签,解析内容标签,解析公共后置标签。问题出在最后一步“解析公共后置标签”这里,这里存在eval()函数调用。这个函数存在的地方其实可以用一句话表示:
只要存在把用户输入输出到前端的地方,就会有代码执行漏洞。

找到漏洞点,看下过滤。回到parserIfLabel()方法,可以看到“$pattern = ‘/{pboot:if(([^}]+))}([\s\S]*?){\/pboot:if}/’;”这个正则把标签 if 后面的内容取了出来,然后经过过滤并执行。这里主要看下最严重的过滤,在第2316-2331行这里。这里会用正则取出“(”前面的字符串(不包括特殊符号),也就是说@eval(‘phpinfo()’),会取出eval和phpinfo两个字符串,然后调用function_exists()函数,如果这两个方法存在,就不会进入eval()里面。 无奈人生安全网
// 带有函数的条件语句进行安全校验
                if (preg_match_all('/([\w]+)([\s]+)?\(/i', $matches[1][$i], $matches2)) {
                    foreach ($matches2[1] as $value) {
                        if ((function_exists($value) || preg_match('/^eval$/i', $value)) && ! in_array($value, $white_fun)) {
                            $danger = true;
                            break;
                        }

无奈人生安全网


                    }
                }
                // 如果有危险函数,则不解析该IF
                if ($danger) {
                    continue;
                } else {
                    $matches[1][$i] = decode_string($matches[1][$i]); // 解码条件字符串
                }
www.wnhack.com

这个是新版本增加的过滤,这里有很多绕过方法,下面说三个:
1 使用空字节,在php中,phpinfo()可以用phpinfo%01()~phpinfo%19()代替,就可以使function_exists()方法返回False。这个绕过只有在留言的地方可以用,经过测试只有那里会进行url解码。
copyright 无奈人生

[1] [2]  下一页

无奈人生安全网

。 (责任编辑:admin)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。