diff --git a/src/config/CookieFinder.java b/src/config/CookieFinder.java new file mode 100644 index 0000000..6b8d643 --- /dev/null +++ b/src/config/CookieFinder.java @@ -0,0 +1,184 @@ +package config; + +import org.apache.commons.lang3.StringUtils; + +import com.bit4woo.utilbox.burp.HelperPlus; +import com.bit4woo.utilbox.utils.DomainUtils; +import com.bit4woo.utilbox.utils.UrlUtils; + +import burp.BurpExtender; +import burp.IHttpRequestResponse; +import burp.Methods; + +public class CookieFinder { + + + public static CookieRecorder getLatestCookieFromHistory(IHttpRequestResponse messageInfo) { + return getLatestHeaderFromHistory(messageInfo,"Cookie"); + } + + + public static CookieRecorder getLatestCookieFromHistory(String sourceUrl) { + return getLatestHeader(sourceUrl,null,BurpExtender.callbacks.getProxyHistory(),"Cookie"); + } + + public static CookieRecorder getLatestHeaderFromHistory(IHttpRequestResponse messageInfo,String headerName) { + String sourceUrl = BurpExtender.getHelperPlus().getFullURL(messageInfo).toString(); + String originUrl = BurpExtender.getHelperPlus().getHeaderValueOf(true,messageInfo,"Origin"); + + return getLatestHeader(sourceUrl,originUrl,BurpExtender.callbacks.getProxyHistory(),headerName); + } + + /** + * + * @param shortUrl + * @param originUrl + * @param historyMessages + * @param headerName + * @return + */ + public static CookieRecorder getLatestHeader(String sourceUrl,String originUrl, IHttpRequestResponse[] historyMessages, String headerName) { + CookieRecorder result = new CookieRecorder(); + + String shortUrl = UrlUtils.getBaseUrl(sourceUrl);//url格式标准化,以保证后面比较的准确性。 + shortUrl = HelperPlus.removeUrlDefaultPort(shortUrl);//url格式标准化,以保证后面比较的准确性。 + //String path = UrlUtils.getPath(sourceUrl); + String host = UrlUtils.getHost(shortUrl); + String rootDomain = null; + String originHost = null; + String originRootDomain = null; + + + if (DomainUtils.isValidDomainMayPort(host)) { + rootDomain = DomainUtils.getRootDomain(host); + } + + if (StringUtils.isNoneBlank(originUrl)) { + originHost = UrlUtils.getHost(originUrl); + + if (DomainUtils.isValidDomainMayPort(originHost)) { + originRootDomain = DomainUtils.getRootDomain(originHost); + } + } + + HelperPlus getter = new HelperPlus(BurpExtender.callbacks.getHelpers()); + + for (int i = historyMessages.length - 1; i >= 0; i--) { + IHttpRequestResponse historyMessage = historyMessages[i]; + String hisShortUrl = HelperPlus.getBaseURL(historyMessage).toString(); + hisShortUrl = HelperPlus.removeUrlDefaultPort(hisShortUrl); + + String hisHost = UrlUtils.getHost(shortUrl); + String hisRootDomain = null; + if (DomainUtils.isValidDomainMayPort(hisHost)) { + hisRootDomain = DomainUtils.getRootDomain(hisHost); + } + + //baseUrl完全相同 + if (hisShortUrl.equalsIgnoreCase(shortUrl)) { + String headerLine = getter.getHeaderLine(true, historyMessage, headerName); + if (StringUtils.isNotBlank(headerLine)){ + result.setSameSiteCookie(headerLine); + } + }else { + //host是domain + if (StringUtils.isNotBlank(rootDomain)) { + if (StringUtils.isNotBlank(hisRootDomain) && rootDomain.equalsIgnoreCase(hisRootDomain)) { + String headerLine = getter.getHeaderLine(true, historyMessage, headerName); + if (StringUtils.isNotBlank(headerLine)){ + result.setSameRootDomainCookie(headerLine); + } + } + }else { + //如果host是IP,可能出现IP和域名是同一个站点的情况。可以尝试查询相同路径的Cookie + + } + } + } + return result; + } + + + + /** + * 是否有必要从sitemap中获取,如果它是按照时间排序的话,还是有用的。后续测试一下//TODO + * + * @param shortUrl + * @param headerName + * @return + */ + public static CookieRecorder getLatestHeaderFromSiteMap(IHttpRequestResponse messageInfo) { + return getLatestHeaderFromSiteMap(messageInfo,"Cookie"); + } + + public static CookieRecorder getLatestHeaderFromSiteMap(IHttpRequestResponse messageInfo,String headerName) { + String sourceUrl = BurpExtender.getHelperPlus().getFullURL(messageInfo).toString(); + String shortUrl = HelperPlus.getBaseURL(messageInfo).toString(); + String originUrl = BurpExtender.getHelperPlus().getHeaderValueOf(true,messageInfo,"Origin"); + + //这里是否使用shortUrl,对后续有明显的影响,详细考虑逻辑TODO + return getLatestHeader(sourceUrl,originUrl,BurpExtender.callbacks.getSiteMap(shortUrl),headerName); + } + + + //Cookie: ISIC_SOP_DES_S22_NG_WEB=ISIC_SOP_DES_S22_NG_196_8; a_authorization_sit=18ac8987-2059-4a3b-a433-7def12dbae4d/97cd8cce-20ba-40df-ac44-0adae67ae2ad/BF32FB9F1479F653496C56DC99299483; custom.name=f12c5888-467d-49af-bcab-9cf4a44c03ff + //判断字符串是否是合格的cookie,每个分号分割的部分是否都是键值对格式。 + public static boolean isValidCookieString(String input) { + String cookieValue = input.trim(); + + if (cookieValue.startsWith("Cookie:")) { + cookieValue = cookieValue.replaceFirst("Cookie:", "").trim(); + } + + String[] items = cookieValue.split(";"); + for (String item : items) { + if (!item.contains("=")) { + return false; + } + } + return true; + } + + /** + * 返回的内容格式是一个header line + * + * @return + */ + public static String getLatestCookieFromUserInput() { + String domainOrCookie = Methods.prompt_and_validate_input("Cookie Value OR URL That Cookie From ", null); + String url1 = ""; + String url2 = ""; + try { + if (domainOrCookie == null) { + return null; + } else if (isValidCookieString(domainOrCookie)) {//直接是cookie + String cookieValue = domainOrCookie.trim(); + + if (!cookieValue.startsWith("Cookie:")) { + cookieValue = "Cookie: " + cookieValue; + } + return cookieValue; + } else if (domainOrCookie.startsWith("http://") || domainOrCookie.startsWith("https://")) {//不包含协议头的域名或url + url1 = domainOrCookie; + } else { + url1 = "http://" + domainOrCookie; + url2 = "https://" + domainOrCookie; + } + + try { + CookieRecorder recorder = getLatestCookieFromHistory(url1); + if (recorder.isAllBlank() && StringUtils.isNotBlank(url2)) { + recorder = getLatestCookieFromHistory(url2); + } + return recorder.getValue(); + } catch (Exception e) { + e.printStackTrace(BurpExtender.getStderr()); + } + } catch (Exception e) { + e.printStackTrace(BurpExtender.getStderr()); + Methods.show_message("Enter proper domain!!!", "Input Not Valid"); + } + return null; + } + +} diff --git a/src/config/CookieRecorder.java b/src/config/CookieRecorder.java new file mode 100644 index 0000000..1d1cb88 --- /dev/null +++ b/src/config/CookieRecorder.java @@ -0,0 +1,58 @@ +package config; + +import org.apache.commons.lang3.StringUtils; + +/** + * 根据当前请求信息,去查找可能的Cookie + * + */ +public class CookieRecorder { + String sameSiteCookie; //protocol+host+port都相同 + String sameRootDomainCookie; //rootDomain相同,比如统一登录的场景 + String sameOriginCookie;//好像还没有什么情况需要这种,后续再看 + String samePathCookie;//host不相同,但是URL Path相同 + + + public String getSameSiteCookie() { + return sameSiteCookie; + } + public void setSameSiteCookie(String sameSiteCookie) { + this.sameSiteCookie = sameSiteCookie; + } + public String getSameRootDomainCookie() { + return sameRootDomainCookie; + } + public void setSameRootDomainCookie(String sameRootDomainCookie) { + this.sameRootDomainCookie = sameRootDomainCookie; + } + public String getSamePathCookie() { + return samePathCookie; + } + public void setSamePathCookie(String samePathCookie) { + this.samePathCookie = samePathCookie; + } + + public boolean isAllBlank() { + return StringUtils.isAllBlank(sameSiteCookie,sameRootDomainCookie,samePathCookie); + } + + public String getValue() { + + String result = sameSiteCookie; + if (StringUtils.isNotBlank(result)) { + return result; + } + + result = sameRootDomainCookie; + if (StringUtils.isNotBlank(result)) { + return result; + } + + result = samePathCookie; + if (StringUtils.isNotBlank(result)) { + return result; + } + return null; + } + +} diff --git a/src/config/ProcessManager.java b/src/config/ProcessManager.java index 6ed3a4f..3b73fa2 100644 --- a/src/config/ProcessManager.java +++ b/src/config/ProcessManager.java @@ -3,12 +3,16 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; -import java.util.regex.MatchResult; -import burp.*; import org.apache.commons.lang3.StringUtils; import com.bit4woo.utilbox.burp.HelperPlus; +import com.bit4woo.utilbox.utils.DomainUtils; +import com.bit4woo.utilbox.utils.UrlUtils; + +import burp.BurpExtender; +import burp.IHttpRequestResponse; +import burp.Methods; public class ProcessManager { @@ -45,142 +49,6 @@ public static IHttpRequestResponse[] Reverse(IHttpRequestResponse[] input) { return input; } - public static String getLatestHeaderFromHistory(IHttpRequestResponse messageInfo, String headerName) { - String sourceshorturl = HelperPlus.getBaseURL(messageInfo).toString(); - return getLatestHeaderFromHistory(sourceshorturl, headerName); - } - - public static String getLatestHeaderFromHistory(String shortUrl, String headerName) { - //还是草粉师傅说得对,直接从history里面拿最好 - - shortUrl = HelperPlus.removeUrlDefaultPort(shortUrl);//url格式标准化,以保证后面比较的准确性。 - IHttpRequestResponse[] historyMessages = BurpExtender.callbacks.getProxyHistory(); - HelperPlus getter = new HelperPlus(BurpExtender.callbacks.getHelpers()); - - for (int i = historyMessages.length - 1; i >= 0; i--) { - IHttpRequestResponse historyMessage = historyMessages[i]; - String hisShortUrl = HelperPlus.getBaseURL(historyMessage).toString(); - hisShortUrl = HelperPlus.removeUrlDefaultPort(hisShortUrl); - if (hisShortUrl.equalsIgnoreCase(shortUrl)) { - String headerLine = getter.getHeaderLine(true, historyMessage, headerName); - if (StringUtils.isNotBlank(headerLine)){ - return headerLine; - } - } - } - return null; - } - - public static String getLatestCookieFromHistory(IHttpRequestResponse messageInfo) { - return getLatestHeaderFromHistory(messageInfo, "Cookie"); - } - - public static String getLatestCookieFromHistory(String shortUrl) { - return getLatestHeaderFromHistory(shortUrl, "Cookie"); - } - - /** - * 是否有必要从sitemap中获取,如果它是按照时间排序的话,还是有用的。后续测试一下//TODO - * - * @param shortUrl - * @param headerName - * @return - */ - public static String getLatestHeaderFromSiteMap(String shortUrl, String headerName) { - //还是草粉师傅说得对,直接从history里面拿最好 - - shortUrl = HelperPlus.removeUrlDefaultPort(shortUrl);//url格式标准化,以保证后面比较的准确性。 - IHttpRequestResponse[] historyMessages = BurpExtender.callbacks.getSiteMap(shortUrl); - HelperPlus getter = new HelperPlus(BurpExtender.callbacks.getHelpers()); - - for (int i = historyMessages.length - 1; i >= 0; i--) { - IHttpRequestResponse historyMessage = historyMessages[i]; - String hisShortUrl = HelperPlus.getBaseURL(historyMessage).toString(); - hisShortUrl = HelperPlus.removeUrlDefaultPort(hisShortUrl); - if (hisShortUrl.equalsIgnoreCase(shortUrl)) { - String headerLine = getter.getHeaderLine(true, historyMessage, headerName); - if (StringUtils.isNotBlank(headerLine)){ - return headerLine; - } - } - } - return null; - } - - public static String getLatestHeaderFromSiteMap(IHttpRequestResponse messageInfo, String headerName) { - String sourceshorturl = HelperPlus.getBaseURL(messageInfo).toString(); - return getLatestHeaderFromSiteMap(sourceshorturl, headerName); - } - - public static String getLatestHeaderFromSiteMap(IHttpRequestResponse messageInfo) { - return getLatestHeaderFromSiteMap(messageInfo, "Cookie"); - } - - public static String getLatestHeaderFromSiteMap(String shortUrl) { - return getLatestHeaderFromSiteMap(shortUrl, "Cookie"); - } - - - //Cookie: ISIC_SOP_DES_S22_NG_WEB=ISIC_SOP_DES_S22_NG_196_8; a_authorization_sit=18ac8987-2059-4a3b-a433-7def12dbae4d/97cd8cce-20ba-40df-ac44-0adae67ae2ad/BF32FB9F1479F653496C56DC99299483; custom.name=f12c5888-467d-49af-bcab-9cf4a44c03ff - //判断字符串是否是合格的cookie,每个分号分割的部分是否都是键值对格式。 - public static boolean isValidCookieString(String input) { - String cookieValue = input.trim(); - - if (cookieValue.startsWith("Cookie:")) { - cookieValue = cookieValue.replaceFirst("Cookie:", "").trim(); - } - - String[] items = cookieValue.split(";"); - for (String item : items) { - if (!item.contains("=")) { - return false; - } - } - return true; - } - - /** - * 返回的内容格式是一个header line - * - * @return - */ - public static String getLatestCookieFromUserInput() { - String domainOrCookie = Methods.prompt_and_validate_input("Cookie Value OR URL That Cookie From ", null); - String url1 = ""; - String url2 = ""; - try { - if (domainOrCookie == null) { - return null; - } else if (isValidCookieString(domainOrCookie)) {//直接是cookie - String cookieValue = domainOrCookie.trim(); - - if (!cookieValue.startsWith("Cookie:")) { - cookieValue = "Cookie: " + cookieValue; - } - return cookieValue; - } else if (domainOrCookie.startsWith("http://") || domainOrCookie.startsWith("https://")) {//不包含协议头的域名或url - url1 = domainOrCookie; - } else { - url1 = "http://" + domainOrCookie; - url2 = "https://" + domainOrCookie; - } - - try { - String latestCookie = getLatestCookieFromHistory(url1); - if (latestCookie == null && !url2.equals("")) { - latestCookie = getLatestCookieFromHistory(url2); - } - return latestCookie; - } catch (Exception e) { - e.printStackTrace(BurpExtender.getStderr()); - } - } catch (Exception e) { - e.printStackTrace(BurpExtender.getStderr()); - Methods.show_message("Enter proper domain!!!", "Input Not Valid"); - } - return null; - } - public static IHttpRequestResponse updateCookie(boolean messageIsRequest, IHttpRequestResponse messageInfo, String cookieValue) { return updateHeader(messageIsRequest, messageInfo, cookieValue); diff --git a/src/knife/SetCookieMenu.java b/src/knife/SetCookieMenu.java index b7d2259..c494eb3 100644 --- a/src/knife/SetCookieMenu.java +++ b/src/knife/SetCookieMenu.java @@ -11,6 +11,7 @@ import burp.IContextMenuInvocation; import burp.IExtensionHelpers; import burp.IHttpRequestResponse; +import config.CookieFinder; import config.ProcessManager; public class SetCookieMenu extends JMenuItem { @@ -45,7 +46,7 @@ public SetCookie_Action(BurpExtender burp,IContextMenuInvocation invocation) { public void actionPerformed(ActionEvent event) { try{ //stdout.println("SetCookie_Action called"); - String cookieEntry = ProcessManager.getLatestCookieFromUserInput(); + String cookieEntry = CookieFinder.getLatestCookieFromUserInput(); if (cookieEntry != null) {//当没有找到相应的cookie时为null IHttpRequestResponse[] messages = invocation.getSelectedMessages(); diff --git a/src/knife/UpdateCookieMenu.java b/src/knife/UpdateCookieMenu.java index 3e9226f..a95c5de 100644 --- a/src/knife/UpdateCookieMenu.java +++ b/src/knife/UpdateCookieMenu.java @@ -9,6 +9,8 @@ import com.bit4woo.utilbox.burp.HelperPlus; import burp.*; +import config.CookieFinder; +import config.CookieRecorder; import config.ProcessManager; public class UpdateCookieMenu extends JMenuItem { @@ -44,20 +46,15 @@ public void actionPerformed(ActionEvent event) { try { //stdout.println("UpdateCookieAction called"); IHttpRequestResponse[] selectedItems = invocation.getSelectedMessages(); - - String latestCookie = ProcessManager.getLatestCookieFromHistory(selectedItems[0]);//自行查找一次 - if (!isVaildCookie(latestCookie)) { - ProcessManager.getLatestHeaderFromSiteMap(selectedItems[0]);//自行查找一次 - } - - //通过弹窗交互 获取Cookie - int time = 0; - while (!isVaildCookie(latestCookie) && time <2) { - latestCookie = ProcessManager.getLatestCookieFromUserInput(); - time++; + CookieRecorder recorder = CookieFinder.getLatestCookieFromHistory(selectedItems[0]);//自行查找一次 + + if (recorder.isAllBlank()) { + recorder = CookieFinder.getLatestHeaderFromSiteMap(selectedItems[0]);//自行查找一次 } + //通过弹窗交互 获取Cookie的方式很不简便,不再使用! + String latestCookie = recorder.getValue(); if (isVaildCookie(latestCookie)) { try{ selectedItems[0] = ProcessManager.updateCookie(true,selectedItems[0], latestCookie); diff --git a/src/knife/UpdateHeaderMenu.java b/src/knife/UpdateHeaderMenu.java index 7756324..fea391d 100644 --- a/src/knife/UpdateHeaderMenu.java +++ b/src/knife/UpdateHeaderMenu.java @@ -19,6 +19,7 @@ import burp.IContextMenuInvocation; import burp.IExtensionHelpers; import burp.IHttpRequestResponse; +import config.CookieFinder; import config.GUI; import config.ProcessManager; @@ -117,7 +118,7 @@ public UpdateHeader_Action(BurpExtender burp,IContextMenuInvocation invocation,S public void actionPerformed(ActionEvent event) { if (invocation.getInvocationContext() == IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST) { IHttpRequestResponse[] selectedItems = invocation.getSelectedMessages(); - String headerLine = ProcessManager.getLatestHeaderFromHistory(selectedItems[0], headerName); + String headerLine = CookieFinder.getLatestHeaderFromHistory(selectedItems[0], headerName).getValue(); if (headerLine != null) { ProcessManager.updateHeader(true,selectedItems[0],headerLine);