前言

最近对某CMS进行了一次审计,发现该CMS在处理登陆认证时底层数据库查询语句存在设计缺陷导致admin用户在不校验密码的情况下直接登录oa系统,下面对该漏洞进行分析介绍。

漏洞分析

文件位置:CMS\oa.php
代码内容:

代码逻辑:该php文件为第一次访问OA子功能模块是的登陆认证页面,默认传递参数c(Public)、a(login),从下面的代码中可以看到此处会先获取参数c和a的值,之后判断参数是否为空,如果为空则赋予相对应的值,如果不为空则值不变,之后判断login是否在参数c中,如果在则导入配置文件,如果不再则继续下面的逻辑,在第一登陆时默认c的值为Public,不会去加载配置信息,在之后的if语句中定义了三个文件路径,其中$control_path为'source/control/oa/login.php',之后回去判断当前的control_path是否存在,如果不存在则提示处理文件未发现,如果存在则将上面的三个文件包含进来,这里简单说明一下下面三个文件的功能:

  • source/control/oabase.php:登陆认证与授权检查、查询系统配置信息、报存登陆日志、显示菜单界面等
  • source/control/apphook.php:加载广告、类型、标签等特征信息。
  • source/control/oa/login.php:登陆检测、登出、获取登陆ip地址。

之后再去new一个control类对象,然后检测action_login方法是否存在,如果存在且a参数值(login)的第一个字符不为'下划线',之后调用该方法,跟踪逻辑,进入到action_login,在这里会去直接调用$this->cptpl.'login.tpl'

文件位置:CMS\source\control\oa\Public.php
代码内容:

之后,继续跟踪代码到tpl/oa/login.tpl下,具体代码如下(有点多,我就直接贴下面了):

<!--{include file="<!--{$oapath}-->public/ins_base.tpl"}-->
<block name="content">
    <div class="Public container">
        <!-- /container -->
        <div class="row">
            <div class="col-xs-12 hidden-xs" style="margin-top:120px;"></div>
        </div>
        <div class="row">
            <div class="col-sm-8 hidden-xs">
                <div class="img"></div>
            </div>
            <div class="col-sm-4 well">
                <div style="margin-bottom:44px;margin-top:20px;">
                    <h1 class="text-center"><!--{$config.system_name}--></h1>
                </div>
                <form method="post" >
                    <div class="form-group">
                        <label class="col-sm-3  control-label" for="emp_no">帐号:</label>
                        <div class="col-sm-9">
                            <input class="form-control"  />
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-3  control-label" for="password">密码:</label>
                        <div class="col-sm-9">
                            <input class="form-control"  />
                        </div>
                    </div>
                                        <!--{if $config.login_verify_code =='1'}-->
                                        <div class="form-group">
                            <label class="col-sm-3  control-label" for="verify">验证码:</label>
                            <div class="col-sm-9 row">
                                <div class="col-xs-6">
                                    <input class="form-control"  />
                                </div>
                                <div class="col-xs-6">
                                    <img src="<!--{$urlpath}-->source/include/imagecode.php?act=verifycode" style='cursor:pointer' title='刷新验证码' id='verifyImg' onclick='freshVerify()'>
                                </div>
                            </div>
                        </div>
                                        <!--{/if}-->

                    <div class="form-group hidden">
                        <span class="col-sm-3  control-label"> </span>
                        <div class="col-sm-9">
                            <label class="inline pull-left col-3">
                                <input class="ace" type="checkbox" name="remember" value="1" />
                                <span class="lbl"> </span> </label>
                            <label for="remember-me">记住我的登录状态</label>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-sm-offset-3 col-sm-9">
                            <input type="button" value="登录" onclick="login();" class="btn btn-sm btn-primary col-10">
                        </div>
                    </div>
                </form>

            </div>
        </div>


        <div class="row text-right">

        </div> -->
    </div>
</block>
<block name="js">
    <script type="text/javascript">
        function login() {
            sendForm("form_login", "oa.php?c=Public&a=check_login");
        }

    </script>
</block>

在这里提供了一个登陆认证的表单,之后当表单提交后会进入到最下面的处理逻辑中,重新赋予c和a的值,之后提交到oa.php中,其中c和a的值如下:

  • c:Public
  • a:check_login

之后我们再次回到oa.php文件中,代码如下:

此时,和之前分析的逻辑一致,唯一不同的是最后会调用control处理类中的action_check_login函数,因为此时的a已经成为了check_login,那么我们再跟踪到Public.php中的control类中的action_check_login函数中,具体代码如下(由于较多,直接贴进来了,可能有点不是那么好看,读者可以自我贴会sublime Text中查看):

<?php
class control extends oabase
{
    public function action_login()
    {
        //    $is_verify_code = $this->get_system_config("login_verify_code");
        TPL::display($this->cptpl . 'login.tpl');
    }
     public function action_check_login()
    {
        $is_verify_code = $this->get_system_config();
        if (!empty($is_verify_code['login_verify_code'])) {
            parent::loadUtil('session');
            if ($_POST['verify'] != XSession::get('verifycode')) {
                XHandle::halt('对不起,验证码不正确!', '', 1);
            }
        }

        if (empty($_POST['emp_no'])) {
            XHandle::halt('对不起,帐号必须!', '', 1);
            $this->error('!');
        } elseif (empty($_POST['password'])) {
            XHandle::halt('密码必须!', '', 1);
        }

        if ($_POST['emp_no'] == 'admin') {
            $_SESSION['ADMIN_AUTH_KEY'] = true;
        }

        // if(C("LDAP_LOGIN")&&!$is_admin){
        if (false) {
            $where['emp_no'] = array('eq', $_POST['emp_no']);
            $dept_name       = D('UserView')->where($where)->getField('dept_name');

            if (empty($dept_name)) {
                XHandle::halt('帐号或密码错误!', '', 1);
            }

            $ldap_host = C("LDAP_SERVER");//LDAP 服务器地址
            $ldap_port = C("LDAP_PORT");//LDAP 服务器端口号
            $ldap_user = "CN=" . $_POST['emp_no'] . ",OU={$dept_name}," . C('LDAP_BASE_DN');
            $ldap_pwd  = $_POST['password']; //设定服务器密码
            $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die(

相关文章:

  • 2021-09-23
  • 2021-10-10
  • 2020-10-28
  • 2022-02-08
  • 2022-12-23
  • 2021-12-02
  • 2022-12-23
  • 2021-04-09
猜你喜欢
  • 2021-10-25
  • 2021-10-18
  • 2021-11-01
  • 2021-11-17
  • 2023-02-21
  • 2022-01-12
  • 2021-11-01
相关资源
相似解决方案