├── README.md ├── __init__.py ├── console.bat ├── core ├── __init__.py └── settings.py ├── engine.py ├── plugins ├── __init__.py ├── wk-132758395188-00.py ├── wk-174745431967-00.py ├── wk-234342342323-00.py └── wk-sqlmap-00.py ├── requirements.txt ├── screen ├── flask-test.py ├── index.png ├── index1.png ├── index2.png ├── index3.png ├── index4.png ├── index5.png ├── index6.png ├── test.py ├── tt.sql └── wk-agent-v2.0.gif └── utils ├── __init__.py ├── exploit.py └── func.py /README.md: -------------------------------------------------------------------------------- 1 | # wk agent v2 2 | 3 | [![License](https://img.shields.io/:license-gpl3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html) 4 | [![platform](https://img.shields.io/badge/platform-osx%2Flinux%2Fwindows-green.svg)](https://github.com/Canbing007/wukong-agent) 5 | [![python](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/) 6 | 7 | 8 | ## Structure 9 | 10 | ![wukong_structure.png](http://upload-images.jianshu.io/upload_images/2693750-90800cae74c39f4a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 11 | 12 | 13 | ## Requisites 14 | python3.6 15 | redis 16 | nessus 17 | awvs 18 | sqlmap 19 | 20 | ## Introduce 21 | 22 | - Cross platform 23 | - Single machine can also be distributed 24 | - Access to third party scannning software 25 | - Custom plugins 26 | - Reports can genrate any formats that follow you 27 | - Include program log and system log 28 | 29 | 30 | ## Installation 31 | 32 | ``` 33 | pip install -r requirements.txt 34 | 35 | Modify "core/setting.py" as following: 36 | 37 | redis_host = 'localhost' #redis address 38 | redis_port = 6379 #redis port 39 | redis_pwd = '' #redis password 40 | 41 | awvs_url : "127.0.0.1" , #awvs url 42 | awvs_port : 8183 , #awvs port 43 | 44 | nessus_url : "https://xxx.com" , #nessus url 45 | nessus_name : "xx" , #nessus username 46 | nessus_pass : "xx" , #nessus passowrd 47 | 48 | ``` 49 | 50 | ## Usage 51 | 52 | ``` 53 | redis-server #start redis 54 | python2.7 sqlmapapi.py -s #start sqlmap 55 | python engine.py #start engine 56 | 57 | then, waiting for scan task queue into redis ... 58 | 59 | 测试样本: 60 | 1.搭建sql注入服务站点,先导入screen目录下的tt.sql数据库 61 | 2.安装flask,运行screen目录下存在注入的flask-test.py 小型web服务 62 | python flask-test.py 63 | 3.模拟写入一条测试sqlmap的数据,修改screen目录下test.py的redis配置,然后运行 64 | ``` 65 | 66 | 测试步骤,如下: 67 | ![wukong_structure.png](https://github.com/Canbing007/wukong-agent/blob/master/screen/wk-agent-v2.0.gif) 68 | 69 | - 提示:windows下并发有线程限制不能超过1024, 如果则linux下任务,可以修改engine.py下每个模块的线程数 70 | - 服务端页面有点low,暂不公布源码;有继续研究的,可以自己写个简单服务端 71 | 72 | 73 | #### 服务端功能界面 74 | 75 | ![wukong_structure.png](https://raw.githubusercontent.com/Canbing007/wukong-agent/master/screen/index1.png) 76 | ![wukong_structure.png](https://raw.githubusercontent.com/Canbing007/wukong-agent/master/screen/index2.png) 77 | ![wukong_structure.png](https://raw.githubusercontent.com/Canbing007/wukong-agent/master/screen/index3.png) 78 | ![wukong_structure.png](https://raw.githubusercontent.com/Canbing007/wukong-agent/master/screen/index4.png) 79 | ![wukong_structure.png](https://raw.githubusercontent.com/Canbing007/wukong-agent/master/screen/index5.png) 80 | ![wukong_structure.png](https://raw.githubusercontent.com/Canbing007/wukong-agent/master/screen/index6.png) 81 | 82 | 83 | ## Custom plug-in 84 | 85 | ``` 86 | # -*- coding:utf-8 -*- 87 | #!/usr/bin/env python3 88 | #Description: wukong exploit 89 | #Author: Bing 90 | #DateTime: 2017-05-10 23:08:39 91 | 92 | import sys 93 | sys.path.append("..") 94 | 95 | from utils.exploit import * 96 | import socket, re, gevent 97 | from gevent.pool import Pool 98 | from gevent import monkey; monkey.patch_all() 99 | 100 | 101 | class wk(object): 102 | def __init__(self, target = None ): 103 | self.info = { 104 | # 输入参数 105 | "protorl" : target["scan_protorl"], 106 | "host" : target["scan_target"], 107 | "port" : target["scan_port"], 108 | "cookie" : target["scan_cookie"], 109 | "proxy" : target["scan_proxy"], 110 | "user_agent" : random_useragent(target["scan_user_agent"]), 111 | "fuzzing" : target["fuzzing"] 112 | #{"user": "" ,"pwd" : "", "brute_char" : ""} 113 | } 114 | self.result = [{ 115 | # 结果信息 116 | "status" : False, 117 | "data" : { 118 | "bug_name" : "", 119 | "bug_author" : "Bing", 120 | "bug_level" : normal, 121 | "bug_type" : other, 122 | "bug_ref" : "", 123 | "bug_desc" : "", 124 | "bug_result" : "", 125 | "bug_repair" : "" 126 | }, 127 | }] 128 | 129 | 130 | def get_port_service(self, content): 131 | REGEX = [['ssh','^b\'SSH'],['ftp','^b\'220.*?ftp|^b\'220-|^b\'220 Service|^b\'220 FileZilla'],['telnet','^b\'\\xff[\\xfa-\\xfe]|^b\'\\x54\\x65\\x6c|Telnet'],['http','http'],['mysql','^b\'.\\0\\0\\0.*?mysql|^b\'.\\0\\0\\0\\n|.*?MariaDB server'],['redis','-ERR|^b\'\\$\\d+\\r\\nredis_version'],['memcached', '11211', '^b\'ERROR']] 132 | for info in REGEX: 133 | name = info[0] 134 | reg = info[1] 135 | matchObj = re.search(reg, content, re.I|re.M) 136 | if matchObj: 137 | return name 138 | return "None" 139 | 140 | 141 | def exploit(self): 142 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 143 | sock.settimeout(2) 144 | host = self.info["host"] 145 | port = int(self.info["fuzzing"]["brute_char"]) 146 | address = (host, port) 147 | 148 | try: 149 | sock.connect(address) 150 | sock.send("OPTION / HTTP 1.1\r\n".encode()) 151 | text = sock.recv(256) 152 | buffers = """{}""".format(str(text.__str__()[0:200])) 153 | finger = self.get_port_service(buffers) 154 | 155 | bug_list = {} 156 | bug = { 157 | "bug_name" : finger, 158 | "bug_author" : "Bing", 159 | "bug_level" : normal, 160 | "bug_type" : other, 161 | "bug_ref" : "", 162 | "bug_desc" : buffers, 163 | "bug_result" : port, 164 | "bug_repair" : "" 165 | } 166 | bug_list["status"] = True 167 | bug_list["data"] = bug 168 | self.result.append(bug_list) 169 | except Exception as e: 170 | sock.close() 171 | sock.close() 172 | 173 | 174 | info = { 175 | 'scan_taskid': '3', 176 | 'scan_protorl': 'http://', 177 | 'scan_target': 'xx.xx.com', 178 | 'scan_port': '80', 179 | 'scan_cookie': 'sdf', 180 | 'scan_proxy': 'sdf', 181 | 'scan_user_agent': True, 182 | 'plugin_name': '端口扫描', 183 | 'plugin_file': 'plugins/wk-174745431967-00.py', 184 | 'model': 'brute', 185 | 'fuzzing': {'user_pwd': '', 'brute_char': '80'} 186 | } 187 | t = wk(info) 188 | t.exploit() 189 | print(t.result) 190 | 191 | ``` 192 | 193 | ## Contribute 194 | 195 | If you want to contribute to my project please don't hesitate to send a pull request. You can also join our users, by sending an email to [me](mailto:wulitouhaha@vip.qq.com), to ask questions and participate in discussions. 196 | 197 | 198 | ## Issue 199 | 200 | Notice: 201 | everything in here that just for fun ... 202 | if you hava some question or good idea,you can leave a message to me! 203 | 204 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/__init__.py -------------------------------------------------------------------------------- /console.bat: -------------------------------------------------------------------------------- 1 | cmd.exe -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/core/__init__.py -------------------------------------------------------------------------------- /core/settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import os 8 | 9 | BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 10 | PLUGIN_PATH = os.path.join(BASE_PATH,"plugins") 11 | DICT_PATH = os.path.join(BASE_PATH,"dictionary") 12 | TMEP_REPORT_PATH = os.path.join(BASE_PATH,"report") 13 | 14 | #消息中间件&缓存日志和结果 15 | redis_host = '127.0.0.1' 16 | redis_port = 6379 17 | redis_pwd = '' 18 | redis_db_task = 1 19 | 20 | #wk 控制台API 21 | API_REPORT_URL = "http://localhost:8888/scan/report/api/" 22 | API_LOG_URL = "http://localhost:8888/scan/log/api/" 23 | 24 | #--------------------- 第三方配置 ----------------------------- 25 | nessus_url = "https://xxx.com" 26 | nessus_name = "xxx" 27 | nessus_pass = "xxx" 28 | 29 | awvs_url = "127.0.0.1" 30 | awvs_port = 8183 31 | awvs_header = { 32 | "Content-Type": "application/json; charset=UTF-8", 33 | "X-Requested-With": "XMLHttpRequest", 34 | "Accept": "application/json, text/javascript, */*; q=0.01", 35 | "RequestValidated": "true" 36 | } 37 | 38 | 39 | report_filter = { 40 | "awvs_white_list": ["orange", "red", "blue" ], # green,blue,orange,red 41 | "nessus_white_list": ["High", "Medium","Low", "Info"], 42 | "bug_black_list": [ 43 | "User credentials are sent in clear text" 44 | ] 45 | } 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /engine.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import gevent, time, os, imp, socket, psutil 8 | from multiprocessing import Process 9 | from gevent import monkey; monkey.patch_all() 10 | from utils.func import * 11 | 12 | 13 | def launcher(poc_file, target): 14 | taskid = target["scan_taskid"] 15 | host = target["scan_target"] 16 | model = target["model"] 17 | plugin_name = target["plugin_name"] 18 | plugin_file = target["plugin_file"] 19 | 20 | program_log({ 21 | "taskid" : taskid, 22 | "model" : model, 23 | "plugin_name" : plugin_name, 24 | "status" : 1, 25 | "info" : "poc running" 26 | }) 27 | 28 | try: 29 | poc_class = imp.load_source('wk', poc_file ) 30 | t = poc_class.wk(target = target) 31 | t.exploit() 32 | result = t.result 33 | program_result(taskid, host, model, plugin_name, result) 34 | 35 | program_log({ 36 | "taskid" : taskid, 37 | "model" : model, 38 | "plugin_name" : plugin_name, 39 | "status" : 2, 40 | "info" : "poc finishing" 41 | }) 42 | except Exception as e: 43 | message = e.__str__() 44 | program_log({ 45 | "taskid" : taskid, 46 | "model" : model, 47 | "plugin_name" : plugin_name, 48 | "status" : 3, 49 | "info" : message 50 | }) 51 | 52 | 53 | def custom_scan(scan_model, num = 5): 54 | while True: 55 | scan_que = get_task("{0}".format(scan_model), num) 56 | if len(scan_que) > 0 : 57 | jobs = [] 58 | for target in scan_que: 59 | taskid = target["scan_taskid"] 60 | model = target["model"] 61 | plugin_name = target["plugin_name"] 62 | plugins = target["plugin_file"].split('-')[1] 63 | 64 | poc_file = get_poc_path(plugins) 65 | if poc_file : 66 | jobs.append(gevent.spawn(launcher, poc_file, target)) 67 | else: 68 | program_log({ 69 | "taskid" : taskid, 70 | "model" : model, 71 | "plugin_name" : plugin_name, 72 | "status" : 3, 73 | "info" : "no poc" 74 | }) 75 | gevent.joinall(jobs) 76 | 77 | else: 78 | system_log({ "status" : 1, "model" : "{0}".format(scan_model), "info" : "waitting task"}) 79 | time.sleep(5) 80 | 81 | 82 | if __name__ == '__main__': 83 | print( 'Run task %s (%s)...' % ("wk scanner engine", os.getpid()) ) 84 | start = time.time() 85 | #开启多个服务模块 86 | func_list = [("third", 200,), ("brute", 200,), ("poc", 200,)] 87 | work = [] 88 | for poc_args in func_list : 89 | p = Process(target = custom_scan, args=poc_args ) 90 | p.start() 91 | work.append(p) 92 | 93 | for job in work: 94 | job.join() 95 | 96 | end = time.time() 97 | print( 'Task %s runs %0.2f seconds.' % ("wk scanner engine", (end - start)) ) 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/plugins/__init__.py -------------------------------------------------------------------------------- /plugins/wk-132758395188-00.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import sys 8 | sys.path.append("..") 9 | 10 | import http.client,json,requests,zipfile,cgi,time,os,random 11 | from datetime import datetime 12 | from time import gmtime, strftime 13 | from xml.dom import minidom 14 | from core.settings import * 15 | from utils.exploit import * 16 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 17 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 18 | 19 | 20 | class wk(object): 21 | def __init__(self, target = None ): 22 | self.info = { 23 | # 输入参数 24 | "protorl" : target["scan_protorl"], 25 | "host" : target["scan_target"], 26 | "port" : target["scan_port"], 27 | "cookie" : target["scan_cookie"], 28 | "proxy" : target["scan_proxy"], 29 | "user_agent" : random_useragent(target["scan_user_agent"]), 30 | "fuzzing" : target["fuzzing"] 31 | } 32 | self.result = [{ 33 | # 结果信息 34 | "status" : False, 35 | "data" : { 36 | "bug_name" : "", 37 | "bug_author" : "Bing", 38 | "bug_level" : normal, 39 | "bug_type" : other, 40 | "bug_ref" : "", 41 | "bug_desc" : "", 42 | "bug_result" : "", 43 | "bug_repair" : "" 44 | }, 45 | }] 46 | 47 | 48 | def parse_xml(self,file_name): 49 | #解析xml数据 50 | root = minidom.parse(file_name).documentElement 51 | ReportItem_list = root.getElementsByTagName('ReportItem') 52 | 53 | if ReportItem_list: 54 | for node in ReportItem_list: 55 | color = node.getAttribute("color") 56 | name = node.getElementsByTagName("Name")[0].firstChild.data 57 | try: 58 | if color in report_filter['awvs_white_list'] and name not in report_filter['bug_black_list']: 59 | temp = {} 60 | temp['bug_name'] = '{0}'.format(name) 61 | temp["bug_author"] = "bing" 62 | 63 | temp['bug_ref'] = '' 64 | temp['bug_desc'] = '{0}'.format(cgi.escape(node.getElementsByTagName("Details")[0].firstChild.data)) 65 | temp['bug_level'] = '{0}'.format(node.getElementsByTagName("Severity")[0].firstChild.data.lower()) 66 | 67 | affect = '{0}'.format(node.getElementsByTagName("Affects")[0].firstChild.data) 68 | 69 | try: 70 | request = '{0}'.format(cgi.escape(node.getElementsByTagName("Request")[0].firstChild.data)) 71 | except: 72 | request = "" 73 | 74 | try: 75 | response = '{0}'.format(cgi.escape(node.getElementsByTagName("Response")[0].firstChild.data)) 76 | except: 77 | response = "" 78 | 79 | test = "Vulnerability link : " + affect + "\n Detail : \n" + request + "\n"+ response 80 | txt = test.replace('\n','
') 81 | temp['bug_result'] = [txt] 82 | temp['bug_repair'] = '{0}'.format(cgi.escape(node.getElementsByTagName("Recommendation")[0].firstChild.data)) 83 | temp["bug_type"] = "awvs" 84 | bug_list = {} 85 | bug_list["status"] = True 86 | bug_list["data"] = temp 87 | self.result.append(bug_list) 88 | except: 89 | pass 90 | 91 | return True 92 | else: 93 | return False 94 | 95 | 96 | def connect(self, method, resource, data = None): 97 | try: 98 | conn = http.client.HTTPConnection(awvs_url, awvs_port) 99 | conn.request(method, resource, json.dumps(data) , awvs_header) 100 | resp = conn.getresponse() 101 | content = resp.read() 102 | return content 103 | except Exception as e: 104 | return False 105 | 106 | 107 | def exploit(self): 108 | #增加任务 109 | target = self.info["protorl"] + self.info["host"] + ":" + str(self.info["port"]) 110 | now_date = time.time() 111 | start_date = now_date + 60*3 112 | days = time.strftime("%m/%d/%Y %H:%M:%S", time.localtime(start_date)).split(" ")[0] 113 | hour = time.strftime("%m/%d/%Y %H:%M:%S", time.localtime(start_date)).split(" ")[1].split(":")[0] 114 | minutes = time.strftime("%m/%d/%Y %H:%M:%S", time.localtime(start_date)).split(" ")[1].split(":")[1] 115 | ACUDATA = { 116 | "scanType":"scan", 117 | "targetList":"", 118 | "target":["%s" % target], 119 | "recurse":"-1", 120 | "date": days, 121 | "dayOfWeek":"1", 122 | "dayOfMonth":"1", 123 | "time": "%s:%s" % (hour,minutes), 124 | "deleteAfterCompletion":"False", 125 | "params":{ 126 | "profile":"Default", 127 | "loginSeq":str(self.info["cookie"]), 128 | "settings":"Default", 129 | "scanningmode":"extensive", 130 | "excludedhours":"", 131 | "savetodatabase":"False", 132 | "savelogs":"False", 133 | "ExportXML":"export.xml", 134 | "emailaddress":"" 135 | } 136 | } 137 | 138 | data = self.connect("POST", "/api/addScan", ACUDATA) 139 | if not data : 140 | return True 141 | result = json.loads(data) 142 | status = result["result"] 143 | if status == "OK": 144 | taskid = result["data"][0] 145 | ACUDATA = {'id': str(taskid)} 146 | while True: 147 | time.sleep(30) 148 | #获取扫描进程 149 | awvs_process_data = self.connect("POST", "/api/getScanHistory", ACUDATA) 150 | if not awvs_process_data : 151 | return True 152 | awvs_process_result = json.loads(awvs_process_data) 153 | awvs_process_status = awvs_process_result["result"] 154 | if awvs_process_status == "FAIL" : 155 | return True 156 | #判断是否完成 157 | if awvs_process_status == "OK" and len(awvs_process_result["data"]) > 0 : 158 | process = awvs_process_result["data"][-1]["msg"] 159 | if "Scan finished" in process: 160 | break 161 | else: 162 | continue 163 | #获取报告 164 | ACUDATA = {"id":str(taskid)} 165 | data = self.connect("POST", "/api/getScanResults", ACUDATA) 166 | if not data : 167 | return True 168 | result = json.loads(data) 169 | status = result["result"] 170 | result_len = len(result["data"][0]) 171 | 172 | if status == "OK" and result_len == 3: 173 | report_id = result["data"][0]["id"] 174 | data = self.connect("GET", "/api/download/{0}:{1}".format(taskid, report_id)) 175 | if not data : 176 | return True 177 | #{'result': 'OK', 'data': [{'id': '334508baa98ba7a245b95944d5c5b2f1', 'date': '周二 12 12月 2017, 11:49:57', 'size': '16.44 KB'}]} 178 | zipfilename = "{0}/{1}_awvs.zip".format(str(TMEP_REPORT_PATH),str(random.randint(1,200))) 179 | xmlfilename = "{0}/{1}_awvs.xml".format(str(TMEP_REPORT_PATH),str(random.randint(1,200))) 180 | #download report and unzip file and format file 181 | try: 182 | with open("{0}".format(zipfilename), "wb") as code: 183 | code.write(data) 184 | code.close() 185 | except: 186 | return True 187 | xml_filename = "" 188 | try: 189 | srcZip = zipfile.ZipFile(zipfilename, "r") 190 | for eachfile in srcZip.namelist(): 191 | if eachfile.endswith(".xml",3): 192 | fd=open(xmlfilename, "wb") 193 | xml_filename = xmlfilename 194 | fd.write(srcZip.read(eachfile)) 195 | fd.close() 196 | srcZip.close() 197 | except: 198 | return True 199 | os.remove(zipfilename) 200 | xml_data = self.parse_xml(xml_filename) 201 | if xml_data: 202 | os.remove(xmlfilename) 203 | return True 204 | else: 205 | return True 206 | 207 | 208 | # info = { 209 | # 'scan_taskid': '3', 210 | # 'scan_protorl': 'http://', 211 | # 'scan_target': 'xxx.sdf.com', 212 | # 'scan_port': '80', 213 | # 'scan_cookie': 'sdf', 214 | # 'scan_proxy': 'sdf', 215 | # 'scan_user_agent': True, 216 | # 'plugin_name': 'awvs', 217 | # 'plugin_file': 'plugins/wk-test-00.py', 218 | # 'model': 'brute', 219 | # 'fuzzing': {'user_pwd': '', 'brute_char': '80'} 220 | # } 221 | # t = wk(info) 222 | # # t.start(443) 223 | # t.exploit() 224 | # print(t.result) 225 | -------------------------------------------------------------------------------- /plugins/wk-174745431967-00.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import sys 8 | sys.path.append("..") 9 | 10 | from utils.exploit import * 11 | import socket, re, gevent 12 | from gevent.pool import Pool 13 | from gevent import monkey; monkey.patch_all() 14 | 15 | 16 | class wk(object): 17 | def __init__(self, target = None ): 18 | self.info = { 19 | # 输入参数 20 | "protorl" : target["scan_protorl"], 21 | "host" : target["scan_target"], 22 | "port" : target["scan_port"], 23 | "cookie" : target["scan_cookie"], 24 | "proxy" : target["scan_proxy"], 25 | "user_agent" : random_useragent(target["scan_user_agent"]), 26 | "fuzzing" : target["fuzzing"] 27 | #{"user": "" ,"pwd" : "", "brute_char" : ""} 28 | } 29 | self.result = [{ 30 | # 结果信息 31 | "status" : False, 32 | "data" : { 33 | "bug_name" : "", 34 | "bug_author" : "Bing", 35 | "bug_level" : normal, 36 | "bug_type" : other, 37 | "bug_ref" : "", 38 | "bug_desc" : "", 39 | "bug_result" : "", 40 | "bug_repair" : "" 41 | }, 42 | }] 43 | 44 | 45 | def get_port_service(self, content): 46 | REGEX = [['ssh','^b\'SSH'],['ftp','^b\'220.*?ftp|^b\'220-|^b\'220 Service|^b\'220 FileZilla'],['telnet','^b\'\\xff[\\xfa-\\xfe]|^b\'\\x54\\x65\\x6c|Telnet'],['http','http'],['mysql','^b\'.\\0\\0\\0.*?mysql|^b\'.\\0\\0\\0\\n|.*?MariaDB server'],['redis','-ERR|^b\'\\$\\d+\\r\\nredis_version'],['memcached', '11211', '^b\'ERROR']] 47 | for info in REGEX: 48 | name = info[0] 49 | reg = info[1] 50 | matchObj = re.search(reg, content, re.I|re.M) 51 | if matchObj: 52 | return name 53 | return "None" 54 | 55 | 56 | def exploit(self): 57 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 58 | sock.settimeout(2) 59 | host = self.info["host"] 60 | port = int(self.info["fuzzing"]["brute_char"]) 61 | address = (host, port) 62 | 63 | try: 64 | sock.connect(address) 65 | sock.send("OPTION / HTTP 1.1\r\n".encode()) 66 | text = sock.recv(256) 67 | buffers = """{}""".format(str(text.__str__()[0:200])) 68 | finger = self.get_port_service(buffers) 69 | 70 | bug_list = {} 71 | bug = { 72 | "bug_name" : finger, 73 | "bug_author" : "Bing", 74 | "bug_level" : normal, 75 | "bug_type" : other, 76 | "bug_ref" : "", 77 | "bug_desc" : buffers, 78 | "bug_result" : port, 79 | "bug_repair" : "" 80 | } 81 | bug_list["status"] = True 82 | bug_list["data"] = bug 83 | self.result.append(bug_list) 84 | except Exception as e: 85 | sock.close() 86 | sock.close() 87 | 88 | 89 | # info = { 90 | # 'scan_taskid': '3', 91 | # 'scan_protorl': 'http://', 92 | # 'scan_target': 'xxx.sdf.com', 93 | # 'scan_port': '80', 94 | # 'scan_cookie': 'sdf', 95 | # 'scan_proxy': 'sdf', 96 | # 'scan_user_agent': True, 97 | # 'plugin_name': '端口扫描', 98 | # 'plugin_file': 'plugins/wk-174745431967-00.py', 99 | # 'model': 'brute', 100 | # 'fuzzing': {'user_pwd': '', 'brute_char': '80'} 101 | # } 102 | # t = wk(info) 103 | # # t.start(443) 104 | # t.exploit() 105 | # print(t.result) 106 | -------------------------------------------------------------------------------- /plugins/wk-234342342323-00.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import sys 8 | sys.path.append("..") 9 | 10 | import json, requests, csv, os, time 11 | from core.settings import * 12 | from utils.exploit import * 13 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 14 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 15 | #http.client 16 | 17 | 18 | class wk(object): 19 | def __init__(self, target = None ): 20 | self.info = { 21 | # 输入参数 22 | "protorl" : target["scan_protorl"], 23 | "host" : target["scan_target"], 24 | "port" : target["scan_port"], 25 | "cookie" : target["scan_cookie"], 26 | "proxy" : target["scan_proxy"], 27 | "user_agent" : random_useragent(target["scan_user_agent"]), 28 | "fuzzing" : target["fuzzing"] 29 | #{"user": "" ,"pwd" : "", "brute_char" : ""} 30 | } 31 | self.result = [{ 32 | # 结果信息 33 | "status" : False, 34 | "data" : { 35 | "bug_name" : "", 36 | "bug_author" : "Bing", 37 | "bug_level" : normal, 38 | "bug_type" : other, 39 | "bug_ref" : "", 40 | "bug_desc" : "", 41 | "bug_result" : "", 42 | "bug_repair" : "" 43 | }, 44 | }] 45 | 46 | 47 | def connect(self, token, resource, datas): 48 | headers = {'X-Cookie': 'token={0}'.format(token),'content-type': 'application/json'} 49 | data = json.dumps(datas) 50 | try: 51 | r = requests.post(url = str(nessus_url + resource) , data = data, headers = headers, verify= False) 52 | except: 53 | return False 54 | 55 | if r.status_code == 200: 56 | try: 57 | data = r.json() 58 | except: 59 | data = r.content 60 | return data 61 | else: 62 | return False 63 | 64 | 65 | def exploit(self): 66 | #登陆 67 | resource = "/session" 68 | datas = {'username': nessus_name, 'password': nessus_pass} 69 | tokens = "" 70 | try: 71 | token = self.connect(tokens, resource, datas)["token"] 72 | except: 73 | return False 74 | 75 | #增加任务 76 | datas = { 77 | #"uuid": 'b9e01ede-c502-a064-cbca-e0f75d7743549709aaa0d800a65e', 78 | "uuid": "ad629e16-03b6-8c1d-cef6-ef8c9dd3c658d24bd260ef5f9e66", 79 | "settings" : { 80 | "name" : self.info["host"], 81 | "scanner_id": "1", 82 | "text_targets": self.info["host"], 83 | "enabled": False, 84 | "launch_now": True, 85 | } 86 | } 87 | resource = "/scans" 88 | result = self.connect(token, resource, datas) 89 | try: 90 | taskid = result["scan"]["id"] 91 | except: 92 | return False 93 | #遍历进程 94 | while True: 95 | time.sleep(30) 96 | headers = {'X-Cookie': 'token={0}'.format(token),'content-type': 'application/json'} 97 | try: 98 | data = requests.get(url = str(nessus_url + '/scans/'), params=None, headers = headers, verify=False) 99 | result = data.json() 100 | except: 101 | return False 102 | id_status = dict((b['id'], b['status']) for b in result['scans']) 103 | try: 104 | process = id_status[taskid] 105 | except: 106 | return False 107 | if str(process) == "completed" : 108 | break 109 | 110 | #获取报告ID 111 | resource = str('/scans/{0}/export'.format(taskid)) 112 | datas = {"format" : "csv"} 113 | try: 114 | file_token = self.connect(token, resource, datas)["token"] 115 | except: 116 | return False 117 | 118 | #下载报告 119 | headers = {'X-Cookie': 'token={0}'.format(token),'content-type': 'application/json'} 120 | resource = str(nessus_url +'/scans/exports/{0}/download'.format(file_token)) 121 | try: 122 | result = requests.get(url = resource, headers = headers, verify = False) 123 | except: 124 | return False 125 | csv_file = "{0}/{1}_nessus.csv".format(str(TMEP_REPORT_PATH),str(taskid)) 126 | f = open(csv_file , 'wb') 127 | data = result.content 128 | f.write(data) 129 | f.close() 130 | 131 | #结果解析 132 | bug_list = {} 133 | with open(csv_file,"r",encoding="utf-8") as csvfile: 134 | csvReader = csv.reader(csvfile) 135 | for row in csvReader : 136 | bug = {} 137 | parameterStr = ','.join(row) 138 | parameters = parameterStr.split(',') 139 | PID = parameters[0] 140 | CVE = parameters[1] 141 | CVSS = parameters[2] 142 | Risk = parameters[3] 143 | Host = parameters[4] 144 | Protocol = parameters[5] 145 | Port = parameters[6] 146 | Name = parameters[7] 147 | Synopsis = parameters[8] 148 | Description = parameters[9] 149 | Solution = parameters[10] 150 | See_Also = parameters[11] 151 | Plugin_Output = parameters[12] 152 | 153 | bug_name = str(Name) 154 | bug_level = str(Risk) 155 | bug_summary = str(Synopsis)+"\r\n"+str(Description) 156 | bug_detail = "Bug Port : "+str(Port)+"\r\n"+"CVE : "+str(CVE) 157 | bug_repair = str(Solution)+"\r\n"+str(Plugin_Output) 158 | 159 | if str(Risk) in report_filter['nessus_white_list'] : 160 | bug['bug_name'] = bug_name 161 | bug['bug_desc'] = bug_summary 162 | bug['bug_level'] = bug_level.lower() 163 | bug['bug_result'] = bug_detail 164 | bug['bug_repair'] = bug_repair 165 | bug['bug_author'] = "bing" 166 | bug["bug_type"] = other 167 | 168 | bug_list["status"] = True 169 | bug_list["data"] = bug 170 | self.result.append(bug_list) 171 | 172 | os.remove(csv_file) 173 | 174 | 175 | # info = { 176 | # 'scan_taskid': '3', 177 | # 'scan_protorl': 'http://', 178 | # 'scan_target': 'xxx.sdf.com', 179 | # 'scan_port': '80', 180 | # 'scan_cookie': 'sdf', 181 | # 'scan_proxy': 'sdf', 182 | # 'scan_user_agent': True, 183 | # 'plugin_name': 'nessus', 184 | # 'plugin_file': 'plugins/wk-174745431967-00.py', 185 | # 'model': 'brute', 186 | # 'fuzzing': {'user_pwd': '', 'brute_char': '80'} 187 | # } 188 | # t = wk(info) 189 | # t.exploit() 190 | # print(t.result) 191 | -------------------------------------------------------------------------------- /plugins/wk-sqlmap-00.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import sys 8 | sys.path.append("..") 9 | 10 | import requests, json, re, time 11 | from utils.exploit import * 12 | 13 | class wk(object): 14 | def __init__(self, target): 15 | self.server_host = "127.0.0.1" 16 | self.server_port = "8775" 17 | self.headers = {'Content-Type': 'application/json'} 18 | self.info = { 19 | # 输入参数 20 | "protorl" : target["scan_protorl"], 21 | "host" : target["scan_target"], 22 | "port" : target["scan_port"], 23 | "cookie" : target["scan_cookie"], 24 | "proxy" : target["scan_proxy"], 25 | "user_agent" : random_useragent(target["scan_user_agent"]), 26 | "fuzzing" : target["fuzzing"] 27 | } 28 | self.result = [{ 29 | # 结果信息 30 | "status" : False, 31 | "data" : { 32 | "bug_name" : "sql injection", 33 | "bug_author" : "Bing", 34 | "bug_level" : high, 35 | "bug_type" : injection, 36 | "bug_ref" : "", 37 | "bug_desc" : "", 38 | "bug_result" : "", 39 | "bug_repair" : "" 40 | }, 41 | }] 42 | 43 | 44 | def connect(self, method, resource, data = None): 45 | if method == "POST": 46 | try: 47 | r = requests.post(url = str("http://" + self.server_host + ":" + self.server_port) + "/" + str(resource) , data = data, headers = self.headers, verify= False) 48 | except: 49 | return False 50 | elif method == "GET": 51 | try: 52 | r = requests.get(url = str("http://" + self.server_host + ":" + self.server_port) + "/" + str(resource) , headers = self.headers, verify= False) 53 | except: 54 | return False 55 | 56 | if r.status_code == 200: 57 | try: 58 | data = r.json() 59 | except: 60 | data = r.content 61 | return data 62 | else: 63 | return False 64 | 65 | 66 | def create_task(self): 67 | #新建扫描任务 68 | result = self.connect(method = "GET", resource = "task/new") 69 | return result 70 | 71 | 72 | def del_task(self, taskid): 73 | #删除任务 74 | result = self.connect(method = "GET", resource = "task/" + str(taskid) + "/delete") 75 | return result 76 | 77 | 78 | def set_args(self, taskid, method = '', url = '', cookie = '', referer = '', data = '', level = 1): 79 | #设置扫描参数 80 | scan_options = { 81 | 'cookie' : "{}".format(cookie), 82 | 'data' : "{}".format(data), 83 | 'url' : "{}".format(url), 84 | 'method' : "{}".format(method), 85 | 'level' : level, 86 | 'randomAgent': True, 87 | 'referer': referer, 88 | 'host': "", 89 | } 90 | result = self.connect(method = "POST", resource = "option/{0}/set".format(taskid), data = json.dumps(scan_options)) 91 | return result 92 | 93 | 94 | def start_task(self, taskid, url): 95 | #开始任务 scan/{}/start 96 | scan_options = {} 97 | scan_options['url'] = url 98 | result = self.connect(method = "POST", resource = "scan/{0}/start".format(taskid), data=json.dumps(scan_options)) 99 | return result 100 | 101 | 102 | def status_task(self, taskid): 103 | #查看任务 scan//status 104 | result = self.connect(method = "GET", resource = "scan/{0}/status".format(taskid) ) 105 | return result 106 | 107 | 108 | def get_data(self,taskid): 109 | #查看结果 110 | result = self.connect(method="GET", resource = "scan/{0}/data".format(taskid)) 111 | return result 112 | 113 | 114 | def exploit(self): 115 | scan_options = self.info["fuzzing"]["brute_char"] 116 | method = scan_options["method"] 117 | url = scan_options["url"] 118 | cookie = self.info["cookie"] 119 | referer = scan_options["referer"] 120 | data = scan_options["data"] 121 | 122 | #新建任务 123 | taskid = self.create_task()["taskid"] 124 | #设置参数 125 | result = self.set_args(taskid = taskid, method = method, url = url, cookie = cookie, referer = referer, data = data, level = 3)['success'] 126 | if result: 127 | #任务开始 128 | start_status = self.start_task(taskid = taskid, url = url)['success'] 129 | if start_status : 130 | while True : 131 | #任务状态 132 | task_status = self.status_task(taskid = taskid)['status'] 133 | if task_status == 'terminated' : 134 | #任务日志 135 | data_result = self.get_data(taskid = taskid) 136 | inject_result = data_result['success'] 137 | inject_data = data_result["data"] 138 | if inject_result and len(inject_data) > 0: 139 | #存在注入,保存结果 140 | inject_title = data_result['data'][0]["value"][0]["data"] 141 | #print(inject_title) 142 | result = {} 143 | result["status"] = True 144 | result["data"] = {} 145 | result["data"]["bug_name"] = "sql injection" 146 | result["data"]["bug_author"] = "Bing" 147 | result["data"]["bug_level"] = high 148 | result["data"]["bug_type"] = injection 149 | result["data"]["bug_ref"] = "" 150 | result["data"]["bug_desc"] = "" 151 | result["data"]["bug_result"] = inject_title 152 | result["data"]["bug_repair"] = "对用户输入数据做验证,sql语句预编译处理!" 153 | self.result.append(result) 154 | #删除任务 155 | self.del_task(taskid) 156 | break 157 | else: 158 | #无注入 159 | break 160 | time.sleep(3) 161 | return True 162 | else: 163 | return True 164 | else: 165 | return True 166 | 167 | 168 | # info = { 169 | # 'scan_taskid': '3', 170 | # 'scan_protorl': 'http://', 171 | # 'scan_target': 'localhost', 172 | # 'scan_port': '5000', 173 | # 'scan_cookie': 'sdf', 174 | # 'scan_proxy': 'sdf', 175 | # 'scan_user_agent': True, 176 | # 'plugin_name': 'sqlmap', 177 | # 'plugin_file': 'plugins/wk-sqlmap-00.py', 178 | # 'model': 'brute', 179 | # 'fuzzing': {'user_pwd': '', 'brute_char': {"method":"POST", "url":"http://localhost:5000/test", "referer":"", "data":"name=tes"} 180 | # } 181 | # } 182 | # t = wk(info) 183 | # t.exploit() 184 | # print(t.result) 185 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | redis 3 | elasticsearch 4 | reportlab 5 | psutil 6 | paramiko 7 | dnspython==1.15.0 8 | splinter==0.7.5 9 | celery==3.1.25 10 | flower==0.7.3 11 | pygeoip==0.3.2 12 | gevent==1.2.1 13 | bs4==0.0.1 14 | beautifulsoup4==4.6.0 15 | -------------------------------------------------------------------------------- /screen/flask-test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # author: bing 3 | # 4 | 5 | import pymysql, time 6 | from flask import Flask, render_template, jsonify, request 7 | 8 | app = Flask(__name__) 9 | 10 | @app.route('/') 11 | def index(name=None): 12 | db = pymysql.connect(host = "127.0.0.1", port = 3306, user = "root", passwd = "test@11~", db = "tt",charset="utf8") 13 | cursor = db.cursor() 14 | sql = 'select * from user where name = {0}'.format(name) 15 | cursor.execute(sql) 16 | row = cursor.fetchall() 17 | return row.__str__() 18 | 19 | @app.route('/test', methods=['GET', 'POST']) 20 | def test(): 21 | if request.method == "POST": 22 | tt = request.values.get("name", 0) 23 | print(tt) 24 | db = pymysql.connect(host = "127.0.0.1", port = 3306, user = "root", passwd = "test@11~", db = "tt",charset="utf8") 25 | cursor = db.cursor() 26 | sql = 'select * from user where name = "{0}"'.format(tt) 27 | cursor.execute(sql) 28 | row = cursor.fetchall() 29 | return row.__str__() 30 | else: 31 | return request.args.get('key', '') 32 | 33 | 34 | if __name__ == '__main__': 35 | app.run(host='0.0.0.0', threaded=True) 36 | 37 | -------------------------------------------------------------------------------- /screen/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index.png -------------------------------------------------------------------------------- /screen/index1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index1.png -------------------------------------------------------------------------------- /screen/index2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index2.png -------------------------------------------------------------------------------- /screen/index3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index3.png -------------------------------------------------------------------------------- /screen/index4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index4.png -------------------------------------------------------------------------------- /screen/index5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index5.png -------------------------------------------------------------------------------- /screen/index6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/index6.png -------------------------------------------------------------------------------- /screen/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | import redis,datetime, cgi,time,time, random,re 5 | 6 | redis_host = '127.0.0.1' 7 | redis_port = 6379 8 | redis_pwd = '' 9 | redis_db_result = 1 10 | redis_db_log = 3 11 | 12 | pool = redis.ConnectionPool(host = redis_host, port = redis_port, db = redis_db_result , password = redis_pwd, socket_timeout=3) 13 | r = redis.Redis(connection_pool=pool) 14 | 15 | info = { 16 | 'scan_taskid': '3', 17 | 'scan_protorl': 'http://', 18 | 'scan_target': 'localhost', 19 | 'scan_port': '5000', 20 | 'scan_cookie': 'sdf', 21 | 'scan_proxy': 'sdf', 22 | 'scan_user_agent': True, 23 | 'plugin_name': 'sqlmap', 24 | 'plugin_file': 'plugins/wk-sqlmap-00.py', 25 | 'model': 'brute', 26 | 'fuzzing': {'user_pwd': '', 'brute_char': {"method":"POST", "url":"http://localhost:5000/test", "referer":"", "data":"name=tes*"} 27 | } 28 | } 29 | r.sadd("brute", info) 30 | 31 | 32 | -------------------------------------------------------------------------------- /screen/tt.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : local 5 | Source Server Version : 50536 6 | Source Host : localhost:3306 7 | Source Database : tt 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50536 11 | File Encoding : 65001 12 | 13 | Date: 2017-12-19 16:18:58 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for user 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `user`; 22 | CREATE TABLE `user` ( 23 | `name` varchar(255) DEFAULT NULL, 24 | `password` varchar(255) DEFAULT NULL 25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 26 | 27 | -- ---------------------------- 28 | -- Records of user 29 | -- ---------------------------- 30 | INSERT INTO `user` VALUES ('test', '111111'); 31 | INSERT INTO `user` VALUES ('admin', 'admin'); 32 | -------------------------------------------------------------------------------- /screen/wk-agent-v2.0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/screen/wk-agent-v2.0.gif -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lee-0x00/wukong-agent/41c89de30c420e59cef7d21325624041beddd0fe/utils/__init__.py -------------------------------------------------------------------------------- /utils/exploit.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | 7 | import random 8 | 9 | ssrf = 'ssrf' 10 | injection = 'injection' 11 | xss = 'xss' 12 | xxe = 'xxe' 13 | file_upload = 'file_upload' 14 | file_operation = 'file_operation' 15 | file_traversal = 'file_traversal' 16 | rce = 'rce' 17 | lfi = 'lfi' 18 | rfi = 'rfi' 19 | info_leak = 'info_leak' 20 | misconfiguration = 'misconfiguration' 21 | android = 'android' 22 | ios = 'ios' 23 | network = 'network' 24 | other = 'other' 25 | 26 | high = 'high' 27 | medium = 'medium' 28 | low = 'low' 29 | normal = 'normal' 30 | 31 | 32 | 33 | USER_AGENTS = [ 34 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20", 35 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", 36 | "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)", 37 | "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", 38 | "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)", 39 | "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)", 40 | "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)", 41 | "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)", 42 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)", 43 | "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", 44 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", 45 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0", 46 | "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5", 47 | "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6", 48 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", 49 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20", 50 | "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52", 51 | ] 52 | 53 | 54 | def random_useragent(condition=False): 55 | if condition: 56 | return random.choice(USER_AGENTS) 57 | else: 58 | return USER_AGENTS[0] 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /utils/func.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python3 3 | #Description: wukong exploit 4 | #Author: Bing 5 | #DateTime: 2017-05-10 23:08:39 6 | import sys 7 | sys.path.append("..") 8 | 9 | from core.settings import * 10 | import re, os, redis, socket, time, requests 11 | 12 | 13 | try: 14 | pool = redis.ConnectionPool(host = redis_host, port = redis_port, db = redis_db_task , password = redis_pwd, socket_timeout=3) 15 | r = redis.Redis(connection_pool=pool) 16 | except: 17 | pass 18 | 19 | 20 | def program_log(datas): 21 | msg = False 22 | web_info = "" 23 | try: 24 | res = requests.post(url = API_LOG_URL, data = datas) 25 | text = res.status_code 26 | if int(text) == 200: 27 | web_info = "日志上传成功" 28 | msg = True 29 | except Exception as e: 30 | web_info = e.__str__() 31 | msg = False 32 | 33 | if not msg : 34 | datas["ctime"] = int(time.time()) 35 | datas["nodeip"] = str(socket.gethostbyname(socket.gethostname())) 36 | try : 37 | r.sadd("scan_log", datas) 38 | except Exception as e: 39 | #进入本地保存 40 | result_text = "{0}/{1}_log.txt".format(TMEP_REPORT_PATH, datas["taskid"]) 41 | result = open(result_text,"a+") 42 | html = datas.__str__() + str(e.__str__()) 43 | result.write( html ) 44 | result.write("\n") 45 | result.close() 46 | return True 47 | else: 48 | return True 49 | 50 | 51 | def system_log(datas): 52 | datas["nodeip"] = str(socket.gethostbyname(socket.gethostname())) 53 | 54 | try : 55 | r.sadd("system_log", datas) 56 | except Exception as e: 57 | #进入本地保存 58 | result_text = "{0}/{1}_systemlog.txt".format(TMEP_REPORT_PATH, datas["model"]) 59 | result = open(result_text,"a+") 60 | html = datas.__str__() + str(e.__str__()) 61 | result.write( html ) 62 | result.write("\n") 63 | result.close() 64 | 65 | return True 66 | 67 | 68 | def program_result(taskid, host, model, plugin_name, result): 69 | if len(result) > 0: 70 | for line in result : 71 | status = line["status"] 72 | if status: 73 | datas = line["data"] 74 | datas["taskid"] = taskid 75 | datas["host"] = host 76 | datas["model"] = model 77 | datas["plugin_name"] = plugin_name 78 | 79 | msg = False 80 | web_info = "" 81 | try: 82 | res = requests.post(url = API_REPORT_URL, data = datas) 83 | text = res.status_code 84 | if int(text) == 200: 85 | web_info = "结果上传成功" 86 | msg = True 87 | except Exception as e: 88 | web_info = e.__str__() 89 | msg = False 90 | 91 | if not msg : 92 | try: 93 | r.sadd("scan_result", datas) 94 | program_log({ 95 | "taskid" : taskid, 96 | "model" : model, 97 | "plugin_name" : plugin_name, 98 | "status" : 1, 99 | "info" : "poc redis result ok" 100 | }) 101 | except Exception as e: 102 | #进入本地保存 103 | result_text = "{0}/{1}_log.txt".format(TMEP_REPORT_PATH, result["taskid"]) 104 | local_result = open(result_text,"a+") 105 | html = result.__str__() + str(e.__str__()) 106 | local_result.write( html ) 107 | local_result.write("\n") 108 | local_result.close() 109 | program_log({ 110 | "taskid" : taskid, 111 | "model" : model, 112 | "plugin_name" : plugin_name, 113 | "status" : 1, 114 | "info" : "poc local result ok" 115 | }) 116 | else: 117 | program_log({ 118 | "taskid" : taskid, 119 | "model" : model, 120 | "plugin_name" : plugin_name, 121 | "status" : 1, 122 | "info" : "poc web result ok" 123 | }) 124 | else: 125 | return True 126 | 127 | 128 | def get_task(scan_model,task_num = 5): 129 | #获取扫描任务 130 | pid = os.getpid() 131 | task_que = [] 132 | try : 133 | for line in list(range(0,task_num)) : 134 | data = r.spop("{0}".format(scan_model)) 135 | target = eval(data) 136 | task_que.append(target) 137 | except Exception as e: 138 | pass 139 | 140 | return task_que 141 | 142 | 143 | def get_poc_path(scan_poc): 144 | #获取插件绝对路径 145 | plugin_files = os.listdir(PLUGIN_PATH) 146 | regex = re.compile('^(wk-).*?' + scan_poc + '.*?\.py$') 147 | 148 | for poc_file in plugin_files: 149 | match = regex.search(poc_file) 150 | if match : 151 | return str(os.path.join(PLUGIN_PATH, poc_file)) 152 | 153 | return False 154 | --------------------------------------------------------------------------------