├── README.md
├── xia_jie_demo.py
└── BurpExtender.java
/README.md:
--------------------------------------------------------------------------------
1 | # xia Jie (瞎解)
2 | ```
3 | 市面上很多类似的插件了,为什么还要重复造轮子呢
4 | 因为很多情况下
5 | 总有各种乱七八糟的问题,如不好查看最终修改后都数据包等信息
6 | ```
7 | ********************
8 | * 通常用于自动化流量加密或解密
9 | * 对burp的 请求包 和 响应包 用python完全自定义修改数据包的流量
10 | ********************
11 | 
12 |
13 |
14 |
15 | ## 0x01 界面截图
16 |
17 | #### 2024-9-10 瞎解 1.0
18 |
19 |
20 | ## 0x02 使用教程
21 |
22 | 1、启动插件
23 | 2、自定义修改好python脚本后运行,如下:我在头部添加了(abcd:1234)和 body体添加了 (&abcd=654321)
24 |
25 |
26 |
27 | 点击发送
28 |
29 |
30 |
31 |
32 |
33 |
34 | 很多网站不是全部加密的,所以有些数据包需要解密or加密,需要多写几个if判断,哪些需要解密or解密 哪些不用
35 |
36 | 比如:
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 当然也支持右键加解密
45 |
46 |
47 |
48 | 点击后会 加密
49 |
50 |
51 |
52 | 正常使用的话,先拿一段 待加密or解密 的数据测试
53 |
54 |
55 |
56 | 测试通过在注释掉,在运行run方法
57 |
58 |
59 |
--------------------------------------------------------------------------------
/xia_jie_demo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding:utf-8
3 | from http.server import HTTPServer, BaseHTTPRequestHandler
4 | import base64
5 | import re
6 |
7 | #************⬇不要动这里⬇****************
8 | class Resquest(BaseHTTPRequestHandler):
9 | def do_GET(self):
10 | self.send_response(200)
11 | self.send_header('Content-type', 'text/html; charset=UTF-8')
12 | self.end_headers()
13 | self.wfile.write("xia_jie".encode())
14 |
15 | def do_POST(self):
16 | req_datas = self.rfile.read(int(self.headers['content-length']))
17 | post_data = req_datas.decode()
18 | try:
19 | header = base64.b64decode(re.search('header=(.*?)[^&]*', post_data).group()[7:]).decode().split("\n")
20 | header.pop()#删除列表中最后一个元素
21 | body = base64.b64decode(re.search('body=(.*?)[^&]*', post_data).group()[5:]).decode()
22 |
23 | def data_handle(data):
24 | #对内容进行base64编码
25 | head_data = ""
26 | for i in data[0]:
27 | head_data+=i+"\n"
28 | ba64_header = base64.b64encode(head_data.encode()).decode()
29 | ba64_body = base64.b64encode(data[1].encode()).decode()
30 | return "header="+ba64_header+"&body="+ba64_body
31 |
32 | if self.path == "/xj_encode":
33 | data = data_handle(xia_jie.xj_encode(self,header,body))
34 | elif self.path == "/xj_decode":
35 | data = data_handle(xia_jie.xj_decode(self,header,body))
36 | else:
37 | data = "xia_jie error:api error"
38 | except Exception as e:
39 | print(e)
40 | data = "xia_jie:"+str(e)
41 | self.send_response(200)
42 | self.send_header('Content-type', 'text/html;')
43 | self.end_headers()
44 | self.wfile.write(data.encode())
45 | #************⬆不要动这里⬆****************
46 |
47 |
48 | class xia_jie:
49 | def __init__(self):
50 | pass
51 |
52 | #加密
53 | def xj_encode(self, header, body):
54 | return header, body
55 | #解密
56 | def xj_decode(self,header,body):
57 | return header, body
58 |
59 |
60 | def run():
61 | host = ('0.0.0.0', 23002)
62 | server = HTTPServer(host, Resquest)
63 | print("run:http://"+host[0]+":"+str(host[1]))
64 | server.serve_forever()
65 |
66 | #启动
67 | run()
68 |
69 | #调试
70 | #header = ["POST / HTTP/1.1","host: 127.0.0.1"]
71 | #body = "1111"
72 | #print(xia_jie.xj_encode(0,header,body))
73 |
--------------------------------------------------------------------------------
/BurpExtender.java:
--------------------------------------------------------------------------------
1 | package burp;
2 |
3 |
4 | import java.io.*;
5 | import java.net.URL;
6 | import java.net.URLConnection;
7 | import java.nio.charset.StandardCharsets;
8 | import java.security.MessageDigest;
9 | import java.awt.Component;
10 | import java.awt.event.ActionEvent;
11 | import java.awt.event.ActionListener;
12 | import java.awt.event.ItemEvent;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import javax.swing.*;
16 | import javax.swing.table.AbstractTableModel;
17 | import javax.swing.table.TableModel;
18 | import java.awt.*;
19 | import java.awt.event.ItemListener;
20 | import java.util.regex.Matcher;
21 | import java.util.regex.Pattern;
22 | import java.util.Base64;
23 |
24 |
25 | public class BurpExtender extends AbstractTableModel implements IBurpExtender, ITab, IHttpListener,IScannerCheck, IMessageEditorController,IContextMenuFactory
26 | {
27 | private IBurpExtenderCallbacks callbacks;
28 | private IExtensionHelpers helpers;
29 | private JSplitPane splitPane;
30 | private IMessageEditor requestViewer;
31 | private IMessageEditor responseViewer;
32 | private IMessageEditor requestViewer_proxy;
33 | private IMessageEditor responseViewer_proxy;
34 | private final List log = new ArrayList();//记录原始流量
35 | private IHttpRequestResponse currentlyDisplayedItem;
36 | private IHttpRequestResponse currentlyDisplayedItem_proxy;
37 | public PrintWriter stdout;
38 | JTabbedPane tabs;//数据包显示框
39 | JTabbedPane tabs_1;//数据包的proxy模块开关
40 | int switchs = 0; //开关 0关 1开
41 | int conut = 0; //记录条数
42 | int original_data_len;//记录原始数据包的长度
43 | int select_row = 0;//选中表格的行数
44 | Table logTable; //第一个表格框
45 | String white_URL = "";
46 | int white_switchs = 0;//白名单开关
47 | int debug = 0;//调试模式 0关 1开
48 |
49 | JTextArea log_ta;//日志
50 | JTextField connect_ip;
51 | JTextArea proxy_decode_data_request;
52 | JTextArea proxy_decode_data_response;
53 |
54 | //复选框
55 | //proxy
56 | JCheckBox p_chkbox1;
57 | JCheckBox p_chkbox2;
58 | JCheckBox p_chkbox3;
59 | //Repeater
60 | JCheckBox r_chkbox1;
61 | JCheckBox r_chkbox2;
62 | //Intruder
63 | JCheckBox i_chkbox1;
64 | JCheckBox i_chkbox2;
65 |
66 |
67 |
68 |
69 | @Override
70 | public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks)
71 | {
72 | //输出
73 | this.stdout = new PrintWriter(callbacks.getStdout(), true);
74 | this.stdout.println("hello xia Jie!");
75 | this.stdout.println("你好 欢迎使用 瞎解!");
76 | this.stdout.println("version:1.0");
77 |
78 |
79 |
80 | // keep a reference to our callbacks object
81 | this.callbacks = callbacks;
82 |
83 | // obtain an extension helpers object
84 | helpers = callbacks.getHelpers();
85 |
86 | // set our extension name
87 | callbacks.setExtensionName("xia Jie V1.0");
88 |
89 | // create our UI
90 | SwingUtilities.invokeLater(new Runnable()
91 | {
92 | @Override
93 | public void run()
94 | {
95 |
96 | // main split pane
97 | splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
98 | JSplitPane splitPanes = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
99 | JSplitPane splitPanes_2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
100 |
101 | //表格
102 | logTable = new Table(BurpExtender.this);
103 | logTable.getColumnModel().getColumn(3).setPreferredWidth(500);
104 | JScrollPane scrollPane = new JScrollPane(logTable); //给列表添加滚动条
105 |
106 | JPanel jp=new JPanel();
107 | jp.setLayout(new GridLayout(1, 1));
108 | jp.add(scrollPane); //将表格加到面板
109 |
110 | //侧边复选框
111 | JPanel jps=new JPanel();
112 | jps.setLayout(new GridLayout(11, 1)); //六行一列
113 | JLabel jls=new JLabel("插件名:瞎解 author:算命縖子"); //创建一个标签
114 | JLabel jls_1=new JLabel("blog:www.nmd5.com"); //创建一个标签
115 | JLabel jls_2=new JLabel("版本:xia Jie V1.0"); //创建一个标签
116 | JLabel jls_3=new JLabel("感谢名单:Moonlit"); //创建一个标签
117 |
118 | JCheckBox chkbox1=new JCheckBox("启动插件"); //创建指定文本和状态的复选框
119 | connect_ip = new JTextField("127.0.0.1:23002");//白名单文本框
120 | JCheckBox chkbox2=new JCheckBox("启动调试模式(抓取最终的数据包)"); //创建指定文本和状态的复选框
121 | JLabel jls_5=new JLabel("如果需要多个域名加白请用,隔开"); //创建一个标签
122 | JTextField textField = new JTextField("填写白名单域名,强烈建议启动");//白名单文本框
123 | JButton btn1=new JButton("清空列表与日志"); //创建JButton对象
124 | JButton btn3=new JButton("启动白名单"); //处理白名单
125 |
126 |
127 | JPanel jps_2=new JPanel();
128 | //proxy模块
129 | JLabel p_lb=new JLabel("proxy:"); //创建一个标签
130 | JLabel p_lb_1=new JLabel("加密会修改原始数据包,解密不会修改原始数据包"); //创建一个标签
131 | p_chkbox1=new JCheckBox("加密proxy请求包流量"); //创建指定文本和状态的复选框
132 | p_chkbox2=new JCheckBox("解密proxy请求包流量"); //创建指定文本和状态的复选框
133 | p_chkbox3=new JCheckBox("解密proxy响应包流量"); //创建指定文本和状态的复选框
134 |
135 | //Repeater模块
136 | JLabel r_lb=new JLabel("Repeater:"); //创建一个标签
137 | JLabel r_lb_2=new JLabel("解密请求包请到Repeater界面右键解密"); //创建一个标签
138 | r_chkbox1=new JCheckBox("加密Repeater请求包流量"); //创建指定文本和状态的复选框
139 | r_chkbox2=new JCheckBox("解密Repeater响应包流量"); //创建指定文本和状态的复选框
140 |
141 | //Intruder模块
142 | JLabel i_lb=new JLabel("Intruder:"); //创建一个标签
143 | i_chkbox1=new JCheckBox("加密Intruder请求包流量"); //创建指定文本和状态的复选框
144 | i_chkbox2=new JCheckBox("解密Intruder响应包流量"); //创建指定文本和状态的复选框、
145 |
146 |
147 |
148 | //指定面板的布局为GridLayout,1行1列,间隙为0
149 | jps_2.setLayout(new GridLayout(16,1,0,0));
150 | jps_2.add(p_lb);
151 | jps_2.add(p_lb_1);
152 | jps_2.add(p_chkbox1);
153 | jps_2.add(p_chkbox2);
154 | jps_2.add(p_chkbox3);
155 | jps_2.add(r_lb);
156 | jps_2.add(r_lb_2);
157 | jps_2.add(r_chkbox1);
158 | jps_2.add(r_chkbox2);
159 | jps_2.add(i_lb);
160 | jps_2.add(i_chkbox1);
161 | jps_2.add(i_chkbox2);
162 |
163 |
164 | //添加复选框监听事件 开关
165 | chkbox1.addItemListener(new ItemListener() {
166 | @Override
167 | public void itemStateChanged(ItemEvent e) {
168 | if(chkbox1.isSelected()){
169 | switchs = 1;
170 | connect_ip.setEditable(false);
171 | connect_ip.setForeground(Color.GRAY);
172 | }else {
173 | switchs = 0;
174 | connect_ip.setEditable(true);
175 | connect_ip.setForeground(Color.BLACK);
176 | }
177 | }
178 | });
179 | //添加复选框监听事件 调试模式
180 | chkbox2.addItemListener(new ItemListener() {
181 | @Override
182 | public void itemStateChanged(ItemEvent e) {
183 | if(chkbox2.isSelected()){
184 | debug = 1;
185 | }else {
186 | debug = 0;
187 | }
188 |
189 | }
190 | });
191 |
192 | btn1.addActionListener(new ActionListener() {//清空列表
193 | @Override
194 | public void actionPerformed(ActionEvent e) {
195 | log.clear();
196 | log_ta.setText("");//清除log的内容
197 | conut = 0;
198 | fireTableRowsInserted(log.size(), log.size());//刷新列表中的展示
199 | }
200 | });
201 | btn3.addActionListener(new ActionListener() {//白名单
202 | @Override
203 | public void actionPerformed(ActionEvent e) {
204 | if(btn3.getText().equals("启动白名单")){
205 | btn3.setText("关闭白名单");
206 | white_URL = textField.getText();
207 | white_switchs = 1;
208 | textField.setEditable(false);
209 | textField.setForeground(Color.GRAY);//设置组件的背景色
210 | }else {
211 | btn3.setText("启动白名单");
212 | white_switchs = 0;
213 | textField.setEditable(true);
214 | textField.setForeground(Color.BLACK);
215 | }
216 | }
217 | });
218 |
219 |
220 | jps.add(jls);
221 | jps.add(jls_1);
222 | jps.add(jls_2);
223 | jps.add(jls_3);
224 | jps.add(chkbox1);
225 | jps.add(connect_ip);
226 | jps.add(chkbox2);
227 | jps.add(btn1);
228 | jps.add(jls_5);
229 | jps.add(textField);
230 | jps.add(btn3);
231 |
232 | // tabs with request/response viewers
233 | tabs = new JTabbedPane();
234 | requestViewer = callbacks.createMessageEditor(BurpExtender.this, false);
235 | responseViewer = callbacks.createMessageEditor(BurpExtender.this, false);
236 | requestViewer_proxy = callbacks.createMessageEditor(BurpExtender.this, false);
237 | responseViewer_proxy = callbacks.createMessageEditor(BurpExtender.this, false);
238 |
239 | //日志
240 | JPanel log_jp=new JPanel();
241 | log_jp.setLayout(new GridLayout(1, 1)); //一行一列
242 | log_ta=new JTextArea("");
243 | log_ta.setForeground(Color.BLACK); //设置组件的背景色
244 | log_ta.setFont(new Font("楷体",Font.BOLD,16)); //修改字体样式
245 | log_ta.setEditable(false);//不可编辑状态
246 | JScrollPane jsp=new JScrollPane(log_ta); //将文本域放入滚动窗口
247 | log_jp.add(jsp); //将JScrollPane添加到JPanel容器中
248 |
249 | //数据包
250 | JSplitPane d_jp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);//原始数据
251 | d_jp.setDividerLocation(500);//左右两边的距离
252 | d_jp.setLeftComponent(requestViewer.getComponent());//添加在左面
253 | d_jp.setRightComponent(responseViewer.getComponent());//添加在右面
254 |
255 | //proxy解密数据包
256 | JSplitPane j_jp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);//原始数据
257 | j_jp.setDividerLocation(500);//左右两边的距离
258 | proxy_decode_data_request = new JTextArea("");
259 | proxy_decode_data_request.setEditable(false);//不可编辑状态
260 | proxy_decode_data_request.setLineWrap(true);//自动换行
261 | JScrollPane proxy_decode_data_request_sp=new JScrollPane(proxy_decode_data_request); //将文本域放入滚动窗口
262 | proxy_decode_data_response = new JTextArea("");
263 | proxy_decode_data_response.setEditable(false);//不可编辑状态
264 | proxy_decode_data_response.setLineWrap(true);//自动换行
265 | JScrollPane proxy_decode_data_response_sp=new JScrollPane(proxy_decode_data_response); //将文本域放入滚动窗口
266 | j_jp.setLeftComponent(proxy_decode_data_request_sp);//添加在左面
267 | j_jp.setRightComponent(proxy_decode_data_response_sp);//添加在右面
268 |
269 | //如果是proxy的流量
270 | tabs_1 = new JTabbedPane();
271 | tabs_1.addTab("最终数据包",d_jp);
272 | tabs_1.addTab("Proxy流量解密后的数据包",j_jp);
273 |
274 | tabs.addTab("日志",log_jp);
275 | tabs.addTab("数据包",tabs_1);
276 |
277 |
278 | //右边
279 | splitPanes_2.setLeftComponent(jps);//上面
280 | splitPanes_2.setRightComponent(jps_2);//下面
281 |
282 | //左边
283 | splitPanes.setLeftComponent(jp);//上面
284 | splitPanes.setRightComponent(tabs);//下面
285 |
286 | //整体分布
287 | splitPane.setLeftComponent(splitPanes);//添加在左面
288 | splitPane.setRightComponent(splitPanes_2);//添加在右面
289 | splitPane.setDividerLocation(1000);//设置分割的大小
290 |
291 | // customize our UI components
292 | callbacks.customizeUiComponent(splitPane);
293 | callbacks.customizeUiComponent(logTable);
294 | callbacks.customizeUiComponent(scrollPane);
295 | callbacks.customizeUiComponent(jps);
296 | callbacks.customizeUiComponent(jp);
297 | callbacks.customizeUiComponent(tabs);
298 |
299 | // add the custom tab to Burp's UI
300 | callbacks.addSuiteTab(BurpExtender.this);
301 |
302 | // register ourselves as an HTTP listener
303 | callbacks.registerHttpListener(BurpExtender.this);
304 | callbacks.registerScannerCheck(BurpExtender.this);
305 | callbacks.registerContextMenuFactory(BurpExtender.this);
306 |
307 | }
308 | });
309 | }
310 |
311 |
312 | @Override
313 | public String getTabCaption()
314 | {
315 | return "xia Jie";
316 | }
317 |
318 | @Override
319 | public Component getUiComponent()
320 | {
321 | return splitPane;
322 | }
323 |
324 |
325 | @Override
326 | public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo)
327 | {
328 |
329 | if(switchs == 1){//插件开关
330 | if(toolFlag == 4 || toolFlag==32 || toolFlag ==64){//监听Proxy/Intruder/Repeater
331 | // only process responses
332 | if (!messageIsRequest)
333 | {//响应包
334 | if((i_chkbox2.isSelected() && toolFlag ==32) || (r_chkbox2.isSelected() && toolFlag ==64)){
335 | //Intruder/Repeater 解密-单线程处理
336 | BurpExtender.this.response_Vul(messageInfo, toolFlag,false);
337 | }
338 |
339 | //proxy解密
340 | if((p_chkbox2.isSelected() && toolFlag==4)||(p_chkbox3.isSelected() && toolFlag==4)) {
341 | //Proxy流量多线程处理
342 | Thread thread = new Thread(new Runnable() {
343 | public void run() {
344 | try {
345 | BurpExtender.this.response_Vul(messageInfo,toolFlag,true);
346 | } catch (Exception ex) {
347 | ex.printStackTrace();
348 | BurpExtender.this.stdout.println(ex);
349 | }
350 | }
351 | });
352 | thread.start();
353 | }
354 |
355 | //开启调试模式,proxy、request、intruder 加密
356 | if(debug == 1) {
357 | if ((p_chkbox1.isSelected() && !p_chkbox2.isSelected() && !p_chkbox3.isSelected() && toolFlag==4) || (r_chkbox1.isSelected() && !r_chkbox2.isSelected() && toolFlag==64) || (i_chkbox1.isSelected() && !i_chkbox2.isSelected() && toolFlag==32)) {
358 | if(white_switchs_boolean(messageInfo,toolFlag)) {//白名单处理
359 | conut += 1;
360 | int id = conut;
361 | log.add(new LogEntry(id, helpers.analyzeRequest(messageInfo).getMethod(), callbacks.saveBuffersToTempFiles(messageInfo), "", "", String.valueOf(helpers.analyzeRequest(messageInfo).getUrl()), messageInfo.getResponse().length - helpers.analyzeResponse(messageInfo.getResponse()).getBodyOffset(), toolFlag));
362 |
363 | //刷新表格
364 | BurpExtender.this.fireTableDataChanged();
365 | BurpExtender.this.logTable.setRowSelectionInterval(BurpExtender.this.select_row, BurpExtender.this.select_row);
366 | }
367 | }
368 | }
369 |
370 |
371 | }else {//请求包
372 | if((p_chkbox1.isSelected() && toolFlag ==4) || (i_chkbox1.isSelected() && toolFlag==32) || (r_chkbox1.isSelected() && toolFlag==64)){
373 | BurpExtender.this.request_Vul(messageInfo,toolFlag);
374 | }
375 |
376 | }
377 | }
378 |
379 | }
380 |
381 | }
382 |
383 | @Override
384 | public List doPassiveScan(IHttpRequestResponse baseRequestResponse) {
385 | return null;
386 | }
387 |
388 |
389 | @Override
390 | public List createMenuItems(final IContextMenuInvocation invocation) {
391 | //右键发送按钮功能
392 |
393 | List listMenuItems = new ArrayList();
394 | if(invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_REPEATER || invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_PROXY){
395 | //父级菜单
396 | IHttpRequestResponse[] responses = invocation.getSelectedMessages();
397 | JMenuItem jMenu_decode = new JMenuItem("Send to xia Jie decode");
398 | JMenuItem jMenu_encode = new JMenuItem("Send to xia Jie encode");
399 |
400 | jMenu_decode.addActionListener(new ActionListener() {
401 | @Override
402 | public void actionPerformed(ActionEvent e) {
403 | if(switchs == 1) {
404 | //不应在Swing事件调度线程中发出HTTP请求,所以需要创建一个Runnable并在 run() 方法中完成工作,后调用 new Thread(runnable).start() 来启动线程
405 | Thread thread = new Thread(new Runnable() {
406 | public void run() {
407 | try {
408 | data_return encode_data = BurpExtender.this.xj_decode(responses[0],true);
409 |
410 | byte[] body = encode_data.body.getBytes();
411 | byte[] newRequest = helpers.buildHttpMessage(encode_data.header,body);
412 | responses[0].setRequest(newRequest);//设置最终新的请求包
413 |
414 | } catch (Exception ex) {
415 | ex.printStackTrace();
416 | BurpExtender.this.stdout.println(ex);
417 | }
418 | }
419 | });
420 | thread.start();
421 | }else {
422 | BurpExtender.this.stdout.println("插件xia Jie关闭状态!");
423 | }
424 |
425 | }
426 | });
427 |
428 | jMenu_encode.addActionListener(new ActionListener() {
429 | @Override
430 | public void actionPerformed(ActionEvent e) {
431 | if(switchs == 1) {
432 | //不应在Swing事件调度线程中发出HTTP请求,所以需要创建一个Runnable并在 run() 方法中完成工作,后调用 new Thread(runnable).start() 来启动线程
433 | Thread thread = new Thread(new Runnable() {
434 | public void run() {
435 | try {
436 | data_return encode_data = BurpExtender.this.xj_encode(responses[0]);
437 |
438 | byte[] body = encode_data.body.getBytes();
439 | byte[] newRequest = helpers.buildHttpMessage(encode_data.header,body);
440 | responses[0].setRequest(newRequest);//设置最终新的请求包
441 |
442 | } catch (Exception ex) {
443 | ex.printStackTrace();
444 | BurpExtender.this.stdout.println(ex);
445 | }
446 | }
447 | });
448 | thread.start();
449 | }else {
450 | BurpExtender.this.stdout.println("插件xia Jie关闭状态!");
451 | }
452 |
453 | }
454 | });
455 | listMenuItems.add(jMenu_encode);
456 | listMenuItems.add(jMenu_decode);
457 | }
458 |
459 | return listMenuItems;
460 | }
461 |
462 | private void request_Vul(IHttpRequestResponse baseRequestResponse, int toolFlag){
463 | //log_ta.insert("请求包\n",0);
464 | String temp_data = String.valueOf(helpers.analyzeRequest(baseRequestResponse).getUrl());//url
465 | String[] temp_data_strarray=temp_data.split("\\?");
466 | temp_data =temp_data_strarray[0];//获取问号前面的字符串
467 |
468 | //检测白名单
469 | String[] white_URL_list = white_URL.split(",");
470 | int white_swith = 0;
471 | if(white_switchs == 1){
472 | white_swith = 0;
473 | for(int i=0;i doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {
632 | return null;
633 | }
634 |
635 | @Override
636 | public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) {
637 | if (existingIssue.getIssueName().equals(newIssue.getIssueName()))
638 | return -1;
639 | else return 0;
640 | }
641 |
642 | @Override
643 | public int getRowCount()
644 | {
645 | return log.size();
646 | }
647 |
648 | @Override
649 | public int getColumnCount()
650 | {
651 | return 5;
652 | }
653 |
654 | @Override
655 | public String getColumnName(int columnIndex)
656 | {
657 | switch (columnIndex)
658 | {
659 | case 0:
660 | return "#";
661 | case 1:
662 | return "来源";
663 | case 2:
664 | return "类型";
665 | case 3:
666 | return "URL";
667 | case 4:
668 | return "响应包长度";
669 | default:
670 | return "";
671 | }
672 | }
673 |
674 | @Override
675 | public Class> getColumnClass(int columnIndex)
676 | {
677 | return String.class;
678 | }
679 |
680 | @Override
681 | public Object getValueAt(int rowIndex, int columnIndex)
682 | {
683 | LogEntry logEntry = log.get(rowIndex);
684 |
685 | switch (columnIndex)
686 | {
687 | case 0:
688 | return logEntry.id;
689 | case 1:
690 | return callbacks.getToolName(logEntry.tool);
691 | case 2:
692 | return logEntry.Method;
693 | case 3:
694 | return logEntry.url;
695 | case 4:
696 | return logEntry.original_len;//返回响应包的长度
697 | default:
698 | return "";
699 | }
700 | }
701 |
702 |
703 |
704 | @Override
705 | public byte[] getRequest()
706 | {
707 | return currentlyDisplayedItem.getRequest();
708 | }
709 |
710 | @Override
711 | public byte[] getResponse()
712 | {
713 | return currentlyDisplayedItem.getResponse();
714 | }
715 |
716 | @Override
717 | public IHttpService getHttpService()
718 | {
719 | return currentlyDisplayedItem.getHttpService();
720 | }
721 |
722 | //表格选中设置
723 | private class Table extends JTable
724 | {
725 | public Table(TableModel tableModel)
726 | {
727 | super(tableModel);
728 | }
729 |
730 | @Override
731 | public void changeSelection(int row, int col, boolean toggle, boolean extend)
732 | {
733 | // show the log entry for the selected row
734 | LogEntry logEntry = log.get(row);
735 | select_row = row;//记录选中的行数
736 |
737 | //设置点击表格,打开对应数据包的界面
738 | tabs.setSelectedIndex(1);
739 | if(logEntry.tool == 4) {
740 | tabs_1.setEnabledAt(1, true);
741 | }else {
742 | tabs_1.setSelectedIndex(0);
743 | tabs_1.setEnabledAt(1, false);//标签不可用
744 | }
745 |
746 |
747 | requestViewer.setMessage(logEntry.requestResponse.getRequest(), true);
748 | responseViewer.setMessage(logEntry.requestResponse.getResponse(), false);
749 | proxy_decode_data_request.setText(logEntry.request_data);
750 | proxy_decode_data_response.setText(logEntry.response_data);
751 | currentlyDisplayedItem = logEntry.requestResponse;
752 |
753 | super.changeSelection(row, col, toggle, extend);
754 | }
755 | }
756 |
757 |
758 | private static class LogEntry
759 | {
760 | final int id;
761 | final String Method;
762 | final IHttpRequestResponsePersisted requestResponse;
763 | final String request_data;
764 | final String response_data;
765 | final String url;
766 | final int original_len;
767 | final int tool;
768 |
769 |
770 | LogEntry(int id,String Method, IHttpRequestResponsePersisted requestResponse,String request_data,String response_data, String url,int original_len,int tool)
771 | {
772 | this.id = id;
773 | this.Method = Method;
774 | this.requestResponse = requestResponse;
775 | this.request_data = request_data;
776 | this.response_data = response_data;
777 | this.url = url;
778 | this.original_len = original_len;
779 | this.tool = tool;
780 | }
781 |
782 | }
783 |
784 | //数据处理,用来返回多个值
785 | final class data_return
786 | {
787 | public List header;
788 | public String body;
789 |
790 | public data_return(List header, String body)
791 | {
792 | this.header = header;
793 | this.body = body;
794 | }
795 | }
796 |
797 | public data_return xj_encode(IHttpRequestResponse baseRequestResponse){
798 | // 使用 `Base64` 编码器对字符串进行编码
799 | Base64.Encoder encoder = Base64.getEncoder();
800 | // 解码编码数据
801 | Base64.Decoder decoder = Base64.getDecoder();
802 |
803 | //加密
804 | List headers = helpers.analyzeRequest(baseRequestResponse).getHeaders();
805 | String headers_data ="";//head头部信息
806 | for(int i=0;i New_headers= new ArrayList<>();
822 | String header_pattern="header=(.*?)[^&]*";//正则匹配字母,数字,特殊字符
823 | Pattern header_Pattern = Pattern.compile(header_pattern);// 创建 Pattern 对象
824 | Matcher header_matcher = header_Pattern.matcher(post_data);// 现在创建 matcher 对象
825 | if (header_matcher.find()) {
826 | //String[] headers_response_data = helpers.bytesToString(helpers.base64Decode(header_matcher.group().substring(7))).split("\n");
827 | String[] headers_response_data = new String(decoder.decode(header_matcher.group().substring(7))).split("\n");
828 | for(String head : headers_response_data){
829 | New_headers.add(head);
830 | }
831 | }
832 | //body
833 | String body_response_data="";
834 | String body_pattern="body=(.*?)[^&]*";//正则匹配字母,数字,特殊字符
835 | Pattern body_Pattern = Pattern.compile(body_pattern);// 创建 Pattern 对象
836 | Matcher body_matcher = body_Pattern.matcher(post_data);// 现在创建 matcher 对象
837 | if (body_matcher.find()) {
838 | //body_response_data = helpers.bytesToString(helpers.base64Decode(body_matcher.group().substring(5)));
839 | body_response_data = new String(decoder.decode(body_matcher.group().substring(5)));
840 | }
841 |
842 | return new data_return(New_headers,body_response_data);
843 | }
844 |
845 | public data_return xj_decode(IHttpRequestResponse baseRequestResponse,boolean messageIsRequest){
846 | // 使用 `Base64` 编码器对字符串进行编码
847 | Base64.Encoder encoder = Base64.getEncoder();
848 | // 解码编码数据
849 | Base64.Decoder decoder = Base64.getDecoder();
850 |
851 | List New_headers= new ArrayList<>();//header
852 | String body_response_data="";//body
853 |
854 | if(messageIsRequest){//请求包
855 | List headers = helpers.analyzeRequest(baseRequestResponse).getHeaders();
856 | String headers_data ="";//head头部信息
857 | for(int i=0;i headers = analyzedResponse.getHeaders();
896 | String headers_data ="";//head头部信息
897 | for(int i=0;i