From 0043f098b0b2ac69f6d1a3262bbfb7cdbaef6beb Mon Sep 17 00:00:00 2001 From: f0ng <422342338@qq.com> Date: Mon, 22 May 2023 17:27:13 +0800 Subject: [PATCH] Add files via upload --- src/Utils/Utils.java | 176 ++++++++++++++ src/burp/BurpExtender.java | 272 ++------------------- src/burp/ui/HackvertorInput.java | 38 +++ src/burp/ui/iMessageEditorTab.java | 378 +++++++++++++++++++++++++++++ src/burp/util/BurpCallbacks.java | 100 ++++++++ 5 files changed, 709 insertions(+), 255 deletions(-) create mode 100644 src/Utils/Utils.java create mode 100644 src/burp/ui/HackvertorInput.java create mode 100644 src/burp/ui/iMessageEditorTab.java create mode 100644 src/burp/util/BurpCallbacks.java diff --git a/src/Utils/Utils.java b/src/Utils/Utils.java new file mode 100644 index 0000000..84e86bb --- /dev/null +++ b/src/Utils/Utils.java @@ -0,0 +1,176 @@ +package Utils; + +import burp.BurpExtender; +import burp.IHttpRequestResponse; +import burp.IRequestInfo; +import burp.ui.HackvertorInput; +//import burp.util.BurpCallbacks; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.fife.ui.rtextarea.RTextArea; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.List; + +/** + * @DESCRIPTION: + * @USER: f0ng + * @DATE: 2023/5/21 下午1:57 + */ +public class Utils { + + private static JPopupMenu menu; + + private static JMenuItem menuRepeater; + private static JMenuItem menuReissue; + private static JMenuItem menuCopy; + private static JMenuItem menuCopySmart; + + public static void applyThemeToRSyntaxTextArea(RSyntaxTextArea area, String themeName) { + try { + Theme theme = Theme.load(Utils.class.getResourceAsStream( + "/org/fife/ui/rsyntaxtextarea/themes/"+themeName+".xml")); + theme.apply(area); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + public static void configureRSyntaxArea(RSyntaxTextArea area) { + area.setLineWrap(true); + if(BurpExtender.isDarkTheme) { + Utils.applyThemeToRSyntaxTextArea(area, "dark"); + } + BurpExtender.callbacks.customizeUiComponent(area); + area.setFont(new Font("Courier New", Font.PLAIN, area.getFont().getSize())); + } + + public static JPopupMenu getPopup(RSyntaxTextArea hackvertorInput ) { + menu = new JPopupMenu("Message"); + menuCopy = new JMenuItem(RSyntaxTextArea.getAction(RTextArea.COPY_ACTION)); + menu.add(menuCopy); + + menuRepeater = new JMenuItem("Send to Repeater"); + menuRepeater.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent arg0) { + + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(hackvertorInput.getText().getBytes()); + BurpExtender.stdout.println(requestInfo); +// c_sendToRepeater(ihttpreqresp); + try { + c_sendToRepeater(requestInfo, hackvertorInput.getText().getBytes()); + }catch (Exception e){ + BurpExtender.stdout.println(e.getMessage()); + } +// BurpExtender.stdout.println(hackvertorInput.getText()); + + + + } + }); + menu.add(menuRepeater); + + menuReissue = new JMenuItem("Send to Intruder"); + menuReissue.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent arg0) { + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(hackvertorInput.getText().getBytes()); + BurpExtender.stdout.println(requestInfo); +// c_sendToRepeater(ihttpreqresp); + try { + c_sendToIntruder(requestInfo, hackvertorInput.getText().getBytes()); + }catch (Exception e){ + BurpExtender.stdout.println(e.getMessage()); + } + } + }); + menu.add(menuReissue); + +// menuCopySmart = new JMenuItem("Copy Smart"); +// menuCopySmart.addActionListener(new ActionListener(){ +// public void actionPerformed(ActionEvent arg0) { +// +// } +// }); +// menu.add(menuCopySmart); + + return menu; + } + + + /** + * void sendToRepeater( + * String host, + * int port, + * boolean useHttps, + * byte[] request, + * String tabCaption); + */ + public static void c_sendToRepeater(IRequestInfo iRequestInfo,byte[] request) { + String host = null; + int port = 0; + List headersList = iRequestInfo.getHeaders(); + for (String header : headersList) { + String[] host_lists = header.split(":"); + if (host_lists[0].toLowerCase().equals("host")) { + host = headersTohost(host_lists[1]).trim(); + port = headersToport(host_lists[1],BurpExtender.usehttps); + } + } + BurpExtender.callbacks.sendToRepeater( + host, + port, + BurpExtender.usehttps, + request , + "autoDecoder"); + } + + public static void c_sendToIntruder(IRequestInfo iRequestInfo,byte[] request) { + String host = null; + int port = 0; + List headersList = iRequestInfo.getHeaders(); + for (String header : headersList) { + String[] host_lists = header.split(":"); + if (host_lists[0].toLowerCase().equals("host")) { + host = headersTohost(host_lists[1]).trim(); + port = headersToport(host_lists[1],BurpExtender.usehttps); + } + } + BurpExtender.callbacks.sendToIntruder( + host, + port, + BurpExtender.usehttps, + request ); + } + + public static String headersTohost(String hostport){ + String host = ""; + String[] hostports ; + if (hostport.contains(":")) { + hostports = hostport.split(":"); + host = hostports[0]; + }else{ + host = hostport; + } + return host; + } + + public static int headersToport(String hostport,Boolean usehttps){ + int port ; + String[] hostports ; + if (hostport.contains(":")) { + hostports = hostport.split(":"); + port = Integer.parseInt(hostports[1]); + }else{ + if (usehttps) + port = 443; + else + port =80; + } + return port; + } + +} diff --git a/src/burp/BurpExtender.java b/src/burp/BurpExtender.java index 77c557d..227df00 100644 --- a/src/burp/BurpExtender.java +++ b/src/burp/BurpExtender.java @@ -13,8 +13,9 @@ import java.awt.*; import java.io.*; import java.net.URL; -import java.net.URLConnection; import java.util.Arrays; + +import burp.ui.iMessageEditorTab; import org.apache.commons.codec.binary.Base64; import java.util.List; import javax.swing.table.AbstractTableModel; @@ -35,13 +36,23 @@ public class BurpExtender extends AbstractTableModel implements IBurpExtender, public static boolean flag; - private IExtensionHelpers helpers; + public static URL URL; + + public static Boolean usehttps = false; + + public static IExtensionHelpers helpers; public static PrintWriter stdout; private IndexautoDecoder indexautoDecoder; - public String version = "0.26"; + public static boolean isDarkTheme; + + public static List DARK_THEMES = Arrays.asList("Darcula","FlatLaf - Burp Dark"); + + public String version = "0.27"; + +// public static IHttpRequestResponse ihttpreqresp ; public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { this.callbacks = callbacks; @@ -111,7 +122,9 @@ public IMessageEditorTab createNewInstance(IMessageEditorController iMessageEdit @Override public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse iHttpRequestResponse) { //处理请求包 + usehttps = iHttpRequestResponse.getHttpService().getProtocol().contains("https"); // 当proxy、intruder、repeater模块的时候调用加解密 +// this.ihttpreqresp = iHttpRequestResponse; if ( ( toolFlag == IBurpExtenderCallbacks.TOOL_PROXY && getRadioButton1111State() ) || ( toolFlag == IBurpExtenderCallbacks.TOOL_REPEATER && getRadioButton2222State() ) || ( toolFlag == IBurpExtenderCallbacks.TOOL_INTRUDER && getRadioButton3333State() )|| (toolFlag == IBurpExtenderCallbacks.TOOL_EXTENDER && getRadioButton4444State() )){ @@ -124,6 +137,7 @@ public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequ byte[] request = iHttpRequestResponse.getRequest(); IRequestInfo iRequestInfo = helpers.analyzeRequest(iHttpRequestResponse); // 获取请求中的所有参数 + List headersList = iRequestInfo.getHeaders(); int bodyOffset = iRequestInfo.getBodyOffset(); @@ -413,258 +427,6 @@ public int[] getSelectionBounds() { } - class iMessageEditorTab implements IMessageEditorTab{ - //实例化iTextEditor返回当前加密数据显示的组件包括加密数据内容 - public ITextEditor iTextEditor = callbacks.createTextEditor(); - - //设置消息编辑器的标题 - public String getTabCaption(){ - return "autoDecoder"; - } - //设置组件 这里直接设置为默认的iTextEditor组件 - public Component getUiComponent(){ - return iTextEditor.getComponent(); - } - - //过滤对特定的请求才生成消息编辑器 当burp中捕捉的请求不符合 - //我们需要的则不生成消息编辑器 - //比如 消息中包含“param”字段、host为www.test.com才生成消息编辑器 - //则如果请求包含它们返回true - - public boolean isEnabled(byte[] content,boolean isRequest){ - //参数content byte[]即是getMessage中获取的iTextEditor中的文本 - //参数isRequest boolean即表示当前文本是request请求 还是 response接收的数据 - //当isRequest true表示request false表示response - - try{ - if (!(IndexautoDecoder.getRadioButton2State() || IndexautoDecoder.getRadioButton1State())) - return false; - - if(isRequest){// 判断当请求为request - flag = false; - IRequestInfo requestInfo = helpers.analyzeRequest(content); - List headersList = requestInfo.getHeaders(); - String[] hosts = IndexautoDecoder.getEncryptHosts(); - for(String header : headersList) { -// System.out.println(header); - //请求头中包含指定域名“applog.xx.cn”才设置我们生成的消息编辑器 - for ( String host:hosts) { - String host_value = ""; - String[] host_lists = header.split(":"); - if (host_lists[0].toLowerCase().equals("host")) { - if (host_lists.length > 2) - host_value = host_lists[1] + ":" + host_lists[2]; - else - host_value = host_lists[1]; - host_value = host_value.trim(); - if(host_value.replace("*", "").replaceAll(":(.*)", "").endsWith(host.replace("*", "").replaceAll(":(.*)", ""))) - flag = true; - break; - } - if ( header.endsWith(host.replace("*", "")) || host_value.replace("*", "").replaceAll(":(.*)", "").endsWith(host.replace("*", "")) || - header.replace("*", "").endsWith(host.replace("*", ""))) { - flag = true; //返回true - break; - } - } - } - }else{ // 响应包也需要解密模块 - if (flag) - return true; - } - }catch(Exception e){ - e.printStackTrace(); - flag = false; - } - return flag; - } - - //我们要在消息编辑器中显示的消息,在额外的扩展栏 - //比如对content解密、添加额外内容、或者替换掉再返回到消息编辑器中 - public void setMessage(byte[] content,boolean isRequest){ - //参数content byte[]即是getMessage中获取的iTextEditor中的文本 - //参数isRequest boolean即表示当前是request请求 还是 response接收的数据 - //当isRequest true表示request false表示response - try{ - IRequestInfo requestInfo = helpers.analyzeRequest(content); - int bodyOffset = requestInfo.getBodyOffset(); - byte[] body = Arrays.copyOfRange(content, bodyOffset, content.length); - List headersList = requestInfo.getHeaders(); - String encodeWords = IndexautoDecoder.gettextArea2(); // 加密关键字 - String[] encodeWords_lists = encodeWords.split("\n"); - - isWords = false; - for (String encodeWords_single : encodeWords_lists) { - if ( (new String(body).contains(encodeWords_single)) ) { - isWords = true; - } - } - String not_encodeWords = IndexautoDecoder.gettextArea3(); // 不加密关键字 - String[] not_encodeWords_lists = not_encodeWords.split("\n"); - - for (String not_encodeWords_single : not_encodeWords_lists) { - if ( (new String(body).contains(not_encodeWords_single)) && !not_encodeWords_single.equals("") ) - isWords = false; - } - - if(isRequest){ // 判断当请求为request才处理数据 todo - String code_body = ""; //新增对二进制流传输的解决方案 - if (IndexautoDecoder.getRadioButton5State()){ - - code_body = Base64.encodeBase64String(body); - - }else{ - code_body = new String(body); - } - - if (IndexautoDecoder.getRadioButton1State()) { // 如果选中 通过加解密算法进行加解密 - if(isWords && IndexautoDecoder.regtextField.getText().trim().equals("")){ // 如果请求的是明文,则正常显示明文 - iTextEditor.setText(content); - } else { // 如果请求的不是明文,则会通过解密 - if (!IndexautoDecoder.regtextField.getText().trim().equals("")){ - String[] DecodeParams = IndexautoDecoder.getDecodeParams(); - String reg = IndexautoDecoder.regtextField.getText(); - String EncryText = MatchReg(code_body, reg); - String decodeBody = decryptKeyivmode(EncryText, DecodeParams[5], DecodeParams[6], DecodeParams[0], DecodeParams[1], DecodeParams[2], DecodeParams[3], DecodeParams[4]); - - String totalHeaders = ""; - for (String singleheader : headersList) - totalHeaders = totalHeaders + singleheader + "\r\n"; - iTextEditor.setText((totalHeaders + "\r\n" + code_body.replace(EncryText,decodeBody)).getBytes()); - } - else { - String[] DecodeParams = IndexautoDecoder.getDecodeParams(); // 获取解密数组 - String decodeBody = decryptKeyivmode(code_body, DecodeParams[5], DecodeParams[6], DecodeParams[0], DecodeParams[1], DecodeParams[2], DecodeParams[3], DecodeParams[4]); - String totalHeaders = ""; - for (String singleheader : headersList) - totalHeaders = totalHeaders + singleheader + "\r\n"; - iTextEditor.setText((totalHeaders + "\r\n" + decodeBody).getBytes()); - } - } - } - - if (IndexautoDecoder.getRadioButton2State()) { // 如果选中 通过接口进行加解密 - - - - if (isWords){ - iTextEditor.setText(content); - } else { - String totalHeaders = ""; - for (String singleheader : headersList) - totalHeaders = totalHeaders + singleheader + "\r\n"; - - // getRadioButton3State 请求头处理 todo - if ( IndexautoDecoder.getRadioButton3State() ) { // 对请求头进行加密 - - if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 - String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body, totalHeaders, "request"); - iTextEditor.setText((decodeTotal[0] + "\r\n" + decodeTotal[1]).getBytes()); - } else { - String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body , totalHeaders); - iTextEditor.setText((decodeTotal[0] + "\r\n" + decodeTotal[1]).getBytes()); - } - - }else if(!IndexautoDecoder.getRadioButton3State()){ // 不对请求头进行加密 - if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 - String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body, "request"); - iTextEditor.setText((totalHeaders + "\r\n" + decodeTotal).getBytes()); - } else { - String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body); - iTextEditor.setText((totalHeaders + "\r\n" + decodeTotal).getBytes()); - - } - } - } - } - - }else { // 处理响应包的数据 todo - - String code_body_resp = ""; //新增对二进制流传输的解决方案 - if (IndexautoDecoder.getRadioButton6State()){ - - code_body_resp = Base64.encodeBase64String(body); - - }else{ - code_body_resp = new String(body); - } - - String[] DecodeParams = IndexautoDecoder.getDecodeParams(); // 获取解密数组 - String totalHeaders = ""; - for (String singleheader : headersList) - totalHeaders = totalHeaders + singleheader + "\r\n"; - if(isWords){ - iTextEditor.setText(content); - }else { - String decodeBody = null; - if (IndexautoDecoder.getRadioButton1State()) { // 如果选中 通过加解密算法进行加解密 - String[] respDecodeParams = IndexautoDecoder.getRespDecodeParams(); // 获取解密数组 - if (!IndexautoDecoder.regtextField_resp.getText().trim().equals("")) { // 响应正则解密 0.24-beta2 - String reg = IndexautoDecoder.regtextField_resp.getText(); - String EncryText = MatchReg(code_body_resp , reg); -// stdout.println(EncryText); - try { - decodeBody = decryptKeyivmode(EncryText, respDecodeParams[5], respDecodeParams[6], respDecodeParams[0], respDecodeParams[1], respDecodeParams[2], respDecodeParams[3], respDecodeParams[4]); - } catch (Exception e) { - e.printStackTrace(); - } - - iTextEditor.setText((totalHeaders + "\r\n" + decodeBody).getBytes()); - - } else { - decodeBody = decryptKeyivmode(code_body_resp , DecodeParams[5], DecodeParams[6], DecodeParams[0], DecodeParams[1], DecodeParams[2], DecodeParams[3], DecodeParams[4]); - for (String singleheader : headersList) - totalHeaders = totalHeaders + singleheader + "\r\n"; - iTextEditor.setText((totalHeaders + "\r\n" + decodeBody).getBytes()); - } - } - if (IndexautoDecoder.getRadioButton2State()) { // 如果选中 通过接口进行加解密 - if(!IndexautoDecoder.getRadioButton3State()) { // 不对请求头进行加密 -// String totalHeaders = ""; - for (String singleheader : headersList) - totalHeaders = totalHeaders + singleheader + "\r\n"; - if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 - String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body_resp, "response"); - iTextEditor.setText((totalHeaders + "\r\n" + decodeTotal).getBytes()); - } else { - String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body_resp); - iTextEditor.setText((totalHeaders + "\r\n" + decodeTotal).getBytes()); - } - }else if (IndexautoDecoder.getRadioButton3State()){ // 对请求头进行加密 - if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 - String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body_resp, totalHeaders, "response"); - iTextEditor.setText((decodeTotal[0] + "\r\n" + decodeTotal[1]).getBytes()); - } else { - String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body_resp , totalHeaders); - iTextEditor.setText((decodeTotal[0] + "\r\n" + decodeTotal[1]).getBytes()); - } - - } - } - } - - } - }catch(Exception e){ - e.printStackTrace(); - } - } - - //返回iTextEditor显示的文本 - public byte[] getMessage(){ - return iTextEditor.getText(); - } - - //允许修改消息 - public boolean isModified(){ - return false; - } - - //返回iTextEditor中选定的文本 没有选择的话 则不返回数据 - public byte[] getSelectedData(){ - return iTextEditor.getSelectedText(); - } - } - public static String getPath(){ String oss = System.getProperty("os.name"); diff --git a/src/burp/ui/HackvertorInput.java b/src/burp/ui/HackvertorInput.java new file mode 100644 index 0000000..8aecb25 --- /dev/null +++ b/src/burp/ui/HackvertorInput.java @@ -0,0 +1,38 @@ +package burp.ui; + +import burp.BurpExtender; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; + +import javax.swing.*; +import java.awt.*; + +/** + * @DESCRIPTION: + * @USER: f0ng + * @DATE: 2023/5/21 下午1:52 + */ +public class HackvertorInput extends RSyntaxTextArea { + public HackvertorInput() { + super(); + BurpExtender.callbacks.customizeUiComponent(this); + this.updateFont(); + } + public void updateUI() { + super.updateUI(); +// BurpExtender.stdout.println(BurpExtender.DARK_THEMES); +// BurpExtender.stdout.println(UIManager.getLookAndFeel().getID()); + BurpExtender.isDarkTheme = UIManager.getLookAndFeel().getID().contains("Dark"); + SwingUtilities.invokeLater(() -> { + if(BurpExtender.isDarkTheme) { + Utils.Utils.applyThemeToRSyntaxTextArea(this, "dark"); + } else { + Utils.Utils.applyThemeToRSyntaxTextArea(this, "default"); + } + }); + BurpExtender.callbacks.customizeUiComponent(this); + this.updateFont(); + } + public void updateFont() { + this.setFont(new Font("Courier New", Font.PLAIN, this.getFont().getSize())); + } +} diff --git a/src/burp/ui/iMessageEditorTab.java b/src/burp/ui/iMessageEditorTab.java new file mode 100644 index 0000000..d89134e --- /dev/null +++ b/src/burp/ui/iMessageEditorTab.java @@ -0,0 +1,378 @@ +package burp.ui; + +import burp.*; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.codec.binary.Base64; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextArea; +import org.fife.ui.rtextarea.RTextScrollPane; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.*; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +import static Utils.Match.MatchReg; +import static burp.BurpExtender.sendPostnew; +import static burp.BurpExtender.sendPostnewHeader; +import static com.autoDecoder.util.codeDecode.decryptKeyivmode; + +/** + * @DESCRIPTION: + * @USER: f0ng + * @DATE: 2023/5/21 上午12:48 + */ +public class iMessageEditorTab implements IMessageEditorTab { + + private JPanel hackvertorContainer = new JPanel(new BorderLayout()); + private JPanel hackvertorPanel = new JPanel(new BorderLayout()); + public RSyntaxTextArea inputArea ;; + + + + public iMessageEditorTab(){ + +// BurpExtender.callbacks.customizeUiComponent(this.inputArea); + JTextComponent.removeKeymap("RTextAreaKeymap"); + UIManager.put("RSyntaxTextAreaUI.actionMap", null); + UIManager.put("RSyntaxTextAreaUI.inputMap", null); + UIManager.put("RTextAreaUI.actionMap", null); + UIManager.put("RTextAreaUI.inputMap", null); +// inputArea = new RSyntaxTextArea(20, 60); + this.inputArea = new HackvertorInput(); +// Utils.Utils.applyThemeToRSyntaxTextArea(inputArea, "dark"); // todo 设置黑暗主体 + inputArea.setWhitespaceVisible(true); +// inputArea.setEOLMarkersVisible(); + SwingUtilities.invokeLater(() -> inputArea.setVisible(true)); + this.inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML); + this.inputArea.setEditable(true); + this.inputArea.setCodeFoldingEnabled(true); + Utils.Utils.configureRSyntaxArea(this.inputArea); + inputArea.setPopupMenu(Utils.Utils.getPopup(this.inputArea)); +// hackvertorPanel.add(this.inputArea); + hackvertorContainer.add(new RTextScrollPane(this.inputArea)); + + } + + + //实例化this.inputArea返回当前加密数据显示的组件包括加密数据内容 +// public this.inputArea this.inputArea = BurpExtender.callbacks.createTextEditor(); + + //设置消息编辑器的标题 + public String getTabCaption(){ + return "autoDecoder"; + } + + //设置组件 这里直接设置为默认的this.inputArea组件 + public Component getUiComponent(){ + return hackvertorContainer; + } + + //过滤对特定的请求才生成消息编辑器 当burp中捕捉的请求不符合 + //我们需要的则不生成消息编辑器 + //比如 消息中包含“param”字段、host为www.test.com才生成消息编辑器 + //则如果请求包含它们返回true + + public boolean isEnabled(byte[] content,boolean isRequest){ + //参数content byte[]即是getMessage中获取的this.inputArea中的文本 + //参数isRequest boolean即表示当前文本是request请求 还是 response接收的数据 + //当isRequest true表示request false表示response + + try{ + if (!(IndexautoDecoder.getRadioButton2State() || IndexautoDecoder.getRadioButton1State())) + return false; + + if(isRequest){// 判断当请求为request + BurpExtender.flag = false; + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(content); + java.util.List headersList = requestInfo.getHeaders(); + String[] hosts = IndexautoDecoder.getEncryptHosts(); + for(String header : headersList) { +// System.out.println(header); + //请求头中包含指定域名“applog.xx.cn”才设置我们生成的消息编辑器 + for ( String host:hosts) { + String host_value = ""; + String[] host_lists = header.split(":"); + if (host_lists[0].toLowerCase().equals("host")) { + if (host_lists.length > 2) + host_value = host_lists[1] + ":" + host_lists[2]; + else + host_value = host_lists[1]; + host_value = host_value.trim(); + if(host_value.replace("*", "").replaceAll(":(.*)", "").endsWith(host.replace("*", "").replaceAll(":(.*)", ""))) + BurpExtender.flag = true; + break; + } + if ( header.endsWith(host.replace("*", "")) || host_value.replace("*", "").replaceAll(":(.*)", "").endsWith(host.replace("*", "")) || + header.replace("*", "").endsWith(host.replace("*", ""))) { + BurpExtender.flag = true; //返回true + break; + } + } + } + }else{ // 响应包也需要解密模块 + if (BurpExtender.flag) + return true; + } + }catch(Exception e){ + e.printStackTrace(); + BurpExtender.flag = false; + } + return BurpExtender.flag; + } + + //我们要在消息编辑器中显示的消息,在额外的扩展栏 + //比如对content解密、添加额外内容、或者替换掉再返回到消息编辑器中 + public void setMessage(byte[] content,boolean isRequest){ + //参数content byte[]即是getMessage中获取的this.inputArea中的文本 + //参数isRequest boolean即表示当前是request请求 还是 response接收的数据 + //当isRequest true表示request false表示response + String contentt = new String(content); + + + + + try{ + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(content); + int bodyOffset = requestInfo.getBodyOffset(); + byte[] body = Arrays.copyOfRange(content, bodyOffset, content.length); + List headersList = requestInfo.getHeaders(); + String encodeWords = IndexautoDecoder.gettextArea2(); // 加密关键字 + String[] encodeWords_lists = encodeWords.split("\n"); + + BurpExtender.isWords = false; + for (String encodeWords_single : encodeWords_lists) { + if ( (new String(body).contains(encodeWords_single)) ) { + BurpExtender.isWords = true; + } + } + String not_encodeWords = IndexautoDecoder.gettextArea3(); // 不加密关键字 + String[] not_encodeWords_lists = not_encodeWords.split("\n"); + + for (String not_encodeWords_single : not_encodeWords_lists) { + if ( (new String(body).contains(not_encodeWords_single)) && !not_encodeWords_single.equals("") ) + BurpExtender.isWords = false; + } + +// if (contentt.contains("application/json")) // todo 包含application/json 设置json高亮 +// inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + + + if(isRequest){ // 判断当请求为request才处理数据 todo + String code_body = ""; //新增对二进制流传输的解决方案 + if (IndexautoDecoder.getRadioButton5State()){ + + code_body = Base64.encodeBase64String(body); + + }else{ + code_body = new String(body); + } + + if (IndexautoDecoder.getRadioButton1State()) { // 如果选中 通过加解密算法进行加解密 + if(BurpExtender.isWords && IndexautoDecoder.regtextField.getText().trim().equals("")){ // 如果请求的是明文,则正常显示明文 +// BurpExtender.stdout.println(isJSON2(new String(body, StandardCharsets.UTF_8))); + if (isJSON2(new String(body, StandardCharsets.UTF_8)) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText(contentt); + } else { // 如果请求的不是明文,则会通过解密 + if (!IndexautoDecoder.regtextField.getText().trim().equals("")){ + String[] DecodeParams = IndexautoDecoder.getDecodeParams(); + String reg = IndexautoDecoder.regtextField.getText(); + String EncryText = MatchReg(code_body, reg); + String decodeBody = decryptKeyivmode(EncryText, DecodeParams[5], DecodeParams[6], DecodeParams[0], DecodeParams[1], DecodeParams[2], DecodeParams[3], DecodeParams[4]); + + String totalHeaders = ""; + for (String singleheader : headersList) + totalHeaders = totalHeaders + singleheader + "\r\n"; + + if (isJSON2(code_body.replace(EncryText,decodeBody)) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + + this.inputArea.setText((totalHeaders + "\r\n" + code_body.replace(EncryText,decodeBody) )); + } + else { + String[] DecodeParams = IndexautoDecoder.getDecodeParams(); // 获取解密数组 + String decodeBody = decryptKeyivmode(code_body, DecodeParams[5], DecodeParams[6], DecodeParams[0], DecodeParams[1], DecodeParams[2], DecodeParams[3], DecodeParams[4]); + String totalHeaders = ""; + for (String singleheader : headersList) + totalHeaders = totalHeaders + singleheader + "\r\n"; + if (isJSON2(decodeBody) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeBody)); + } + } + } + + if (IndexautoDecoder.getRadioButton2State()) { // 如果选中 通过接口进行加解密 + + + + if (BurpExtender.isWords){ + this.inputArea.setText(contentt); + } else { + String totalHeaders = ""; + for (String singleheader : headersList) + totalHeaders = totalHeaders + singleheader + "\r\n"; + + // getRadioButton3State 请求头处理 todo + if ( IndexautoDecoder.getRadioButton3State() ) { // 对请求头进行加密 + + if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 + String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body, totalHeaders, "request"); + if (isJSON2(decodeTotal[1]) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((decodeTotal[0] + "\r\n" + decodeTotal[1])); + } else { + String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body , totalHeaders); + if (isJSON2(decodeTotal[1]) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((decodeTotal[0] + "\r\n" + decodeTotal[1])); + } + + }else if(!IndexautoDecoder.getRadioButton3State()){ // 不对请求头进行加密 + if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 + String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body, "request"); + if (isJSON2(decodeTotal) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeTotal)); + } else { + String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body); + if (isJSON2(decodeTotal) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeTotal)); + + } + } + } + } + + }else { // 处理响应包的数据 todo + + String code_body_resp = ""; //新增对二进制流传输的解决方案 + if (IndexautoDecoder.getRadioButton6State()){ + + code_body_resp = Base64.encodeBase64String(body); + + }else{ + code_body_resp = new String(body); + } + + String[] DecodeParams = IndexautoDecoder.getDecodeParams(); // 获取解密数组 + String totalHeaders = ""; + for (String singleheader : headersList) + totalHeaders = totalHeaders + singleheader + "\r\n"; + if(BurpExtender.isWords){ + if (isJSON2(new String(body, StandardCharsets.UTF_8)) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText(contentt); + }else { + String decodeBody = null; + if (IndexautoDecoder.getRadioButton1State()) { // 如果选中 通过加解密算法进行加解密 + String[] respDecodeParams = IndexautoDecoder.getRespDecodeParams(); // 获取解密数组 + if (!IndexautoDecoder.regtextField_resp.getText().trim().equals("")) { // 响应正则解密 0.24-beta2 + String reg = IndexautoDecoder.regtextField_resp.getText(); + String EncryText = MatchReg(code_body_resp , reg); +// stdout.println(EncryText); + try { + decodeBody = decryptKeyivmode(EncryText, respDecodeParams[5], respDecodeParams[6], respDecodeParams[0], respDecodeParams[1], respDecodeParams[2], respDecodeParams[3], respDecodeParams[4]); + } catch (Exception e) { + e.printStackTrace(); + } + if (isJSON2(decodeBody) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeBody)); + + } else { + decodeBody = decryptKeyivmode(code_body_resp , DecodeParams[5], DecodeParams[6], DecodeParams[0], DecodeParams[1], DecodeParams[2], DecodeParams[3], DecodeParams[4]); + for (String singleheader : headersList) + totalHeaders = totalHeaders + singleheader + "\r\n"; + if (isJSON2(decodeBody) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeBody)); + } + } + if (IndexautoDecoder.getRadioButton2State()) { // 如果选中 通过接口进行加解密 + if(!IndexautoDecoder.getRadioButton3State()) { // 不对请求头进行加密 +// String totalHeaders = ""; + for (String singleheader : headersList) + totalHeaders = totalHeaders + singleheader + "\r\n"; + if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 + String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body_resp, "response"); + if (isJSON2(decodeTotal) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeTotal)); + } else { + String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), code_body_resp); + if (isJSON2(decodeTotal) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((totalHeaders + "\r\n" + decodeTotal)); + } + }else if (IndexautoDecoder.getRadioButton3State()){ // 对请求头进行加密 + if (IndexautoDecoder.getRadioButton4State()) { // 如果选中了请求包、响应包分开解密 + String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body_resp, totalHeaders, "response"); + if (isJSON2(decodeTotal[1]) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((decodeTotal[0] + "\r\n" + decodeTotal[1])); + } else { + String[] decodeTotal = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), code_body_resp , totalHeaders); + if (isJSON2(decodeTotal[1]) ) { + inputArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + } + this.inputArea.setText((decodeTotal[0] + "\r\n" + decodeTotal[1])); + } + + } + } + } + + } + }catch(Exception e){ + e.printStackTrace(); + } + } + + public static boolean isJSON2(String str) { + boolean result = false; + str = str.trim(); + BurpExtender.stdout.println(str); + try { + Object obj=JSON.parse(str); + result = true; + } catch (Exception e) { + result=false; + } + return result; + } + + //返回this.inputArea显示的文本 + public byte[] getMessage(){ + return this.inputArea.getText().getBytes(); + } + + //允许修改消息 + public boolean isModified(){ + return false; + } + + //返回this.inputArea中选定的文本 没有选择的话 则不返回数据 + public byte[] getSelectedData(){ + return this.inputArea.getSelectedText().getBytes(); + } +} diff --git a/src/burp/util/BurpCallbacks.java b/src/burp/util/BurpCallbacks.java new file mode 100644 index 0000000..c1c1226 --- /dev/null +++ b/src/burp/util/BurpCallbacks.java @@ -0,0 +1,100 @@ +///* +// * Copyright (C) 2013 DobinRutishauser@broken.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +//package burp.util; +// +//import burp.IBurpExtenderCallbacks; +//import burp.IHttpRequestResponse; +//import burp.IHttpService; +//import burp.IRequestInfo; +//import burp.IResponseInfo; +////import burp.model.SentinelHttpMessage; +////import gui.viewMessage.ExternalUpdater; +//import java.io.PrintWriter; +//import java.net.MalformedURLException; +//import java.net.URL; +////import model.SentinelHttpMessage; +////import model.SentinelHttpService; +// +///** +// * +// * @author unreal +// */ +//public class BurpCallbacks { +// +// static private BurpCallbacks burpCallbacks = null; +// private IBurpExtenderCallbacks callback; +// private PrintWriter stdout; +// +// public void init(IBurpExtenderCallbacks callback) { +// this.callback = callback; +// stdout = new PrintWriter(callback.getStdout(), true); +// } +// +// public IBurpExtenderCallbacks getBurp() { +// return callback; +// } +// +// public void print(String s) { +// if (stdout != null) { +// stdout.println(s); +// } +// } +// +// public static BurpCallbacks getInstance() { +// if (burpCallbacks == null) { +// burpCallbacks = new BurpCallbacks(); +// } +// return burpCallbacks; +// } +// +// +// +// +// +// private boolean isRedirect(byte[] response) { +// IResponseInfo responseInfo = BurpCallbacks.getInstance().getBurp().getHelpers().analyzeResponse(response); +// if (responseInfo.getStatusCode() == 302) { +// return true; +// } else { +// return false; +// } +// } +// +// +// +// private URL followRedirectUrl(String redirStr, IHttpRequestResponse message) { +// // get old url +// System.out.println("FOLLOW!"); +// IRequestInfo requestInfo = BurpCallbacks.getInstance().getBurp().getHelpers().analyzeRequest(message); +// URL origUrl = requestInfo.getUrl(); +// +// // create new url +// URL url; +// try { +// url = new URL(origUrl, redirStr); +// } catch (MalformedURLException ex) { +// BurpCallbacks.getInstance().print("302 found, but could not convert location header!"); +// return null; +// } +// +// return url; +// } +// +// +// +// +//}