├── .gitignore ├── Grpc ├── Class_Poc.py ├── dist_all │ ├── rpc_server_linux_arm64 │ ├── rpc_server_linux_x64 │ └── rpc_server_windows_x64.exe ├── plugins.py ├── protoc-gen-grpc-java.exe ├── protoc.exe ├── readme.md ├── requirements.txt ├── rpc_server.py ├── scan.proto ├── scan_pb2.py └── scan_pb2_grpc.py ├── README.md ├── attachment ├── 2024-09-20_09-57-12.jpg ├── image-20240804150024292.png ├── image-20240804150034449.png ├── image-20240804150439416.png ├── image-20240804151359956.png ├── image-20240920095906076.png └── image-20240920095944182.png ├── config.yml ├── data.db ├── pom.xml └── src └── main ├── java └── burp │ ├── BurpExtender.java │ ├── CustomMessageEditorTab.java │ ├── CustomMessageEditorTabFactory.java │ ├── LogEntry.java │ ├── LogTableModel.java │ ├── MainApplication.java │ ├── Main_Vuln.java │ ├── PocEntry.java │ ├── PocTableModel.java │ ├── finger │ ├── FingerEntry.java │ └── FingerTableModel.java │ ├── log │ ├── LogEntry.java │ └── LogTableModel.java │ ├── model │ ├── finger │ │ ├── FingerEntry.java │ │ └── FingerTableModel.java │ ├── group │ │ ├── CheckHeaderCellRenderer.java │ │ ├── GroupEntry.java │ │ └── GroupTableModel.java │ ├── log │ │ ├── LogEntry.java │ │ └── LogTableModel.java │ └── poc │ │ ├── PocEntry.java │ │ └── PocTableModel.java │ ├── poc │ ├── PocEntry.java │ └── PocTableModel.java │ ├── rpc │ ├── Poc_Request.java │ ├── Poc_RequestOrBuilder.java │ ├── Poc_Response.java │ ├── Poc_ResponseOrBuilder.java │ ├── Scan.java │ └── pocGrpc.java │ ├── scan │ ├── FingerScan.java │ ├── PocScan.java │ └── Scan.java │ ├── testgrpc.java │ ├── utils │ ├── Config.java │ ├── Conn.java │ ├── CustHttpService.java │ ├── Finger.java │ ├── Group.java │ ├── Plugins.java │ ├── Poc.java │ ├── Scan.java │ └── Sql.java │ └── vuln │ ├── LogEntry.java │ └── LogTableModel.java └── resources └── lib └── beautyeye_lnf.jar /.gitignore: -------------------------------------------------------------------------------- 1 | /out 2 | /.idea 3 | *.class 4 | src/META-INF/* 5 | .DS_Store 6 | target/ 7 | *.iml -------------------------------------------------------------------------------- /Grpc/Class_Poc.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from colorama import Fore 3 | from prettytable import PrettyTable 4 | import re,os,importlib 5 | import random,sys 6 | from tqdm import tqdm 7 | import operator 8 | from string import Template 9 | import requests,string 10 | import datetime 11 | from requests.adapters import HTTPAdapter 12 | from requests.packages.urllib3.util.retry import Retry 13 | #屏蔽SSl警告 14 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 15 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 16 | 17 | 18 | application_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "modules") 19 | if application_path not in sys.path: 20 | sys.path.append(application_path) 21 | # 遍历目录下的所有模块并导入 22 | for module in os.listdir(application_path): 23 | if module.endswith('.py') and not module.startswith("Class_") and not module.startswith("Main.py"): 24 | try: 25 | module_name = module[:-3] # 假设您的模块名为my_module.py 26 | module = importlib.import_module(module_name) 27 | # 将模块注册到全局变量中 28 | globals()[module_name] = module 29 | except Exception as e: 30 | print("引入模块失败:"+str(e)) 31 | # print(str(e) + '----' + str(e.__traceback__.tb_lineno) + '行') 32 | retry_times = 3 # 设置重试次数 33 | retry_backoff_factor = 1 # 设置重试间隔时间 34 | user_agent_list = [ 35 | 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1' 36 | 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36' 37 | 'Mozilla/5.0 (Linux; Android 10; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Mobile Safari/537.36' 38 | 'Mozilla/5.0 (iPad; CPU OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1' 39 | 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 40 | 'Mozilla/5.0 (Linux; Android) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.109 Safari/537.36 CrKey/1.54.248666' 41 | 'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320' 42 | 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+' 43 | 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+' 44 | 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30' 45 | 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30' 46 | 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30' 47 | 'Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36' 48 | 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36' 49 | 'Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36' 50 | 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true' 51 | 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.0.0 Mobile Safari/537.36' 52 | 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263' 53 | 'Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 54 | 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36' 55 | 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 56 | 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 57 | 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 58 | 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 59 | 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 60 | 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36' 61 | 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)' 62 | 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13' 63 | 'Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36' 64 | 'Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36' 65 | 'Mozilla/5.0 (Linux; Android 11; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36' 66 | 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 67 | 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 68 | 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36' 69 | 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1' 70 | 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1' 71 | 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1' 72 | ] 73 | class Class_Poc: 74 | def __init__(self,url,poc,timeout,debug): 75 | self.url = url.strip() 76 | self.poc=poc 77 | self.timeout=timeout 78 | self.session = requests.Session() 79 | retry = Retry(total=retry_times, backoff_factor=retry_backoff_factor) 80 | adapter = HTTPAdapter(max_retries=retry) 81 | self.session.mount('http://', adapter) 82 | self.session.mount('https://', adapter) 83 | self.all_global_var={}#存放所有的全局变量 84 | self.all_global_payload = {} #所有payload 85 | self.all_request_name_list={} 86 | self.debug=debug 87 | def main(self): 88 | poc_name = self.poc.get("name") 89 | poc_transport = self.poc.get("transport") 90 | poc_rules = self.poc.get("rules") 91 | poc_expression = self.poc.get("expression") 92 | poc_detail = self.poc.get("detail") 93 | poc_re_str = self.poc.get("output") 94 | poc_set = self.poc.get("set") 95 | poc_payload = self.poc.get("payload") 96 | self.set_bianliang(poc_set) 97 | self.set_payload(poc_payload) 98 | # print(self.all_global_var) 99 | if poc_transport.lower()=="http": 100 | try: 101 | response = self.poc_request_http(poc_rules) 102 | if type(response) !=requests.models.Response: 103 | result = {"url":self.url,"poc":self.poc,"result":False,"others":response} 104 | else: 105 | is_success = self.main_poc_expression(poc_expression) 106 | resultaa="" 107 | if is_success: 108 | resultaa = self.re_others(response,poc_re_str) 109 | result = {"url":self.url,"poc":self.poc,"result":is_success,"others":resultaa} 110 | if self.debug: 111 | tqdm.write(self.out_debug_info("Replace Main Output","原始字符串:%s 替换后:%s"%(poc_re_str,resultaa))) 112 | except Exception as e: 113 | result = {"url":self.url,"poc":self.poc,"result":False,"others":'Error:'+str(e)+' 行:'+str(e.__traceback__.tb_lineno)} 114 | elif poc_transport.lower()=="tcp": 115 | result = {"url":self.url,"name":self.poc.get("name"),"result":"False","others":"暂不支持此协议,待开发!"} 116 | elif poc_transport.lower()=="udp": 117 | result = {"url":self.url,"name":self.poc.get("name"),"result":"False","others":"暂不支持此协议,待开发!"} 118 | else: 119 | result = {"url":self.url,"name":self.poc.get("name"),"result":"False","others":"协议不正确"} 120 | if self.debug: 121 | tqdm.write(self.out_debug_info("Return","输出结果:%s"%(result))) 122 | return result 123 | def re_others(self,response,poc_re_str): 124 | #此处先匹配{{}}进行代码执行替换,然后实现字符串模板替换。$a形式 125 | poc_re_str = self.replace_Template_var(poc_re_str) 126 | if poc_re_str: 127 | pattern = r'\{\{(.*?)\}\}' 128 | result = re.findall(pattern, poc_re_str) 129 | if result: 130 | for item in result: 131 | try: 132 | try: 133 | var_str = str(eval(item)) 134 | except Exception as e: 135 | self.out_error_info("eval code",e,"代码["+item+"] 执行错误:"+str(e)) 136 | var_str="" 137 | poc_re_str =poc_re_str.replace("{{%s}}"%item,var_str) 138 | except Exception as e: 139 | self.out_error_info("eval code",e,str(e)) 140 | # poc_re_str = self.replace_Template_var(poc_re_str) 141 | return poc_re_str 142 | else: 143 | return "" 144 | 145 | def out_error_info(self,type_str,e,text): 146 | tqdm.write(Fore.RED+"[E] ["+str(e.__traceback__.tb_lineno).strip()+"行]["+self.poc.get("name")+"]["+type_str+"] "+text) 147 | def out_debug_info(self,type,text): 148 | return Fore.MAGENTA +"["+Fore.CYAN+"Debug"+Fore.MAGENTA+"]["+Fore.CYAN+type+Fore.MAGENTA+"] "+text 149 | def main_poc_expression(self,expression): 150 | poc_expression = self.replace_Template_var(expression) 151 | poc_expression =expression.replace("&&"," and ").replace("||"," or ") 152 | for i in self.all_request_name_list: 153 | poc_expression = poc_expression.replace(str(i)+"()",str(self.all_request_name_list[i])) 154 | # print(poc_expression) 155 | if self.debug: 156 | tqdm.write(self.out_debug_info("Main Expression","原始字符串:%s 替换后:%s"%(expression,poc_expression))) 157 | try: 158 | if eval(poc_expression): 159 | return True 160 | else: 161 | return False 162 | except Exception as e: 163 | self.out_error_info("eval code",e,"代码["+poc_expression+"] 执行错误:"+str(e)) 164 | 165 | def set_payload(self,poc_set): 166 | try: 167 | if poc_set: 168 | for i in poc_set.keys(): 169 | try: 170 | self.all_global_payload[i]=poc_set[i] 171 | except Exception as e: 172 | self.out_error_info("set payload",e,"Payload名:"+i+" Payload值:"+poc_set[i]+" 错误信息:"+str(e)) 173 | if self.debug: 174 | tqdm.write(self.out_debug_info("set payload", "Payload名%s Payload值:%s"%(i,poc_set[i]))) 175 | # exec(f'global {i}\n{i}={poc_set[i]}') 176 | except Exception as e: 177 | self.out_error_info("set var",e,"设置变量出错:"+str(e)) 178 | 179 | def set_bianliang(self,poc_set): 180 | try: 181 | if poc_set: 182 | for i in poc_set.keys(): 183 | try: 184 | exec(f'self.all_global_var[i]={poc_set[i]}') 185 | except Exception as e: 186 | self.out_error_info("set var",e,"变量名:"+i+" 变量值:"+poc_set[i]+" 错误信息:"+str(e)) 187 | if self.debug: 188 | tqdm.write(self.out_debug_info("set var", "变量名:%s 变量Str:%s 变量值:%s"%(i,poc_set[i],self.all_global_var[i]))) 189 | # exec(f'global {i}\n{i}={poc_set[i]}') 190 | except Exception as e: 191 | self.out_error_info("set var",e,"设置变量出错:"+str(e)) 192 | def poc_request_http(self,poc_rules): 193 | try: 194 | # r = s.post(url,headers=headers) 195 | for i in poc_rules: 196 | request_methods= poc_rules[i].get("request").get("method").strip() 197 | request_path= poc_rules[i].get("request").get("path").strip() 198 | request_headers= poc_rules[i].get("request").get("headers") 199 | request_body= poc_rules[i].get("request").get("body") 200 | request_body =self.replace_Template_var(request_body) 201 | request_headers =self.replace_Template_var_headers(request_headers) 202 | if not request_headers.get("User-Agent"): 203 | request_headers['User-Agent'] = random.choice(user_agent_list) 204 | if self.debug: 205 | #debug 206 | http_request_str="[%s] HTTP请求:%s\n%s\n%s %s\nHost: %s\n"%(self.poc.get("name"),i,"-"*100,request_methods,request_path,self.url) 207 | if len(request_headers)>0: 208 | for header in request_headers: 209 | if header: 210 | http_request_str+="%s: %s\n"%(header,str(request_headers[header])) 211 | if request_body: 212 | http_request_str+="\n%s"%(str(request_body)+"\n"+"-"*100) 213 | 214 | tqdm.write(self.out_debug_info("Request",http_request_str) ) 215 | if request_path.startswith("^"): 216 | request_url = self.url 217 | elif request_path.strip().startswith("/"): 218 | if self.url.strip().endswith("/"): 219 | request_url = self.url[:-1].strip()+ request_path.strip() 220 | else: 221 | request_url = self.url.strip()+ request_path.strip() 222 | else: 223 | request_url = self.url.strip()+ "/"+request_path.strip() 224 | # request_methods= poc_rules[i].get("request").get("method") 225 | request_url =self.replace_Template_var(request_url) 226 | # print(request_url) 227 | output_list= poc_rules[i].get("output") 228 | 229 | if poc_rules[i].get("request").get("follow_redirects"): 230 | request_follow_redirects= True 231 | else: 232 | request_follow_redirects= False 233 | try: 234 | response = self.single_request_http(request_url,request_methods,request_body,request_headers,request_follow_redirects) 235 | except requests.exceptions.RequestException as e: 236 | response="HTTP请求异常:"+str(e) 237 | # tqdm.write(response) 238 | continue 239 | if self.debug: 240 | #debug 241 | return_result_str= "[%s][%s] HTTP返回:%s\n%s\n"%(self.poc.get("name"),request_url,i,'-'*100) 242 | return_result_str += "HTTP/1.1 %s %s\n"%(response.status_code,response.reason) 243 | if response.headers: 244 | for zz in response.headers: 245 | return_result_str += "%s: %s\n"%(zz,response.headers[zz]) 246 | if response.text: 247 | return_result_str += "\n%s"%(response.text) 248 | tqdm.write(self.out_debug_info("Response",return_result_str+"\n"+'-'*100) ) 249 | expression =poc_rules[i].get("expression") 250 | expression = self.replace_Template_var(expression) 251 | expression =expression.replace("&&","and").replace("||","or") 252 | if self.is_expression(response,expression): 253 | if self.debug: 254 | tqdm.write(self.out_debug_info("Expression","判断条件:%s 判断结果:%s"%(expression,'True'))) 255 | self.all_request_name_list[i] = True 256 | # exec(f'global {i}\n{i}=True') 257 | self.output_var(response,output_list) 258 | #匹配成功读取output做环境变量 259 | else: 260 | self.all_request_name_list[i] = False 261 | if self.debug: 262 | tqdm.write(self.out_debug_info("Expression","判断条件:%s 判断结果:%s"%(expression,'Flase'))) 263 | # exec(f'global {i}\n{i}=False') 264 | #失败则下一个请求 265 | 266 | return response 267 | except Exception as e: 268 | self.out_error_info("poc rquests",e,str(e)) 269 | # tqdm.write(Fore.RED+"[E] ["+self.poc.get("name")+"]"+str(e) + '----' + str(e.__traceback__.tb_lineno) + '行') 270 | return None 271 | def replace_Template_var(self,body): 272 | if body: 273 | temp_request_body = Template(body) 274 | try: 275 | # body = temp_request_body.substitute(self.all_global_var) 276 | body = temp_request_body.safe_substitute(self.all_global_var) 277 | temp2_request_body = Template(body) 278 | body = temp2_request_body.safe_substitute(self.all_global_payload) 279 | except Exception as e: 280 | self.out_error_info("replace template",e,"模板替换异常:"+str(e)) 281 | # tqdm.write(Fore.RED+"[E] ["+self.poc.get("name")+"]"+str(e) + '----' + str(e.__traceback__.tb_lineno) + '行') 282 | return body 283 | def replace_Template_var_headers(self,headers): 284 | for i in headers: 285 | headers[i] = self.replace_Template_var(headers[i]) 286 | return headers 287 | def is_expression(self,response,expression): 288 | # print(expression) 289 | # if response.status_code==200 and operator.contains(response.text,'html'): 290 | try: 291 | if eval(expression): 292 | return True 293 | else: 294 | return False 295 | except Exception as e: 296 | self.out_error_info("eval code",e,"代码["+expression+"] 执行错误:"+str(e)) 297 | 298 | def output_var(self,response,output_list): 299 | 300 | try: 301 | if output_list: 302 | for i in output_list: 303 | replace_result = self.re_others(response,output_list[i]) 304 | self.all_global_var[i] = replace_result 305 | if self.debug: 306 | tqdm.write(self.out_debug_info("Replace Output","变量名:%s 替换前:%s 替换后:%s"%(i,output_list[i],replace_result))) 307 | except Exception as e: 308 | self.out_error_info("output",e,str(e)) 309 | # tqdm.write(Fore.RED+"[E] ["+self.poc.get("name")+"]"+str(e) + '----' + str(e.__traceback__.tb_lineno) + '行') 310 | 311 | def single_request_http(self,request_url,request_methods,data,headers,request_follow_redirects): 312 | response = self.session.request(request_methods.upper(), request_url,data=data,headers=headers,allow_redirects=request_follow_redirects,verify=False,timeout=self.timeout) 313 | # print(type(response.status_code), response.status_code) 314 | return response 315 | # print(type(response.status_code), response.status_code) 316 | # print(type(response.headers), response.headers) 317 | # print(type(response.cookies), response.cookies) 318 | # print(type(response.url), response.url) 319 | # print(type(response.history), response.history) -------------------------------------------------------------------------------- /Grpc/dist_all/rpc_server_linux_arm64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/Grpc/dist_all/rpc_server_linux_arm64 -------------------------------------------------------------------------------- /Grpc/dist_all/rpc_server_linux_x64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/Grpc/dist_all/rpc_server_linux_x64 -------------------------------------------------------------------------------- /Grpc/dist_all/rpc_server_windows_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/Grpc/dist_all/rpc_server_windows_x64.exe -------------------------------------------------------------------------------- /Grpc/plugins.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | #!/usr/bin/python 3 | import sys 4 | import requests,argparse,os 5 | from urllib.parse import urlparse 6 | def vuln_info(): 7 | vuln_info = { 8 | "vuln_name":"POC测试漏洞", #漏洞名称 9 | 'vuln_referer':'http://baidu.com', #漏洞来源 10 | 'vuln_author':'qianxiao996', #插件作者 11 | 'cms_name':'test',#cms_name需要和上级目录保持一致。扫描器自动添加会调用。GUI版本不会调用 12 | 'vuln_description':'''漏洞描述''', 13 | 'vuln_identifier':'''漏洞编号。''', 14 | 'vuln_class':'漏洞分类',#如:信息泄漏、远程命令执行、任意文件上传、SQL注入、XML注入、任意文件读取、本地文件包含、认证绕过/未认证、弱口令、目录遍历、其他、反序列化漏洞、OGNL表达式注入、SSRF、后门、任意文件下载、鉴权绕过、暴力破解、命令注入、路径泄露、XSS、远程文件包含、CSRF、任意文件包含、代码注入、任意文件写入、密码硬编码、文件包含、任意用户注册、缓冲区溢出、用户枚举漏洞、任意文件删除、任意页面上传、管理权限等 15 | 'vuln_solution':'''修复建议。''', 16 | 'FofaQuery_type':'socket', #socket、http 17 | 'FofaQuery_link':'/', #此处的路径会加在url拼接访问,进行FofaQuery的条件匹配 此处为all为全部页面都检测 18 | 'FofaQuery_rule':'title="百度"',#header="JSESSIONID" || body="Struts Problem Report" || body="There is no Action mapped for namespace" || body="No result defined for action and result input" || header="Servlet" || header="JBoss",port="60001" 19 | #header', 'body', 'title', 'banner','port','banner','service','protocol','server' 20 | 'ispoc':0, #是否有poc 1为有 0为无 21 | 'isexp':1 #是否有exp 1为有 0为无 22 | } 23 | return vuln_info 24 | def _out(type,text): 25 | print("[*] "+type+":\n "+text) 26 | # func_out 输出函数对象 url:url hostname:主机地址 port:端口 scheme:服务 heads:http自定义头信息 27 | # plugins_temp_data 全局变量,可存储数据至do_exp使用 28 | def do_poc(url,hostname,port,scheme,heads={},func_out=_out,plugins_temp_data={}): 29 | try: 30 | #存储数据至do_exp函数使用 31 | plugins_temp_data['key']='11' 32 | 33 | # func_out('Debug',"debug信息") 34 | func_out('Error',"错误信息",) 35 | # func_out('Info',"info信息") 36 | # 返回参数 37 | #Result返回是否存在, 38 | #Result_Info为返回的信息,可以为Paylaod 39 | #Debug debug信息 默认不会显示,勾选显示调试信息会输出此结果 40 | #Error_Info无论何时都会输出 41 | result = {"Result":False,"Result_Info":""} 42 | result['Result'] = True 43 | result['Result_Info']= url 44 | return result 45 | except Exception as e: 46 | func_out('Error',str(e)+str(e.__traceback__.tb_lineno)+'行') 47 | 48 | 49 | #exp_data 50 | # { 51 | # "type":"cmd", #cmd,shell,uploadfile 52 | # "command":"whoami", #cmd命令 53 | # "reverse_ip":"127.0.0.1", #反弹shell的ip 54 | # "reverse_port":"8888", #反弹shell的端口 55 | # "filename":"conf.php", #写入文件的名字 56 | # "filename_contents":"shell内容", #shell文件内容 57 | # } 58 | # url:url hostname:主机地址 port:端口 scheme:服务 heads:自定义请求头 func_out 输出函数对象 59 | def do_exp(url,hostname,port,scheme,heads={},exp_data={},func_out=_out,plugins_temp_data={}): 60 | # 返回参数 61 | # Result返回是否成功, 62 | # Result_Info为返回的信息,可以为Paylaod 63 | result = {"Result": False, "Result_Info": ""} 64 | try: 65 | 66 | #获取全局变量数据 67 | key = plugins_temp_data.get('key') 68 | 69 | #输出各种信息。参数一类型,默认Debug,可选【Debug、Error、Info】 参数二位具体内容 70 | func_out('Debug',"debug信息") 71 | func_out('Error',"错误信息",) 72 | func_out('Info',"info信息") 73 | 74 | #命令执行 75 | if exp_data['type']=='cmd': 76 | ##处理你的命令执行 77 | result['Result'] = True 78 | result['Result_Info'] = "root" 79 | result['Result_Info'] =plugins_temp_data 80 | 81 | #反弹shell 82 | elif exp_data['type']=='shell': 83 | ##处理你的反弹shell 84 | result['Result'] = True 85 | result['Result_Info'] = "反弹成功" 86 | #上传文件 87 | elif exp_data['type']=='uploadfile': 88 | ##处理你的上传操作 89 | result['Result'] = True 90 | result['Result_Info'] = "上传成功" 91 | except Exception as e: 92 | func_out('Error',str(e)+str(e.__traceback__.tb_lineno)+'行') 93 | return result -------------------------------------------------------------------------------- /Grpc/protoc-gen-grpc-java.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/Grpc/protoc-gen-grpc-java.exe -------------------------------------------------------------------------------- /Grpc/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/Grpc/protoc.exe -------------------------------------------------------------------------------- /Grpc/readme.md: -------------------------------------------------------------------------------- 1 | ## Burpsuit-FrameScan RPC Server 2 | 3 | ## 开始使用 4 | 5 | ### 源码运行 6 | 7 | ``` 8 | //创建虚拟环境 9 | conda create -n FrameScan-Grpc python=3.8 10 | conda activate FrameScan-Grpc 11 | 导出requirements.txt 12 | python -m pip freeze > requirements.txt 13 | 安装requirements.txt 14 | python -m pip install -r requirements.txt 15 | 16 | python rpc_server.py 17 | python rpc_server.py 0.0.0.0:50051 18 | ``` 19 | ### 二进制文件运行 20 | 21 | #### Windwos 22 | 23 | ``` 24 | rpc_server.exe 25 | rpc_server.exe 0.0.0.0:11122 26 | ``` 27 | 28 | 其他平台请自行打包。 29 | 30 | #### 打包exe 31 | 32 | ``` 33 | windows 34 | nuitka --mingw64 --standalone --onefile rpc_server.py --show-progress --follow-imports --include-package=argparse 35 | ``` 36 | 编译选项 37 | 38 | ``` 39 | --nofollow-imports :不编译代码中所有的import,比如keras,numpy之类的。 40 | --mingw64 #默认为已经安装的vs2017去编译,否则就按指定的比如mingw(官方建议) 41 | --standalone 独立环境,这是必须的(否则拷给别人无法使用) 42 | --windows-disable-console 没有CMD控制窗口 43 | --output-dir=out 生成exe到out文件夹下面去 44 | --show-progress 显示编译的进度,很直观 45 | --show-memory 显示内存的占用 46 | --include-qt-plugins=sensible,styles 打包后PyQt的样式就不会变了 47 | --plugin-enable=qt-plugins 需要加载的PyQt插件 48 | --plugin-enable=tk-inter 打包tkinter模块的刚需 49 | --plugin-enable=numpy 打包numpy,pandas,matplotlib模块的刚需 50 | --plugin-enable=torch 打包pytorch的刚需 51 | --plugin-enable=tensorflow 打包tensorflow的刚需 52 | --windows-icon-from-ico=你的.ico 软件的图标 53 | --windows-company-name=Windows下软件公司信息 54 | --windows-product-name=Windows下软件名称 55 | --windows-file-version=Windows下软件的信息 56 | --windows-product-version=Windows下软件的产品信息 57 | --windows-file-description=Windows下软件的作用描述 58 | --windows-uac-admin=Windows下用户可以使用管理员权限来安装 59 | --linux-onefile-icon=Linux下的图标位置 60 | --onefile 像pyinstaller一样打包成单个exe文件 61 | --include-package=复制比如numpy,PyQt5 这些带文件夹的叫包或者轮子 62 | --include-module=复制比如when.py 这些以.py结尾的叫模块 63 | ``` 64 | 65 | 66 | 67 | ## Java GRP代码生成 68 | 69 | 70 | ### 1、软件安装 71 | 下载protoc.exe 工具 , 选择 win64.zip 下载地址:https://github.com/protocolbuffers/protobuf/releases 72 | 73 | 下载protoc-gen-grpc.exe 插件 ,选择搞版本下载 , 下载地址: https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/ 74 | 75 | 下载之后重命名软件名称,并放置在 D:/SoftWare/ (其他地方也可以) 76 | 77 | ### 2、编译生成java代码 78 | 命令解释: 79 |   --java_out:生成之后输出java文件目录 80 |   --proto_path:proto文件依赖地址,可以写多个 81 |   --plugin:插件地址 82 |   user.proto:需要生成的proto协议文件 83 | 84 | 打开cmd执行: 85 | 86 | #### 生成java代码 87 | 88 | ```shell 89 | protoc.exe --java_out=. --proto_path=. scan.proto 90 | ``` 91 | 92 | #### 生成Grpc类 93 | 94 | ```shell 95 | protoc.exe --plugin=protoc-gen-grpc-java.exe --grpc-java_out=. --proto_path=. scan.proto 96 | ``` 97 | 98 | 将生成的java文件复制到burp.rpc目录即可。 99 | 100 | #### 注意事项: 101 | 102 | 1、如果 执行过程中发现 import依赖的文件找不到,需要多指定几个 proto_path(如--proto_path:. --proto_path:/common/base) 103 | 104 | 2、如果 需要生产多个类需要在 proto文件中加入 105 | 106 | ```shell 107 | option java_multiple_files = true; 108 | ``` 109 | 110 | 111 | 3、如果 需要指定生成的类路径需要在 proto文件中加入 112 | 113 | ``` 114 | option java_package="com.xxxx.xxx.xxx"; 115 | ``` 116 | 117 | ## python生成 118 | 119 | 需要安装`grpcio-tools `模块 120 | 121 | ```shell 122 | python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. scan.proto 123 | ``` 124 | 125 | 直接使用即可。 -------------------------------------------------------------------------------- /Grpc/requirements.txt: -------------------------------------------------------------------------------- 1 | charset-normalizer==3.3.2 2 | colorama==0.4.6 3 | dnspython==2.3.0 4 | eventlet==0.36.1 5 | greenlet==3.0.3 6 | grpcio==1.62.2 7 | idna==3.7 8 | importlib-metadata==6.7.0 9 | Nuitka==1.7.9 10 | ordered-set==4.1.0 11 | prettytable==3.7.0 12 | protobuf==4.24.4 13 | PyYAML==6.0.1 14 | requests==2.31.0 15 | some-package==0.1 16 | tqdm==4.66.5 17 | typing_extensions==4.7.1 18 | urllib3==2.0.7 19 | wcwidth==0.2.13 20 | wincertstore==0.2 21 | zipp==3.15.0 22 | zstandard==0.21.0 23 | -------------------------------------------------------------------------------- /Grpc/rpc_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | from concurrent import futures 3 | import grpc 4 | import scan_pb2 5 | import urllib 6 | import scan_pb2_grpc 7 | import yaml 8 | import sys,eventlet 9 | from Class_Poc import Class_Poc 10 | sys.path.append('./modules') 11 | class PocServicer(scan_pb2_grpc.pocServicer): 12 | def vuln_scan_python_by_souce_code(self,source_code,url): 13 | # print("【Scan11】【%s】【%s】【%s】"%("Python Poc",url,poc.get("detail").get("name"))) 14 | eventlet.monkey_patch(thread=False, time=True) 15 | with eventlet.Timeout(int(120), False): 16 | try: 17 | # 创建一个干净的局部命名空间 18 | local_vars = {} 19 | # 创建一个全局命名空间 20 | global_vars = globals() 21 | # 执行代码 22 | try: 23 | exec(source_code, global_vars, local_vars) 24 | except Exception as e: 25 | print(f"Error executing code: {e}") 26 | return {"url":url,"name":"","result":False,"others":str(e)} 27 | vul_info = {"vuln_name":""} 28 | if 'vuln_info' in local_vars: 29 | vul_info = local_vars['vuln_info']() 30 | print("【Scan】【%s】【%s】【%s】"%("Python",url,vul_info.get("vuln_name"))) 31 | if 'do_poc' in local_vars: 32 | _url = urllib.parse.urlparse(url) 33 | hostname = _url.hostname 34 | port = _url.port 35 | scheme = _url.scheme 36 | result = local_vars['do_poc'](url, hostname, port, scheme, '') 37 | result = {"url":url,"name":vul_info.get("vuln_name"),"result":bool(result.get("Result")),"others":str(result.get("Result_Info"))} 38 | return result 39 | else: 40 | print("do_poc not found in local namespace") 41 | result = {"url":url,"name":vul_info.get("vuln_name"),"result":False,"others":"未找到do_poc方法"} 42 | return result 43 | except Exception as e: 44 | return {"url":url,"name":vul_info.get("vuln_name"),"result":False,"others":str(e)} 45 | def vuln_scan_yaml_by_souce_code(self,poc,url): 46 | eventlet.monkey_patch(thread=False, time=True) 47 | with eventlet.Timeout(int(120), False): 48 | try: 49 | poc_obj = Class_Poc(url,poc,120,False) 50 | result = poc_obj.main() 51 | return {"url":url,"name":poc.get("detail").get("name"),"result":result.get("result"),"others":result.get("others")} 52 | except Exception as e: 53 | return {"url":url,"name":poc.get("detail").get("name"),"result":False,"others":str(e)} 54 | def pocscan(self, request, context): 55 | url = request.url 56 | poc_type = request.poc_type 57 | poc = request.poc 58 | # print(poc_type,url,poc) 59 | if poc_type == "Yaml": 60 | try: 61 | poc = yaml.safe_load(poc) 62 | except: 63 | print("【Error】【%s】【%s】【%s】 %s"%(poc_type,url,poc,"POC Yaml转换失败!")) 64 | return scan_pb2.Poc_Response(is_success=False, result="POC Yaml转换失败!") 65 | print("【Scan】【%s】【%s】【%s】"%(poc_type,url,poc.get("detail").get("name"))) 66 | result = self.vuln_scan_yaml_by_souce_code(poc,url) 67 | print("【Result】【%s】【%s】【%s】【%s】【%s】"%(poc_type,url,poc.get("detail").get("name"),result.get("result"),result.get("others"))) 68 | return scan_pb2.Poc_Response(is_success=bool(result.get("result")), result=str(result.get("others"))) 69 | 70 | elif poc_type == "Python": 71 | print("【Scan】【%s】【%s】【%s】"%(poc_type,url,poc)) 72 | # result = {"url":url,"name":vul_info.get("vuln_name"),"result":False,"others":"未找到do_poc方法"} 73 | result = self.vuln_scan_python_by_souce_code(poc,url) 74 | if result.get("url"): 75 | url = result.get("url") 76 | print("【Result】【%s】【%s】【%s】【%s】【%s】"%(poc_type,url,result.get("name"),result.get("result"),result.get("others"))) 77 | return scan_pb2.Poc_Response(is_success=bool(result.get("result")), result=str(result.get("others"))) 78 | else: 79 | print("【Error】【%s】【%s】【%s】 %s"%(poc_type,url,poc,"POC插件类型错误!")) 80 | return scan_pb2.Poc_Response(is_success=False, result="POC插件类型错误!") 81 | # def check_python(source_code): 82 | # # 读取文件内容 83 | # with open("plugins.py", 'r',encoding='utf-8') as file: 84 | # source_code = file.read() 85 | 86 | # # 创建一个干净的局部命名空间 87 | # local_vars = {} 88 | 89 | # # 创建一个全局命名空间 90 | # global_vars = globals() 91 | 92 | # # 执行代码 93 | # try: 94 | # exec(source_code, global_vars, local_vars) 95 | # except Exception as e: 96 | # print(f"Error executing code: {e}") 97 | # return 98 | # if 'vuln_info' in local_vars: 99 | # print(local_vars['vuln_info']()) 100 | # else: 101 | # print("vuln_info not found in local namespace") 102 | def serve(host="127.0.0.1:23333"): 103 | server = grpc.server(futures.ThreadPoolExecutor(max_workers=20000)) 104 | scan_pb2_grpc.add_pocServicer_to_server(PocServicer(), server) 105 | server.add_insecure_port(host) 106 | server.start() 107 | print("【Server】Starting server. Listening on "+host) 108 | server.wait_for_termination() 109 | if __name__ == '__main__': 110 | if(len(sys.argv))==1: 111 | serve() 112 | elif (len(sys.argv))==2: 113 | serve(sys.argv[1]) 114 | else: 115 | print("Usage: python rpc_server.py [host:port]") 116 | print(len(sys.argv)) 117 | # PocServicer.check_python("") -------------------------------------------------------------------------------- /Grpc/scan.proto: -------------------------------------------------------------------------------- 1 | //python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. scan.proto 2 | //protoc -I. --java_out=. --grpc-java_out=. scan.proto 3 | // 语法版本声明,必须放在非注释的第一行 4 | syntax = "proto3"; 5 | 6 | // 包名定义, Python中使用时可以省略不写 7 | package burp.rpc; 8 | option java_multiple_files = true; 9 | /* 10 | `message`是用来定义传输的数据的格式的, 等号后面的是字段编号 11 | 消息定义中的每个字段都有唯一的编号 12 | 总体格式类似于Python中定义一个类或者Golang中定义一个结构体 13 | */ 14 | message Poc_Request { 15 | string poc_type=1; 16 | string url = 2; 17 | string poc = 3; 18 | } 19 | 20 | message Poc_Response { 21 | bool is_success = 1; 22 | string result = 2; 23 | } 24 | // `service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口 25 | service poc { 26 | // 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应) 27 | rpc pocscan(Poc_Request) returns (Poc_Response); 28 | } -------------------------------------------------------------------------------- /Grpc/scan_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: scan.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import descriptor_pool as _descriptor_pool 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | # @@protoc_insertion_point(imports) 11 | 12 | _sym_db = _symbol_database.Default() 13 | 14 | 15 | 16 | 17 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nscan.proto\x12\x08\x62urp.rpc\"9\n\x0bPoc_Request\x12\x10\n\x08poc_type\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x0b\n\x03poc\x18\x03 \x01(\t\"2\n\x0cPoc_Response\x12\x12\n\nis_success\x18\x01 \x01(\x08\x12\x0e\n\x06result\x18\x02 \x01(\t2?\n\x03poc\x12\x38\n\x07pocscan\x12\x15.burp.rpc.Poc_Request\x1a\x16.burp.rpc.Poc_ResponseB\x02P\x01\x62\x06proto3') 18 | 19 | 20 | 21 | _POC_REQUEST = DESCRIPTOR.message_types_by_name['Poc_Request'] 22 | _POC_RESPONSE = DESCRIPTOR.message_types_by_name['Poc_Response'] 23 | Poc_Request = _reflection.GeneratedProtocolMessageType('Poc_Request', (_message.Message,), { 24 | 'DESCRIPTOR' : _POC_REQUEST, 25 | '__module__' : 'scan_pb2' 26 | # @@protoc_insertion_point(class_scope:burp.rpc.Poc_Request) 27 | }) 28 | _sym_db.RegisterMessage(Poc_Request) 29 | 30 | Poc_Response = _reflection.GeneratedProtocolMessageType('Poc_Response', (_message.Message,), { 31 | 'DESCRIPTOR' : _POC_RESPONSE, 32 | '__module__' : 'scan_pb2' 33 | # @@protoc_insertion_point(class_scope:burp.rpc.Poc_Response) 34 | }) 35 | _sym_db.RegisterMessage(Poc_Response) 36 | 37 | _POC = DESCRIPTOR.services_by_name['poc'] 38 | if _descriptor._USE_C_DESCRIPTORS == False: 39 | 40 | DESCRIPTOR._options = None 41 | DESCRIPTOR._serialized_options = b'P\001' 42 | _POC_REQUEST._serialized_start=24 43 | _POC_REQUEST._serialized_end=81 44 | _POC_RESPONSE._serialized_start=83 45 | _POC_RESPONSE._serialized_end=133 46 | _POC._serialized_start=135 47 | _POC._serialized_end=198 48 | # @@protoc_insertion_point(module_scope) 49 | -------------------------------------------------------------------------------- /Grpc/scan_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | """Client and server classes corresponding to protobuf-defined services.""" 3 | import grpc 4 | 5 | import scan_pb2 as scan__pb2 6 | 7 | 8 | class pocStub(object): 9 | """`service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口 10 | """ 11 | 12 | def __init__(self, channel): 13 | """Constructor. 14 | 15 | Args: 16 | channel: A grpc.Channel. 17 | """ 18 | self.pocscan = channel.unary_unary( 19 | '/burp.rpc.poc/pocscan', 20 | request_serializer=scan__pb2.Poc_Request.SerializeToString, 21 | response_deserializer=scan__pb2.Poc_Response.FromString, 22 | ) 23 | 24 | 25 | class pocServicer(object): 26 | """`service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口 27 | """ 28 | 29 | def pocscan(self, request, context): 30 | """一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应) 31 | """ 32 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 33 | context.set_details('Method not implemented!') 34 | raise NotImplementedError('Method not implemented!') 35 | 36 | 37 | def add_pocServicer_to_server(servicer, server): 38 | rpc_method_handlers = { 39 | 'pocscan': grpc.unary_unary_rpc_method_handler( 40 | servicer.pocscan, 41 | request_deserializer=scan__pb2.Poc_Request.FromString, 42 | response_serializer=scan__pb2.Poc_Response.SerializeToString, 43 | ), 44 | } 45 | generic_handler = grpc.method_handlers_generic_handler( 46 | 'burp.rpc.poc', rpc_method_handlers) 47 | server.add_generic_rpc_handlers((generic_handler,)) 48 | 49 | 50 | # This class is part of an EXPERIMENTAL API. 51 | class poc(object): 52 | """`service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口 53 | """ 54 | 55 | @staticmethod 56 | def pocscan(request, 57 | target, 58 | options=(), 59 | channel_credentials=None, 60 | call_credentials=None, 61 | insecure=False, 62 | compression=None, 63 | wait_for_ready=None, 64 | timeout=None, 65 | metadata=None): 66 | return grpc.experimental.unary_unary(request, target, '/burp.rpc.poc/pocscan', 67 | scan__pb2.Poc_Request.SerializeToString, 68 | scan__pb2.Poc_Response.FromString, 69 | options, channel_credentials, 70 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FrameScan | burp插件 2 | FrameScan插件是一款插件化的指纹POC扫描插件。 3 | 4 | ## 温馨提示 5 | 6 | 正常使用请关闭debug,不然可能会白屏哦~ 7 | 8 | ## 工具使用 9 | 10 | 1、使用Burpsuit或者双击jar包。 11 | 12 | 2、启动后,请确保本地127.0.0.1:23333端口开放。如未开放,请手动启动rpc_server服务。Yaml Poc 、Python Poc依赖此组件。编译好的server已放到根目录。如不适用,请下载GRPC文件夹,使用`python rpc_server.py`启动rpc服务。 13 | 14 | ## 漏洞探测 15 | 16 | burp发现的指纹及poc扫描结果会显示在此处。 17 | 18 | ![2024-09-20_09-57-12](attachment/2024-09-20_09-57-12.jpg) 19 | 20 | ## 漏洞poc 21 | 22 | ![image-20240804150024292](attachment/image-20240804150024292.png) 23 | 24 | 25 | 26 | 此模块支持4种POC类型如下: 27 | 28 | ### 简单HTTP请求 29 | 30 | 该POC会替换请求包中的字段,然后根据expression匹配规则进行漏洞探测。 31 | 32 | ```yaml 33 | expression: 34 | match_method: Contain 35 | status_code: 200 36 | scope: response body 37 | match_value: openapi 38 | requests: 39 | method: GET 40 | url: /v3/api-docs 41 | body: '' 42 | ``` 43 | 44 | ### 高级 HTTP请求 45 | 46 | 该模块为源HTTP请求包,支持以下变量进行替换。 47 | 48 | 完整 URL:http://127.0.0.1:8080/aa/bb.txt 49 | 50 | | 替换关键字 | 替换说明 | 替换示例 | 51 | | ------------------------ | ---------------------------- | -------------- | 52 | | {{Host}} | 替换为请求包的Host字段 | 127.0.0.1:8080 | 53 | | {{Random_UserAgent}} | 替换为随机的User-Agent头 | | 54 | | {{Cookie}} | 替换为源数据包的Cookie值 | | 55 | | {{Body}} | 替换为源数据包的Body值 | | 56 | | {{源数据包的任意请求头}} | 替换为源数据包的任意请求头值 | | 57 | | {{Base_Url}} | 替换为请求相对地址 | | 58 | | {{Base_Path}} | 替换为请求相对地址 的路径 | | 59 | | {{Url}} | 替换为完整 URL | | 60 | 61 | 62 | 63 | ```yaml 64 | requests_raw: | 65 | GET / HTTP/1.1 66 | Host: {{Host}} 67 | Pragma: no-cache 68 | Cache-Control: no-cache 69 | User-Agent: {{Random_UserAgent}} 70 | Accept-Encoding: gzip, deflate 71 | Accept-Language: zh-CN,zh;q=0.9 72 | Connection: close 73 | Cookie: {{Cookie}} 74 | 75 | a=1{{Body}} 76 | expression: 77 | match_method: Contain 78 | status_code: 22 79 | scope: response 80 | match_value: '22' 81 | ``` 82 | 83 | ### Yaml Poc 84 | 85 | 该POC格式为FrameScan_Yaml的格式,插件可相互调用。请参考[FrameScan_Yaml插件编写](https://github.com/qianxiao996/FrameScan-Yaml/),基础插件如下: 86 | 87 | ```yaml 88 | #插件名称 89 | name: poc-yaml-example-com 90 | # 脚本部分 91 | transport: http 92 | rules: 93 | r1: 94 | request: 95 | method: GET 96 | path: / 97 | body: addd $num 98 | headers: 99 | Content-Type: application/json 100 | expression: | 101 | response.status_code==200 && operator.contains(response.text,'html') 102 | output: 103 | serial: re.search('\w+',response.text).group() 104 | html: re.search('refresh',response.text).group() 105 | expression: r1() && r2() 106 | #信息部分 107 | detail: 108 | author: qianxiao996 109 | vuln_id: cve-2019-2222 110 | description: '111' 111 | group: 敏感信息泄露 112 | category: ALL 113 | links: 114 | - http://example.com 115 | #全局变量 116 | set: 117 | a: 1 118 | num: randint(1000, 2000) 119 | ``` 120 | 121 | ### Python Poc 122 | 123 | 该POC格式为FrameScan的格式,插件可相互调用。请参考[FrameScan插件编写](https://github.com/qianxiao996/FrameScan),插件模板如下: 124 | 125 | ```python 126 | # -*- coding: UTF-8 -*- 127 | #!/usr/bin/python 128 | import requests 129 | def vuln_info(): 130 | info={ 131 | 'vuln_name': 'POC测试漏洞', #漏洞名称 132 | 'vuln_referer':'http://baidu.com', #漏洞来源 133 | 'vuln_author':'qianxiao996', #插件作者 134 | 'cms_name':'test',#cms_name需要和上级目录保持一致。扫描器自动添加会调用。GUI版本不会调用 135 | 'vuln_description':'''漏洞描述''', 136 | 'vuln_identifier':'''漏洞编号。''', 137 | 'vuln_class':'漏洞分类',#如:信息泄漏、远程命令执行、任意文件上传、SQL注入、XML注入、任意文件读取、本地文件包含、认证绕过/未认证、弱口令、目录遍历、其他、反序列化漏洞、OGNL表达式注入、SSRF、后门、任意文件下载、鉴权绕过、暴力破解、命令注入、路径泄露、XSS、远程文件包含、CSRF、任意文件包含、代码注入、任意文件写入、密码硬编码、文件包含、任意用户注册、缓冲区溢出、用户枚举漏洞、任意文件删除、任意页面上传、管理权限等 138 | 'vuln_solution':'''修复建议。''', 139 | 'FofaQuery_type':'socket', #socket、http 140 | 'FofaQuery_link':'/', #此处的路径会加在url拼接访问,进行FofaQuery的条件匹配 此处为all为全部页面都检测 141 | 'FofaQuery_rule':'title="百度"',#header="JSESSIONID" || body="Struts Problem Report" || body="There is no Action mapped for namespace" || body="No result defined for action and result input" || header="Servlet" || header="JBoss",port="60001" 142 | #header', 'body', 'title', 'banner','port','banner','service','protocol','server' 143 | 'ispoc':1, #是否有poc 1为有 0为无 144 | 'isexp':1 #是否有exp 1为有 0为无 145 | } 146 | return info 147 | # url:url hostname:主机地址 port:端口 scheme:服务 heads:http自定义头信息 148 | def do_poc(url,hostname,port,scheme,heads={}): 149 | try: 150 | # 返回参数 151 | #Result返回是否存在, 152 | #Result_Info为返回的信息,可以为Paylaod 153 | #Debug debug信息 默认不会显示,勾选显示调试信息会输出此结果 154 | #Error_Info无论何时都会输出 155 | result = {"Result":True,"Result_Info":"payload","Debug_Info":"","Error_Info":""} 156 | result['Result_Info']= 'payload' 157 | result['Debug_Info'] = 'ddd' 158 | result['Error_Info'] = "dsaaaaaaaa" 159 | except Exception as e: 160 | result['Error_Info'] = str(e)+str(e.__traceback__.tb_lineno)+'行' 161 | return result 162 | 163 | # { 164 | # "type":"cmd", #cmd,shell,uploadfile 165 | # "command":"whoami", #cmd命令 166 | # "reverse_ip":"127.0.0.1", #反弹shell的ip 167 | # "reverse_port":"8888", #反弹shell的端口 168 | # "filename":"conf.php", #写入文件的名字 169 | # "filename_contents":"shell内容", #shell文件内容 170 | # } 171 | # url:url hostname:主机地址 port:端口 scheme:服务 heads:自定义请求头 172 | ``` 173 | 174 | ## 指纹POC 175 | 176 | ![image-20240804150034449](attachment/image-20240804150034449.png) 177 | 178 | 指纹POC编辑 179 | 180 | ![image-20240804151359956](attachment/image-20240804151359956.png) 181 | 182 | ## 分组管理 183 | 184 | 启用漏洞POC:指纹匹配后,只有在此组的漏洞POC才会进行扫描。 185 | 186 | 跳过指纹POC:不进行指纹扫描。直接进行扫描的POC。 187 | 188 | ![image-20240920095944182](attachment/image-20240920095944182.png) 189 | 190 | 191 | 192 | ## 插件设置 193 | 194 | ![image-20240920095906076](attachment/image-20240920095906076.png) 195 | 196 | 197 | 198 | ## 配置文件介绍 199 | 200 | ```yaml 201 | #是否启用代理 202 | Is_Proxy: true 203 | #是否启用Debug 204 | Is_Debug: true 205 | #是否开启白名单 206 | WhiteEnable: false 207 | #是否启用POC插件 208 | Enable_Poc: true 209 | #是否开启Repeater 210 | Is_Repeater: true 211 | #白名单域名列表 212 | WhiteList: baidu.com 213 | #黑名单域名列表 214 | BlackList: www.baidu.com 215 | #是否启用指纹插件 216 | Enable_Finger: true 217 | #指纹扫描后,匹配的POC插件列表 218 | EnablePocList: 高危漏洞,渗透测试,接口泄露,默认分组,信息泄露 219 | #不进行指纹扫描,直接扫描的漏洞POC插件 220 | DisenableFingerPocList: Yaml Poc测试,高级HTTP请求测试,Python Poc测试 221 | #GRPC ip地址 222 | Grpc_Host: localhost 223 | #GRPC 端口 224 | Grpc_Port: 23333 225 | #GUI主题,配置项:FlatDarkLaf、FlatIntelliJLaf、FlatLightLaf、FlatCyanLightIJTheme、FlatArcIJTheme、FlatArcOrangeIJTheme、FlatLightFlatIJTheme、FlatSolarizedLightIJTheme、FlatGitHubDarkIJTheme、FlatSpacegrayIJTheme、FlatVuesionIJTheme、FlatXcodeDarkIJTheme、FlatAtomOneDarkIJTheme、FlatGrayIJTheme、FlatArcDarkIJTheme、FlatArcDarkOrangeIJTheme、FlatCarbonIJTheme、FlatCobalt2IJTheme、FlatHighContrastIJTheme、FlatDarkFlatIJTheme、FlatDarkPurpleIJTheme、FlatDraculaIJTheme、FlatGradiantoDarkFuchsiaIJTheme、FlatGradiantoDeepOceanIJTheme、FlatGradiantoMidnightBlueIJTheme、FlatGradiantoNatureGreenIJTheme、FlatGruvboxDarkHardIJTheme 226 | Themes: FlatIntelliJLaf 227 | 228 | #系统+架构:系统配置项 windows|mac os x| linux 架构配置项:amd64|x86_64|amd64|arm|aarch64 229 | Platform: windows 10:amd64 230 | 231 | #简单请求替换插件模板 232 | Simple_HTTP_Request: | 233 | methd: GET 234 | url: /ddd 235 | haders: 236 | - User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 237 | body: a=1 238 | 239 | #Yaml Poc插件模板 240 | Yaml_Poc: | 241 | name: poc-yaml-.DS_Store-info 242 | transport: http 243 | rules: 244 | r1: 245 | request: 246 | method: GET 247 | path: /.DS_Store 248 | headers: 249 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 250 | expression: | 251 | response.status_code==200 252 | output: "发现.DS_Store文件" 253 | expression: r1() 254 | detail: 255 | name: '.DS_Store文件泄露' 256 | author: qianxiao996 257 | category: 敏感信息泄露 258 | subassembly: ALL 259 | vuln_id: 无 260 | description: '.DS_Store文件泄露' 261 | links: [] 262 | #高级HTTP请求插件模板 263 | Advanced_HTTP_Request: | 264 | GET / HTTP/1.1 265 | Host: {{Host}} 266 | Pragma: no-cache 267 | Cache-Control: no-cache 268 | User-Agent: {{Random_UserAgent}} 269 | Accept-Encoding: gzip, deflate 270 | Accept-Language: zh-CN,zh;q=0.9 271 | Connection: close 272 | Cookie: {{Cookie}} 273 | 274 | {{Body}} 275 | #Python_Poc插件模板 276 | Python_Poc: "" 277 | 278 | ``` 279 | 280 | -------------------------------------------------------------------------------- /attachment/2024-09-20_09-57-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/2024-09-20_09-57-12.jpg -------------------------------------------------------------------------------- /attachment/image-20240804150024292.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/image-20240804150024292.png -------------------------------------------------------------------------------- /attachment/image-20240804150034449.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/image-20240804150034449.png -------------------------------------------------------------------------------- /attachment/image-20240804150439416.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/image-20240804150439416.png -------------------------------------------------------------------------------- /attachment/image-20240804151359956.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/image-20240804151359956.png -------------------------------------------------------------------------------- /attachment/image-20240920095906076.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/image-20240920095906076.png -------------------------------------------------------------------------------- /attachment/image-20240920095944182.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/attachment/image-20240920095944182.png -------------------------------------------------------------------------------- /config.yml: -------------------------------------------------------------------------------- 1 | Is_Proxy: true 2 | Is_Debug: true 3 | WhiteEnable: false 4 | Enable_Poc: true 5 | Is_Repeater: true 6 | WhiteList: baidu.com 7 | BlackList: www.baidu.com 8 | Enable_Finger: false 9 | Grpc_Host: localhost 10 | Grpc_Port: 23333 11 | Themes: FlatIntelliJLaf 12 | Platform: windows 10:amd64 13 | Simple_HTTP_Request: | 14 | methd: GET 15 | url: /ddd 16 | haders: 17 | - User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 18 | body: a=1 19 | Yaml_Poc: | 20 | name: poc-yaml-.DS_Store-info 21 | transport: http 22 | rules: 23 | r1: 24 | request: 25 | method: GET 26 | path: /.DS_Store 27 | headers: 28 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 29 | expression: | 30 | response.status_code==200 31 | output: "发现.DS_Store文件" 32 | expression: r1() 33 | detail: 34 | name: '.DS_Store文件泄露' 35 | author: qianxiao996 36 | category: 敏感信息泄露 37 | subassembly: ALL 38 | vuln_id: 无 39 | description: '.DS_Store文件泄露' 40 | links: [] 41 | Advanced_HTTP_Request: | 42 | GET / HTTP/1.1 43 | Host: {{Host}} 44 | Pragma: no-cache 45 | Cache-Control: no-cache 46 | User-Agent: {{Random_UserAgent}} 47 | Accept-Encoding: gzip, deflate 48 | Accept-Language: zh-CN,zh;q=0.9 49 | Connection: close 50 | Cookie: {{Cookie}} 51 | 52 | {{Body}} 53 | Python_Poc: "# -*- coding: UTF-8 -*-\n#!/usr/bin/python\nimport sys\nimport requests,argparse,os\n\ 54 | from urllib.parse import urlparse\ndef vuln_info():\n vuln_info = {\n \ 55 | \ \"vuln_name\":\"POC测试漏洞\", #漏洞名称\n 'vuln_referer':'http://baidu.com',\ 56 | \ #漏洞来源\n 'vuln_author':'qianxiao996', #插件作者\n 'cms_name':'test',#cms_name需\ 57 | 要和上级目录保持一致。扫描器自动添加会调用。GUI版本不会调用\n 'vuln_description':'''漏洞描述''',\n \ 58 | \ 'vuln_identifier':'''漏洞编号。''',\n 'vuln_class':'漏洞分类',#如:信息泄漏、远程命令执行、任意\ 59 | 文件上传、SQL注入、XML注入、任意文件读取、本地文件包含、认证绕过/未认证、弱口令、目录遍历、其他、反序列化漏洞、OGNL表达式注入、SSRF、后门、任意文\ 60 | 件下载、鉴权绕过、暴力破解、命令注入、路径泄露、XSS、远程文件包含、CSRF、任意文件包含、代码注入、任意文件写入、密码硬编码、文件包含、任意用户注册、缓冲区\ 61 | 溢出、用户枚举漏洞、任意文件删除、任意页面上传、管理权限等\n 'vuln_solution':'''修复建议。''',\n 'FofaQuery_type':'socket',\ 62 | \ #socket、http\n 'FofaQuery_link':'/', #此处的路径会加在url拼接访问,进行FofaQuery的条件匹配\ 63 | \ 此处为all为全部页面都检测\n 'FofaQuery_rule':'title=\"百度\"',#header=\"JSESSIONID\"\ 64 | \ || body=\"Struts Problem Report\" || body=\"There is no Action mapped for namespace\"\ 65 | \ || body=\"No result defined for action and result input\" || header=\"Servlet\"\ 66 | \ || header=\"JBoss\",port=\"60001\"\n #header', 'body', 'title', 'banner','port','banner','service','protocol','server'\n\ 67 | \ 'ispoc':0, #是否有poc 1为有 0为无\n 'isexp':1 #是否有exp 1为有 0为无\n \ 68 | \ }\n return vuln_info\ndef _out(type,text):\n print(\"[*] \"+type+\":\\n\ 69 | \ \"+text)\n# func_out 输出函数对象 url:url hostname:主机地址 port:端口 scheme:服务 heads:\ 70 | http自定义头信息\n# plugins_temp_data 全局变量,可存储数据至do_exp使用\ndef do_poc(url,hostname,port,scheme,heads={},func_out=_out,plugins_temp_data={}):\n\ 71 | \ try:\n #存储数据至do_exp函数使用\n plugins_temp_data['key']='11'\n\n \ 72 | \ # func_out('Debug',\"debug信息\")\n func_out('Error',\"错误信息\",)\n \ 73 | \ # func_out('Info',\"info信息\")\n # 返回参数\n #Result返回是否存在,\n\ 74 | \ #Result_Info为返回的信息,可以为Paylaod \n #Debug debug信息 默认不会显示,勾选显示调试信息会\ 75 | 输出此结果\n #Error_Info无论何时都会输出\n result = {\"Result\":False,\"Result_Info\"\ 76 | :\"\"}\n result['Result'] = True\n result['Result_Info']= url\n \ 77 | \ return result\n except Exception as e:\n func_out('Error',str(e)+str(e.__traceback__.tb_lineno)+'行\ 78 | ')\n\n\n#exp_data\n# {\n# \"type\":\"cmd\", #cmd,shell,uploadfile\n# \"\ 79 | command\":\"whoami\", #cmd命令\n# \"reverse_ip\":\"127.0.0.1\", #反弹shell的ip\n\ 80 | # \"reverse_port\":\"8888\", #反弹shell的端口\n# \"filename\":\"conf.php\", #写\ 81 | 入文件的名字\n# \"filename_contents\":\"shell内容\", #shell文件内容\n# }\n# url:url hostname:\ 82 | 主机地址 port:端口 scheme:服务 heads:自定义请求头 func_out 输出函数对象\ndef do_exp(url,hostname,port,scheme,heads={},exp_data={},func_out=_out,plugins_temp_data={}):\n\ 83 | \ # 返回参数\n # Result返回是否成功,\n # Result_Info为返回的信息,可以为Paylaod\n result\ 84 | \ = {\"Result\": False, \"Result_Info\": \"\"}\n try:\n\n #获取全局变量数据\n\ 85 | \ key = plugins_temp_data.get('key')\n\n #输出各种信息。参数一类型,默认Debug,可选【\ 86 | Debug、Error、Info】 参数二位具体内容\n func_out('Debug',\"debug信息\")\n func_out('Error',\"\ 87 | 错误信息\",)\n func_out('Info',\"info信息\")\n\n #命令执行\n if exp_data['type']=='cmd':\n\ 88 | \ ##处理你的命令执行\n result['Result'] = True\n result['Result_Info']\ 89 | \ = \"root\"\n result['Result_Info'] =plugins_temp_data\n\n #反\ 90 | 弹shell \n elif exp_data['type']=='shell':\n ##处理你的反弹shell\n\ 91 | \ result['Result'] = True\n result['Result_Info'] = \"反弹成功\ 92 | \"\n #上传文件 \n elif exp_data['type']=='uploadfile':\n \ 93 | \ ##处理你的上传操作\n result['Result'] = True\n result['Result_Info']\ 94 | \ = \"上传成功\"\n except Exception as e:\n func_out('Error',str(e)+str(e.__traceback__.tb_lineno)+'行\ 95 | ')\n return result\n" 96 | -------------------------------------------------------------------------------- /data.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/data.db -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.qianxiao996.tools.burpextend 7 | FrameScan 8 | 2.7 9 | 10 | UTF-8 11 | ${java.version} 12 | ${java.version} 13 | 1.45.1 14 | 3.21.9 15 | 16 | 17 | 18 | 19 | 20 | com.formdev 21 | flatlaf 22 | 3.5.1 23 | compile 24 | 25 | 26 | com.formdev 27 | flatlaf-intellij-themes 28 | 3.5.1 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | net.portswigger.burp.extender 41 | burp-extender-api 42 | 1.7.22 43 | 44 | 45 | org.xerial 46 | sqlite-jdbc 47 | 3.41.2.2 48 | 49 | 50 | org.yaml 51 | snakeyaml 52 | 2.0 53 | 54 | 55 | com.fifesoft 56 | rsyntaxtextarea 57 | 3.4.1 58 | 59 | 60 | com.fasterxml.jackson.core 61 | jackson-databind 62 | 2.13.1 63 | 64 | 65 | com.google.guava 66 | guava 67 | 32.0.0-android 68 | 69 | 70 | com.google.code.gson 71 | gson 72 | 2.10 73 | 74 | 75 | io.grpc 76 | grpc-netty-shaded 77 | ${grpc.version} 78 | 79 | 80 | io.grpc 81 | grpc-protobuf 82 | ${grpc.version} 83 | 84 | 85 | io.grpc 86 | grpc-stub 87 | ${grpc.version} 88 | 89 | 90 | com.google.protobuf 91 | protobuf-java 92 | ${protobuf.version} 93 | 94 | 95 | 96 | 97 | 98 | 99 | org.apache.maven.plugins 100 | maven-assembly-plugin 101 | 102 | 103 | 104 | 105 | burp.MainApplication 106 | 107 | 108 | 109 | 110 | 111 | jar-with-dependencies 112 | 113 | 114 | 115 | 116 | 117 | package 118 | 119 | single 120 | 121 | 122 | 123 | 124 | 125 | org.apache.maven.plugins 126 | maven-compiler-plugin 127 | 3.11.0 128 | 129 | 8 130 | 8 131 | 132 | -extdirs 133 | ${project.basedir}/src/main/resources/lib/ 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /src/main/java/burp/BurpExtender.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | import burp.scan.Scan; 3 | 4 | import java.awt.*; 5 | import java.io.*; 6 | import java.nio.file.Paths; 7 | import java.sql.SQLException; 8 | import java.util.*; 9 | import java.util.List; 10 | import javax.swing.*; 11 | import burp.utils.Config; 12 | 13 | import static burp.Main_Vuln.*; 14 | 15 | 16 | public class BurpExtender implements IBurpExtender, ITab, IHttpListener,IScannerCheck, IMessageEditorController,IContextMenuFactory,IExtensionStateListener 17 | { 18 | public static JPanel MainPane; 19 | public static IBurpExtenderCallbacks callbacks; 20 | public static IExtensionHelpers helpers; 21 | public static IHttpRequestResponse currentlyDisplayedItem; 22 | 23 | public static String BurpConfigPath ; 24 | public static PrintWriter stdout; 25 | 26 | 27 | 28 | // implement IBurpExtender 29 | // 30 | @Override 31 | public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) 32 | { 33 | //输出 34 | stdout = new PrintWriter(callbacks.getStdout(), true); 35 | stdout.println("Loading.."); 36 | 37 | // keep a reference to our callbacks object 38 | BurpExtender.callbacks = callbacks; 39 | 40 | // obtain an extension helpers object 41 | helpers = callbacks.getHelpers(); 42 | 43 | // set our extension name 44 | callbacks.setExtensionName(app_name+ " "+ app_version); 45 | 46 | // create our UI 47 | SwingUtilities.invokeLater(new Runnable() 48 | { 49 | @Override 50 | public void run() 51 | { 52 | MainPane = new JPanel(); 53 | MainPane.setPreferredSize(new Dimension(1000, 500)); 54 | MainPane.setLayout(new BoxLayout(MainPane, BoxLayout.X_AXIS)); 55 | //插件物理路径 56 | BurpConfigPath = callbacks.getExtensionFilename().substring(0, (callbacks.getExtensionFilename().lastIndexOf(File.separator))) + File.separator; 57 | // main split pane 58 | //配置文件 59 | String Config_PATH = String.format("%s/%s", BurpExtender.BurpConfigPath, Main_Vuln.Config_FILE); 60 | Main_Vuln.load_config_bypath(Config_PATH); 61 | //sql数据库物理路径 62 | Main_Vuln.SQL_DB_PATH = Paths.get(BurpConfigPath, Main_Vuln.SQL_DB_FILE).toString(); 63 | 64 | //tab 65 | JTabbedPane tab = new JTabbedPane(); 66 | try { 67 | Main_Vuln.is_burp = true; 68 | Main_Vuln.load_plugins(BurpExtender.this,tab); 69 | } catch (SQLException | ClassNotFoundException e) { 70 | stdout.println(e); 71 | } catch (IOException e) { 72 | printErr(e.getMessage()); 73 | printErr(Arrays.toString(e.getStackTrace())); 74 | } 75 | 76 | MainPane.add(tab); 77 | 78 | // add the custom tab to Burp's UI 79 | callbacks.addSuiteTab(BurpExtender.this); 80 | 81 | // register ourselves as an HTTP listener 82 | callbacks.registerHttpListener(BurpExtender.this); 83 | callbacks.registerScannerCheck(BurpExtender.this); 84 | callbacks.registerContextMenuFactory(BurpExtender.this); 85 | // callbacks.registerMessageEditorTabFactory(BurpExtender.this); 86 | } 87 | 88 | }); 89 | stdout.println("Success.."); 90 | stdout.println(app_title); 91 | } 92 | 93 | 94 | 95 | @Override 96 | public String getTabCaption() 97 | { 98 | return app_name; 99 | } 100 | 101 | @Override 102 | public Component getUiComponent() 103 | { 104 | return MainPane; 105 | } 106 | 107 | // 108 | // implement IHttpListener 109 | // 110 | 111 | 112 | 113 | 114 | @Override 115 | public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) 116 | { 117 | //漏洞扫描 118 | Scan.accept_Http_Info(toolFlag,messageIsRequest,messageInfo); 119 | } 120 | 121 | @Override 122 | public List doPassiveScan(IHttpRequestResponse baseRequestResponse) { 123 | return null; 124 | } 125 | 126 | @Override 127 | public List createMenuItems(final IContextMenuInvocation invocation) { 128 | //右键发送按钮功能 129 | if(invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_REPEATER || invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_PROXY){ 130 | return Main_Vuln.returnMenuItems(invocation); 131 | // listMenuItems.add(jMenu); 132 | } 133 | return new ArrayList<>(); 134 | } 135 | @Override 136 | public List doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) { 137 | return null; 138 | } 139 | 140 | @Override 141 | public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) { 142 | if (existingIssue.getIssueName().equals(newIssue.getIssueName())) 143 | return -1; 144 | else return 0; 145 | } 146 | 147 | @Override 148 | public IHttpService getHttpService() { 149 | // return null; 150 | return currentlyDisplayedItem.getHttpService(); 151 | 152 | } 153 | 154 | @Override 155 | public byte[] getRequest() { 156 | return currentlyDisplayedItem.getRequest(); 157 | 158 | // return new byte[0]; 159 | } 160 | @Override 161 | public void extensionUnloaded() { 162 | // 插件被卸载时执行的操作 163 | System.out.println("Extension unloaded. Cleaning up resources..."); 164 | channel.shutdown(); 165 | Main_Vuln.grpc_server_thread_stop_flag=false; 166 | 167 | Main_Vuln.grpc_server_thread.stop(); 168 | } 169 | 170 | @Override 171 | public byte[] getResponse() { 172 | return currentlyDisplayedItem.getResponse(); 173 | 174 | // return new byte[0]; 175 | } 176 | 177 | 178 | 179 | // @Override 180 | // public byte[] getRequest() 181 | // { 182 | // return Main_Vuln.currentlyDisplayedItem.getRequest(); 183 | // } 184 | // 185 | // @Override 186 | // public byte[] getResponse() 187 | // { 188 | // return Main_Vuln.currentlyDisplayedItem.getResponse(); 189 | // } 190 | // 191 | // @Override 192 | // public IHttpService getHttpService() 193 | // { 194 | // return Main_Vuln.currentlyDisplayedItem.getHttpService(); 195 | // } 196 | 197 | 198 | } -------------------------------------------------------------------------------- /src/main/java/burp/CustomMessageEditorTab.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | 4 | import burp.model.log.LogEntry; 5 | 6 | import javax.swing.*; 7 | import javax.swing.text.JTextComponent; 8 | import java.awt.*; 9 | import java.nio.charset.StandardCharsets; 10 | import java.util.List; 11 | 12 | import static burp.Main_Vuln.model; 13 | 14 | 15 | public class CustomMessageEditorTab implements IMessageEditorTab { 16 | 17 | private IBurpExtenderCallbacks callbacks; 18 | private IMessageEditorController controller; 19 | private ITextEditor iTextEditor; 20 | 21 | public CustomMessageEditorTab(IBurpExtenderCallbacks callbacks, IMessageEditorController controller) { 22 | this.callbacks = callbacks; 23 | this.controller = controller; 24 | iTextEditor = callbacks.createTextEditor(); 25 | // 启用自动换行 26 | } 27 | 28 | 29 | @Override 30 | public String getTabCaption() { 31 | return "FS POC"; 32 | } 33 | 34 | @Override 35 | public Component getUiComponent() { 36 | return iTextEditor.getComponent(); 37 | } 38 | 39 | @Override 40 | public boolean isEnabled(byte[] bytes, boolean b) { 41 | return true; 42 | } 43 | 44 | @Override 45 | public void setMessage(byte[] content, boolean isRequest) { 46 | // 检查控制器是否是自定义插件的实例 47 | // if (controller instanceof BurpExtender) { 48 | // 处理消息内容 49 | if (content != null) { 50 | // List all_table_Data= model.getAllValue(); 51 | int row = Main_Vuln.logTable.getSelectedRow(); 52 | row =Main_Vuln.logTable.convertRowIndexToModel(row); 53 | if(!(row >= 0 && row < model.getRowCount())){ 54 | return; 55 | } 56 | int id = (int)Main_Vuln.logTable.getValueAt(row,0); 57 | LogEntry current_log = model.getValueByid(id); 58 | // 解析HTTP请求或响应 59 | if (isRequest) { 60 | if (current_log != null) { 61 | iTextEditor.setText(current_log.poc_requestResponse.getRequest()); 62 | } 63 | } else { 64 | if (current_log != null) { 65 | iTextEditor.setText(current_log.poc_requestResponse.getResponse()); 66 | } 67 | } 68 | } else { 69 | iTextEditor.setText("".getBytes(StandardCharsets.UTF_8)); 70 | } 71 | // } else { 72 | // iTextEditor.setText("".getBytes(StandardCharsets.UTF_8)); 73 | // } 74 | } 75 | 76 | @Override 77 | public byte[] getMessage() { 78 | // 返回当前显示的消息内容 79 | return iTextEditor.getText(); 80 | } 81 | 82 | @Override 83 | public boolean isModified() { 84 | // 判断消息是否被修改 85 | return iTextEditor.isTextModified(); 86 | } 87 | 88 | @Override 89 | public byte[] getSelectedData() { 90 | return iTextEditor.getSelectedText(); 91 | // 返回当前选中的数据 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/burp/CustomMessageEditorTabFactory.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | public class CustomMessageEditorTabFactory implements IMessageEditorTabFactory { 4 | 5 | private IBurpExtenderCallbacks callbacks; 6 | private IMessageEditorController controller; 7 | public CustomMessageEditorTabFactory(IBurpExtenderCallbacks callbacks, IMessageEditorController controller) { 8 | this.callbacks = callbacks; 9 | this.controller = controller; 10 | } 11 | 12 | @Override 13 | public IMessageEditorTab createNewInstance(IMessageEditorController controller, boolean editable) { 14 | // 创建新的自定义标签页实例 15 | return new CustomMessageEditorTab(callbacks, controller); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /src/main/java/burp/LogEntry.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.net.URL; 4 | 5 | public class LogEntry 6 | { 7 | final int id; 8 | final int tool; 9 | final IHttpRequestResponsePersisted requestResponse; 10 | final URL url; 11 | final String parameter; 12 | final String value; 13 | final String data_md5; 14 | final int times; 15 | final int response_code; 16 | 17 | final String scan_result; 18 | 19 | 20 | LogEntry(int id, int tool, IHttpRequestResponsePersisted requestResponse, URL url, String parameter, String value, String data_md5, int times, Integer response_code, String scan_result) 21 | { 22 | this.id = id; 23 | this.tool = tool; 24 | this.requestResponse = requestResponse; 25 | this.url = url; 26 | this.parameter = parameter; 27 | this.value = value; 28 | this.data_md5 = data_md5; 29 | this.times = times; 30 | this.response_code = response_code; 31 | this.scan_result = scan_result; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/burp/LogTableModel.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import javax.swing.table.AbstractTableModel; 4 | import java.awt.event.ActionEvent; 5 | 6 | public class LogTableModel extends AbstractTableModel { 7 | private final String[] columnNames = {"序号", "来源", "URL", "返回包长度", "状态码","精确扫描结果"}; 8 | @Override 9 | public int getRowCount() 10 | { 11 | return BurpExtender.table_log_data.size(); 12 | 13 | } 14 | 15 | @Override 16 | public int getColumnCount() 17 | { 18 | return columnNames.length; 19 | } 20 | 21 | @Override 22 | public String getColumnName(int columnIndex) 23 | { 24 | return columnNames[columnIndex]; 25 | } 26 | 27 | @Override 28 | public Class getColumnClass(int columnIndex) 29 | { 30 | switch (columnIndex) 31 | { 32 | case 0: 33 | return Integer.class; 34 | case 1: 35 | return String.class; 36 | case 2: 37 | return String.class; 38 | case 3: 39 | return Integer.class;//返回响应包的长度 40 | case 4: 41 | return Integer.class; 42 | case 5: 43 | return String.class; 44 | default: 45 | return String.class; 46 | } 47 | } 48 | public void ClearData() { 49 | BurpExtender.table_log_data.clear(); 50 | // int rowCount = logTable.getRowCount(); 51 | // model.fireTableRowsDeleted(0, rowCount); 52 | fireTableDataChanged(); 53 | // 54 | } 55 | @Override 56 | public Object getValueAt(int rowIndex, int columnIndex) 57 | { 58 | if (rowIndex < 0 || rowIndex >= BurpExtender.table_log_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 59 | return ""; 60 | } 61 | LogEntry logEntry = BurpExtender.table_log_data.get(rowIndex); 62 | switch (columnIndex) 63 | { 64 | case 0: 65 | return logEntry.id; 66 | case 1: 67 | return BurpExtender.callbacks.getToolName(logEntry.tool); 68 | case 2: 69 | return logEntry.url.toString(); 70 | case 3: 71 | return logEntry.requestResponse.getResponse().length;//返回响应包的长度 72 | case 4: 73 | return logEntry.response_code; 74 | case 5: 75 | return logEntry.scan_result; 76 | default: 77 | return ""; 78 | } 79 | } 80 | 81 | 82 | } -------------------------------------------------------------------------------- /src/main/java/burp/MainApplication.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | import com.formdev.flatlaf.*; 3 | import com.formdev.flatlaf.intellijthemes.*; 4 | import com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme; 5 | import com.formdev.flatlaf.intellijthemes.FlatDraculaIJTheme; 6 | import com.formdev.flatlaf.intellijthemes.FlatMonokaiProIJTheme; 7 | import com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme; 8 | import com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme; 9 | import com.formdev.flatlaf.intellijthemes.materialthemeuilite.*; 10 | 11 | import javax.swing.*; 12 | import java.awt.*; 13 | import java.io.IOException; 14 | import java.nio.file.Paths; 15 | import java.sql.SQLException; 16 | public class MainApplication extends JFrame { 17 | public MainApplication() { 18 | // 初始化窗口 19 | this.initUI(); 20 | } 21 | 22 | private void initUI() { 23 | setTitle(Main_Vuln.app_title); 24 | //插件物理路径 25 | //配置文件 26 | String currentDir = System.getProperty("user.dir"); 27 | String Config_PATH = String.format("%s/%s", currentDir, Main_Vuln.Config_FILE); 28 | Main_Vuln.load_config_bypath(Config_PATH); 29 | try 30 | { 31 | 32 | String themes = (String) Main_Vuln.Global_Config.get("Themes"); 33 | // String themes = "FlatIntelliJLaf"; 34 | // String themes = "FlatArcIJTheme"; 35 | // String themes = "FlatArcOrangeIJTheme"; 36 | switch (themes){ 37 | case "FlatDarkLaf": 38 | FlatDarkLaf.setup(); 39 | break; 40 | case "FlatIntelliJLaf": 41 | FlatIntelliJLaf.setup(); 42 | break; 43 | case "FlatLightLaf": 44 | FlatLightLaf.setup(); 45 | break; 46 | case "FlatCyanLightIJTheme": 47 | FlatCyanLightIJTheme.setup(); 48 | break; 49 | case "FlatArcIJTheme": 50 | FlatArcIJTheme.setup(); 51 | break; 52 | case "FlatArcOrangeIJTheme": 53 | FlatArcOrangeIJTheme.setup(); 54 | break; 55 | case "FlatLightFlatIJTheme": 56 | FlatLightFlatIJTheme.setup(); 57 | break; 58 | case "FlatSolarizedLightIJTheme": 59 | FlatSolarizedLightIJTheme.setup(); 60 | break; 61 | case "FlatGitHubDarkIJTheme": 62 | FlatGitHubDarkIJTheme.setup(); 63 | break; 64 | case "FlatSpacegrayIJTheme": 65 | FlatSpacegrayIJTheme.setup(); 66 | break; 67 | case "FlatVuesionIJTheme": 68 | FlatVuesionIJTheme.setup(); 69 | break; 70 | case "FlatXcodeDarkIJTheme": 71 | FlatXcodeDarkIJTheme.setup(); 72 | break; 73 | case "FlatAtomOneDarkIJTheme": 74 | FlatAtomOneDarkIJTheme.setup(); 75 | break; 76 | case "FlatGrayIJTheme": 77 | FlatGrayIJTheme.setup(); 78 | break; 79 | case "FlatArcDarkIJTheme": 80 | FlatArcDarkIJTheme.setup(); 81 | break; 82 | case "FlatArcDarkOrangeIJTheme": 83 | FlatArcDarkOrangeIJTheme.setup(); 84 | break; 85 | case "FlatCarbonIJTheme": 86 | FlatCarbonIJTheme.setup(); 87 | break; 88 | case "FlatCobalt2IJTheme": 89 | FlatCobalt2IJTheme.setup(); 90 | break; 91 | case "FlatHighContrastIJTheme": 92 | FlatHighContrastIJTheme.setup(); 93 | break; 94 | case "FlatDarkFlatIJTheme": 95 | FlatDarkFlatIJTheme.setup(); 96 | break; 97 | case "FlatDarkPurpleIJTheme": 98 | FlatDarkPurpleIJTheme.setup(); 99 | break; 100 | case "FlatDraculaIJTheme": 101 | FlatDraculaIJTheme.setup(); 102 | break; 103 | case "FlatGradiantoDarkFuchsiaIJTheme": 104 | FlatGradiantoDarkFuchsiaIJTheme.setup(); 105 | break; 106 | case "FlatGradiantoDeepOceanIJTheme": 107 | FlatGradiantoDeepOceanIJTheme.setup(); 108 | break; 109 | case "FlatGradiantoMidnightBlueIJTheme": 110 | FlatGradiantoMidnightBlueIJTheme.setup(); 111 | break; 112 | case "FlatGradiantoNatureGreenIJTheme": 113 | FlatGradiantoNatureGreenIJTheme.setup(); 114 | break; 115 | case "FlatGruvboxDarkHardIJTheme": 116 | FlatGruvboxDarkHardIJTheme.setup(); 117 | break; 118 | case "FlatGruvboxDarkSoftIJTheme": 119 | FlatGruvboxDarkSoftIJTheme.setup(); 120 | break; 121 | case "FlatHiberbeeDarkIJTheme": 122 | FlatHiberbeeDarkIJTheme.setup(); 123 | break; 124 | case "FlatMaterialDesignDarkIJTheme": 125 | FlatMaterialDesignDarkIJTheme.setup(); 126 | break; 127 | case "FlatMonocaiIJTheme": 128 | FlatMonocaiIJTheme.setup(); 129 | break; 130 | case "FlatMonokaiProIJTheme": 131 | FlatMonokaiProIJTheme.setup(); 132 | break; 133 | case "FlatGruvboxDarkMediumIJTheme": 134 | FlatGruvboxDarkMediumIJTheme.setup(); 135 | break; 136 | case "FlatNordIJTheme": 137 | FlatNordIJTheme.setup(); 138 | break; 139 | case "FlatOneDarkIJTheme": 140 | FlatOneDarkIJTheme.setup(); 141 | break; 142 | case "FlatSolarizedDarkIJTheme": 143 | FlatSolarizedDarkIJTheme.setup(); 144 | break; 145 | } 146 | } 147 | catch(Exception e) 148 | { 149 | //TODO exception 150 | } 151 | 152 | Main_Vuln.is_burp=false; 153 | //sql数据库物理路径 154 | Main_Vuln.SQL_DB_PATH = Paths.get(currentDir, Main_Vuln.SQL_DB_FILE).toString(); 155 | JTabbedPane tab = new JTabbedPane(); 156 | try { 157 | Main_Vuln.load_plugins(MainApplication.this,tab); 158 | } catch (SQLException | ClassNotFoundException | IOException e) { 159 | System.out.println(e.getMessage()); 160 | } 161 | add(tab); 162 | // 设置窗口的默认关闭操作 163 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 164 | // 设置窗口的大小 165 | setSize(1300, 800); 166 | // 设置窗口的位置 167 | setLocationRelativeTo(null); // 居中显示 168 | // 设置窗口可见 169 | setVisible(true); 170 | Main_Vuln.splitPane_request_response.setDividerLocation(0.5);//设置分割的大小 171 | 172 | } 173 | 174 | public static void main(String[] args) { 175 | 176 | java.awt.EventQueue.invokeLater(new Runnable() { 177 | public void run() { 178 | new MainApplication(); 179 | } 180 | }); 181 | } 182 | // public JTabbedPane load_scan_ui(JTabbedPane tab){ 183 | // JLabel aa =new JLabel("ddd"); 184 | // JPanel tab_index = new JPanel(); 185 | // tab_index.setLayout(new GridLayout(1,1,5,5)); 186 | // tab_index.add(aa); 187 | // tab.addTab("扫描目标",tab_index); 188 | // return tab; 189 | // } 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/burp/PocEntry.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.net.URL; 4 | 5 | public class PocEntry 6 | { 7 | final int id; 8 | String name ; 9 | 10 | String url ; 11 | String regex ; 12 | String scope; 13 | String match_method; 14 | String match_value; 15 | int status_code; 16 | 17 | PocEntry(int id, String name, String url, String scope,String match_method, String match_value,int status_code) 18 | { 19 | this.id = id; 20 | this.name = name; 21 | this.url = url; 22 | this.scope = scope; 23 | this.match_method = match_method; 24 | this.match_value = match_value; 25 | this.status_code = status_code; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/burp/PocTableModel.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import javax.swing.table.AbstractTableModel; 4 | 5 | public class PocTableModel extends AbstractTableModel { 6 | private final String[] columnNames = {"序号", "漏洞名称", "URL", "匹配位置","匹配方式","匹配值","匹配状态码"}; 7 | 8 | @Override 9 | public int getRowCount() 10 | { 11 | return BurpExtender.all_poc_data.size(); 12 | 13 | } 14 | 15 | @Override 16 | public int getColumnCount() 17 | { 18 | return columnNames.length; 19 | } 20 | 21 | @Override 22 | public Object getValueAt(int rowIndex, int columnIndex) { 23 | if (rowIndex < 0 || rowIndex >= BurpExtender.all_poc_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 24 | return ""; 25 | } 26 | PocEntry pocEntry = BurpExtender.all_poc_data.get(rowIndex); 27 | switch (columnIndex) 28 | { 29 | case 0: 30 | return pocEntry.id; 31 | case 1: 32 | return pocEntry.name; 33 | case 2: 34 | return pocEntry.url; 35 | case 3: 36 | return pocEntry.scope; 37 | case 4: 38 | return pocEntry.match_method; 39 | case 5: 40 | return pocEntry.match_value; 41 | case 6: 42 | return pocEntry.status_code; 43 | default: 44 | return ""; 45 | } 46 | } 47 | 48 | public Object getValueRow(int rowIndex) { 49 | if (rowIndex < 0 || rowIndex >= BurpExtender.all_poc_data.size()) { 50 | return ""; 51 | } 52 | PocEntry pocEntry = BurpExtender.all_poc_data.get(rowIndex); 53 | return pocEntry; 54 | } 55 | 56 | @Override 57 | public String getColumnName(int columnIndex) 58 | { 59 | return columnNames[columnIndex]; 60 | } 61 | public Class getColumnClass(int columnIndex) 62 | { 63 | switch (columnIndex) 64 | { 65 | case 0: 66 | return Integer.class; 67 | case 1: 68 | return String.class; 69 | case 2: 70 | return String.class; 71 | case 3: 72 | return String.class; 73 | case 4: 74 | return String.class; 75 | case 5: 76 | return String.class; 77 | case 6: 78 | return Integer.class; 79 | default: 80 | return String.class; 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/burp/finger/FingerEntry.java: -------------------------------------------------------------------------------- 1 | package burp.finger; 2 | 3 | public class FingerEntry 4 | { 5 | public final int id; 6 | public String cms ; 7 | 8 | public String method ; 9 | 10 | public String location ; 11 | public String keyword; 12 | public int isImportant; 13 | public String type; 14 | 15 | public FingerEntry(int id, String cms, String method, String location, String keyword, int isImportant, String type) 16 | { 17 | this.id = id; 18 | this.cms = cms; 19 | this.method = method; 20 | this.location = location; 21 | this.keyword = keyword; 22 | this.isImportant = isImportant; 23 | this.type = type; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/burp/finger/FingerTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.finger; 2 | 3 | import javax.swing.table.AbstractTableModel; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class FingerTableModel extends AbstractTableModel { 8 | private final String[] columnNames = {"序号", "漏洞分类","匹配方式", "匹配位置","匹配值","重要程度","CMS分类"}; 9 | public static final List all_finger_data = new ArrayList<>();//用于展现poc 10 | 11 | @Override 12 | public int getRowCount() 13 | { 14 | return all_finger_data.size(); 15 | 16 | } 17 | 18 | @Override 19 | public int getColumnCount() 20 | { 21 | return columnNames.length; 22 | } 23 | 24 | @Override 25 | public Object getValueAt(int rowIndex, int columnIndex) { 26 | if (rowIndex < 0 || rowIndex >= all_finger_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 27 | return ""; 28 | } 29 | FingerEntry fingerEntry = all_finger_data.get(rowIndex); 30 | switch (columnIndex) 31 | { 32 | 33 | 34 | case 0: 35 | return fingerEntry.id; 36 | case 1: 37 | return fingerEntry.cms; 38 | case 2: 39 | return fingerEntry.method; 40 | case 3: 41 | return fingerEntry.location; 42 | case 4: 43 | return fingerEntry.keyword; 44 | case 5: 45 | return fingerEntry.isImportant; 46 | case 6: 47 | return fingerEntry.type; 48 | default: 49 | return ""; 50 | } 51 | } 52 | 53 | public Object getValueRow(int rowIndex) { 54 | if (rowIndex < 0 || rowIndex >= all_finger_data.size()) { 55 | return ""; 56 | } 57 | return all_finger_data.get(rowIndex); 58 | } 59 | 60 | @Override 61 | public String getColumnName(int columnIndex) 62 | { 63 | return columnNames[columnIndex]; 64 | } 65 | public Class getColumnClass(int columnIndex) 66 | { 67 | switch (columnIndex) 68 | { 69 | case 0: 70 | case 5: 71 | return Integer.class; 72 | case 4: 73 | case 3: 74 | case 2: 75 | case 6: 76 | case 1: 77 | default: 78 | return String.class; 79 | } 80 | } 81 | public List getAllValue(){ 82 | return all_finger_data; 83 | } 84 | 85 | public void ClearData() { 86 | all_finger_data.clear(); 87 | fireTableDataChanged(); 88 | } 89 | 90 | public void addValueAt(FingerEntry value) 91 | { 92 | all_finger_data.add(value); 93 | fireTableDataChanged(); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/burp/log/LogEntry.java: -------------------------------------------------------------------------------- 1 | package burp.log; 2 | import burp.IHttpRequestResponse; 3 | 4 | import java.net.URL; 5 | 6 | public class LogEntry 7 | { 8 | public final int id; 9 | final String tool; 10 | // public final IHttpRequestResponsePersisted requestResponse; 11 | public final IHttpRequestResponse requestResponse; 12 | final URL url; 13 | final String parameter; 14 | final String value; 15 | final String data_md5; 16 | final int times; 17 | final int response_code; 18 | public String finger_scan_result; 19 | public String vuln_scan_result; 20 | 21 | public int vuln_poc_id; 22 | 23 | public LogEntry(int id, String tool, IHttpRequestResponse requestResponse, URL url, String parameter, String value, String data_md5, int times, Integer response_code, String finger_scan_result, String vuln_scan_result,int vuln_poc_id) 24 | { 25 | this.id = id; 26 | this.tool = tool; 27 | this.requestResponse = requestResponse; 28 | this.url = url; 29 | this.parameter = parameter; 30 | this.value = value; 31 | this.data_md5 = data_md5; 32 | this.times = times; 33 | this.response_code = response_code; 34 | this.finger_scan_result = finger_scan_result; 35 | this.vuln_scan_result = vuln_scan_result; 36 | this.vuln_poc_id = vuln_poc_id; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/burp/log/LogTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.log; 2 | 3 | 4 | import burp.poc.PocEntry; 5 | 6 | import javax.swing.table.AbstractTableModel; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class LogTableModel extends AbstractTableModel { 11 | 12 | 13 | private final String[] columnNames = {"序号", "来源", "URL", "返回包长度", "状态码","指纹信息","漏洞扫描结果"}; 14 | public static final List table_log_data = new ArrayList<>();//用于展现结果 15 | 16 | @Override 17 | public int getRowCount() 18 | { 19 | return table_log_data.size(); 20 | 21 | } 22 | 23 | @Override 24 | public int getColumnCount() 25 | { 26 | return columnNames.length; 27 | } 28 | 29 | @Override 30 | public String getColumnName(int columnIndex) 31 | { 32 | return columnNames[columnIndex]; 33 | } 34 | 35 | @Override 36 | public Class getColumnClass(int columnIndex) 37 | { 38 | switch (columnIndex) 39 | { 40 | case 0: 41 | case 4: 42 | return Integer.class; 43 | case 3: 44 | return Integer.class;//返回响应包的长度 45 | case 1: 46 | case 2: 47 | case 5: 48 | case 6: 49 | default: 50 | return String.class; 51 | } 52 | } 53 | 54 | 55 | public void ClearData() { 56 | table_log_data.clear(); 57 | // 通知视图数据发生了变化 58 | fireTableDataChanged(); 59 | } 60 | public void addValueAt(LogEntry value) 61 | { 62 | table_log_data.add(value); 63 | } 64 | @Override 65 | public Object getValueAt(int rowIndex, int columnIndex) 66 | { 67 | if (rowIndex < 0 || rowIndex >= table_log_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 68 | return null; 69 | } 70 | LogEntry logEntry = table_log_data.get(rowIndex); 71 | switch (columnIndex) 72 | { 73 | case 0: 74 | return logEntry.id; 75 | case 1: 76 | return logEntry.tool; 77 | // return BurpExtender.callbacks.getToolName(logEntry.tool); 78 | case 2: 79 | return logEntry.url.toString(); 80 | case 3: 81 | return logEntry.requestResponse.getResponse().length;//返回响应包的长度 82 | case 4: 83 | return logEntry.response_code; 84 | case 5: 85 | return logEntry.finger_scan_result; 86 | case 6: 87 | return logEntry.vuln_scan_result; 88 | default: 89 | return ""; 90 | } 91 | } 92 | public List getAllValue(){ 93 | return table_log_data; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/finger/FingerEntry.java: -------------------------------------------------------------------------------- 1 | package burp.model.finger; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class FingerEntry { 6 | public int id; 7 | public String cms; 8 | public String method; 9 | public String location; 10 | public String keyword; 11 | public int isImportant; 12 | public String type; 13 | 14 | // 无参构造函数 15 | public FingerEntry() {} 16 | 17 | // 有参构造函数 18 | public FingerEntry(int id, String cms, String method, String location, String keyword, int isImportant, String type) { 19 | this.id = id; 20 | this.cms = cms; 21 | this.method = method; 22 | this.location = location; 23 | this.keyword = keyword; 24 | this.isImportant = isImportant; 25 | this.type = type; 26 | } 27 | 28 | // Getter and Setter methods 29 | @JsonProperty("id") 30 | public int getId() { 31 | return id; 32 | } 33 | 34 | public void setId(int id) { 35 | this.id = id; 36 | } 37 | 38 | @JsonProperty("cms") 39 | public String getCms() { 40 | return cms; 41 | } 42 | 43 | public void setCms(String cms) { 44 | this.cms = cms; 45 | } 46 | 47 | @JsonProperty("method") 48 | public String getMethod() { 49 | return method; 50 | } 51 | 52 | public void setMethod(String method) { 53 | this.method = method; 54 | } 55 | 56 | @JsonProperty("location") 57 | public String getLocation() { 58 | return location; 59 | } 60 | 61 | public void setLocation(String location) { 62 | this.location = location; 63 | } 64 | 65 | @JsonProperty("keyword") 66 | public String getKeyword() { 67 | return keyword; 68 | } 69 | 70 | public void setKeyword(String keyword) { 71 | this.keyword = keyword; 72 | } 73 | 74 | @JsonProperty("isImportant") 75 | public int getIsImportant() { 76 | return isImportant; 77 | } 78 | 79 | public void setIsImportant(int isImportant) { 80 | this.isImportant = isImportant; 81 | } 82 | 83 | @JsonProperty("type") 84 | public String getType() { 85 | return type; 86 | } 87 | 88 | public void setType(String type) { 89 | this.type = type; 90 | } 91 | 92 | @Override 93 | public String toString() { 94 | return "FingerEntry{" + 95 | "id=" + id + 96 | ", cms='" + cms + '\'' + 97 | ", method='" + method + '\'' + 98 | ", location='" + location + '\'' + 99 | ", keyword='" + keyword + '\'' + 100 | ", isImportant=" + isImportant + 101 | ", type='" + type + '\'' + 102 | '}'; 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/finger/FingerTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.model.finger; 2 | 3 | import burp.utils.Finger; 4 | 5 | import javax.swing.table.AbstractTableModel; 6 | import java.sql.SQLException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | public class FingerTableModel extends AbstractTableModel { 10 | private final String[] columnNames = {"序号", "漏洞分类","匹配方式", "匹配位置","匹配值","重要程度","CMS分组"}; 11 | public static List all_finger_data = new ArrayList<>();//用于展现poc 12 | 13 | @Override 14 | public int getRowCount() 15 | { 16 | return all_finger_data.size(); 17 | 18 | } 19 | 20 | @Override 21 | public int getColumnCount() 22 | { 23 | return columnNames.length; 24 | } 25 | 26 | @Override 27 | public Object getValueAt(int rowIndex, int columnIndex) { 28 | if (rowIndex < 0 || rowIndex >= all_finger_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 29 | return ""; 30 | } 31 | FingerEntry fingerEntry = all_finger_data.get(rowIndex); 32 | switch (columnIndex) 33 | { 34 | 35 | 36 | case 0: 37 | return fingerEntry.id; 38 | case 1: 39 | return fingerEntry.cms; 40 | case 2: 41 | return fingerEntry.method; 42 | case 3: 43 | return fingerEntry.location; 44 | case 4: 45 | return fingerEntry.keyword; 46 | case 5: 47 | return fingerEntry.isImportant; 48 | case 6: 49 | return fingerEntry.type; 50 | default: 51 | return ""; 52 | } 53 | } 54 | 55 | public Object getValueRow(int rowIndex) { 56 | if (rowIndex < 0 || rowIndex >= all_finger_data.size()) { 57 | return ""; 58 | } 59 | return all_finger_data.get(rowIndex); 60 | } 61 | 62 | @Override 63 | public String getColumnName(int columnIndex) 64 | { 65 | return columnNames[columnIndex]; 66 | } 67 | public Class getColumnClass(int columnIndex) 68 | { 69 | switch (columnIndex) 70 | { 71 | case 0: 72 | case 5: 73 | return Integer.class; 74 | case 4: 75 | case 3: 76 | case 2: 77 | case 6: 78 | case 1: 79 | default: 80 | return String.class; 81 | } 82 | } 83 | public List getAllValue(){ 84 | return all_finger_data; 85 | } 86 | 87 | public void ClearData() { 88 | all_finger_data.clear(); 89 | fireTableDataChanged(); 90 | } 91 | 92 | public void addValueAt(FingerEntry value) 93 | { 94 | all_finger_data.add(value); 95 | } 96 | public static void save_data_to_db() throws SQLException { 97 | System.out.println("8888"); 98 | Finger.Save_Finger_Data_All(all_finger_data); 99 | System.out.println("89999"); 100 | 101 | Finger.reload_read_finger_Data(); 102 | 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/burp/model/group/CheckHeaderCellRenderer.java: -------------------------------------------------------------------------------- 1 | package burp.model.group; 2 | import javax.swing.*; 3 | import javax.swing.table.JTableHeader; 4 | import javax.swing.table.TableCellRenderer; 5 | import java.awt.*; 6 | import java.awt.event.MouseAdapter; 7 | import java.awt.event.MouseEvent; 8 | import java.util.List; 9 | 10 | public class CheckHeaderCellRenderer implements TableCellRenderer { 11 | GroupTableModel tableModel; 12 | JTableHeader tableHeader; 13 | JCheckBox selectBox; 14 | int column_index; 15 | public CheckHeaderCellRenderer(JTable table,int column_index) { 16 | this.column_index = column_index; 17 | this.tableModel = (GroupTableModel) table.getModel(); 18 | this.tableHeader = table.getTableHeader(); 19 | selectBox = new JCheckBox(tableModel.getColumnName(column_index)); // 设置为第四列的标题 20 | List all = tableModel.getAllValue(); 21 | boolean is_select =true; 22 | for (GroupEntry a :all){ 23 | if(column_index==3){ 24 | if(!a.is_finger_poc){ 25 | is_select=false; 26 | break; 27 | } 28 | } else if (column_index==4) { 29 | if(!a.is_finger_jump_poc){ 30 | is_select=false; 31 | break; 32 | } 33 | } 34 | } 35 | // System.out.println(is_select); 36 | selectBox.setSelected(is_select); 37 | tableHeader.addMouseListener(new MouseAdapter() { 38 | public void mouseClicked(MouseEvent e) { 39 | if (e.getClickCount() > 0) { 40 | // 获得选中列 41 | int selectColumn = tableHeader.columnAtPoint(e.getPoint()); 42 | if (selectColumn == column_index) { // 检查是否点击的是第四列 43 | boolean value = !selectBox.isSelected(); 44 | selectBox.setSelected(value); 45 | tableModel.selectAllOrNull(value,column_index); // 假设这个方法存在于 GroupTableModel 中 46 | tableHeader.repaint(); 47 | } 48 | } 49 | } 50 | }); 51 | } 52 | 53 | 54 | public void setSelectBox(boolean value) { 55 | selectBox.setSelected(value); 56 | tableHeader.repaint(); 57 | } 58 | 59 | @Override 60 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 61 | int row, int column) { 62 | String valueStr = (String) value; 63 | JLabel label = new JLabel(valueStr); 64 | label.setHorizontalAlignment(SwingConstants.CENTER); // 表头标签居中 65 | selectBox.setHorizontalAlignment(SwingConstants.CENTER); // 表头标签居中 66 | selectBox.setBorderPainted(true); 67 | JComponent component = (column == column_index) ? selectBox : label; // 检查是否为第四列 68 | component.setForeground(tableHeader.getForeground()); 69 | component.setBackground(tableHeader.getBackground()); 70 | component.setFont(tableHeader.getFont()); 71 | component.setBorder(UIManager.getBorder("TableHeader.cellBorder")); 72 | return component; 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/group/GroupEntry.java: -------------------------------------------------------------------------------- 1 | package burp.model.group; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class GroupEntry { 6 | public int id; 7 | public String name; 8 | public String type; 9 | public boolean is_finger_poc; 10 | public boolean is_finger_jump_poc; 11 | 12 | // 无参构造函数 13 | public GroupEntry() {} 14 | 15 | // 有参构造函数 16 | public GroupEntry(int id, String name, String type, boolean is_finger_poc, boolean is_finger_jump_poc) { 17 | this.id = id; 18 | this.name = name; 19 | this.type = type; 20 | this.is_finger_poc = is_finger_poc; 21 | this.is_finger_jump_poc = is_finger_jump_poc; 22 | } 23 | 24 | // Getter and Setter methods 25 | @JsonProperty("id") 26 | public int getId() { 27 | return id; 28 | } 29 | 30 | public void setId(int id) { 31 | this.id = id; 32 | } 33 | 34 | @JsonProperty("name") 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public void setName(String name) { 40 | this.name = name; 41 | } 42 | 43 | @JsonProperty("type") 44 | public String getType() { 45 | return type; 46 | } 47 | 48 | public void setType(String type) { 49 | this.type = type; 50 | } 51 | 52 | @JsonProperty("is_finger_poc") 53 | public boolean getIsFingerPoc() { 54 | return is_finger_poc; 55 | } 56 | 57 | public void setIsFingerPoc(boolean is_finger_poc) { 58 | this.is_finger_poc = is_finger_poc; 59 | } 60 | 61 | @JsonProperty("is_finger_jump_poc") 62 | public boolean getIsFingerJumpPoc() { 63 | return is_finger_jump_poc; 64 | } 65 | 66 | public void setIsFingerJumpPoc(boolean is_finger_jump_poc) { 67 | this.is_finger_jump_poc = is_finger_jump_poc; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "GroupEntry{" + 73 | "id=" + id + 74 | ", name='" + name + '\'' + 75 | ", type='" + type + '\'' + 76 | ", is_finger_poc=" + is_finger_poc + 77 | ", is_finger_jump_poc=" + is_finger_jump_poc + 78 | '}'; 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/group/GroupTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.model.group; 2 | 3 | import burp.utils.Group; 4 | import burp.utils.Poc; 5 | 6 | import javax.swing.table.AbstractTableModel; 7 | import java.sql.SQLException; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class GroupTableModel extends AbstractTableModel { 12 | private final String[] columnNames = {"序号","分组名称","分组类型","指纹匹配后启用的POC", "直接进行扫描的POC"}; 13 | public static List all_group_data = new ArrayList<>(); 14 | 15 | @Override 16 | public int getRowCount() 17 | { 18 | return all_group_data.size(); 19 | 20 | } 21 | 22 | @Override 23 | public int getColumnCount() 24 | { 25 | return columnNames.length; 26 | } 27 | 28 | @Override 29 | public Object getValueAt(int rowIndex, int columnIndex) { 30 | if (rowIndex < 0 || rowIndex >= all_group_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 31 | return ""; 32 | } 33 | burp.model.group.GroupEntry group = all_group_data.get(rowIndex); 34 | 35 | switch (columnIndex) 36 | { 37 | case 0: 38 | return group.id; 39 | case 1: 40 | return group.name; 41 | case 2: 42 | return group.type; 43 | case 3: 44 | return group.is_finger_poc; 45 | case 4: 46 | return group.is_finger_jump_poc; 47 | default: 48 | return ""; 49 | } 50 | } 51 | 52 | public Object getValueRow(int rowIndex) { 53 | if (rowIndex < 0 || rowIndex >= all_group_data.size()) { 54 | return ""; 55 | } 56 | return all_group_data.get(rowIndex); 57 | } 58 | 59 | @Override 60 | public String getColumnName(int columnIndex) 61 | { 62 | return columnNames[columnIndex]; 63 | } 64 | public Class getColumnClass(int columnIndex) 65 | { 66 | switch (columnIndex) 67 | { 68 | case 0: 69 | return Integer.class; 70 | case 3: 71 | case 4: 72 | return Boolean.class; 73 | case 1: 74 | case 2: 75 | default: 76 | return String.class; 77 | } 78 | } 79 | public List getAllValue(){ 80 | return all_group_data; 81 | } 82 | 83 | 84 | public void ClearData() { 85 | all_group_data.clear(); 86 | fireTableDataChanged(); 87 | } 88 | 89 | public void addValueAt(burp.model.group.GroupEntry value) 90 | { 91 | all_group_data.add(value); 92 | } 93 | 94 | public burp.model.group.GroupEntry getValueByGroupid(int id){ 95 | for(burp.model.group.GroupEntry i :all_group_data){ 96 | if(i.id==id){ 97 | return i; 98 | } 99 | } 100 | return null; 101 | } 102 | public boolean isCellEditable(int rowIndex, int columnIndex) { 103 | return columnIndex == 3 || columnIndex == 4; 104 | } 105 | public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 106 | // 点击事件的处理逻辑 107 | if (aValue instanceof Boolean) { 108 | GroupEntry temp = (GroupEntry) getValueRow(rowIndex); 109 | if(columnIndex==3){ 110 | temp.is_finger_poc = (boolean) aValue; 111 | } else if (columnIndex==4) { 112 | temp.is_finger_jump_poc = (boolean) aValue; 113 | } 114 | for (int i = 0; i < all_group_data.size(); i++) { 115 | GroupEntry group = all_group_data.get(i); 116 | if (group.id == temp.id) { 117 | all_group_data.set(i, temp); 118 | break; 119 | } 120 | } 121 | Group.Save_Group_Data(temp); 122 | Poc.reload_poc(); 123 | } 124 | } 125 | public void selectAllOrNull(boolean value,int colunmn_index) { 126 | for (int i = 0; i < all_group_data.size(); i++) { 127 | GroupEntry group = all_group_data.get(i); 128 | if(colunmn_index==3){ 129 | group.is_finger_poc=value; 130 | } else if (colunmn_index==4) { 131 | group.is_finger_jump_poc=value; 132 | } 133 | all_group_data.set(i, group); 134 | Group.Save_Group_Data(group); 135 | } 136 | Poc.reload_poc(); 137 | } 138 | public static void save_data_to_db() throws SQLException { 139 | for (GroupEntry i : all_group_data){ 140 | Group.Save_Group_Data(i); 141 | } 142 | Group.reload_read_group_Data(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/burp/model/log/LogEntry.java: -------------------------------------------------------------------------------- 1 | package burp.model.log; 2 | import burp.IHttpRequestResponse; 3 | 4 | import java.net.URL; 5 | 6 | public class LogEntry 7 | { 8 | public final int id; 9 | final String tool; 10 | // public final IHttpRequestResponsePersisted requestResponse; 11 | public final IHttpRequestResponse requestResponse; 12 | final URL url; 13 | final String parameter; 14 | final String value; 15 | final String data_md5; 16 | final int times; 17 | final int response_code; 18 | public String finger_scan_result; 19 | public String vuln_scan_result; 20 | public int vuln_poc_id; 21 | public final IHttpRequestResponse poc_requestResponse; 22 | 23 | public LogEntry(int id, String tool, IHttpRequestResponse requestResponse, URL url, String parameter, String value, String data_md5, int times, Integer response_code, String finger_scan_result, String vuln_scan_result,int vuln_poc_id,IHttpRequestResponse poc_requestResponse) 24 | { 25 | this.id = id; 26 | this.tool = tool; 27 | this.requestResponse = requestResponse; 28 | this.url = url; 29 | this.parameter = parameter; 30 | this.value = value; 31 | this.data_md5 = data_md5; 32 | this.times = times; 33 | this.response_code = response_code; 34 | this.finger_scan_result = finger_scan_result; 35 | this.vuln_scan_result = vuln_scan_result; 36 | this.vuln_poc_id = vuln_poc_id; 37 | this.poc_requestResponse = poc_requestResponse; 38 | 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/log/LogTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.model.log; 2 | 3 | 4 | 5 | import javax.swing.table.AbstractTableModel; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class LogTableModel extends AbstractTableModel { 10 | 11 | 12 | private final String[] columnNames = {"序号", "来源", "URL", "返回包长度", "状态码","指纹信息","漏洞扫描结果"}; 13 | public static final List table_log_data = new ArrayList<>();//用于展现结果 14 | 15 | @Override 16 | public int getRowCount() 17 | { 18 | return table_log_data.size(); 19 | 20 | } 21 | 22 | @Override 23 | public int getColumnCount() 24 | { 25 | return columnNames.length; 26 | } 27 | 28 | @Override 29 | public String getColumnName(int columnIndex) 30 | { 31 | return columnNames[columnIndex]; 32 | } 33 | 34 | @Override 35 | public Class getColumnClass(int columnIndex) 36 | { 37 | switch (columnIndex) 38 | { 39 | case 0: 40 | case 4: 41 | return Integer.class; 42 | case 3: 43 | return Integer.class;//返回响应包的长度 44 | case 1: 45 | case 2: 46 | case 5: 47 | case 6: 48 | default: 49 | return String.class; 50 | } 51 | } 52 | 53 | 54 | public void ClearData() { 55 | table_log_data.clear(); 56 | // 通知视图数据发生了变化 57 | fireTableDataChanged(); 58 | } 59 | public void addValueAt(LogEntry value) 60 | { 61 | table_log_data.add(value); 62 | } 63 | @Override 64 | public Object getValueAt(int rowIndex, int columnIndex) 65 | { 66 | if (rowIndex < 0 || rowIndex >= table_log_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 67 | return null; 68 | } 69 | LogEntry logEntry = table_log_data.get(rowIndex); 70 | switch (columnIndex) 71 | { 72 | case 0: 73 | return logEntry.id; 74 | case 1: 75 | return logEntry.tool; 76 | // return BurpExtender.callbacks.getToolName(logEntry.tool); 77 | case 2: 78 | return logEntry.url.toString(); 79 | case 3: 80 | return logEntry.requestResponse.getResponse().length;//返回响应包的长度 81 | case 4: 82 | return logEntry.response_code; 83 | case 5: 84 | return logEntry.finger_scan_result; 85 | case 6: 86 | return logEntry.vuln_scan_result; 87 | default: 88 | return ""; 89 | } 90 | } 91 | public List getAllValue(){ 92 | return table_log_data; 93 | } 94 | public LogEntry getValueByid(int id){ 95 | for(LogEntry i :table_log_data){ 96 | if(i.id==id){ 97 | return i; 98 | } 99 | } 100 | return null; 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/poc/PocEntry.java: -------------------------------------------------------------------------------- 1 | package burp.model.poc; 2 | 3 | public class PocEntry { 4 | public int id; 5 | public String type; 6 | public String name; 7 | public String group; 8 | public int dir_count; 9 | public String plugin_type; 10 | public String plugins_data; 11 | public String description; 12 | 13 | // 无参构造函数 14 | public PocEntry() {} 15 | 16 | // 有参构造函数 17 | public PocEntry(int id, String group, String type, String name, int dir_count, String plugin_type, String plugins_data, String description) { 18 | this.id = id; 19 | this.group = group; 20 | this.type = type; 21 | this.name = name; 22 | this.dir_count = dir_count; 23 | this.plugin_type = plugin_type; 24 | this.plugins_data = plugins_data; 25 | this.description = description; 26 | } 27 | 28 | // Getter and Setter methods 29 | public int getId() { 30 | return id; 31 | } 32 | 33 | public void setId(int id) { 34 | this.id = id; 35 | } 36 | 37 | public String getType() { 38 | return type; 39 | } 40 | 41 | public void setType(String type) { 42 | this.type = type; 43 | } 44 | 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | 53 | public String getGroup() { 54 | return group; 55 | } 56 | 57 | public void setGroup(String group) { 58 | this.group = group; 59 | } 60 | 61 | public int getDirCount() { 62 | return dir_count; 63 | } 64 | 65 | public void setDirCount(int dir_count) { 66 | this.dir_count = dir_count; 67 | } 68 | 69 | public String getPluginType() { 70 | return plugin_type; 71 | } 72 | 73 | public void setPluginType(String plugin_type) { 74 | this.plugin_type = plugin_type; 75 | } 76 | 77 | public String getPluginsData() { 78 | return plugins_data; 79 | } 80 | 81 | public void setPluginsData(String plugins_data) { 82 | this.plugins_data = plugins_data; 83 | } 84 | 85 | public String getDescription() { 86 | return description; 87 | } 88 | 89 | public void setDescription(String description) { 90 | this.description = description; 91 | } 92 | 93 | @Override 94 | public String toString() { 95 | return "PocEntry{" + 96 | "id=" + id + 97 | ", type='" + type + '\'' + 98 | ", name='" + name + '\'' + 99 | ", group='" + group + '\'' + 100 | ", dir_count=" + dir_count + 101 | ", plugin_type='" + plugin_type + '\'' + 102 | ", plugins_data='" + plugins_data + '\'' + 103 | ", description='" + description + '\'' + 104 | '}'; 105 | } 106 | } -------------------------------------------------------------------------------- /src/main/java/burp/model/poc/PocTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.model.poc; 2 | 3 | import burp.utils.Poc; 4 | 5 | import javax.swing.table.AbstractTableModel; 6 | import java.sql.SQLException; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | import static burp.Main_Vuln.printErr; 12 | import static burp.utils.Poc.reload_read_poc_Data; 13 | 14 | public class PocTableModel extends AbstractTableModel { 15 | private final String[] columnNames = {"序号","漏洞分组","漏洞分类","漏洞名称", "目录层级","插件类型"}; 16 | public static List all_poc_data = new ArrayList<>();//用于展现poc 17 | 18 | @Override 19 | public int getRowCount() 20 | { 21 | return all_poc_data.size(); 22 | 23 | } 24 | 25 | @Override 26 | public int getColumnCount() 27 | { 28 | return columnNames.length; 29 | } 30 | 31 | @Override 32 | public Object getValueAt(int rowIndex, int columnIndex) { 33 | if (rowIndex < 0 || rowIndex >= all_poc_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 34 | return ""; 35 | } 36 | burp.model.poc.PocEntry PocEntry = all_poc_data.get(rowIndex); 37 | switch (columnIndex) 38 | { 39 | case 0: 40 | return PocEntry.id; 41 | case 1: 42 | return PocEntry.group; 43 | case 2: 44 | return PocEntry.type; 45 | case 3: 46 | return PocEntry.name; 47 | case 4: 48 | return PocEntry.dir_count; 49 | case 5: 50 | return PocEntry.plugin_type; 51 | default: 52 | return ""; 53 | } 54 | } 55 | 56 | public Object getValueRow(int rowIndex) { 57 | if (rowIndex < 0 || rowIndex >= all_poc_data.size()) { 58 | return ""; 59 | } 60 | return all_poc_data.get(rowIndex); 61 | } 62 | 63 | @Override 64 | public String getColumnName(int columnIndex) 65 | { 66 | return columnNames[columnIndex]; 67 | } 68 | public Class getColumnClass(int columnIndex) 69 | { 70 | switch (columnIndex) 71 | { 72 | case 0: 73 | case 4: 74 | return Integer.class; 75 | case 1: 76 | case 3: 77 | case 2: 78 | case 5: 79 | default: 80 | return String.class; 81 | } 82 | } 83 | public List getAllValue(){ 84 | return all_poc_data; 85 | } 86 | 87 | 88 | public void ClearData() { 89 | all_poc_data.clear(); 90 | fireTableDataChanged(); 91 | } 92 | 93 | public void addValueAt(burp.model.poc.PocEntry value) 94 | { 95 | all_poc_data.add(value); 96 | } 97 | 98 | public burp.model.poc.PocEntry getValueByPocid(int id){ 99 | for(burp.model.poc.PocEntry i :all_poc_data){ 100 | if(i.id==id){ 101 | return i; 102 | } 103 | } 104 | return null; 105 | } 106 | public static void save_data_to_db() throws SQLException { 107 | Poc.Save_Poc_Data_All(all_poc_data); 108 | reload_read_poc_Data(); 109 | Poc.reload_poc(); 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/burp/poc/PocEntry.java: -------------------------------------------------------------------------------- 1 | package burp.poc; 2 | 3 | public class PocEntry 4 | { 5 | public int id; 6 | public String type ; 7 | 8 | public String name ; 9 | 10 | public String group; 11 | public int dir_count; 12 | public String plugin_type; 13 | public String plugins_data; 14 | public String description; 15 | 16 | 17 | public PocEntry(int id, String group,String type ,String name,int dir_count,String plugin_type, String plugins_data,String description) 18 | { 19 | this.id = id; 20 | this.group = group; 21 | this.type = type; 22 | this.name = name; 23 | this.dir_count = dir_count; 24 | this.plugin_type = plugin_type; 25 | this.plugins_data = plugins_data; 26 | this.description = description; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/burp/poc/PocTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.poc; 2 | 3 | import javax.swing.table.AbstractTableModel; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class PocTableModel extends AbstractTableModel { 8 | private final String[] columnNames = {"序号","漏洞分组","漏洞分类","漏洞名称", "目录层级","插件类型"}; 9 | public static final List all_poc_data = new ArrayList<>();//用于展现poc 10 | 11 | @Override 12 | public int getRowCount() 13 | { 14 | return all_poc_data.size(); 15 | 16 | } 17 | 18 | @Override 19 | public int getColumnCount() 20 | { 21 | return columnNames.length; 22 | } 23 | 24 | @Override 25 | public Object getValueAt(int rowIndex, int columnIndex) { 26 | if (rowIndex < 0 || rowIndex >= all_poc_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 27 | return ""; 28 | } 29 | PocEntry pocEntry = all_poc_data.get(rowIndex); 30 | switch (columnIndex) 31 | { 32 | case 0: 33 | return pocEntry.id; 34 | case 1: 35 | return pocEntry.group; 36 | case 2: 37 | return pocEntry.type; 38 | case 3: 39 | return pocEntry.name; 40 | case 4: 41 | return pocEntry.dir_count; 42 | case 5: 43 | return pocEntry.plugin_type; 44 | default: 45 | return ""; 46 | } 47 | } 48 | 49 | public Object getValueRow(int rowIndex) { 50 | if (rowIndex < 0 || rowIndex >= all_poc_data.size()) { 51 | return ""; 52 | } 53 | return all_poc_data.get(rowIndex); 54 | } 55 | 56 | @Override 57 | public String getColumnName(int columnIndex) 58 | { 59 | return columnNames[columnIndex]; 60 | } 61 | public Class getColumnClass(int columnIndex) 62 | { 63 | switch (columnIndex) 64 | { 65 | case 0: 66 | case 4: 67 | return Integer.class; 68 | case 1: 69 | case 3: 70 | case 2: 71 | case 5: 72 | default: 73 | return String.class; 74 | } 75 | } 76 | public List getAllValue(){ 77 | return all_poc_data; 78 | } 79 | 80 | 81 | public void ClearData() { 82 | all_poc_data.clear(); 83 | fireTableDataChanged(); 84 | } 85 | 86 | public void addValueAt(PocEntry value) 87 | { 88 | all_poc_data.add(value); 89 | fireTableDataChanged(); 90 | } 91 | 92 | public PocEntry getValueByPocid(int id){ 93 | for(PocEntry i :all_poc_data){ 94 | if(i.id==id){ 95 | return i; 96 | } 97 | } 98 | return null; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/burp/rpc/Poc_RequestOrBuilder.java: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: scan.proto 3 | 4 | // Protobuf Java Version: 3.25.3 5 | package burp.rpc; 6 | 7 | public interface Poc_RequestOrBuilder extends 8 | // @@protoc_insertion_point(interface_extends:burp.rpc.Poc_Request) 9 | com.google.protobuf.MessageOrBuilder { 10 | 11 | /** 12 | * string poc_type = 1; 13 | * @return The pocType. 14 | */ 15 | java.lang.String getPocType(); 16 | /** 17 | * string poc_type = 1; 18 | * @return The bytes for pocType. 19 | */ 20 | com.google.protobuf.ByteString 21 | getPocTypeBytes(); 22 | 23 | /** 24 | * string url = 2; 25 | * @return The url. 26 | */ 27 | java.lang.String getUrl(); 28 | /** 29 | * string url = 2; 30 | * @return The bytes for url. 31 | */ 32 | com.google.protobuf.ByteString 33 | getUrlBytes(); 34 | 35 | /** 36 | * string poc = 3; 37 | * @return The poc. 38 | */ 39 | java.lang.String getPoc(); 40 | /** 41 | * string poc = 3; 42 | * @return The bytes for poc. 43 | */ 44 | com.google.protobuf.ByteString 45 | getPocBytes(); 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/burp/rpc/Poc_ResponseOrBuilder.java: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: scan.proto 3 | 4 | // Protobuf Java Version: 3.25.3 5 | package burp.rpc; 6 | 7 | public interface Poc_ResponseOrBuilder extends 8 | // @@protoc_insertion_point(interface_extends:burp.rpc.Poc_Response) 9 | com.google.protobuf.MessageOrBuilder { 10 | 11 | /** 12 | * bool is_success = 1; 13 | * @return The isSuccess. 14 | */ 15 | boolean getIsSuccess(); 16 | 17 | /** 18 | * string result = 2; 19 | * @return The result. 20 | */ 21 | java.lang.String getResult(); 22 | /** 23 | * string result = 2; 24 | * @return The bytes for result. 25 | */ 26 | com.google.protobuf.ByteString 27 | getResultBytes(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/burp/rpc/Scan.java: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: scan.proto 3 | 4 | // Protobuf Java Version: 3.25.3 5 | package burp.rpc; 6 | 7 | public final class Scan { 8 | private Scan() {} 9 | public static void registerAllExtensions( 10 | com.google.protobuf.ExtensionRegistryLite registry) { 11 | } 12 | 13 | public static void registerAllExtensions( 14 | com.google.protobuf.ExtensionRegistry registry) { 15 | registerAllExtensions( 16 | (com.google.protobuf.ExtensionRegistryLite) registry); 17 | } 18 | static final com.google.protobuf.Descriptors.Descriptor 19 | internal_static_burp_rpc_Poc_Request_descriptor; 20 | static final 21 | com.google.protobuf.GeneratedMessageV3.FieldAccessorTable 22 | internal_static_burp_rpc_Poc_Request_fieldAccessorTable; 23 | static final com.google.protobuf.Descriptors.Descriptor 24 | internal_static_burp_rpc_Poc_Response_descriptor; 25 | static final 26 | com.google.protobuf.GeneratedMessageV3.FieldAccessorTable 27 | internal_static_burp_rpc_Poc_Response_fieldAccessorTable; 28 | 29 | public static com.google.protobuf.Descriptors.FileDescriptor 30 | getDescriptor() { 31 | return descriptor; 32 | } 33 | private static com.google.protobuf.Descriptors.FileDescriptor 34 | descriptor; 35 | static { 36 | java.lang.String[] descriptorData = { 37 | "\n\nscan.proto\022\010burp.rpc\"9\n\013Poc_Request\022\020\n" + 38 | "\010poc_type\030\001 \001(\t\022\013\n\003url\030\002 \001(\t\022\013\n\003poc\030\003 \001(" + 39 | "\t\"2\n\014Poc_Response\022\022\n\nis_success\030\001 \001(\010\022\016\n" + 40 | "\006result\030\002 \001(\t2?\n\003poc\0228\n\007pocscan\022\025.burp.r" + 41 | "pc.Poc_Request\032\026.burp.rpc.Poc_ResponseB\002" + 42 | "P\001b\006proto3" 43 | }; 44 | descriptor = com.google.protobuf.Descriptors.FileDescriptor 45 | .internalBuildGeneratedFileFrom(descriptorData, 46 | new com.google.protobuf.Descriptors.FileDescriptor[] { 47 | }); 48 | internal_static_burp_rpc_Poc_Request_descriptor = 49 | getDescriptor().getMessageTypes().get(0); 50 | internal_static_burp_rpc_Poc_Request_fieldAccessorTable = new 51 | com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( 52 | internal_static_burp_rpc_Poc_Request_descriptor, 53 | new java.lang.String[] { "PocType", "Url", "Poc", }); 54 | internal_static_burp_rpc_Poc_Response_descriptor = 55 | getDescriptor().getMessageTypes().get(1); 56 | internal_static_burp_rpc_Poc_Response_fieldAccessorTable = new 57 | com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( 58 | internal_static_burp_rpc_Poc_Response_descriptor, 59 | new java.lang.String[] { "IsSuccess", "Result", }); 60 | } 61 | 62 | // @@protoc_insertion_point(outer_class_scope) 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/burp/rpc/pocGrpc.java: -------------------------------------------------------------------------------- 1 | package burp.rpc; 2 | 3 | import static io.grpc.MethodDescriptor.generateFullMethodName; 4 | import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; 5 | import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; 6 | import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; 7 | import static io.grpc.stub.ClientCalls.asyncUnaryCall; 8 | import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; 9 | import static io.grpc.stub.ClientCalls.blockingUnaryCall; 10 | import static io.grpc.stub.ClientCalls.futureUnaryCall; 11 | import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; 12 | import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; 13 | import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; 14 | import static io.grpc.stub.ServerCalls.asyncUnaryCall; 15 | import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; 16 | import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; 17 | 18 | /** 19 | *
 20 |  * `service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口
 21 |  * 
22 | */ 23 | @javax.annotation.Generated( 24 | value = "by gRPC proto compiler (version 1.32.1)", 25 | comments = "Source: scan.proto") 26 | public final class pocGrpc { 27 | 28 | private pocGrpc() {} 29 | 30 | public static final String SERVICE_NAME = "burp.rpc.poc"; 31 | 32 | // Static method descriptors that strictly reflect the proto. 33 | private static volatile io.grpc.MethodDescriptor getPocscanMethod; 35 | 36 | @io.grpc.stub.annotations.RpcMethod( 37 | fullMethodName = SERVICE_NAME + '/' + "pocscan", 38 | requestType = burp.rpc.Poc_Request.class, 39 | responseType = burp.rpc.Poc_Response.class, 40 | methodType = io.grpc.MethodDescriptor.MethodType.UNARY) 41 | public static io.grpc.MethodDescriptor getPocscanMethod() { 43 | io.grpc.MethodDescriptor getPocscanMethod; 44 | if ((getPocscanMethod = pocGrpc.getPocscanMethod) == null) { 45 | synchronized (pocGrpc.class) { 46 | if ((getPocscanMethod = pocGrpc.getPocscanMethod) == null) { 47 | pocGrpc.getPocscanMethod = getPocscanMethod = 48 | io.grpc.MethodDescriptor.newBuilder() 49 | .setType(io.grpc.MethodDescriptor.MethodType.UNARY) 50 | .setFullMethodName(generateFullMethodName(SERVICE_NAME, "pocscan")) 51 | .setSampledToLocalTracing(true) 52 | .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( 53 | burp.rpc.Poc_Request.getDefaultInstance())) 54 | .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( 55 | burp.rpc.Poc_Response.getDefaultInstance())) 56 | .setSchemaDescriptor(new pocMethodDescriptorSupplier("pocscan")) 57 | .build(); 58 | } 59 | } 60 | } 61 | return getPocscanMethod; 62 | } 63 | 64 | /** 65 | * Creates a new async stub that supports all call types for the service 66 | */ 67 | public static pocStub newStub(io.grpc.Channel channel) { 68 | io.grpc.stub.AbstractStub.StubFactory factory = 69 | new io.grpc.stub.AbstractStub.StubFactory() { 70 | @java.lang.Override 71 | public pocStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 72 | return new pocStub(channel, callOptions); 73 | } 74 | }; 75 | return pocStub.newStub(factory, channel); 76 | } 77 | 78 | /** 79 | * Creates a new blocking-style stub that supports unary and streaming output calls on the service 80 | */ 81 | public static pocBlockingStub newBlockingStub( 82 | io.grpc.Channel channel) { 83 | io.grpc.stub.AbstractStub.StubFactory factory = 84 | new io.grpc.stub.AbstractStub.StubFactory() { 85 | @java.lang.Override 86 | public pocBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 87 | return new pocBlockingStub(channel, callOptions); 88 | } 89 | }; 90 | return pocBlockingStub.newStub(factory, channel); 91 | } 92 | 93 | /** 94 | * Creates a new ListenableFuture-style stub that supports unary calls on the service 95 | */ 96 | public static pocFutureStub newFutureStub( 97 | io.grpc.Channel channel) { 98 | io.grpc.stub.AbstractStub.StubFactory factory = 99 | new io.grpc.stub.AbstractStub.StubFactory() { 100 | @java.lang.Override 101 | public pocFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 102 | return new pocFutureStub(channel, callOptions); 103 | } 104 | }; 105 | return pocFutureStub.newStub(factory, channel); 106 | } 107 | 108 | /** 109 | *
110 |    * `service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口
111 |    * 
112 | */ 113 | public static abstract class pocImplBase implements io.grpc.BindableService { 114 | 115 | /** 116 | *
117 |      * 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应)
118 |      * 
119 | */ 120 | public void pocscan(burp.rpc.Poc_Request request, 121 | io.grpc.stub.StreamObserver responseObserver) { 122 | asyncUnimplementedUnaryCall(getPocscanMethod(), responseObserver); 123 | } 124 | 125 | @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { 126 | return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) 127 | .addMethod( 128 | getPocscanMethod(), 129 | asyncUnaryCall( 130 | new MethodHandlers< 131 | burp.rpc.Poc_Request, 132 | burp.rpc.Poc_Response>( 133 | this, METHODID_POCSCAN))) 134 | .build(); 135 | } 136 | } 137 | 138 | /** 139 | *
140 |    * `service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口
141 |    * 
142 | */ 143 | public static final class pocStub extends io.grpc.stub.AbstractAsyncStub { 144 | private pocStub( 145 | io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 146 | super(channel, callOptions); 147 | } 148 | 149 | @java.lang.Override 150 | protected pocStub build( 151 | io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 152 | return new pocStub(channel, callOptions); 153 | } 154 | 155 | /** 156 | *
157 |      * 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应)
158 |      * 
159 | */ 160 | public void pocscan(burp.rpc.Poc_Request request, 161 | io.grpc.stub.StreamObserver responseObserver) { 162 | asyncUnaryCall( 163 | getChannel().newCall(getPocscanMethod(), getCallOptions()), request, responseObserver); 164 | } 165 | } 166 | 167 | /** 168 | *
169 |    * `service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口
170 |    * 
171 | */ 172 | public static final class pocBlockingStub extends io.grpc.stub.AbstractBlockingStub { 173 | private pocBlockingStub( 174 | io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 175 | super(channel, callOptions); 176 | } 177 | 178 | @java.lang.Override 179 | protected pocBlockingStub build( 180 | io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 181 | return new pocBlockingStub(channel, callOptions); 182 | } 183 | 184 | /** 185 | *
186 |      * 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应)
187 |      * 
188 | */ 189 | public burp.rpc.Poc_Response pocscan(burp.rpc.Poc_Request request) { 190 | return blockingUnaryCall( 191 | getChannel(), getPocscanMethod(), getCallOptions(), request); 192 | } 193 | } 194 | 195 | /** 196 | *
197 |    * `service` 是用来给gRPC服务定义方法的, 格式固定, 类似于Golang中定义一个接口
198 |    * 
199 | */ 200 | public static final class pocFutureStub extends io.grpc.stub.AbstractFutureStub { 201 | private pocFutureStub( 202 | io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 203 | super(channel, callOptions); 204 | } 205 | 206 | @java.lang.Override 207 | protected pocFutureStub build( 208 | io.grpc.Channel channel, io.grpc.CallOptions callOptions) { 209 | return new pocFutureStub(channel, callOptions); 210 | } 211 | 212 | /** 213 | *
214 |      * 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应)
215 |      * 
216 | */ 217 | public com.google.common.util.concurrent.ListenableFuture pocscan( 218 | burp.rpc.Poc_Request request) { 219 | return futureUnaryCall( 220 | getChannel().newCall(getPocscanMethod(), getCallOptions()), request); 221 | } 222 | } 223 | 224 | private static final int METHODID_POCSCAN = 0; 225 | 226 | private static final class MethodHandlers implements 227 | io.grpc.stub.ServerCalls.UnaryMethod, 228 | io.grpc.stub.ServerCalls.ServerStreamingMethod, 229 | io.grpc.stub.ServerCalls.ClientStreamingMethod, 230 | io.grpc.stub.ServerCalls.BidiStreamingMethod { 231 | private final pocImplBase serviceImpl; 232 | private final int methodId; 233 | 234 | MethodHandlers(pocImplBase serviceImpl, int methodId) { 235 | this.serviceImpl = serviceImpl; 236 | this.methodId = methodId; 237 | } 238 | 239 | @java.lang.Override 240 | @java.lang.SuppressWarnings("unchecked") 241 | public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { 242 | switch (methodId) { 243 | case METHODID_POCSCAN: 244 | serviceImpl.pocscan((burp.rpc.Poc_Request) request, 245 | (io.grpc.stub.StreamObserver) responseObserver); 246 | break; 247 | default: 248 | throw new AssertionError(); 249 | } 250 | } 251 | 252 | @java.lang.Override 253 | @java.lang.SuppressWarnings("unchecked") 254 | public io.grpc.stub.StreamObserver invoke( 255 | io.grpc.stub.StreamObserver responseObserver) { 256 | switch (methodId) { 257 | default: 258 | throw new AssertionError(); 259 | } 260 | } 261 | } 262 | 263 | private static abstract class pocBaseDescriptorSupplier 264 | implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { 265 | pocBaseDescriptorSupplier() {} 266 | 267 | @java.lang.Override 268 | public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { 269 | return burp.rpc.Scan.getDescriptor(); 270 | } 271 | 272 | @java.lang.Override 273 | public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { 274 | return getFileDescriptor().findServiceByName("poc"); 275 | } 276 | } 277 | 278 | private static final class pocFileDescriptorSupplier 279 | extends pocBaseDescriptorSupplier { 280 | pocFileDescriptorSupplier() {} 281 | } 282 | 283 | private static final class pocMethodDescriptorSupplier 284 | extends pocBaseDescriptorSupplier 285 | implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { 286 | private final String methodName; 287 | 288 | pocMethodDescriptorSupplier(String methodName) { 289 | this.methodName = methodName; 290 | } 291 | 292 | @java.lang.Override 293 | public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { 294 | return getServiceDescriptor().findMethodByName(methodName); 295 | } 296 | } 297 | 298 | private static volatile io.grpc.ServiceDescriptor serviceDescriptor; 299 | 300 | public static io.grpc.ServiceDescriptor getServiceDescriptor() { 301 | io.grpc.ServiceDescriptor result = serviceDescriptor; 302 | if (result == null) { 303 | synchronized (pocGrpc.class) { 304 | result = serviceDescriptor; 305 | if (result == null) { 306 | serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) 307 | .setSchemaDescriptor(new pocFileDescriptorSupplier()) 308 | .addMethod(getPocscanMethod()) 309 | .build(); 310 | } 311 | } 312 | } 313 | return result; 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/main/java/burp/scan/FingerScan.java: -------------------------------------------------------------------------------- 1 | package burp.scan; 2 | 3 | import burp.IHttpRequestResponse; 4 | import burp.IHttpService; 5 | import burp.model.finger.FingerEntry; 6 | import burp.model.log.LogEntry; 7 | 8 | import java.io.IOException; 9 | import java.net.URL; 10 | import java.security.KeyManagementException; 11 | import java.security.NoSuchAlgorithmException; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Objects; 15 | 16 | import static burp.BurpExtender.callbacks; 17 | import static burp.BurpExtender.helpers; 18 | import static burp.Main_Vuln.*; 19 | import static burp.Main_Vuln.count; 20 | import static burp.utils.Conn.*; 21 | import static burp.utils.Finger.*; 22 | 23 | public class FingerScan { 24 | public static LogEntry Check_Finger(int toolFlag, IHttpRequestResponse messageInfo) throws IOException, NoSuchAlgorithmException, KeyManagementException { 25 | List all_finger = model_finger.getAllValue(); 26 | if(stop_finger_scan || all_finger.isEmpty()){ 27 | return null; 28 | } 29 | IHttpService httpService = messageInfo.getHttpService(); 30 | IHttpRequestResponse soucrce_messageInfo = messageInfo; 31 | // 获取主机名 32 | String host_url = get_requests_url(messageInfo,false); 33 | 34 | String host = httpService.getHost(); 35 | printDebug("Start Finger Scan Host:"+host_url); 36 | if(finger_ico_hash_map.isEmpty() || finger_ico_hash_map.get(host)==null || Objects.equals(finger_ico_hash_map.get(host), "")){ 37 | printDebug("【GET ICO】"+host_url); 38 | String iconhash= get_host_ico(host_url,messageInfo); 39 | if(!iconhash.isEmpty()){ 40 | printDebug("【GET ICO】"+host_url+"【Hash】"+iconhash); 41 | finger_ico_hash_map.put(host,iconhash); 42 | }else{ 43 | printDebug("【GET ICO】"+host_url+"【Ico Hash】null, all faviconhash plugins is close!"); 44 | } 45 | } 46 | printDebug("【Finger num】"+all_finger.size()); 47 | List all_finger_result=new ArrayList<>(); 48 | for(FingerEntry item :all_finger){ 49 | count++; 50 | String mathc_result=""; 51 | if(Objects.equals(item.method, "keyword")){ 52 | mathc_result = Match_keyword_finger(messageInfo,item); 53 | 54 | } else if (Objects.equals(item.method, "faviconhash")) { 55 | mathc_result = Match_faviconhash_finger(messageInfo,item,host); 56 | } 57 | if (mathc_result!=null && !mathc_result.isEmpty()){ 58 | all_finger_result.add(mathc_result); 59 | } 60 | } 61 | String tool_name="Others"; 62 | URL reuslt_url; 63 | String[] head_list = get_requests_head_line(messageInfo); 64 | if(is_burp){ 65 | tool_name = callbacks.getToolName(toolFlag); 66 | reuslt_url = helpers.analyzeRequest(messageInfo).getUrl(); 67 | }else{ 68 | String req_url; 69 | if (head_list != null) { 70 | req_url = get_requests_url(messageInfo,false)+head_list[1]; 71 | }else{ 72 | req_url = get_requests_url(messageInfo,false); 73 | } 74 | reuslt_url = new URL(req_url); 75 | } 76 | 77 | String enable_poc_str = String.join("$$$", all_finger_result); 78 | printDebug("【Match End】"+reuslt_url+"【Enable_poc_str】"+enable_poc_str); 79 | if (!enable_poc_str.isEmpty()){ 80 | return new LogEntry(count, tool_name, soucrce_messageInfo, reuslt_url, "", "", "", 0, GetMessageStatusCode(messageInfo), enable_poc_str, "",-1,messageInfo); 81 | // return new LogEntry(count, tool_name, callbacks.saveBuffersToTempFiles(messageInfo), helpers.analyzeRequest(messageInfo).getUrl(), "", "", "", 0, (int) (helpers.analyzeResponse(messageInfo.getResponse()).getStatusCode()), enable_poc_str, ""); 82 | }else{ 83 | return null; 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/burp/scan/Scan.java: -------------------------------------------------------------------------------- 1 | package burp.scan; 2 | import burp.IHttpRequestResponse; 3 | import burp.model.log.LogEntry; 4 | import java.util.Arrays; 5 | 6 | import static burp.BurpExtender.callbacks; 7 | import static burp.Main_Vuln.*; 8 | import static burp.scan.PocScan.Check_Vuln; 9 | public class Scan { 10 | public static void accept_Http_Info(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo){ 11 | if (!messageIsRequest) { 12 | if((toolFlag == callbacks.TOOL_PROXY && clicks_Proxy)|| (toolFlag == callbacks.TOOL_REPEATER && clicks_Repeater)){ 13 | //指纹扫描 14 | if(switchs_finger){ 15 | finger_scan(toolFlag,messageInfo,true); 16 | } 17 | if(switchs_poc) { 18 | poc_scan(toolFlag,messageInfo); 19 | } 20 | 21 | } 22 | } 23 | } 24 | public static void poc_scan(int toolFlag, IHttpRequestResponse messageInfo){ 25 | Thread thread = new Thread(() -> { 26 | try { 27 | Check_Vuln(toolFlag,messageInfo,null); 28 | } catch (Exception ex) { 29 | printErr(ex.getMessage()); 30 | printErr(Arrays.toString(ex.getStackTrace())); 31 | } 32 | }); 33 | thread.start(); 34 | } 35 | 36 | public static void finger_scan(int toolFlag, IHttpRequestResponse messageInfo,Boolean enable_poc){ 37 | Thread thread = new Thread(() -> { 38 | try { 39 | LogEntry finger_info = FingerScan.Check_Finger(toolFlag, messageInfo); 40 | if (finger_info != null && !finger_info.finger_scan_result.isEmpty()) { 41 | if (enable_poc && switchs_poc) { 42 | Check_Vuln(toolFlag, messageInfo, finger_info); 43 | } else { 44 | finger_info.finger_scan_result = finger_info.finger_scan_result.replaceAll("\\$\\$\\$", ","); 45 | model.addValueAt(finger_info); 46 | model.fireTableDataChanged(); 47 | } 48 | } 49 | } catch (Exception ex) { 50 | printErr(ex.getMessage()); 51 | printErr(Arrays.toString(ex.getStackTrace())); 52 | } 53 | }); 54 | thread.start(); 55 | } 56 | 57 | public static void myappscan(){ 58 | Thread thread = new Thread(() -> { 59 | for(String url_str :all_scan_url){ 60 | try { 61 | IHttpRequestResponse messageInfo = createHttpRequestResponse(url_str); 62 | if(messageInfo!=null && messageInfo.getResponse().length>0&& switchs_finger){ 63 | finger_scan(1024,messageInfo,true); 64 | } 65 | if(messageInfo!=null && messageInfo.getResponse().length>0 && switchs_poc) { 66 | poc_scan(1024,messageInfo); 67 | } 68 | } catch (Exception ex) { 69 | printErr(ex.getMessage()); 70 | printErr(Arrays.toString(ex.getStackTrace())); 71 | } 72 | } 73 | }); 74 | thread.start(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/burp/testgrpc.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import burp.rpc.pocGrpc; 4 | import burp.rpc.pocGrpc; 5 | import io.grpc.ManagedChannel; 6 | import io.grpc.ManagedChannelBuilder; 7 | import burp.rpc.pocGrpc.pocBlockingStub; 8 | import burp.rpc.Poc_Request; 9 | import burp.rpc.Poc_Response; 10 | 11 | public class testgrpc { 12 | public static void main(String[] args) { 13 | ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext().build(); 14 | pocGrpc.pocBlockingStub client = pocGrpc.newBlockingStub(channel); 15 | 16 | Poc_Request requests = Poc_Request.newBuilder() 17 | .setPocType("example") 18 | .setUrl("http://example.com") 19 | .setPoc("...") 20 | .build(); 21 | 22 | Poc_Response response = client.pocscan(requests); 23 | System.out.println("扫描结果: " + response.getResult()); 24 | System.out.println("是否成功: " + response.getIsSuccess()); 25 | 26 | channel.shutdown(); 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/burp/utils/Config.java: -------------------------------------------------------------------------------- 1 | package burp.utils; 2 | 3 | import static burp.Main_Vuln.*; 4 | import org.yaml.snakeyaml.Yaml; 5 | 6 | import javax.swing.*; 7 | import java.io.*; 8 | import java.nio.charset.StandardCharsets; 9 | import java.nio.file.Files; 10 | import java.nio.file.Paths; 11 | import java.util.Arrays; 12 | import java.util.Map; 13 | import java.util.Objects; 14 | 15 | public class Config { 16 | public static Map read_config(String Config_PATH) throws IOException { 17 | BufferedReader in = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(Config_PATH)), StandardCharsets.UTF_8)); 18 | String str; 19 | StringBuilder str_data= new StringBuilder(); 20 | while ((str = in.readLine()) != null) { 21 | str_data.append(str).append("\n"); 22 | } 23 | Yaml yaml = new Yaml(); 24 | return yaml.load(str_data.toString()); 25 | } 26 | public static void save_config() { 27 | if(Objects.equals(btn3_white.getText(), "当前白名单状态:启用")){ 28 | Global_Config.put("WhiteEnable", true) ; 29 | }else{ 30 | Global_Config.put("WhiteEnable",false) ; 31 | } 32 | Global_Config.put("Enable_Poc",chkbox_poc.isSelected()) ; 33 | Global_Config.put("Enable_Finger",chkbox_finger.isSelected()) ; 34 | Global_Config.put("Is_Proxy", chkbox_proxy.isSelected()) ; 35 | Global_Config.put("Is_Repeater", chkbox_repeater.isSelected()) ; 36 | Global_Config.put("Is_Debug",chkbox_is_debug.isSelected()) ; 37 | Global_Config.put("WhiteList", textField_white.getText()) ; 38 | Global_Config.put("BlackList", textField_black.getText()) ; 39 | // Global_Config.put("EnablePocList", vuln_poc_combox.getSelectedItem()) ; 40 | // Global_Config.put("DisenableFingerPocList", vuln_disenable_finger_poc_combox.getSelectedItem()) ; 41 | 42 | Poc.reload_poc(); 43 | Yaml yaml = new Yaml(options); 44 | String yamlString = yaml.dump(Global_Config); 45 | try (Writer out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(Paths.get(Config_PATH)), StandardCharsets.UTF_8))) { 46 | out.write(yamlString); 47 | } catch (IOException e) { 48 | printErr(Arrays.toString(e.getStackTrace())); 49 | } 50 | JOptionPane.showMessageDialog(null, "配置保存成功!", "提示", JOptionPane.INFORMATION_MESSAGE); 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/burp/utils/Conn.java: -------------------------------------------------------------------------------- 1 | package burp.utils; 2 | 3 | import burp.IHttpRequestResponse; 4 | import burp.IHttpService; 5 | import burp.rpc.Poc_Request; 6 | import burp.rpc.Poc_Response; 7 | import io.grpc.StatusRuntimeException; 8 | 9 | import java.net.URL; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.*; 12 | 13 | import static burp.BurpExtender.helpers; 14 | import static burp.Main_Vuln.*; 15 | 16 | public class Conn { 17 | private static final List userAgents = new ArrayList<>(); 18 | static { 19 | // 初始化User-Agent列表 20 | userAgents.add("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"); 21 | userAgents.add("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"); 22 | userAgents.add("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"); 23 | userAgents.add("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"); 24 | userAgents.add("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0"); 25 | userAgents.add("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0"); 26 | userAgents.add("Mozilla/5.0 (iPhone; CPU iPhone OS 14_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Mobile/15E148 Safari/604.1"); 27 | userAgents.add("Mozilla/5.0 (iPad; CPU OS 14_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Mobile/15E148 Safari/604.1"); 28 | } 29 | public static String Get_Random_UserAgent() { 30 | Random random = new Random(); 31 | int index = random.nextInt(userAgents.size()); 32 | return userAgents.get(index); 33 | } 34 | public static Boolean is_white_black(URL url) 35 | { 36 | 37 | String paths = url.getProtocol()+"://"+url.getAuthority(); 38 | String black_text = (String) Global_Config.get("BlackList"); 39 | //判断黑名单 40 | if(!black_text.isEmpty()){ 41 | String[] blackList = black_text.split(","); 42 | for (String wl : blackList) { 43 | if (paths.contains(wl)) { // 如果在黑名单里面 44 | printDebug("【匹配到黑名单】path:" + paths + " 域名:" + wl ); 45 | return false; 46 | } 47 | } 48 | } 49 | 50 | //是否继续往下执行 51 | boolean b = false; 52 | Boolean is_enable_white = (Boolean) Global_Config.get("WhiteEnable"); 53 | if(is_enable_white) { // 判断是否启用白名单 54 | String white_text = (String) Global_Config.get("WhiteList"); 55 | String[] whiteList = white_text.split(","); 56 | for(String wl:whiteList) { 57 | if(paths.contains(wl)) { // 如果在白名单里面 58 | b = true; 59 | break; 60 | } 61 | } 62 | if(!b) { // 如果不是白名单 那么退出 63 | printDebug("【不在白名单内】path:"+paths); 64 | } 65 | 66 | }else{ 67 | b= true; 68 | } 69 | return b; 70 | } 71 | //得到请求方法 路径 HTTP版本 72 | public static String[] get_requests_head_line(IHttpRequestResponse messageInfo) { 73 | String[] return_result = new String[3]; 74 | String headersPart = new String(messageInfo.getRequest(), StandardCharsets.UTF_8); 75 | List httpHeaders = new ArrayList<>(Arrays.asList(headersPart.split("\r\n"))); 76 | if(httpHeaders.isEmpty()){ 77 | return null; 78 | } 79 | String headUrl = httpHeaders.get(0); 80 | String[] head_list = headUrl.split(" "); 81 | if(head_list.length>=3){ 82 | return head_list; 83 | } else if (head_list.length==2) { 84 | return_result[0] = head_list[0]; 85 | return_result[1] = head_list[1]; 86 | return_result[2] ="HTTP/1.1"; 87 | } else if (head_list.length==1) { 88 | return_result[0] = head_list[0]; 89 | return_result[1] = "/"; 90 | return_result[2] ="HTTP/1.1"; 91 | }else{ 92 | return_result[0] = "GET"; 93 | return_result[1] = "/"; 94 | return_result[2] ="HTTP/1.1"; 95 | } 96 | return return_result; 97 | } 98 | public static Map get_requests_response_head_body(byte[] req_resp_byte) { 99 | Map return_sult = new HashMap<>(); 100 | String headersPart = new String(req_resp_byte, StandardCharsets.UTF_8); 101 | String[] http_body_head = headersPart.split("\n\n|\r\n\r\n"); 102 | List header_list = Arrays.asList(http_body_head[0].split("\r\n|\n|\r")); 103 | return_sult.put("header",header_list); 104 | if(http_body_head.length>=2){ 105 | return_sult.put("body",http_body_head[1]); 106 | }else{ 107 | return_sult.put("body",""); 108 | } 109 | return return_sult; 110 | } 111 | 112 | public static int GetMessageStatusCode(IHttpRequestResponse requestResponse){ 113 | if(is_burp){ 114 | return helpers.analyzeResponse(requestResponse.getResponse()).getStatusCode(); 115 | }else{ 116 | 117 | String response = new String(requestResponse.getResponse()); 118 | String[] response_ =response.split("\\n"); 119 | String head_line_str= response_[0]; 120 | if(head_line_str.startsWith("HTTP/")){ 121 | String[] head_line_list = head_line_str.split(" "); 122 | if(head_line_list.length>=2){ 123 | return Integer.parseInt(head_line_list[1]); 124 | }else{ 125 | return -1; 126 | } 127 | }else{ 128 | return -1; 129 | } 130 | } 131 | } 132 | public static String get_requests_url(IHttpRequestResponse messageInfo,boolean is_path){ 133 | IHttpService iHttpService = messageInfo.getHttpService(); 134 | String host_url; 135 | if(iHttpService.getPort()!=-1){ 136 | host_url = iHttpService.getProtocol()+"://"+iHttpService.getHost()+":"+iHttpService.getPort(); 137 | }else{ 138 | host_url = iHttpService.getProtocol()+"://"+iHttpService.getHost(); 139 | } 140 | if(is_path){ 141 | String[] temp = get_requests_head_line(messageInfo); 142 | if (temp != null) { 143 | host_url =host_url +temp[1]; 144 | } 145 | } 146 | return host_url; 147 | } 148 | 149 | public static Poc_Response Grpc_Send(Poc_Request requests){ 150 | // Poc_Response response = client.pocscan(requests); 151 | try { 152 | return client.pocscan(requests); 153 | } catch (StatusRuntimeException e) { 154 | printErr("RPC failed: "+e.getStatus()); 155 | return null; 156 | } 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/burp/utils/CustHttpService.java: -------------------------------------------------------------------------------- 1 | package burp.utils; 2 | 3 | import burp.IHttpRequestResponse; 4 | import burp.IHttpService; 5 | 6 | import javax.net.ssl.HttpsURLConnection; 7 | import javax.net.ssl.SSLContext; 8 | import javax.net.ssl.TrustManager; 9 | import javax.net.ssl.X509TrustManager; 10 | import java.io.*; 11 | import java.net.HttpURLConnection; 12 | import java.net.URL; 13 | import java.nio.charset.StandardCharsets; 14 | import java.security.KeyManagementException; 15 | import java.security.NoSuchAlgorithmException; 16 | import java.security.cert.X509Certificate; 17 | import java.util.ArrayList; 18 | import java.util.Arrays; 19 | import java.util.List; 20 | import java.util.Objects; 21 | 22 | import static burp.Main_Vuln.printErr; 23 | 24 | public class CustHttpService { 25 | public static IHttpRequestResponse GetHttpRequestResponse(String url_str,List req_headers, String req_body) { 26 | try { 27 | List all_headers = new ArrayList<>(); 28 | if(req_body==null){ 29 | req_body=""; 30 | } 31 | String requests_raw; 32 | String req_method="GET"; 33 | String head_str = req_headers.get(0); 34 | String[] heads_list=new String[3]; 35 | if(head_str.contains("HTTP")){ 36 | String[] temp_head_list = head_str.split(" "); 37 | if(temp_head_list.length>=3){ 38 | heads_list[0] = temp_head_list[0]; 39 | heads_list[1] = temp_head_list[1]; 40 | heads_list[2] = temp_head_list[2]; 41 | }else if(temp_head_list.length==2){ 42 | heads_list[0] = temp_head_list[0]; 43 | heads_list[1] = temp_head_list[1]; 44 | heads_list[2] = "HTTP/1.1"; 45 | } else if (temp_head_list.length==1) { 46 | heads_list[1] ="/"; 47 | heads_list[2]="HTTP/1.1"; 48 | } 49 | try{ 50 | all_headers = req_headers.subList(1, req_headers.size()); 51 | }catch (Exception ex){ 52 | printErr(ex.getMessage()); 53 | printErr(Arrays.toString(ex.getStackTrace())); 54 | } 55 | req_method=heads_list[0]; 56 | }else{ 57 | heads_list[0] ="GET"; 58 | heads_list[1] ="/"; 59 | heads_list[2]="HTTP/1.1"; 60 | } 61 | if(all_headers.isEmpty()){ 62 | requests_raw = req_method+" "+heads_list[1]+" "+heads_list[2]+"\r\n\r\n"+req_body; 63 | }else{ 64 | requests_raw = req_method+" "+heads_list[1]+" "+heads_list[2]+"\r\n"+String.join("\r\n", all_headers)+"\r\n\r\n"+req_body; 65 | } 66 | 67 | // 初始化一个信任所有证书的 SSLContext 68 | // SSLContext sslContext = createUnsafeSSLContext(); 69 | // HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 70 | // 创建 URL 对象 71 | URL url = new URL(url_str); 72 | 73 | // 打开连接 74 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 75 | 76 | // 设置请求方法为 POST 77 | connection.setRequestMethod(req_method); 78 | // 设置允许输出 79 | connection.setDoOutput(true); 80 | // 设置请求头 81 | for (String single_heade :all_headers ){ 82 | String[] temp_header = single_heade.split(":"); 83 | if(temp_header.length==2){ 84 | connection.setRequestProperty(temp_header[0],temp_header[1]); 85 | } else if (temp_header.length==1) { 86 | connection.setRequestProperty(temp_header[0],""); 87 | } 88 | } 89 | // String requests_raw = req_method+" "+url.getPath()+" HTTP/1.1\r\n"+String.join("\r\n", req_headers);; 90 | // 写入请求体 91 | try (OutputStream out = connection.getOutputStream()) { 92 | out.write(req_body.getBytes(StandardCharsets.UTF_8)); 93 | } 94 | // 获取响应状态码 95 | // int responseCode = connection.getResponseCode(); 96 | // 读取响应 97 | List response_header = new ArrayList<>(); 98 | for (String key : connection.getHeaderFields().keySet()) { 99 | // if(!Objects.equals(key, "Accept-Ranges")) { 100 | if (key == null) { 101 | if(connection.getHeaderField(null).startsWith("HTTP/")){ 102 | response_header.add(0, connection.getHeaderField(null)); 103 | }else{ 104 | response_header.add(connection.getHeaderField(null)); 105 | } 106 | } else { 107 | response_header.add(key + ": " + connection.getHeaderField(key)); 108 | } 109 | // } 110 | } 111 | String response_header_str = String.join("\r\n",response_header); 112 | StringBuilder response_body = new StringBuilder(); 113 | try (InputStream in = connection.getInputStream(); 114 | BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { 115 | String bodyLine; 116 | while ((bodyLine = reader.readLine()) != null) { 117 | response_body.append(bodyLine); 118 | } 119 | }catch (Exception e) 120 | { 121 | if(connection.getResponseCode()==HttpURLConnection.HTTP_NOT_FOUND){ 122 | 123 | }else{ 124 | printErr(e.getMessage()); 125 | printErr(Arrays.toString(e.getStackTrace())); 126 | } 127 | 128 | } 129 | // 关闭连接 130 | connection.disconnect(); 131 | return new IHttpRequestResponse() { 132 | @Override 133 | public byte[] getRequest() { 134 | return requests_raw.getBytes(); 135 | } 136 | 137 | @Override 138 | public void setRequest(byte[] bytes) { 139 | 140 | } 141 | 142 | @Override 143 | public byte[] getResponse() { 144 | return (response_header_str+"\r\n\r\n"+response_body).getBytes(); 145 | } 146 | 147 | @Override 148 | public void setResponse(byte[] bytes) { 149 | 150 | } 151 | 152 | @Override 153 | public String getComment() { 154 | return null; 155 | } 156 | 157 | @Override 158 | public void setComment(String s) { 159 | 160 | } 161 | 162 | @Override 163 | public String getHighlight() { 164 | return null; 165 | } 166 | 167 | @Override 168 | public void setHighlight(String s) { 169 | 170 | } 171 | 172 | @Override 173 | public IHttpService getHttpService() { 174 | return new IHttpService() { 175 | @Override 176 | public String getHost() { 177 | return url.getHost(); 178 | } 179 | 180 | @Override 181 | public int getPort() { 182 | // if (port == -1) { 183 | // if(Objects.equals(url.getProtocol(), "https")){ 184 | // port=443; 185 | // }else{ 186 | // port=80; 187 | // } 188 | // } 189 | return url.getPort(); 190 | } 191 | 192 | @Override 193 | public String getProtocol() { 194 | return url.getProtocol(); 195 | } 196 | }; 197 | } 198 | 199 | @Override 200 | public void setHttpService(IHttpService iHttpService) { 201 | 202 | } 203 | }; 204 | } catch (IOException e) { 205 | printErr(Arrays.toString(e.getStackTrace())); 206 | printErr(e.getMessage()); 207 | } 208 | return null; 209 | } 210 | /** 211 | * 创建一个信任所有证书的 SSLContext。 212 | * 213 | * @return SSLContext 214 | * @throws NoSuchAlgorithmException 如果算法不存在 215 | * @throws KeyManagementException 如果密钥管理器初始化失败 216 | */ 217 | private static SSLContext createUnsafeSSLContext() throws NoSuchAlgorithmException, KeyManagementException { 218 | // 创建一个信任所有证书的信任管理器 219 | TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { 220 | @Override 221 | public void checkClientTrusted(X509Certificate[] chain, String authType) { 222 | // 信任所有客户端证书 223 | } 224 | 225 | @Override 226 | public void checkServerTrusted(X509Certificate[] chain, String authType) { 227 | // 信任所有服务器证书 228 | } 229 | 230 | @Override 231 | public X509Certificate[] getAcceptedIssuers() { 232 | return null; 233 | } 234 | }}; 235 | 236 | // 使用信任所有证书的信任管理器初始化 SSLContext 237 | SSLContext sslContext = SSLContext.getInstance("TLS"); 238 | sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); 239 | return sslContext; 240 | } 241 | public static String get_host_ico_http_requests(String urlpath) throws IOException, NoSuchAlgorithmException, KeyManagementException { 242 | 243 | 244 | // 初始化一个信任所有证书的 SSLContext 245 | SSLContext sslContext = createUnsafeSSLContext(); 246 | HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 247 | // 创建URL对象 248 | URL url = new URL(urlpath); 249 | // 打开连接 250 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 251 | // 设置请求方法为GET 252 | connection.setRequestMethod("GET"); 253 | // 设置是否允许输入输出流 254 | connection.setDoInput(true); 255 | connection.setDoOutput(false); 256 | // int responseCode ; 257 | // try{ 258 | // responseCode = connection.getResponseCode(); 259 | // }catch (Exception ex) { 260 | // printErr("send_http_get Error:"+urlpath+" "+ex.getMessage()); 261 | // return ""; 262 | // } 263 | StringBuilder content = new StringBuilder(); 264 | if(connection.getResponseCode()==HttpURLConnection.HTTP_OK){ 265 | // 读取响应 266 | BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 267 | String inputLine; 268 | content = new StringBuilder(); 269 | while ((inputLine = in.readLine()) != null) { 270 | content.append(inputLine); 271 | } 272 | in.close(); 273 | connection.disconnect(); 274 | }else{ 275 | return ""; 276 | } 277 | return content.toString(); 278 | } 279 | } -------------------------------------------------------------------------------- /src/main/java/burp/utils/Group.java: -------------------------------------------------------------------------------- 1 | package burp.utils; 2 | import burp.IHttpRequestResponse; 3 | import burp.IResponseInfo; 4 | import burp.Main_Vuln; 5 | import burp.model.group.GroupEntry; 6 | import burp.model.poc.PocEntry; 7 | import com.google.common.hash.Hashing; 8 | import com.google.gson.Gson; 9 | import com.google.gson.reflect.TypeToken; 10 | import javax.swing.*; 11 | import javax.swing.border.EmptyBorder; 12 | import java.awt.*; 13 | import java.awt.event.KeyAdapter; 14 | import java.awt.event.KeyEvent; 15 | import java.io.IOException; 16 | import java.lang.reflect.Type; 17 | import java.net.URL; 18 | import java.nio.charset.StandardCharsets; 19 | import java.security.KeyManagementException; 20 | import java.security.NoSuchAlgorithmException; 21 | import java.sql.Connection; 22 | import java.sql.DriverManager; 23 | import java.sql.PreparedStatement; 24 | import java.sql.SQLException; 25 | import java.util.Arrays; 26 | import java.util.List; 27 | import java.util.Map; 28 | import java.util.Objects; 29 | import java.util.regex.Matcher; 30 | import java.util.regex.Pattern; 31 | 32 | import static burp.BurpExtender.helpers; 33 | import static burp.Main_Vuln.*; 34 | import static burp.utils.Conn.get_requests_response_head_body; 35 | import static burp.utils.Conn.get_requests_url; 36 | import static burp.utils.CustHttpService.get_host_ico_http_requests; 37 | import static burp.utils.Poc.Add_Component; 38 | import static burp.utils.Poc.countString; 39 | 40 | public class Group { 41 | public static void Add_Group(String name,String type) { 42 | List result = get_group_by_name(name,type); 43 | if(!result.isEmpty()){ 44 | return; 45 | } 46 | int last_id; 47 | // 获取最后一个元素 48 | if (model_group.getRowCount()>0) { 49 | List all_value = model_group.getAllValue(); 50 | last_id = all_value.get(all_value.size() - 1).id+1; 51 | } else { 52 | last_id=1; 53 | } 54 | GroupEntry _Data = new GroupEntry(last_id,name,type,true,false); 55 | Group.Save_Group_Data(_Data); 56 | } 57 | 58 | 59 | 60 | public static String delete_Group_data(GroupEntry temp) { 61 | String sql = "delete from `group` where id = "+temp.id; 62 | return Sql.Delete(sql); 63 | } 64 | 65 | public static void reload_read_group_Data() throws SQLException { 66 | model_group.ClearData(); 67 | model_group.fireTableDataChanged(); 68 | String sql = "select * from `group`"; 69 | List> sql_result = Sql.Select(sql); 70 | for (Map item : sql_result) { 71 | int id = (int) item.get("id"); 72 | String name= (String) item.get("name"); 73 | String type = (String) item.get("type"); 74 | int is_finger_poc_int = (int) item.get("is_finger_poc"); 75 | Boolean is_finger_poc = (is_finger_poc_int != 0) ? Boolean.TRUE : Boolean.FALSE; 76 | int is_finger_jump_poc_bool= (int) item.get("is_finger_jump_poc"); 77 | Boolean is_finger_jump_poc = (is_finger_jump_poc_bool != 0) ? Boolean.TRUE : Boolean.FALSE; 78 | GroupEntry temp = new GroupEntry(id,name,type,is_finger_poc,is_finger_jump_poc); 79 | model_group.addValueAt(temp); 80 | model_group.fireTableDataChanged(); 81 | } 82 | printMsg("Group Data Load Suceess!"); 83 | } 84 | public static String Save_Group_Data(GroupEntry Groupdata) { 85 | String url = "jdbc:sqlite:/"+ Main_Vuln.SQL_DB_PATH; 86 | try (Connection connection = DriverManager.getConnection(url); 87 | PreparedStatement pstmt = connection.prepareStatement( 88 | "INSERT INTO `group` (`id`,`name`, `type`, `is_finger_poc`, `is_finger_jump_poc`) VALUES (?, ?, ?, ?,?) " + 89 | "ON CONFLICT(id) DO UPDATE SET " + 90 | "type = EXCLUDED.type, is_finger_poc = EXCLUDED.is_finger_poc, is_finger_jump_poc = EXCLUDED.is_finger_jump_poc")) { 91 | // 设置PreparedStatement参数,注意这里没有设置id 92 | pstmt.setInt(1, Groupdata.id); 93 | pstmt.setString(2, Groupdata.name); 94 | pstmt.setString(3, Groupdata.type); 95 | pstmt.setInt(4, Groupdata.is_finger_poc ? 1 : 0); 96 | pstmt.setInt(5, Groupdata.is_finger_jump_poc ? 1 : 0); 97 | // 执行更新或插入操作 98 | int rowsAffected = pstmt.executeUpdate(); 99 | if (rowsAffected > 0) { 100 | return "保存成功!"; 101 | 102 | } else { 103 | return "保存失败!"; 104 | } 105 | 106 | } catch (SQLException e) { 107 | printErr(Arrays.toString(e.getStackTrace())); 108 | // e.printStackTrace(); 109 | return Arrays.toString(e.getStackTrace()); 110 | } 111 | } 112 | public static void Save_Group_Data_All(List Entries) { 113 | String url = "jdbc:sqlite:" + Main_Vuln.SQL_DB_PATH; 114 | try (Connection connection = DriverManager.getConnection(url)) { 115 | // 开启事务 116 | connection.setAutoCommit(false); 117 | String sql = "INSERT OR REPLACE INTO `group` (`id`,`name`,`type`,`is_finger_poc`,`is_finger_jump_poc`) VALUES (?,?,?, ?,?)"; 118 | try (PreparedStatement pstmt = connection.prepareStatement(sql)) { 119 | for (GroupEntry Groupdata : Entries) { 120 | pstmt.setInt(1, Groupdata.id); 121 | pstmt.setString(2, Groupdata.name); 122 | pstmt.setString(3, Groupdata.type); 123 | if(Groupdata.is_finger_poc){ 124 | pstmt.setInt(4, 1); 125 | }else{ 126 | pstmt.setInt(4, 0); 127 | } 128 | if(Groupdata.is_finger_jump_poc){ 129 | pstmt.setInt(5, 1); 130 | }else{ 131 | pstmt.setInt(5, 0); 132 | } 133 | pstmt.addBatch(); // 添加到批处理中 134 | } 135 | // 执行批处理 136 | int[] rowsAffected = pstmt.executeBatch(); 137 | // 提交事务 138 | connection.commit(); 139 | // 检查是否有数据被影响 140 | boolean anySuccess = false; 141 | for (int rows : rowsAffected) { 142 | if (rows > 0) { 143 | anySuccess = true; 144 | break; 145 | } 146 | } 147 | if (anySuccess) { 148 | } else { 149 | } 150 | } catch (SQLException e) { 151 | // 回滚事务 152 | connection.rollback(); 153 | printErr(e.getMessage()); 154 | printErr(Arrays.toString(e.getStackTrace())); 155 | } 156 | } catch (SQLException e) { 157 | printErr(e.getMessage()); 158 | printErr(Arrays.toString(e.getStackTrace())); 159 | } 160 | } 161 | public static void Group_edit(GroupEntry Group_data) { 162 | mainFrame_Group = new JFrame("编辑分组"); 163 | mainFrame_Group.setLayout(new BorderLayout()); 164 | 165 | JLabel label_group_name = new JLabel("分组名称:"); 166 | JTextField text_group_name= new JTextField(Group_data.name); 167 | 168 | 169 | JLabel label_vuln_type = new JLabel("分组类型:"); 170 | String[] group_list = {"漏洞POC","指纹POC"}; 171 | JComboBox comboBox_type = new JComboBox<>(group_list); 172 | comboBox_type.setSelectedItem(Group_data.type); 173 | 174 | String[] is_items = {"是","否"}; 175 | JLabel label_finger_enable = new JLabel("指纹匹配插件:"); 176 | JComboBox comboBox_finger_enable = new JComboBox<>(is_items); 177 | if(!Group_data.is_finger_poc){ 178 | comboBox_finger_enable.setSelectedItem("否"); 179 | }else{ 180 | comboBox_finger_enable.setSelectedItem("是"); 181 | } 182 | 183 | JLabel label_is_poc = new JLabel("直接进行扫描:"); 184 | JComboBox comboBox_is_poc = new JComboBox<>(is_items); 185 | if(Group_data.is_finger_jump_poc){ 186 | comboBox_is_poc.setSelectedItem("是"); 187 | }else{ 188 | comboBox_is_poc.setSelectedItem("否"); 189 | } 190 | JButton Group_button_go = new JButton("确定"); 191 | JButton Group_button_cancal = new JButton("取消"); 192 | 193 | Group_button_go.addActionListener(e -> { 194 | Group_data.name = (String) text_group_name.getText(); 195 | Group_data.type = (String) comboBox_type.getSelectedItem(); 196 | String is_true_finger_enable = (String) comboBox_finger_enable.getSelectedItem(); 197 | if(Objects.equals(is_true_finger_enable, "是")){ 198 | Group_data.is_finger_poc=true; 199 | }else{ 200 | Group_data.is_finger_poc=false; 201 | } 202 | String is_true_is_poc = (String) comboBox_is_poc.getSelectedItem(); 203 | if(Objects.equals(is_true_is_poc, "是")){ 204 | Group_data.is_finger_jump_poc=true; 205 | }else{ 206 | Group_data.is_finger_jump_poc=false; 207 | } 208 | String message = Save_Group_Data(Group_data); 209 | JOptionPane.showMessageDialog(null, message, "提示", JOptionPane.INFORMATION_MESSAGE); 210 | if (message.contains("保存成功")) { 211 | mainFrame_Group.setVisible(false); 212 | try { 213 | Group.reload_read_group_Data(); 214 | } catch (SQLException ex) { 215 | printErr(String.valueOf(ex)); 216 | } 217 | } 218 | 219 | 220 | }); 221 | Group_button_cancal.addActionListener(e -> mainFrame_Group.setVisible(false)); 222 | JPanel jpanel_Group_ = new JPanel(); 223 | GridBagLayout gbl=new GridBagLayout();//创建网格包布局管理器 224 | GridBagConstraints gbc=new GridBagConstraints();//GridBagConstraints对象来给出每个组件的大小和摆放位置 225 | jpanel_Group_.setLayout(gbl);//设置容器布局为网格包布局类型 226 | gbc.fill=GridBagConstraints.BOTH;//组件填充显示区域,当格子有剩余空间时,填充空间 227 | gbc.insets = new Insets(5, 5, 5, 5); // 边距 228 | gbc.anchor = GridBagConstraints.NORTHWEST; // 对齐方式 229 | // gridx 和 gridy:指定组件放置在网格中的起始位置。 230 | // gridwidth 和 gridheight:指定组件跨越的网格单元数量。 231 | // fill:指定组件如何填充其网格单元。 232 | // weightx 和 weighty:指定组件在可伸缩空间中的权重 233 | 234 | jpanel_Group_.add(Add_Component(gbl,label_group_name,gbc,0,0,1,1,0,0)); 235 | jpanel_Group_.add(Add_Component(gbl,text_group_name,gbc,1,0,1,2,1,0)); 236 | 237 | jpanel_Group_.add(Add_Component(gbl,label_vuln_type,gbc,0,1,1,1,0,0)); 238 | jpanel_Group_.add(Add_Component(gbl,comboBox_type,gbc,1,1,1,2,1,0)); 239 | 240 | jpanel_Group_.add(Add_Component(gbl,label_finger_enable,gbc,0,2,1,1,0,0)); 241 | jpanel_Group_.add(Add_Component(gbl,comboBox_finger_enable,gbc,1,2,1,2,1,0)); 242 | 243 | jpanel_Group_.add(Add_Component(gbl,label_is_poc,gbc,0,3,1,1,0,0)); 244 | jpanel_Group_.add(Add_Component(gbl,comboBox_is_poc,gbc,1,3,1,2,1,0)); 245 | 246 | 247 | //按钮行 248 | gbc.fill=GridBagConstraints.NORTH;//组件填充显示区域,当格子有剩余空间时,填充空间 249 | gbc.anchor = GridBagConstraints.CENTER; // 对齐方式 250 | jpanel_Group_.add(Add_Component(gbl,Group_button_go,gbc,1,4,1,1,0,0)); 251 | jpanel_Group_.add(Add_Component(gbl,Group_button_cancal,gbc,2,4,1,1,0,0)); 252 | jpanel_Group_.setBorder(new EmptyBorder(10, 10, 10, 10)); // 设置外边距为10 253 | mainFrame_Group.getContentPane().add(jpanel_Group_); 254 | mainFrame_Group.setSize(500, 300); 255 | mainFrame_Group.setLocationRelativeTo(null); 256 | mainFrame_Group.setVisible(true); 257 | } 258 | 259 | public static String[] get_all_group(){ 260 | String sql = "select DISTINCT `name` from `group`"; 261 | List> sql_result = Sql.Select(sql); 262 | String[] resultArray = new String[sql_result.size()]; 263 | int i=0; 264 | for (Map item : sql_result) { 265 | resultArray[i] = (String) item.get("name"); 266 | i++; 267 | } 268 | return resultArray; 269 | } 270 | 271 | public static String[] get_group_by_type(String type){ 272 | String sql; 273 | if(Objects.equals(type, "vuln")){ 274 | sql = "select DISTINCT `name` from `group` where is_finger_poc >0 "; 275 | } else if (Objects.equals(type, "finger")) { 276 | sql = "select DISTINCT `name` from `group` where is_finger_jump_poc>0"; 277 | }else { 278 | sql = "select DISTINCT `name` from `group`"; 279 | } 280 | List> sql_result = Sql.Select(sql); 281 | String[] resultArray = new String[sql_result.size()]; 282 | int i=0; 283 | for (Map item : sql_result) { 284 | resultArray[i] = (String) item.get("name"); 285 | i++; 286 | } 287 | return resultArray; 288 | } 289 | 290 | public static List>get_group_by_name(String name,String type){ 291 | String sql; 292 | if(Objects.equals(type, "vuln")){ 293 | sql = "select DISTINCT * from `group` where name = '"+name+"' and type='漏洞POC'"; 294 | 295 | } else if (Objects.equals(type, "finger")) { 296 | sql = "select DISTINCT * from `group` where name = '"+name+"' and type='指纹POC'"; 297 | }else { 298 | sql = "select DISTINCT * from `group` where name ='"+name+"'"; 299 | } 300 | List> sql_result = Sql.Select(sql); 301 | return sql_result; 302 | } 303 | 304 | 305 | 306 | 307 | } 308 | -------------------------------------------------------------------------------- /src/main/java/burp/utils/Plugins.java: -------------------------------------------------------------------------------- 1 | package burp.utils; 2 | import burp.Main_Vuln; 3 | import burp.model.finger.FingerEntry; 4 | import burp.model.finger.FingerTableModel; 5 | import burp.model.group.GroupEntry; 6 | import burp.model.group.GroupTableModel; 7 | import burp.model.poc.PocEntry; 8 | import burp.model.poc.PocTableModel; 9 | import com.fasterxml.jackson.core.JsonProcessingException; 10 | import com.fasterxml.jackson.databind.ObjectMapper; 11 | 12 | import javax.swing.*; 13 | import javax.swing.border.EmptyBorder; 14 | import javax.swing.filechooser.FileNameExtensionFilter; 15 | import java.awt.*; 16 | import java.awt.event.ActionEvent; 17 | import java.awt.event.ActionListener; 18 | import java.io.*; 19 | import java.lang.reflect.Field; 20 | import java.nio.charset.StandardCharsets; 21 | import java.nio.file.Files; 22 | import java.nio.file.Paths; 23 | import java.sql.SQLException; 24 | import java.util.*; 25 | import java.util.List; 26 | import java.util.stream.Collectors; 27 | 28 | import static burp.Main_Vuln.*; 29 | import static burp.model.poc.PocTableModel.all_poc_data; 30 | import static burp.utils.Config.save_config; 31 | import static burp.utils.Poc.Add_Component; 32 | 33 | public class Plugins { 34 | private static String lastDirectory; 35 | public static void plugins_edit(String type_) { 36 | 37 | mainFrame_Plugins = new JFrame("插件导入/导出"); 38 | mainFrame_Plugins.setLayout(new BorderLayout()); 39 | JCheckBox vuln_poc_checkbox = new JCheckBox("漏洞POC"); 40 | vuln_poc_checkbox.setSelected(true); 41 | JCheckBox plugins_poc_checkbox = new JCheckBox("指纹POC"); 42 | JCheckBox catrgory_checkbox = new JCheckBox("所有分组"); 43 | JCheckBox config_checkbox = new JCheckBox("配置文件"); 44 | JButton plugins_button_go = new JButton("确定"); 45 | 46 | plugins_button_go.addActionListener(new ActionListener() { 47 | @Override 48 | public void actionPerformed(ActionEvent e) { 49 | if(Objects.equals(type_, "export")){ 50 | try { 51 | plugin_export(vuln_poc_checkbox.isSelected(),plugins_poc_checkbox.isSelected(),catrgory_checkbox.isSelected(),config_checkbox.isSelected()); 52 | } catch (JsonProcessingException ex) { 53 | printErr(ex.getMessage()); 54 | printErr(Arrays.toString(ex.getStackTrace())); 55 | } 56 | } else if (Objects.equals(type_, "import")) { 57 | try { 58 | plugin_import(vuln_poc_checkbox.isSelected(),plugins_poc_checkbox.isSelected(),catrgory_checkbox.isSelected(),config_checkbox.isSelected()); 59 | } catch (IOException | SQLException ex) { 60 | printErr(ex.getMessage()); 61 | printErr(Arrays.toString(ex.getStackTrace())); 62 | 63 | } 64 | }else{ 65 | JOptionPane.showMessageDialog(null, "导入导出类型错误!", "提示", JOptionPane.INFORMATION_MESSAGE); 66 | } 67 | } 68 | }); 69 | 70 | JButton plugins_button_cancal = new JButton("取消"); 71 | plugins_button_cancal.addActionListener(e -> mainFrame_Plugins.setVisible(false)); 72 | JPanel jpanel_plugins_ = new JPanel(); 73 | GridBagLayout gbl=new GridBagLayout();//创建网格包布局管理器 74 | GridBagConstraints gbc=new GridBagConstraints();//GridBagConstraints对象来给出每个组件的大小和摆放位置 75 | jpanel_plugins_.setLayout(gbl);//设置容器布局为网格包布局类型 76 | gbc.fill=GridBagConstraints.BOTH;//组件填充显示区域,当格子有剩余空间时,填充空间 77 | gbc.insets = new Insets(5, 5, 5, 5); // 边距 78 | gbc.anchor = GridBagConstraints.NORTHWEST; // 对齐方式 79 | 80 | jpanel_plugins_.add(Add_Component(gbl,vuln_poc_checkbox,gbc,0,0,1,1,1,0)); 81 | jpanel_plugins_.add(Add_Component(gbl,plugins_poc_checkbox,gbc,1,0,1,1,1,0)); 82 | 83 | jpanel_plugins_.add(Add_Component(gbl,catrgory_checkbox,gbc,0,1,1,1,1,0)); 84 | jpanel_plugins_.add(Add_Component(gbl,config_checkbox,gbc,1,1,1,1,1,0)); 85 | 86 | // 按钮行 87 | gbc.fill=GridBagConstraints.NORTH;//组件填充显示区域,当格子有剩余空间时,填充空间 88 | gbc.anchor = GridBagConstraints.CENTER; // 对齐方式 89 | jpanel_plugins_.add(Add_Component(gbl,plugins_button_go,gbc,0,2,1,1,0,0)); 90 | jpanel_plugins_.add(Add_Component(gbl,plugins_button_cancal,gbc,1,2,1,1,0,0)); 91 | // 92 | jpanel_plugins_.setBorder(new EmptyBorder(10, 10, 10, 10)); // 设置外边距为10 93 | mainFrame_Plugins.getContentPane().add(jpanel_plugins_); 94 | mainFrame_Plugins.setSize(300, 180); 95 | mainFrame_Plugins.setLocationRelativeTo(null); 96 | mainFrame_Plugins.setVisible(true); 97 | } 98 | 99 | private static void plugin_export(boolean vuln_poc, boolean finger_poc, boolean group, boolean config) throws JsonProcessingException { 100 | Map data = new HashMap<>(); 101 | if (vuln_poc){ 102 | List all_poc = model_poc.getAllValue(); 103 | // List all_poc_map = new ArrayList<>(); 104 | // // 遍历 PocEntry 列表 105 | // for (PocEntry poc : all_poc) { 106 | // // 创建一个新的 HashMap 来存放当前 PocEntry 的属性 107 | // HashMap temp = new HashMap<>(); 108 | // // 获取 PocEntry 类的所有公共字段 109 | // Field[] fields = PocEntry.class.getDeclaredFields(); 110 | // // 遍历字段 111 | // for (Field field : fields) { 112 | // // 获取字段名称 113 | // String fieldName = field.getName(); 114 | // // 获取字段值 115 | // try { 116 | // field.setAccessible(true); // 允许访问私有字段 117 | // Object fieldValue = field.get(poc); 118 | // temp.put(fieldName, fieldValue); 119 | // } catch (IllegalAccessException e) { 120 | // printErr(e.getMessage()); 121 | // printErr(Arrays.toString(e.getStackTrace())); 122 | // } 123 | // } 124 | // // 将 temp Map 添加到 allPocMap 列表中 125 | // all_poc_map.add(temp); 126 | // } 127 | data.put("vuln_poc",all_poc); 128 | } 129 | if (finger_poc){ 130 | List all_poc = model_finger.getAllValue(); 131 | // List all_poc_map = new ArrayList<>(); 132 | // // 遍历 PocEntry 列表 133 | // for (FingerEntry poc : all_poc) { 134 | // // 创建一个新的 HashMap 来存放当前 PocEntry 的属性 135 | // HashMap temp = new HashMap<>(); 136 | // // 获取 PocEntry 类的所有公共字段 137 | // Field[] fields = FingerEntry.class.getDeclaredFields(); 138 | // // 遍历字段 139 | // for (Field field : fields) { 140 | // // 获取字段名称 141 | // String fieldName = field.getName(); 142 | // // 获取字段值 143 | // try { 144 | // field.setAccessible(true); // 允许访问私有字段 145 | // Object fieldValue = field.get(poc); 146 | // temp.put(fieldName, fieldValue); 147 | // } catch (IllegalAccessException e) { 148 | // printErr(e.getMessage()); 149 | // printErr(Arrays.toString(e.getStackTrace())); 150 | // } 151 | // } 152 | // 将 temp Map 添加到 allPocMap 列表中 153 | // all_poc_map.add(temp); 154 | // } 155 | data.put("finger_poc",all_poc); 156 | } 157 | if (group){ 158 | List all_group = model_group.getAllValue(); 159 | // List all_poc_map = new ArrayList<>(); 160 | // // 遍历 PocEntry 列表 161 | // for (GroupEntry poc : all_group) { 162 | // // 创建一个新的 HashMap 来存放当前 PocEntry 的属性 163 | // HashMap temp = new HashMap<>(); 164 | // // 获取 PocEntry 类的所有公共字段 165 | // Field[] fields = GroupEntry.class.getDeclaredFields(); 166 | // // 遍历字段 167 | // for (Field field : fields) { 168 | // // 获取字段名称 169 | // String fieldName = field.getName(); 170 | // // 获取字段值 171 | // try { 172 | // field.setAccessible(true); // 允许访问私有字段 173 | // Object fieldValue = field.get(poc); 174 | // temp.put(fieldName, fieldValue); 175 | // } catch (IllegalAccessException e) { 176 | // printErr(e.getMessage()); 177 | // printErr(Arrays.toString(e.getStackTrace())); 178 | // } 179 | // } 180 | // // 将 temp Map 添加到 allPocMap 列表中 181 | // all_poc_map.add(temp); 182 | // } 183 | data.put("group",all_group); 184 | } 185 | if (config){ 186 | data.put("config", Main_Vuln.Global_Config); 187 | } 188 | String filepath = fileChooser_save(); 189 | if(filepath.isEmpty()){ 190 | JOptionPane.showMessageDialog(null, "请选择一个Json文件", "提示", JOptionPane.INFORMATION_MESSAGE); 191 | return; 192 | } 193 | ObjectMapper mapper = new ObjectMapper(); 194 | // String jsonOutput = mapper.writeValueAsString(data); 195 | String jsonOutput = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data); 196 | // 197 | // Yaml yaml = new Yaml(options); 198 | // String yamlString = yaml.dump(data); 199 | try (Writer out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(Paths.get(filepath)), StandardCharsets.UTF_8))) { 200 | out.write(jsonOutput); 201 | mainFrame_Plugins.setVisible(false); 202 | JOptionPane.showMessageDialog(null, "导出成功!文件位置:"+filepath, "提示", JOptionPane.INFORMATION_MESSAGE); 203 | } catch (IOException e) { 204 | printErr(Arrays.toString(e.getStackTrace())); 205 | JOptionPane.showMessageDialog(null, e.getMessage(), "提示", JOptionPane.INFORMATION_MESSAGE); 206 | } 207 | } 208 | 209 | private static void plugin_import(boolean vuln_poc, boolean finger_poc, boolean group, boolean config) throws IOException, SQLException { 210 | ObjectMapper mapper = new ObjectMapper(); 211 | String filepath = fileChooser_open(); 212 | Map data; 213 | if(filepath.isEmpty()){ 214 | JOptionPane.showMessageDialog(null, "请选择一个Json文件", "提示", JOptionPane.INFORMATION_MESSAGE); 215 | return; 216 | } 217 | try { 218 | data = mapper.readValue(new File(filepath), Map.class); 219 | }catch (Exception ex){ 220 | JOptionPane.showMessageDialog(null, "文件加载失败!Error:"+ex.getMessage(), "提示", JOptionPane.INFORMATION_MESSAGE); 221 | return; 222 | } 223 | if (vuln_poc){ 224 | @SuppressWarnings("unchecked") 225 | List> PocList = (List>) data.get("vuln_poc"); 226 | // 将 List 转换为 List 227 | List pocEntries = PocList.stream() 228 | .map(map -> mapper.convertValue(map, PocEntry.class)) 229 | .collect(Collectors.toList()); 230 | all_poc_data = pocEntries; 231 | PocTableModel.save_data_to_db(); 232 | 233 | } 234 | if (finger_poc){ 235 | @SuppressWarnings("unchecked") 236 | List> PocList = (List>) data.get("finger_poc"); 237 | // 将 List 转换为 List 238 | List pocEntries = PocList.stream() 239 | .map(map -> mapper.convertValue(map, FingerEntry.class)) 240 | .collect(Collectors.toList()); 241 | 242 | FingerTableModel.all_finger_data = pocEntries; 243 | System.out.println("777"); 244 | 245 | FingerTableModel.save_data_to_db(); 246 | System.out.println("222"); 247 | } 248 | if (group){ 249 | @SuppressWarnings("unchecked") 250 | List> PocList = (List>) data.get("group"); 251 | // 将 List 转换为 List 252 | List pocEntries = PocList.stream() 253 | .map(map -> mapper.convertValue(map, GroupEntry.class)) 254 | .collect(Collectors.toList()); 255 | GroupTableModel.all_group_data = pocEntries; 256 | GroupTableModel.save_data_to_db(); 257 | } 258 | if (config){ 259 | Global_Config = (Map)data.get("config"); 260 | save_config(); 261 | } 262 | mainFrame_Plugins.setVisible(false); 263 | JOptionPane.showMessageDialog(null, "导入成功!", "提示", JOptionPane.INFORMATION_MESSAGE); 264 | 265 | } 266 | 267 | private static String fileChooser_open() { 268 | JFileChooser fileChooser = new JFileChooser(); 269 | // 创建一个新的JFrame实例 270 | JFrame frame = new JFrame("导入配置"); 271 | fileChooser.setSelectedFile(new File("data.json")); 272 | fileChooser.setFileFilter(new FileNameExtensionFilter("Json文件(*.json)", "json")); 273 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 274 | // 创建一个JFileChooser实例 275 | // 设置默认显示目录 276 | if (lastDirectory != null) { 277 | fileChooser.setCurrentDirectory(new File(lastDirectory)); 278 | } else { 279 | fileChooser.setCurrentDirectory(new File(System.getProperty("user.home"))); 280 | } 281 | 282 | // 显示打开文件对话框 283 | int result = fileChooser.showOpenDialog(frame); 284 | if (result == JFileChooser.APPROVE_OPTION) { 285 | File selectedFile = fileChooser.getSelectedFile(); 286 | // 更新 lastDirectory 变量 287 | lastDirectory = String.valueOf(selectedFile.getParentFile()); 288 | // 在这里你可以添加读取文件的逻辑 289 | return selectedFile.getAbsolutePath(); 290 | } else { 291 | return ""; 292 | } 293 | } 294 | private static String fileChooser_save(){ 295 | // 创建一个JFileChooser实例 296 | JFileChooser fileChooser = new JFileChooser(); 297 | fileChooser.setDialogTitle("导出配置"); 298 | fileChooser.setSelectedFile(new File("data.json")); 299 | fileChooser.setFileFilter(new FileNameExtensionFilter("Json文件(*.json)", "json")); 300 | // 设置默认显示目录 301 | if (lastDirectory != null) { 302 | fileChooser.setCurrentDirectory(new File(lastDirectory)); 303 | } else { 304 | // 设置默认显示目录 305 | fileChooser.setCurrentDirectory(new File(System.getProperty("user.home"))); 306 | } 307 | // 显示保存文件对话框 308 | int result = fileChooser.showSaveDialog(mainFrame_Plugins); 309 | 310 | if (result == JFileChooser.APPROVE_OPTION) { 311 | File selectedFile = fileChooser.getSelectedFile(); 312 | // 如果文件名不包含扩展名,你可以添加一个 313 | if (!selectedFile.getName().endsWith(".json")) { 314 | selectedFile = new File(selectedFile.getPath() + ".json"); 315 | } 316 | lastDirectory = String.valueOf(selectedFile.getParentFile()); 317 | return selectedFile.getAbsolutePath(); 318 | // 在这里你可以添加保存文件的逻辑 319 | } else { 320 | return ""; 321 | } 322 | } 323 | } 324 | 325 | -------------------------------------------------------------------------------- /src/main/java/burp/utils/Sql.java: -------------------------------------------------------------------------------- 1 | package burp.utils; 2 | 3 | import java.sql.*; 4 | import java.util.*; 5 | 6 | import static burp.Main_Vuln.SQL_DB_PATH; 7 | import static burp.Main_Vuln.printErr; 8 | 9 | public class Sql { 10 | /** 11 | * 从数据库中选择所有 POC 数据并加载到模型中。 12 | * 13 | * @return 14 | */ 15 | public static List> Select(String sql) { 16 | try { 17 | List> ret_result = new ArrayList<>(); 18 | // 加载 SQLite JDBC 驱动 19 | Class.forName("org.sqlite.JDBC"); 20 | // 获取数据库连接 21 | try (Connection connection = getConnection(); 22 | Statement statement = connection.createStatement()) { 23 | // 执行查询 24 | // String sql = "SELECT * FROM poc"; 25 | ResultSet rs = statement.executeQuery(sql); 26 | ResultSetMetaData metaData = rs.getMetaData(); 27 | int columnCount = metaData.getColumnCount(); 28 | // 处理查询结果 29 | while (rs.next()) { 30 | Map rowData = new HashMap<>(); 31 | for (int i = 1; i <= columnCount; i++) { 32 | String columnName = metaData.getColumnName(i); 33 | int columnType = metaData.getColumnType(i); 34 | switch (columnType) { 35 | case java.sql.Types.INTEGER: 36 | rowData.put(columnName, rs.getInt(i)); 37 | break; 38 | case java.sql.Types.VARCHAR: 39 | case java.sql.Types.LONGVARCHAR: 40 | rowData.put(columnName, rs.getString(i)); 41 | break; 42 | // 添加其他数据类型的处理 43 | default: 44 | // 如果有其他类型,你可以在这里处理 45 | rowData.put(columnName, rs.getObject(i)); 46 | break; 47 | } 48 | } 49 | ret_result.add(rowData); 50 | } 51 | } catch (SQLException e) { 52 | printErr(e.getMessage()); 53 | printErr(Arrays.toString(e.getStackTrace())); 54 | } 55 | return ret_result; 56 | } catch (ClassNotFoundException e) { 57 | // 打印类未找到异常 58 | printErr(e.getMessage()); 59 | printErr(Arrays.toString(e.getStackTrace())); 60 | } 61 | return new ArrayList<>(); 62 | } 63 | public static String Delete(String sql) { 64 | try{ 65 | // 加载 SQLite JDBC 驱动 66 | Class.forName("org.sqlite.JDBC"); 67 | // 获取数据库连接 68 | try (Connection connection = getConnection(); 69 | Statement statement = connection.createStatement()) { 70 | int deletedRows = statement.executeUpdate(sql); 71 | statement.close(); 72 | if(deletedRows>0){ 73 | return "success"; 74 | }else{ 75 | return "删除失败!"; 76 | } 77 | } catch (SQLException e) { 78 | // 打印异常堆栈跟踪 79 | printErr(Arrays.toString(e.getStackTrace())); 80 | } 81 | } catch (ClassNotFoundException e) { 82 | // 打印类未找到异常 83 | printErr(e.getMessage()); 84 | return e.getMessage(); 85 | } 86 | return ""; 87 | } 88 | 89 | /** 90 | * 获取数据库连接。 91 | * 92 | * @return 数据库连接 93 | * @throws SQLException 如果连接失败 94 | */ 95 | private static Connection getConnection() throws SQLException { 96 | String databaseUrl = "jdbc:sqlite:" + SQL_DB_PATH; 97 | return DriverManager.getConnection(databaseUrl); 98 | } 99 | } -------------------------------------------------------------------------------- /src/main/java/burp/vuln/LogEntry.java: -------------------------------------------------------------------------------- 1 | package burp.vuln; 2 | 3 | import burp.IHttpRequestResponsePersisted; 4 | 5 | import java.net.URL; 6 | 7 | public class LogEntry 8 | { 9 | public final int id; 10 | final String tool; 11 | public final IHttpRequestResponsePersisted requestResponse; 12 | final URL url; 13 | final String parameter; 14 | final String value; 15 | final String data_md5; 16 | final int times; 17 | final int response_code; 18 | public String finger_scan_result; 19 | public String vuln_scan_result; 20 | 21 | 22 | public LogEntry(int id, String tool, IHttpRequestResponsePersisted requestResponse, URL url, String parameter, String value, String data_md5, int times, Integer response_code,String finger_scan_result, String vuln_scan_result) 23 | { 24 | this.id = id; 25 | this.tool = tool; 26 | this.requestResponse = requestResponse; 27 | this.url = url; 28 | this.parameter = parameter; 29 | this.value = value; 30 | this.data_md5 = data_md5; 31 | this.times = times; 32 | this.response_code = response_code; 33 | this.finger_scan_result = finger_scan_result; 34 | this.vuln_scan_result = vuln_scan_result; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/burp/vuln/LogTableModel.java: -------------------------------------------------------------------------------- 1 | package burp.vuln; 2 | 3 | 4 | import javax.swing.event.ListSelectionEvent; 5 | import javax.swing.table.AbstractTableModel; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class LogTableModel extends AbstractTableModel { 10 | 11 | 12 | private final String[] columnNames = {"序号", "来源", "URL", "返回包长度", "状态码","指纹信息","漏洞扫描结果"}; 13 | public static final List table_log_data = new ArrayList<>();//用于展现结果 14 | 15 | @Override 16 | public int getRowCount() 17 | { 18 | return table_log_data.size(); 19 | 20 | } 21 | 22 | @Override 23 | public int getColumnCount() 24 | { 25 | return columnNames.length; 26 | } 27 | 28 | @Override 29 | public String getColumnName(int columnIndex) 30 | { 31 | return columnNames[columnIndex]; 32 | } 33 | 34 | @Override 35 | public Class getColumnClass(int columnIndex) 36 | { 37 | switch (columnIndex) 38 | { 39 | case 0: 40 | return Integer.class; 41 | case 1: 42 | return String.class; 43 | case 2: 44 | return String.class; 45 | case 3: 46 | return Integer.class;//返回响应包的长度 47 | case 4: 48 | return Integer.class; 49 | case 5: 50 | return String.class; 51 | case 6: 52 | return String.class; 53 | default: 54 | return String.class; 55 | } 56 | } 57 | public void ClearData() { 58 | table_log_data.clear(); 59 | // int rowCount = logTable.getRowCount(); 60 | // model.fireTableRowsDeleted(0, rowCount); 61 | // fireTableDataChanged(); 62 | // 63 | } 64 | public void addValueAt(LogEntry value) 65 | { 66 | table_log_data.add(value); 67 | // fireTableDataChanged(); 68 | } 69 | @Override 70 | public Object getValueAt(int rowIndex, int columnIndex) 71 | { 72 | if (rowIndex < 0 || rowIndex >= table_log_data.size() || columnIndex < 0 || columnIndex >= columnNames.length) { 73 | return ""; 74 | } 75 | LogEntry logEntry = table_log_data.get(rowIndex); 76 | switch (columnIndex) 77 | { 78 | case 0: 79 | return logEntry.id; 80 | case 1: 81 | return logEntry.tool; 82 | // return BurpExtender.callbacks.getToolName(logEntry.tool); 83 | case 2: 84 | return logEntry.url.toString(); 85 | case 3: 86 | return logEntry.requestResponse.getResponse().length;//返回响应包的长度 87 | case 4: 88 | return logEntry.response_code; 89 | case 5: 90 | return logEntry.finger_scan_result; 91 | case 6: 92 | return logEntry.vuln_scan_result; 93 | default: 94 | return ""; 95 | } 96 | } 97 | public List getAllValue(){ 98 | return table_log_data; 99 | } 100 | 101 | 102 | 103 | 104 | } -------------------------------------------------------------------------------- /src/main/resources/lib/beautyeye_lnf.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianxiao996/BurpSuite-FrameScan/4c6e3e417739b743473515ca6b5fee6cc3c2a692/src/main/resources/lib/beautyeye_lnf.jar --------------------------------------------------------------------------------