|
1 | 1 | package burp;
|
2 | 2 |
|
3 |
| -import javax.swing.*; |
4 |
| -import javax.swing.table.AbstractTableModel; |
5 |
| -import javax.swing.table.TableModel; |
6 |
| -import java.awt.*; |
7 | 3 | import java.io.PrintWriter;
|
8 |
| -import java.net.URL; |
9 | 4 | import java.nio.charset.StandardCharsets;
|
10 | 5 | import java.util.ArrayList;
|
11 | 6 | import java.util.List;
|
12 | 7 |
|
13 |
| -public class BurpExtender extends AbstractTableModel implements IBurpExtender, ITab, IHttpListener, IMessageEditorController |
14 |
| -{ |
| 8 | +public class BurpExtender implements IBurpExtender,IScannerCheck{ |
| 9 | + |
15 | 10 | private IBurpExtenderCallbacks callbacks;
|
16 | 11 | private IExtensionHelpers helpers;
|
17 |
| - private JSplitPane splitPane; |
18 |
| - private IMessageEditor requestViewer; |
19 |
| - private IMessageEditor responseViewer; |
20 |
| - private final List<LogEntry> log = new ArrayList<LogEntry>(); |
21 |
| - private IHttpRequestResponse currentlyDisplayedItem; |
22 | 12 | private PrintWriter stdout;
|
23 | 13 | private PrintWriter stderr;
|
24 |
| - |
25 |
| - |
26 |
| - // |
27 |
| - // implement IBurpExtender |
28 |
| - // |
29 |
| - |
30 | 14 | @Override
|
31 |
| - public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) |
32 |
| - { |
33 |
| - // keep a reference to our callbacks object |
| 15 | + public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { |
34 | 16 | this.callbacks = callbacks;
|
| 17 | + this.helpers = callbacks.getHelpers(); |
| 18 | + callbacks.setExtensionName("Json Xss Finder"); |
| 19 | + callbacks.registerScannerCheck(this); |
35 | 20 |
|
36 | 21 | stdout = new PrintWriter(callbacks.getStdout(), true);
|
37 | 22 | stderr = new PrintWriter(callbacks.getStderr(), true);
|
38 |
| - // obtain an extension helpers object |
39 |
| - helpers = callbacks.getHelpers(); |
40 |
| - stdout.println(System.getProperty("user.dir")); |
41 |
| - stdout.println("Load Plugin Success"); |
42 |
| - |
43 |
| -// this.callbacks.restoreState(new File("xss.file")); |
44 |
| - |
45 |
| - // set our extension name |
46 |
| - callbacks.setExtensionName("Json Xss Finder"); |
47 |
| - |
48 |
| - |
49 |
| - // create our UI |
50 |
| - SwingUtilities.invokeLater(new Runnable() |
51 |
| - { |
52 |
| - @Override |
53 |
| - public void run() |
54 |
| - { |
55 |
| - // main split pane |
56 |
| - splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); |
57 |
| - |
58 |
| - // table of log entries |
59 |
| - Table logTable = new Table(BurpExtender.this); |
60 |
| - JScrollPane scrollPane = new JScrollPane(logTable);// add scroll |
61 |
| - splitPane.setLeftComponent(scrollPane); |
62 |
| - |
63 |
| - // tabs with request/response viewers |
64 |
| - JTabbedPane tabs = new JTabbedPane(); |
65 |
| - requestViewer = callbacks.createMessageEditor(BurpExtender.this, false); |
66 |
| - responseViewer = callbacks.createMessageEditor(BurpExtender.this, false); |
67 |
| - tabs.addTab("Request", requestViewer.getComponent()); |
68 |
| - tabs.addTab("Response", responseViewer.getComponent()); |
69 |
| - splitPane.setRightComponent(tabs); |
70 |
| - |
71 |
| - // customize our UI components |
72 |
| - callbacks.customizeUiComponent(splitPane); |
73 |
| - callbacks.customizeUiComponent(logTable); |
74 |
| - callbacks.customizeUiComponent(scrollPane); |
75 |
| - callbacks.customizeUiComponent(tabs); |
76 |
| - |
77 |
| - // add the custom tab to Burp's UI |
78 |
| - callbacks.addSuiteTab(BurpExtender.this); |
79 |
| - |
80 |
| - // register ourselves as an HTTP listener |
81 |
| - callbacks.registerHttpListener(BurpExtender.this); |
82 |
| - } |
83 |
| - }); |
84 |
| - } |
85 |
| - |
86 |
| - |
87 |
| - |
88 | 23 |
|
| 24 | + stdout.println(System.getProperty("user.dir")); |
| 25 | + stdout.println("Load Json Xss Finder Plugin Success"); |
89 | 26 |
|
90 | 27 |
|
91 |
| - // |
92 |
| - // implement ITab |
93 |
| - // |
94 | 28 |
|
95 |
| - @Override |
96 |
| - public String getTabCaption() |
97 |
| - { |
98 |
| - return "Json Xss Finder"; |
99 | 29 | }
|
100 | 30 |
|
101 |
| - @Override |
102 |
| - public Component getUiComponent() |
| 31 | + //todo getmatches and highlight |
| 32 | + private List<int[]> getMatches(byte[] response, byte[] match) |
103 | 33 | {
|
104 |
| - return splitPane; |
105 |
| - } |
| 34 | + List<int[]> matches = new ArrayList<int[]>(); |
106 | 35 |
|
107 |
| - // |
108 |
| - // implement IHttpListener |
109 |
| - // |
110 |
| - |
111 |
| - @Override |
112 |
| - public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) |
113 |
| - { |
114 |
| - // only process responses |
115 |
| - if (!messageIsRequest) |
| 36 | + int start = 0; |
| 37 | + while (start < response.length) |
116 | 38 | {
|
117 |
| - // create a new log entry with the message details |
118 |
| - synchronized(log) |
119 |
| - { |
120 |
| - IResponseInfo responseInfo = helpers.analyzeResponse(messageInfo.getResponse()); |
121 |
| - IRequestInfo requestInfo = helpers.analyzeRequest(messageInfo.getRequest()); |
122 |
| - |
123 |
| - String statedMimeType = responseInfo.getStatedMimeType(); |
124 |
| -// String inferredMimeType = responseInfo.getInferredMimeType(); burp has bug |
125 |
| - |
126 |
| - int bodyOffset = responseInfo.getBodyOffset(); |
127 |
| - String resp = new String(messageInfo.getResponse(), StandardCharsets.UTF_8); |
128 |
| - String rBody = resp.substring(bodyOffset); |
129 |
| - |
130 |
| - |
131 |
| - |
132 |
| - if(statedMimeType.equals("HTML")&&Utils.IsJSON(rBody)){ |
133 |
| - int row = log.size(); |
134 |
| - log.add(new LogEntry(requestInfo.getMethod(), callbacks.saveBuffersToTempFiles(messageInfo), |
135 |
| - helpers.analyzeRequest(messageInfo).getUrl())); |
136 |
| - fireTableRowsInserted(row, row); |
137 |
| - |
138 |
| - |
139 |
| - |
140 |
| - } |
141 |
| - |
142 |
| - } |
| 39 | + start = helpers.indexOf(response, match, true, start, response.length); |
| 40 | + if (start == -1) |
| 41 | + break; |
| 42 | + matches.add(new int[] { start, start + match.length }); |
| 43 | + start += match.length; |
143 | 44 | }
|
144 |
| - } |
145 | 45 |
|
146 |
| - // |
147 |
| - // extend AbstractTableModel |
148 |
| - // |
149 |
| - |
150 |
| - @Override |
151 |
| - public int getRowCount() |
152 |
| - { |
153 |
| - return log.size(); |
| 46 | + return matches; |
154 | 47 | }
|
155 | 48 |
|
156 | 49 | @Override
|
157 |
| - public int getColumnCount() |
158 |
| - { |
159 |
| - return 3; |
160 |
| - } |
| 50 | + public List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse) { |
161 | 51 |
|
162 |
| - @Override |
163 |
| - public String getColumnName(int columnIndex) |
164 |
| - { |
165 |
| - switch (columnIndex) |
166 |
| - { |
167 |
| - case 0: |
168 |
| - return "ID"; |
169 |
| - case 1: |
170 |
| - return "METHOD"; |
171 |
| - case 2: |
172 |
| - return "URL"; |
173 |
| - default: |
174 |
| - return ""; |
175 |
| - } |
176 |
| - } |
| 52 | + IResponseInfo iResponseInfo = helpers.analyzeResponse(baseRequestResponse.getResponse()); |
| 53 | + IRequestInfo iRequestInfo = helpers.analyzeRequest(baseRequestResponse.getRequest()); |
177 | 54 |
|
178 |
| - @Override |
179 |
| - public Class<?> getColumnClass(int columnIndex) |
180 |
| - { |
181 |
| - return String.class; |
182 |
| - } |
| 55 | + String stateMimeType = iResponseInfo.getStatedMimeType(); |
| 56 | + int rBodyOffset = iResponseInfo.getBodyOffset(); |
| 57 | + String resp = new String(baseRequestResponse.getResponse(), StandardCharsets.UTF_8); |
| 58 | + String rBody = resp.substring(rBodyOffset); |
183 | 59 |
|
184 |
| - @Override |
185 |
| - public Object getValueAt(int rowIndex, int columnIndex) |
186 |
| - { |
187 |
| - LogEntry logEntry = log.get(rowIndex); |
| 60 | + if(stateMimeType.equals("HTML")&&Utils.IsJSON(rBody)){ |
| 61 | + List<IScanIssue> issues = new ArrayList<>(1); |
| 62 | + issues.add(new CustomScanIssue(baseRequestResponse.getHttpService(),helpers.analyzeRequest(baseRequestResponse).getUrl(), |
| 63 | + new IHttpRequestResponse[]{callbacks.applyMarkers(baseRequestResponse, null, null)}, |
| 64 | + "Json Xss","Content-type: text/html","High")); |
| 65 | + |
| 66 | + return issues; |
188 | 67 |
|
189 |
| - switch (columnIndex) |
190 |
| - { |
191 |
| - case 0: |
192 |
| - return rowIndex; |
193 |
| - case 1: |
194 |
| - return logEntry.method; |
195 |
| - case 2: |
196 |
| - return logEntry.url.toString(); |
197 |
| - default: |
198 |
| - return ""; |
199 | 68 | }
|
200 |
| - } |
201 | 69 |
|
202 |
| - // |
203 |
| - // implement IMessageEditorController |
204 |
| - // this allows our request/response viewers to obtain details about the messages being displayed |
205 |
| - // |
206 |
| - |
207 |
| - @Override |
208 |
| - public byte[] getRequest() |
209 |
| - { |
210 |
| - return currentlyDisplayedItem.getRequest(); |
211 |
| - } |
212 | 70 |
|
213 |
| - @Override |
214 |
| - public byte[] getResponse() |
215 |
| - { |
216 |
| - return currentlyDisplayedItem.getResponse(); |
217 |
| - } |
218 | 71 |
|
219 |
| - @Override |
220 |
| - public IHttpService getHttpService() |
221 |
| - { |
222 |
| - return currentlyDisplayedItem.getHttpService(); |
| 72 | + return null; |
223 | 73 | }
|
224 | 74 |
|
225 |
| - // |
226 |
| - // extend JTable to handle cell selection |
227 |
| - // |
228 |
| - |
229 |
| - |
230 |
| - |
231 |
| - |
232 |
| - private class Table extends JTable |
233 |
| - { |
234 |
| - public Table(TableModel tableModel) |
235 |
| - { |
236 |
| - super(tableModel); |
237 |
| - } |
238 |
| - |
239 |
| - @Override |
240 |
| - public void changeSelection(int row, int col, boolean toggle, boolean extend) |
241 |
| - { |
242 |
| - // show the log entry for the selected row |
243 |
| - LogEntry logEntry = log.get(row); |
244 |
| - requestViewer.setMessage(logEntry.requestResponse.getRequest(), true); |
245 |
| - responseViewer.setMessage(logEntry.requestResponse.getResponse(), false); |
246 |
| - currentlyDisplayedItem = logEntry.requestResponse; |
247 |
| - |
248 |
| - super.changeSelection(row, col, toggle, extend); |
249 |
| - } |
250 |
| - |
251 |
| - |
| 75 | + @Override |
| 76 | + public List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) { |
| 77 | + return null; |
252 | 78 | }
|
253 |
| - |
254 |
| - // |
255 |
| - // class to hold details of each log entry |
256 |
| - // |
257 |
| - |
258 |
| - private static class LogEntry |
259 |
| - { |
260 |
| - final IHttpRequestResponsePersisted requestResponse; |
261 |
| - final URL url; |
262 |
| - final String method; |
263 | 79 |
|
264 |
| - LogEntry(String method, IHttpRequestResponsePersisted requestResponse, URL url) |
265 |
| - { |
266 |
| - this.method = method; |
267 |
| - this.requestResponse = requestResponse; |
268 |
| - this.url = url; |
269 |
| - } |
270 |
| - |
271 |
| - @Override |
272 |
| - public String toString() { |
273 |
| - return "LogEntry{" + |
274 |
| - "requestResponse=" + requestResponse + |
275 |
| - ", url=" + url + |
276 |
| - ", method='" + method + '\'' + |
277 |
| - '}'; |
278 |
| - } |
| 80 | + //todo |
| 81 | + @Override |
| 82 | + public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) { |
| 83 | + return 0; |
279 | 84 | }
|
280 | 85 | }
|
0 commit comments