Cmsms_2.2.9前台sql注入(复现)
漏洞原理
- 没有对sql语句进行过滤
- unset操作绕过对字符串的强制类型操作
漏洞分析
class.CMS_Content_Block.php,第237行执行对传入的mact参数进行拆分
$modulename=”news”、$action=”default”
class.CMS_Content_Block.php第289行GetModuleParameters方法 ,解析传入的参数,注册变量,并未做任何过滤,$key值在不为’id’、’returnid’将直接以字符串的形式传递到$param数组中。$param[‘idlist’]=”0,1)) and sleep(9) –”
继续跟进代码,代码进入第295行DoAtionBase方法,第1481行执行模块中的方法.
将$name=’default’拼接至文件名中,第1405行include之.
$filename=’’/var/www/html/cms/cmsms-2.2.9-install/modules/News/action.default.php’
action.default.php第59行漏洞触发关键点,将$idlist拼接进字符串,explode函数拆分字符串,截取关键代码进行分析
for循环第一次count($tmp)=2
,由于进入if条件语句删除了数组第一个字符。第二次判断count($tmp)=1
,此时$i=1不满足跳出循环,第二个字符串'1)) and sleep(5) --'
就不会被强制转换为数值
$idlist='0,1)) and sleep(5) --';
$tmp = explode(',',$idlist);
for( $i = 0; $i < count($tmp); $i++ ) {
$tmp[$i] = (int)$tmp[$i];
if( $tmp[$i] < 1 ) unset($tmp[$i]);
}
漏洞复现
逗号、单引号被实体编码需要绕过
mact=News,m1_,default,0&m1_idlist=0,1))and(case+when+ascii((select+substr(database()+from+1+for+1))%3d99)+then+sleep(1)+else+0+end)%23
漏洞修复
2.2.11版本对该处进行修复
in_array加强了对非法字符串的判断,去掉unset操作
if( isset($params['idlist']) ) {
$idlist = $params['idlist'];
if( is_string($idlist) ) {
$tmp = explode(',',$idlist);
$idlist = [];
for( $i = 0; $i < count($tmp); $i++ ) {
$val = (int)$tmp[$i];
if( $val > 0 && !in_array($val,$idlist) ) $idlist[] = $val;
}
}
if( !empty($idlist) ) $query1 .= ' (mn.news_id IN ('.implode(',',$idlist).')) AND ';
}
参考链接
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!