Board logo

标题: 深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell [打印本页]

作者: Zeus    时间: 2014-12-29 18:34     标题: 深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell

漏洞概要
缺陷编号:        WooYun-2014-64698
漏洞标题:        深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell
相关厂商:        深信服
漏洞作者:        f4ckbaidu
提交时间:        2014-06-12 20:01
公开时间:        2014-09-10 20:02
漏洞类型:        SQL注射漏洞
危害等级:        高
自评Rank:        20
漏洞状态:        厂商已经确认
漏洞来源:        http://www.wooyun.org
Tags标签:       php源码分析 sessionid泄漏

漏洞详情披露状态:
2014-06-12:        细节已通知厂商并且等待厂商处理中
2014-06-13:        厂商已经确认,细节仅向厂商公开
2014-06-16:        细节向第三方安全合作伙伴开放
2014-06-23:        细节向核心白帽子及相关领域专家公开
2014-07-03:        细节向普通白帽子公开
2014-07-23:        细节向实习白帽子公开
2014-09-10:        细节向公众公开

简要描述:测试版本为SSL 5.7的外置DC,主要有两个问题:
1、管理员sessionid泄漏
2、SQL注入

详细说明:一、敏感信息泄漏:

Admin用户登录后,会出现一个文件(Admin未登录时此文件不存在)

里面包含了Admin用户的phpsessionid,并且任意用户可访问,如下图:

https://192.168.222.128/global_admin.ini





利用方法类似XSS,其它用户将浏览器cookie phpsessionid改成对应的值,再访问/src/index.php就是管理员用户了,无需知道帐号密码

利用fiddler把phpsessionid改成Admin对应的sessionid:





再访问/src/index.php,直接登录了:





系统设置--环境设置--其它,可以看到服务器绝对路径:







二、SQL注入

/src/login.php代码审核:


