From 4b0935a5c0a702f7cf787f915ee90e121b84d1b7 Mon Sep 17 00:00:00 2001 From: bit4woo Date: Sat, 13 Jul 2024 13:20:04 +0800 Subject: [PATCH] =?UTF-8?q?Info=20Tab=E6=93=8D=E4=BD=9C=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/FindUrlAction.java | 690 +++++++++++++------------ src/messageTab/Info/InfoTable.java | 23 +- src/messageTab/Info/InfoTableMenu.java | 113 ++-- 3 files changed, 433 insertions(+), 393 deletions(-) diff --git a/src/base/FindUrlAction.java b/src/base/FindUrlAction.java index 05f4c26..a9000aa 100644 --- a/src/base/FindUrlAction.java +++ b/src/base/FindUrlAction.java @@ -8,17 +8,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import javax.swing.JOptionPane; -import burp.*; import org.apache.commons.lang3.StringUtils; import com.bit4woo.utilbox.burp.HelperPlus; @@ -26,340 +22,356 @@ import com.bit4woo.utilbox.utils.TextUtils; import com.bit4woo.utilbox.utils.UrlUtils; +import burp.BurpExtender; +import burp.IBurpExtenderCallbacks; +import burp.IContextMenuInvocation; +import burp.IExtensionHelpers; +import burp.IHttpRequestResponse; +import burp.IHttpService; +import burp.threadRequester; + public class FindUrlAction implements ActionListener { - private IContextMenuInvocation invocation; - public IExtensionHelpers helpers; - public PrintWriter stdout; - public PrintWriter stderr; - public IBurpExtenderCallbacks callbacks; - public BurpExtender burp; - - public static final String[] blackHostList = {"www.w3.org", "ns.adobe.com", "iptc.org", "openoffice.org" - , "schemas.microsoft.com", "schemas.openxmlformats.org", "sheetjs.openxmlformats.org", "registry.npmjs.org" - , "json-schema.org", "jmespath.org"}; - - public static final List blackPath = TextUtils.textToLines("text/css\r\n" - + " text/html\r\n" - + " text/plain\r\n" - + " image/pdf\r\n"); - - - public static Proxy CurrentProxy; - public static HashMap httpServiceBaseUrlMap = new HashMap<>(); - - public FindUrlAction(BurpExtender burp, IContextMenuInvocation invocation) { - this.burp = burp; - this.invocation = invocation; - this.helpers = BurpExtender.helpers; - this.callbacks = BurpExtender.callbacks; - } - - - public static void doSendRequest(String baseurl, List urlPath, String refererToUse) { - try { - BlockingQueue inputQueue = new LinkedBlockingQueue<>(); - - try { - for (String url : urlPath) { - if (!url.startsWith("http://") && !url.startsWith("https://")) { - if (url.startsWith("/")) { - url = url.replaceFirst("/", ""); - } - if (url.startsWith("./")) { - url = url.replaceFirst("\\./", ""); - } - url = baseurl + url; //baseurl统一以“/”结尾;url统一删除“/”的开头 - inputQueue.put(new RequestTask(url, RequestType.GET)); - - if (url.toLowerCase().endsWith(".js") || url.toLowerCase().endsWith(".html")) { - //不严谨,TODO应该判断path - } else { - inputQueue.put(new RequestTask(url, RequestType.POST)); - inputQueue.put(new RequestTask(url, RequestType.JSON)); - } - } - } - } catch (Exception e) { - e.printStackTrace(BurpExtender.getStderr()); - } - - doRequest(inputQueue, refererToUse); - } catch (Exception e1) { - e1.printStackTrace(BurpExtender.getStderr()); - } - } - - @Override - public void actionPerformed(ActionEvent event) { - Runnable requestRunner = new Runnable() { - @Override - public void run() { - IHttpRequestResponse[] messages = invocation.getSelectedMessages(); - if (messages == null || messages.length == 0) { - return; - } - String targetBaseUrl = getTargetSiteBaseUrl(messages[0]); - - List urls = FindAllUrlsOfTarget(targetBaseUrl); - - String baseurl = choseAndEditBaseURL(urls); - - if (null == baseurl) { - return; - } - - httpServiceBaseUrlMap.put(targetBaseUrl, baseurl); - - urls = choseURLPath(urls); - if (urls.size() == 0) return; - - doSendRequest(baseurl, urls, targetBaseUrl); - } - }; - new Thread(requestRunner).start(); - } - - /** - * 根据当前web的baseUrl找JS,特征就是referer以它开头 - * - * @return - */ - public static List FindAllUrlsOfTarget(IHttpService httpService, byte[] request, byte[] response) { - String targetBaseUrl = getTargetSiteBaseUrl(httpService, request); - return FindAllUrlsOfTarget(targetBaseUrl); - } - - - public static List FindAllUrlsOfTarget(String targetBaseUrl) { - List urls = new ArrayList<>(); - urls.add(targetBaseUrl); - //List urls = findUrls(response); - //siteMap中应该也会包含这个请求的 - - HelperPlus getter = BurpExtender.getHelperPlus(); - IHttpRequestResponse[] messages = BurpExtender.getCallbacks().getSiteMap(null); - for (IHttpRequestResponse item : messages) { - if (item == null || item.getResponse() == null) { - continue; - } - int code = getter.getStatusCode(item); - if (code != 200) { - continue; - } - - URL url = getter.getFullURL(item); - if (url == null) { - continue; - } - - String referUrl = getter.getHeaderValueOf(true, item, "Referer"); - //JS请求必然有referer,js.map请求则没有referer,首页的.html请求也没有 - if (url.toString().toLowerCase().endsWith(".js")) { - if (referUrl == null) { - continue; - } - if (referUrl.toLowerCase().startsWith(targetBaseUrl.toLowerCase())) { - urls.addAll(findUrls(item.getResponse())); - } - } - //没必要处理js.map。 - if (url.toString().toLowerCase().endsWith(".js.map")) { - - } - - if (!url.toString().toLowerCase().endsWith(".html")) { - if (referUrl == null) { - if (url.toString().toLowerCase().startsWith(targetBaseUrl.toLowerCase())) { - urls.addAll(findUrls(item.getResponse())); - } - } else { - if (referUrl.toLowerCase().startsWith(targetBaseUrl.toLowerCase())) { - urls.addAll(findUrls(item.getResponse())); - } - } - } - } - return urls; - } - - - /** - * 一个数据包,确定它的【来源】 - * - * @param message - * @return - */ - public static String getTargetSiteBaseUrl(IHttpRequestResponse message) { - return getTargetSiteBaseUrl(message.getHttpService(), message.getRequest()); - } - - - public static String getTargetSiteBaseUrl(IHttpService httpService, byte[] request) { - HelperPlus getter = BurpExtender.getHelperPlus(); - - String current_referUrl = getter.getHeaderValueOf(true, request, "Referer"); - String current_fullUrl = getter.getFullURL(httpService, request).toString(); - - if (current_referUrl != null) { - //认为当前数据包是前端触发的 - return UrlUtils.getBaseUrl(current_referUrl); - } else { - //认为其是当前数据包是浏览器地址栏访问直接触发的 - return UrlUtils.getBaseUrl(current_fullUrl); - } - } - - - public static List findUrls(byte[] content) { - List urls = new ArrayList<>(); - - if (content == null) { - return urls; - } else { - return findUrls(new String(content)); - } - } - - /** - * 在数据包中查找URL - * - * @param content - * @return - */ - public static List findUrls(String content) { - List urls = new ArrayList<>(); - if (StringUtils.isEmpty(content)) { - return urls; - } - - content = TextUtils.decodeAll(content); - urls.addAll(UrlUtils.grepUrlsWithProtocol(content)); - urls.addAll(UrlUtils.grepUrlPathNotStartWithSlashInQuotes(content)); - urls.addAll(UrlUtils.grepUrlsInQuotes(content)); - urls = cleanUrls(urls); - - return urls; - } - - /** - * 多线程执行请求 - * - * @param inputQueue - */ - public static void doRequest(BlockingQueue inputQueue, String referUrl) { - if (CurrentProxy == null) { - CurrentProxy = Proxy.inputProxy(); - } - if (CurrentProxy == null) { - return; - } - - int max = threadNumberShouldUse(inputQueue.size()); - - for (int i = 0; i <= max; i++) { - threadRequester requester = new threadRequester(inputQueue, CurrentProxy.getHost(), CurrentProxy.getPort(), referUrl, i); - requester.start(); - } - } - - /** - * 根据已有的域名梳理,预估应该使用的线程数 - * 假设1个任务需要1秒钟。线程数在1-100之间,如何选择线程数使用最小的时间? - * - * @param domainNum - * @return - */ - public static int threadNumberShouldUse(int domainNum) { - - int tmp = (int) Math.sqrt(domainNum); - if (tmp <= 1) { - return 1; - } else if (tmp >= 10) { - return 10; - } else { - return tmp; - } - } - - public static List findPossibleBaseURL(List urls) { - List baseURLs = new ArrayList<>(); - for (String tmpurl : urls) { - //这部分提取的是含有协议头的完整URL地址 - if (tmpurl.toLowerCase().startsWith("http://") - || tmpurl.toLowerCase().startsWith("https://")) { - if (!baseURLs.contains(tmpurl)) { - baseURLs.add(tmpurl); - } - } - } - return baseURLs; - } - - - public static String choseAndEditBaseURL(List inputs) { - - Collections.sort(inputs); - inputs = findPossibleBaseURL(inputs); - - int n = inputs.size() + 1; - String[] possibleValues = new String[n]; - - // Copying contents of domains to arr[] - System.arraycopy(inputs.toArray(), 0, possibleValues, 0, n - 1); - possibleValues[n - 1] = "Let Me Input"; - - String selectedValue = (String) JOptionPane.showInputDialog(null, - "Chose Base URL", "Chose And Edit Base URL", - JOptionPane.INFORMATION_MESSAGE, null, - possibleValues, possibleValues[0]); - if (null != selectedValue) { - String baseUrl = JOptionPane.showInputDialog("Confirm The Base URL", selectedValue); - if (baseUrl == null) { - return null; - } - if (!baseUrl.endsWith("/")) { - baseUrl = baseUrl.trim() + "/"; - } - return baseUrl.trim(); - } - return selectedValue; - } - - - public static List choseURLPath(List urls) { - - Collections.sort(urls); - - String text = SwingUtils.showTextAreaDialog(String.join(System.lineSeparator(), urls)); - if (StringUtils.isEmpty(text)) { - return new ArrayList(); - } else { - return TextUtils.textToLines(text); - } - } - - - public static List cleanUrls(List urls) { - - urls = TextUtils.deduplicate(urls); - Iterator it = urls.iterator(); - while (it.hasNext()) { - String urlItem = it.next(); - if (UrlUtils.uselessExtension(urlItem)) { - it.remove(); - } - if (blackPath.contains(urlItem)) { - it.remove(); - } - try { - String host = new URL(urlItem).getHost(); - if (Arrays.asList(blackHostList).contains(host)) { - it.remove(); - } - } catch (Exception E) { - continue; - } - } - return urls; - } + private IContextMenuInvocation invocation; + public IExtensionHelpers helpers; + public PrintWriter stdout; + public PrintWriter stderr; + public IBurpExtenderCallbacks callbacks; + public BurpExtender burp; + + public static final String[] blackHostList = {"www.w3.org", "ns.adobe.com", "iptc.org", "openoffice.org" + , "schemas.microsoft.com", "schemas.openxmlformats.org", "sheetjs.openxmlformats.org", "registry.npmjs.org" + , "json-schema.org", "jmespath.org"}; + + public static final List blackPath = TextUtils.textToLines("text/css\r\n" + + " text/html\r\n" + + " text/plain\r\n" + + " image/pdf\r\n"); + + + public static Proxy CurrentProxy; + public static HashMap httpServiceBaseUrlMap = new HashMap<>(); + + public FindUrlAction(BurpExtender burp, IContextMenuInvocation invocation) { + this.burp = burp; + this.invocation = invocation; + this.helpers = BurpExtender.helpers; + this.callbacks = BurpExtender.callbacks; + } + + public static List buildUrls(String baseurl, List urlPath){ + List result = new ArrayList<>(); + + for (String url : urlPath) { + if (!url.startsWith("http://") && !url.startsWith("https://")) { + if (url.startsWith("/")) { + url = url.replaceFirst("/", ""); + } + if (url.startsWith("./")) { + url = url.replaceFirst("\\./", ""); + } + url = baseurl + url; //baseurl统一以“/”结尾;url统一删除“/”的开头 + result.add(url); + } + } + return result; + } + + public static void doSendRequest(List full_urls, String refererToUse) { + try { + BlockingQueue inputQueue = new LinkedBlockingQueue<>(); + + try { + for (String url : full_urls) { + inputQueue.put(new RequestTask(url, RequestType.GET)); + + if (url.toLowerCase().endsWith(".js") || url.toLowerCase().endsWith(".html")) { + //不严谨,TODO应该判断path + } else { + inputQueue.put(new RequestTask(url, RequestType.POST)); + inputQueue.put(new RequestTask(url, RequestType.JSON)); + } + } + } catch (Exception e) { + e.printStackTrace(BurpExtender.getStderr()); + } + + doRequest(inputQueue, refererToUse); + } catch (Exception e1) { + e1.printStackTrace(BurpExtender.getStderr()); + } + } + + @Override + public void actionPerformed(ActionEvent event) { + Runnable requestRunner = new Runnable() { + @Override + public void run() { + IHttpRequestResponse[] messages = invocation.getSelectedMessages(); + if (messages == null || messages.length == 0) { + return; + } + String targetBaseUrl = getTargetSiteBaseUrl(messages[0]); + + List urls = FindAllUrlsOfTarget(targetBaseUrl); + + String baseurl = choseAndEditBaseURL(urls); + + if (null == baseurl) { + return; + } + + httpServiceBaseUrlMap.put(targetBaseUrl, baseurl); + + urls = choseURLPath(urls); + if (urls.size() == 0) return; + List full_urls = buildUrls(baseurl, urls); + doSendRequest(full_urls, targetBaseUrl); + } + }; + new Thread(requestRunner).start(); + } + + /** + * 根据当前web的baseUrl找JS,特征就是referer以它开头 + * + * @return + */ + public static List FindAllUrlsOfTarget(IHttpService httpService, byte[] request, byte[] response) { + String targetBaseUrl = getTargetSiteBaseUrl(httpService, request); + return FindAllUrlsOfTarget(targetBaseUrl); + } + + + public static List FindAllUrlsOfTarget(String targetBaseUrl) { + List urls = new ArrayList<>(); + urls.add(targetBaseUrl); + //List urls = findUrls(response); + //siteMap中应该也会包含这个请求的 + + HelperPlus getter = BurpExtender.getHelperPlus(); + IHttpRequestResponse[] messages = BurpExtender.getCallbacks().getSiteMap(null); + for (IHttpRequestResponse item : messages) { + if (item == null || item.getResponse() == null) { + continue; + } + int code = getter.getStatusCode(item); + if (code != 200) { + continue; + } + + URL url = getter.getFullURL(item); + if (url == null) { + continue; + } + + String referUrl = getter.getHeaderValueOf(true, item, "Referer"); + //JS请求必然有referer,js.map请求则没有referer,首页的.html请求也没有 + if (url.toString().toLowerCase().endsWith(".js")) { + if (referUrl == null) { + continue; + } + if (referUrl.toLowerCase().startsWith(targetBaseUrl.toLowerCase())) { + urls.addAll(findUrls(item.getResponse())); + } + } + //没必要处理js.map。 + if (url.toString().toLowerCase().endsWith(".js.map")) { + + } + + if (!url.toString().toLowerCase().endsWith(".html")) { + if (referUrl == null) { + if (url.toString().toLowerCase().startsWith(targetBaseUrl.toLowerCase())) { + urls.addAll(findUrls(item.getResponse())); + } + } else { + if (referUrl.toLowerCase().startsWith(targetBaseUrl.toLowerCase())) { + urls.addAll(findUrls(item.getResponse())); + } + } + } + } + return urls; + } + + + /** + * 一个数据包,确定它的【来源】 + * + * @param message + * @return + */ + public static String getTargetSiteBaseUrl(IHttpRequestResponse message) { + return getTargetSiteBaseUrl(message.getHttpService(), message.getRequest()); + } + + + public static String getTargetSiteBaseUrl(IHttpService httpService, byte[] request) { + HelperPlus getter = BurpExtender.getHelperPlus(); + + String current_referUrl = getter.getHeaderValueOf(true, request, "Referer"); + String current_fullUrl = getter.getFullURL(httpService, request).toString(); + + if (current_referUrl != null) { + //认为当前数据包是前端触发的 + return UrlUtils.getBaseUrl(current_referUrl); + } else { + //认为其是当前数据包是浏览器地址栏访问直接触发的 + return UrlUtils.getBaseUrl(current_fullUrl); + } + } + + + public static List findUrls(byte[] content) { + List urls = new ArrayList<>(); + + if (content == null) { + return urls; + } else { + return findUrls(new String(content)); + } + } + + /** + * 在数据包中查找URL + * + * @param content + * @return + */ + public static List findUrls(String content) { + List urls = new ArrayList<>(); + if (StringUtils.isEmpty(content)) { + return urls; + } + + content = TextUtils.decodeAll(content); + urls.addAll(UrlUtils.grepUrlsWithProtocol(content)); + urls.addAll(UrlUtils.grepUrlPathNotStartWithSlashInQuotes(content)); + urls.addAll(UrlUtils.grepUrlsInQuotes(content)); + urls = cleanUrls(urls); + + return urls; + } + + /** + * 多线程执行请求 + * + * @param inputQueue + */ + public static void doRequest(BlockingQueue inputQueue, String referUrl) { + if (CurrentProxy == null) { + CurrentProxy = Proxy.inputProxy(); + } + if (CurrentProxy == null) { + return; + } + + int max = threadNumberShouldUse(inputQueue.size()); + + for (int i = 0; i <= max; i++) { + threadRequester requester = new threadRequester(inputQueue, CurrentProxy.getHost(), CurrentProxy.getPort(), referUrl, i); + requester.start(); + } + } + + /** + * 根据已有的域名梳理,预估应该使用的线程数 + * 假设1个任务需要1秒钟。线程数在1-100之间,如何选择线程数使用最小的时间? + * + * @param domainNum + * @return + */ + public static int threadNumberShouldUse(int domainNum) { + + int tmp = (int) Math.sqrt(domainNum); + if (tmp <= 1) { + return 1; + } else if (tmp >= 10) { + return 10; + } else { + return tmp; + } + } + + public static List findPossibleBaseURL(List urls) { + List baseURLs = new ArrayList<>(); + for (String tmpurl : urls) { + //这部分提取的是含有协议头的完整URL地址 + if (tmpurl.toLowerCase().startsWith("http://") + || tmpurl.toLowerCase().startsWith("https://")) { + if (!baseURLs.contains(tmpurl)) { + baseURLs.add(tmpurl); + } + } + } + return baseURLs; + } + + + public static String choseAndEditBaseURL(List inputs) { + + Collections.sort(inputs); + inputs = findPossibleBaseURL(inputs); + + int n = inputs.size() + 1; + String[] possibleValues = new String[n]; + + // Copying contents of domains to arr[] + System.arraycopy(inputs.toArray(), 0, possibleValues, 0, n - 1); + possibleValues[n - 1] = "Let Me Input"; + + String selectedValue = (String) JOptionPane.showInputDialog(null, + "Chose Base URL", "Chose And Edit Base URL", + JOptionPane.INFORMATION_MESSAGE, null, + possibleValues, possibleValues[0]); + if (null != selectedValue) { + String baseUrl = JOptionPane.showInputDialog("Confirm The Base URL", selectedValue); + if (baseUrl == null) { + return null; + } + if (!baseUrl.endsWith("/")) { + baseUrl = baseUrl.trim() + "/"; + } + return baseUrl.trim(); + } + return selectedValue; + } + + + public static List choseURLPath(List urls) { + + Collections.sort(urls); + + String text = SwingUtils.showTextAreaDialog(String.join(System.lineSeparator(), urls)); + if (StringUtils.isEmpty(text)) { + return new ArrayList(); + } else { + return TextUtils.textToLines(text); + } + } + + + public static List cleanUrls(List urls) { + + urls = TextUtils.deduplicate(urls); + Iterator it = urls.iterator(); + while (it.hasNext()) { + String urlItem = it.next(); + if (UrlUtils.uselessExtension(urlItem)) { + it.remove(); + } + if (blackPath.contains(urlItem)) { + it.remove(); + } + try { + String host = new URL(urlItem).getHost(); + if (Arrays.asList(blackHostList).contains(host)) { + it.remove(); + } + } catch (Exception E) { + continue; + } + } + return urls; + } } diff --git a/src/messageTab/Info/InfoTable.java b/src/messageTab/Info/InfoTable.java index cd02a70..a931080 100644 --- a/src/messageTab/Info/InfoTable.java +++ b/src/messageTab/Info/InfoTable.java @@ -19,7 +19,6 @@ import org.apache.commons.lang3.StringUtils; import com.bit4woo.utilbox.utils.SystemUtils; -import com.bit4woo.utilbox.utils.UrlUtils; import base.FindUrlAction; import burp.BurpExtender; @@ -125,8 +124,8 @@ public void mouseClicked(MouseEvent e) { int row = target.getSelectedRow(); int column = target.getSelectedColumn(); - //双击浏览器打开url - if (headers[column].equalsIgnoreCase("Value")) {//双击url在浏览器中打开 + //双击浏览器打开url,弃用 + if (headers[column].equalsIgnoreCase("Value____xxxxxxx")) {//双击url在浏览器中打开 try { InfoEntry entry = getEntryAt(row); if (entry.getType().equals(InfoEntry.Type_URL)) { @@ -182,7 +181,7 @@ public String choseBaseUrlToRequest(List allUrlsOfTarget) { return FindUrlAction.choseAndEditBaseURL(allUrlsOfTarget); } - public void doRequestUrl(List urlsToRequest) { + public String getOrFindBaseUrl() { String targetBaseUrl = getTargetBaseUrl(); String baseurl = FindUrlAction.httpServiceBaseUrlMap.get(targetBaseUrl); @@ -192,8 +191,22 @@ public void doRequestUrl(List urlsToRequest) { FindUrlAction.httpServiceBaseUrlMap.put(targetBaseUrl, baseurl); } } + return baseurl; + } + + public void doRequestUrl(List urlsToRequest) { + String targetBaseUrl = getOrFindBaseUrl(); + List full_urls = FindUrlAction.buildUrls(targetBaseUrl, urlsToRequest); + FindUrlAction.doSendRequest(full_urls, targetBaseUrl); + } - FindUrlAction.doSendRequest(baseurl, urlsToRequest, targetBaseUrl); + public void doOpenUrlInBrowser(List urlsToRequest) { + String targetBaseUrl = getOrFindBaseUrl(); + List full_urls = FindUrlAction.buildUrls(targetBaseUrl, urlsToRequest); + String browserPath = BurpExtender.getConfigTableModel().getConfigValueByKey("browserPath"); + for (String url:full_urls) { + SystemUtils.browserOpen(url, browserPath); + } } public List getSelectedUrls() { diff --git a/src/messageTab/Info/InfoTableMenu.java b/src/messageTab/Info/InfoTableMenu.java index d946e6d..ce071ab 100644 --- a/src/messageTab/Info/InfoTableMenu.java +++ b/src/messageTab/Info/InfoTableMenu.java @@ -1,59 +1,74 @@ package messageTab.Info; -import base.FindUrlAction; -import com.bit4woo.utilbox.utils.SystemUtils; -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; import java.awt.event.ActionEvent; import java.util.List; +import javax.swing.AbstractAction; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; + +import org.apache.commons.lang3.StringUtils; + +import com.bit4woo.utilbox.utils.SystemUtils; + +import base.FindUrlAction; + public class InfoTableMenu extends JPopupMenu { - private static final long serialVersionUID = 1L; - /** - * 这处理传入的行index数据是经过转换的 model中的index,不是原始的JTable中的index。 - * - * @param infoTable - */ - InfoTableMenu(final InfoTable infoTable) { - - JMenuItem numItem = new JMenuItem(infoTable.getSelectedRows().length + " items selected"); - - JMenuItem copyItem = new JMenuItem(new AbstractAction("Copy") { - @Override - public void actionPerformed(ActionEvent actionEvent) { - String content = infoTable.getSelectedContent(); - SystemUtils.writeToClipboard(content); - } - }); - - JMenuItem changeBaseUrlItem = new JMenuItem(new AbstractAction("Set/Change Base URL") { - @Override - public void actionPerformed(ActionEvent actionEvent) { - String targetBaseUrl = infoTable.getTargetBaseUrl(); - List allUrlsOfTarget = infoTable.getAllUrlsOfTarget(); - String baseurl = infoTable.choseBaseUrlToRequest(allUrlsOfTarget); - - if (StringUtils.isNotEmpty(targetBaseUrl) && StringUtils.isNotEmpty(baseurl)) { - FindUrlAction.httpServiceBaseUrlMap.put(targetBaseUrl, baseurl); - } - } - }); - - JMenuItem doRequestItem = new JMenuItem(new AbstractAction("Do Request") { - @Override - public void actionPerformed(ActionEvent actionEvent) { - List urls = infoTable.getSelectedUrls(); - infoTable.doRequestUrl(urls); - } - }); - - add(numItem); - add(copyItem); - add(doRequestItem); - add(changeBaseUrlItem); - } + private static final long serialVersionUID = 1L; + /** + * 这处理传入的行index数据是经过转换的 model中的index,不是原始的JTable中的index。 + * + * @param infoTable + */ + InfoTableMenu(final InfoTable infoTable) { + + JMenuItem numItem = new JMenuItem(infoTable.getSelectedRows().length + " items selected"); + + JMenuItem copyItem = new JMenuItem(new AbstractAction("Copy (double click)") { + @Override + public void actionPerformed(ActionEvent actionEvent) { + String content = infoTable.getSelectedContent(); + SystemUtils.writeToClipboard(content); + } + }); + + JMenuItem changeBaseUrlItem = new JMenuItem(new AbstractAction("Set/Change Base URL") { + @Override + public void actionPerformed(ActionEvent actionEvent) { + String targetBaseUrl = infoTable.getTargetBaseUrl(); + List allUrlsOfTarget = infoTable.getAllUrlsOfTarget(); + String baseurl = infoTable.choseBaseUrlToRequest(allUrlsOfTarget); + + if (StringUtils.isNotEmpty(targetBaseUrl) && StringUtils.isNotEmpty(baseurl)) { + FindUrlAction.httpServiceBaseUrlMap.put(targetBaseUrl, baseurl); + } + } + }); + + JMenuItem doRequestItem = new JMenuItem(new AbstractAction("Request URL With Burp Proxy") { + @Override + public void actionPerformed(ActionEvent actionEvent) { + List urls = infoTable.getSelectedUrls(); + infoTable.doRequestUrl(urls); + } + }); + + + JMenuItem openInBrowerItem = new JMenuItem(new AbstractAction("Open URL In Brower") { + @Override + public void actionPerformed(ActionEvent actionEvent) { + List urls = infoTable.getSelectedUrls(); + infoTable.doOpenUrlInBrowser(urls); + } + }); + + add(numItem); + add(copyItem); + add(doRequestItem); + add(openInBrowerItem); + add(changeBaseUrlItem); + } }