code 区域if(isset($_REQUEST['action_c'])&&$_REQUEST['action_c'] == 'login')
{
        header("Content-type: text/html; charset=utf-8");
        $user_type = $_REQUEST['user_type'];
        $user = $_REQUEST['user'];
        $pass = $_REQUEST['pass'];
        $pass_dec = base64_decode($pass);
        $nodeid = $_REQUEST['nodeid'];        //nodeid参数输入部分,未做过滤
        if(!empty($nodeid) && !is_numeric($nodeid) && !is_numeric($user_type))
    //这部分逻辑搞笑了,当nodeid不为空且nodeid不为数字且user_type不为数字才返回参数错误。当user_type为数字型,而nodeid不为数字型的时候,这里逻辑为假,不提示参数错误并进入后续代码处理
        {
                backmsg("参数错误");
                exit;
        }
        if($user_type != 0)
        {
                $user_type = 1;
        }
        // 封锁IP检测
        $path = $_SERVER['DOCUMENT_ROOT']."/src/temp";
        $handle = @opendir($path);
        if($handle)
        {
                while(false !== ($file_name = @readdir($handle)))
                {
                        $file = $path."/".$file_name;
                        if(time() - @filemtime($file) > 300)  //300秒后清除IP黑名单文件
                        {
                                @unlink($file);
                        }
                }
        }
        $time = 0;
        $file = $path."/".$_SERVER['REMOTE_ADDR'].$user_type;
        $handle = @fopen($file, "r");
        if($handle)
        {
                $time = @fread($handle, 10);
                if(($time !== false) && ($time > 4))
                {
                        backmsg('同一IP登录登录失败次数超过5次,拒绝登录,请稍后再试');
                        exit;
                }
                @fclose($handle);
        }
        $handle = @fopen($file, "w");
        if($handle)
        {
                ++$time;
                @fwrite($handle, $time);
                @fclose($handle);
        }
    //上面的封锁逻辑,当用户登录失败5次后,封锁300秒
        //验证用户名密码
        $adlogin = new adtLogin($user_type);
        if(!$adlogin->checkAdtPsw($nodeid,$user,$pass_dec))  //验证帐号密码流程,需跟踪
        {
                backmsg(_E($adlogin->geterrno()));
                exit;
        }
        // 通过验证,删除临时文件
        @unlink($file);

php class adtLogin代码文件:/src/inc/class/adtLogin.class.php


code 区域class adtLogin  
{
        var $Gloadmin=1;//记录是否是全局管理员,0表示全局管理员,1表示节点管理员 存入session
        var $type;//记录用户选择管理员类型 0表示全局管理员,1表示节点管理员
        var $errno;
        var $nodeid;
        function adtLogin($type)
        {
                $this->type=trim($type);
        }
        public function checkAdtPsw($nodeid,$username,$pass)
        {
        /*@参数:$nodeid 数值 客户端提交数据,0表示用户选择全局数据库,其他值对应相应节点ID

                $this->nodeid=trim($nodeid);  //nodeid未过滤
                $username=filterStr(trim($username));
                $pass = @EncryptDes2(filterStr($pass));
                //$pass =md5($pass);
                $con=new SinforDbBase();               
                if($this->type==0)  //type=0也就是全局管理员的检查流程,这里没有问题,不用看
                {   
  省略......
                }
                else  //type=1也就是节点管理员的检查流程
                {
                        if($nodeid == null)
                        {
                                $this->errno=50;
                                return false;
                        }
                        if(!$con->OpenDb($this->nodeid))  //变量nodeid进入OpenDb函数,需跟踪
                        {
                                $this->errno=50;
                                return false;
                        }
省略......

OpenDb函数定义在/src/inc/class/SinforDbBase.class.php里


code 区域  省略......
        function OpenDb($NodeId=GLOBAL_DB)  //需跟踪的OpenDb函数
        {
            $db_config["hostname"]  = $this->hostname.":".$this->port;
            $db_config["username"]  = $this->username;
            $db_config["password"]  = $this->pass;
            $db_config["charset"]   = "UTF8";
            $db_config["database"]  = _S("DatabaseConfig", "DataBase"); // 默认为全局数据库
            
            if( $NodeId != GLOBAL_DB )  //触发注入的前提,也就是nodeid不为0
            {
                //$dbObj  = new DBMantain();
                //$db_config["database"] = $dbObj->getdbname($NodeId);

                /* 取数据库名字 */
                if( ! $this->connect($db_config) )
                {
                    return false;
                }               
                $sql = 。。。  //SQL注入点
                $row = $this -> row_query_one($sql);
                $this -> close_db();   
                if( ! $row )
                {
                    return false;
                }
                $db_config["database"] = $row["DB_Name"];   // 非全局数据库
            }

注入POC:

https://IP/src/login.php?action_c=login&user_type=1g&user=admin&pass=admin&nodeid=3。。。

提示“用户名或密码不正确”

https://IP/src/login.php?action_c=login&user_type=1g&user=admin&pass=admin&nodeid=3。。。

提示“连接数据库失败”



由于有防爆破登录机制,这里用sqlmap注入会有很大麻烦,需要很长时间

由于mysql用户是root,并且magic_quotes_gpc = Off,系统又是windows,呵呵了,直接getshell:



https://IP/src/login.php?action_c=login&user_type=1&user=admin&pass=admin&nodeid=3。。。

生成一句话,密码sb,访问地址:https://IP/test.php

具体路径可以利用上面的管理员session泄漏漏洞登录系统后获取






漏洞证明:getshell:






修复方案:1、修正那搞笑的逻辑

2、对参数做严格检查。比如intval

版权声明:转载请注明来源 f4ckbaidu@乌云
漏洞回应
厂商回应:
危害等级:中
漏洞Rank:10
确认时间:2014-06-13 14:14
厂商回复:首先感谢白帽子对深信服产品提出的建议,经内部验证,有3点需要向您说明:
1、SSL VPN外置的数据中心主要存放VPN的相关日志,用于给管理员进行分析,对于SSL VPN的安全性影响较低;
2、SSL VPN的外置数据中心用户量较少,大部分功能都已经在SSL VPN设备上实现,只有少数用户会使用外置数据中心;
3、SSL VPN的数据中心部署于内网。

基于以上三点原因,我们将漏洞级别降低为中级。同时,我们已经启动应急程序,会对数据中心安装包的安全性进行严格的审查和改善,尽快发布新版安装包。

另外,工作人员已经私信给您,请留下联系方式,后续我们会寄出小礼物来对您表示感谢。 (^_^)




首先感谢白帽子对深信服产品提出的建议,经内部验证:

1、SSL VPN外置的数据中心主要存放VPN的操作日志,用于给管理员进行分析,不涉及到SSL VPN的权限安全问题,.....
2、SSL VPN的外置数据中心用量较小,大部分功能都已经在SSL VPN设备上实现,只有少数用户会使用外置数据中心;
3、SSL VPN的数据中心主要部署于内网,

基于以上三点原因,我们将漏洞级别降低为中级。我们已经启动应急程序,会对数据中心安装包的安全性进行严格的审查和改善,尽快发布新版安装包。

另外,工作人员已经私信给您,请留下联系方式,后续我们会寄出小礼物来表示对您的感谢。

最新状态:暂无
原文:http://www.wooyun.org/bugs/wooyun-2014-064698

[ 本帖最后由 linda 于 2016-2-4 16:25 编辑 ]




欢迎光临 中神通公司技术论坛 (http://trustcomputing.com.cn/bbs/) Powered by Discuz! 6.0.0