From 4ea7c664d5d15005e6c61366e2fb5fe73369b048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ram=C3=ADrez=20Mart=C3=ADnez?= Date: Wed, 12 Apr 2023 05:35:36 -0500 Subject: [PATCH] Refactor UI component creation This change adds new classes for user interface generation to be more understandable for developers. --- src/main/java/burp/BurpExtender.java | 10 +- src/main/java/burp/Header.java | 4 +- src/main/java/burp/Util.java | 5 +- src/main/java/burp/burptab/PocCreatorTab.java | 173 ------------------ src/main/java/burp/pocs/AjaxPoc.java | 10 +- src/main/java/burp/pocs/Pocs.java | 72 ++++---- .../java/burp/{burptab => tab}/CloseIcon.java | 2 +- .../burp/tab/MessageEditorController.java | 36 ++++ src/main/java/burp/tab/POCTypesComboBox.java | 43 +++++ src/main/java/burp/tab/PocCreatorTab.java | 75 ++++++++ .../burp/{burptab => tab}/PocTabManager.java | 34 +++- .../ITabImpl.java => tab/TabImpl.java} | 8 +- .../java/burp/tab/buttons/CopyPOCButton.java | 33 ++++ .../java/burp/tab/buttons/SavePOCButton.java | 50 +++++ 14 files changed, 313 insertions(+), 242 deletions(-) delete mode 100644 src/main/java/burp/burptab/PocCreatorTab.java rename src/main/java/burp/{burptab => tab}/CloseIcon.java (96%) create mode 100644 src/main/java/burp/tab/MessageEditorController.java create mode 100644 src/main/java/burp/tab/POCTypesComboBox.java create mode 100644 src/main/java/burp/tab/PocCreatorTab.java rename src/main/java/burp/{burptab => tab}/PocTabManager.java (57%) rename src/main/java/burp/{burptab/ITabImpl.java => tab/TabImpl.java} (74%) create mode 100644 src/main/java/burp/tab/buttons/CopyPOCButton.java create mode 100644 src/main/java/burp/tab/buttons/SavePOCButton.java diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index b81c841..e3c3c97 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -1,9 +1,10 @@ package burp; -import burp.burptab.ITabImpl; -import burp.burptab.PocCreatorTab; -import burp.burptab.PocTabManager; import burp.pocs.Pocs; +import burp.tab.TabImpl; +import burp.tab.PocCreatorTab; +import burp.tab.PocTabManager; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Iterator; @@ -38,8 +39,7 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks ibec) { this.pocTabManager = new PocTabManager(); ibec.registerContextMenuFactory(this); ibec.setExtensionName("CSRF PoC Creator"); - BurpExtender.burpExtenderCallbacks.addSuiteTab(new ITabImpl("CSRF PoC", this.pocTabManager)); - Pocs.initialize(); + BurpExtender.burpExtenderCallbacks.addSuiteTab(new TabImpl("CSRF PoC", this.pocTabManager)); // add menus Iterator pocKeys = Pocs.getPocKeys(); while (pocKeys.hasNext()) { diff --git a/src/main/java/burp/Header.java b/src/main/java/burp/Header.java index 9aa1aee..e7cee7f 100644 --- a/src/main/java/burp/Header.java +++ b/src/main/java/burp/Header.java @@ -21,9 +21,7 @@ public Header(String name, String value) { * @param header the string to parse (name:value) * @return The header object created */ - public static Header build(String header){ - if(header == null) - throw new NullPointerException("header must not be null"); + public static Header parse(String header){ String[] split = header.split(":"); String name = split[0].trim(), value=""; if (split.length > 1) { diff --git a/src/main/java/burp/Util.java b/src/main/java/burp/Util.java index 2d11cc1..f6553a0 100644 --- a/src/main/java/burp/Util.java +++ b/src/main/java/burp/Util.java @@ -18,6 +18,7 @@ public class Util { public static String escape(String escape){ return escape.replace("\\", "\\\\").replace("\"", "\\\""); } + /** * Generates a random string (for Multipart requests) * @param lenght the char number of the random string @@ -55,9 +56,9 @@ public static String joinParameters(List p) { * @param headers the string to build * @return a list of Header objects */ - public static List
parseHeaderList(List headers){ + public static List
parseHeaders(List headers){ List
a = new LinkedList<>(); - headers.stream().map(next -> Header.build(next)).forEach(build -> { + headers.stream().map(next -> Header.parse(next)).forEach(build -> { a.add(build); }); return a; diff --git a/src/main/java/burp/burptab/PocCreatorTab.java b/src/main/java/burp/burptab/PocCreatorTab.java deleted file mode 100644 index 17fc9bb..0000000 --- a/src/main/java/burp/burptab/PocCreatorTab.java +++ /dev/null @@ -1,173 +0,0 @@ - -package burp.burptab; - -import burp.BurpExtender; -import burp.IExtensionHelpers; -import burp.IHttpRequestResponse; -import burp.IHttpService; -import burp.IHttpServiceImpl; -import burp.IMessageEditor; -import burp.IMessageEditorController; -import burp.IRequestInfo; -import burp.ITextEditor; -import burp.pocs.Pocs; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.FlowLayout; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Iterator; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JSplitPane; -import burp.pocs.IPoc; - -/** - * POC Creator tab - * @author Joaquin R. Martinez - */ -public class PocCreatorTab extends JPanel implements ActionListener, ItemListener { - - private static final long serialVersionUID = 1L; - private final ITextEditor textEditor; - private final IMessageEditor messageEditor; - private final JButton saveButton, copyButton;//, btn_close; - private final JFileChooser saveFileDialog; - private final JComboBox pocTypesCombo; - private final IHttpRequestResponse request; - - /** - * Creates pocString new tab for pocString poc - * - * @param req the request to show on the left - * @param poc the poc code - */ - public PocCreatorTab(IHttpRequestResponse req, byte[] poc) { - super(new BorderLayout(10, 10)); - this.request = req; - this.saveButton = new JButton("save to file"); - this.copyButton = new JButton("copy"); - this.saveButton.setForeground(Color.blue); - this.copyButton.addActionListener(PocCreatorTab.this); - this.saveButton.addActionListener(PocCreatorTab.this); - this.saveFileDialog = new JFileChooser(); - this.pocTypesCombo = new JComboBox<>(); - Iterator pocKeys = Pocs.getPocKeys(); - while (pocKeys.hasNext()) { - this.pocTypesCombo.addItem(pocKeys.next()); - } - this.pocTypesCombo.addItemListener(PocCreatorTab.this); - /*Create pocString TextEditor*/ - this.textEditor = BurpExtender.getBurpExtenderCallbacks().createTextEditor(); - /*Making our message editor great with burp normal popup menu*/ - this.messageEditor = BurpExtender.getBurpExtenderCallbacks().createMessageEditor(new IMessageEditorController() { - @Override - public IHttpService getHttpService() { - IRequestInfo analyzeRequest = BurpExtender.getBurpExtenderCallbacks().getHelpers().analyzeRequest(req); - return new IHttpServiceImpl(analyzeRequest); - } - - @Override - public byte[] getRequest() { - return messageEditor.getMessage(); - } - - @Override - public byte[] getResponse() { - return req.getResponse(); - } - }, true); - - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - splitPane.add(this.messageEditor.getComponent()); - splitPane.add(this.textEditor.getComponent()); - PocCreatorTab.this.add("Center", splitPane); - - //buttons panel - JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - buttonsPanel.add(new JLabel("PoC type: ")); - buttonsPanel.add(this.pocTypesCombo); - buttonsPanel.add(this.copyButton); - buttonsPanel.add(this.saveButton); - - //add buttons to end - PocCreatorTab.this.add("South", buttonsPanel); - this.textEditor.setText(poc); - this.messageEditor.setMessage(req.getRequest(), true); - BurpExtender.getBurpExtenderCallbacks().customizeUiComponent(PocCreatorTab.this);//burp lookandfeel - } - - /** - * When pocString button is clicked into this tab. - * @param e event argument. - */ - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() == this.copyButton) { - copy(); - } else if (e.getSource() == this.saveButton) { - save(); - } - } - - /** - * Passes the poc code to the system clipboard - */ - private void copy() { - IExtensionHelpers helpers = BurpExtender.getBurpExtenderCallbacks().getHelpers(); - String bytesToString = helpers.bytesToString(this.textEditor.getText()); - Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - systemClipboard.setContents(new StringSelection(bytesToString), null); - } - - /** - * Handler for the 'save' button. - */ - private void save() { - int showSaveDialog = this.saveFileDialog.showSaveDialog(this.textEditor.getComponent()); - if (showSaveDialog == JFileChooser.APPROVE_OPTION) { - File file = this.saveFileDialog.getSelectedFile(); - try (FileWriter fileWriter = new FileWriter(file); - BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { - bufferedWriter.write(BurpExtender.getBurpExtenderCallbacks().getHelpers().bytesToString(this.textEditor.getText())); - } - catch (IOException ex) { - JOptionPane.showMessageDialog(this, ex, "Error", JOptionPane.ERROR_MESSAGE); - } - } - } - - @Override - public void itemStateChanged(ItemEvent e) { - String selectedItem = this.pocTypesCombo.getSelectedItem().toString(); - IPoc poc = Pocs.getPoc(selectedItem); - try { - byte[] pocContent = poc.getPoc(this.request); - this.textEditor.setText(pocContent); - } catch (Exception ex) { - JOptionPane.showMessageDialog(this, ex, "Error", JOptionPane.ERROR_MESSAGE); - } - } - - /** - * Sets the selected poc item. - * @param key the item. - */ - public void setSelectedItem(String key){ - this.pocTypesCombo.setSelectedItem(key); - } - -} diff --git a/src/main/java/burp/pocs/AjaxPoc.java b/src/main/java/burp/pocs/AjaxPoc.java index c9afde0..0d57654 100644 --- a/src/main/java/burp/pocs/AjaxPoc.java +++ b/src/main/java/burp/pocs/AjaxPoc.java @@ -30,19 +30,19 @@ public byte[] getPoc(final IHttpRequestResponse request) { pocString.append(" xhr.open(\"").append(method).append("\", \""); if ("GET".equals(method)) { - pocString.append(request.getHttpService()).append("\", true);").append(lineSeparator); + pocString.append(requestInfo.getUrl()).append("\", true);").append(lineSeparator); pocString.append(" xhr.send();\n"); } else { pocString.append(requestInfo.getUrl().toString()).append("\", true);").append(lineSeparator); String body = iexHelpers.bytesToString(request.getRequest()).substring(requestInfo.getBodyOffset()); body = Util.escape(body); - String accept = "xt/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; + String accept = "*/*"; String content = "text/plain"; - for (Parameter next : Util.parseHeaderList(requestInfo.getHeaders())) { - if ("Accept".equals(next.getName())) { + for (Parameter next : Util.parseHeaders(requestInfo.getHeaders())) { + if ("Accept".equalsIgnoreCase(next.getName())) { accept = next.getValue(); } - if ("Content-Type".equals(next.getName())) { + if ("Content-Type".equalsIgnoreCase(next.getName())) { content = next.getValue(); } } diff --git a/src/main/java/burp/pocs/Pocs.java b/src/main/java/burp/pocs/Pocs.java index d31f867..7487880 100644 --- a/src/main/java/burp/pocs/Pocs.java +++ b/src/main/java/burp/pocs/Pocs.java @@ -8,46 +8,40 @@ /** * Contains all types of PoC's supported by this plugin. + * * @author Joaquin R. Martinez */ public class Pocs { - - private static final Map POCS = new HashMap<>() ; - private static Pocs poc = null; - - /** - * Inaccesible constructor. - */ - private Pocs() { - Pocs.POCS.put("Ajax",new AjaxPoc()); - Pocs.POCS.put("HTML",new HtmlPoc()); - // Add more kind of PoC's - } - - /** - * Initializes the types of pocs supported. - */ - public static void initialize(){ - if(poc == null){ - Pocs.poc = new Pocs(); - } - } - - /** - * Get the {@link IPoc} object by its key. - * @param key the key of the {@link IPoc}. - * @return the {@link IPoc} object. - */ - public static IPoc getPoc(String key) { - return Pocs.POCS.get(key); - } - - /** - * Get the {@link IPoc} as a {@link Enumeration}. - * @return an {@link Iterator} with the keys of all {@link IPoc} objects. - */ - public static Iterator getPocKeys(){ - return Pocs.POCS.keySet().iterator(); - } - + + private static final Map POCS = new HashMap<>(); + static Pocs poc = new Pocs(); + + /** + * Inaccesible constructor. + */ + private Pocs() { + Pocs.POCS.put("Ajax", new AjaxPoc()); + Pocs.POCS.put("HTML", new HtmlPoc()); + // Add more kind of PoC's + } + + /** + * Get the {@link IPoc} object by its key. + * + * @param key the key of the {@link IPoc}. + * @return the {@link IPoc} object. + */ + public static IPoc getPoc(String key) { + return Pocs.POCS.get(key); + } + + /** + * Get the {@link IPoc} as a {@link Enumeration}. + * + * @return an {@link Iterator} with the keys of all {@link IPoc} objects. + */ + public static Iterator getPocKeys() { + return Pocs.POCS.keySet().iterator(); + } + } diff --git a/src/main/java/burp/burptab/CloseIcon.java b/src/main/java/burp/tab/CloseIcon.java similarity index 96% rename from src/main/java/burp/burptab/CloseIcon.java rename to src/main/java/burp/tab/CloseIcon.java index 3894c4c..30a7969 100644 --- a/src/main/java/burp/burptab/CloseIcon.java +++ b/src/main/java/burp/tab/CloseIcon.java @@ -1,5 +1,5 @@ -package burp.burptab; +package burp.tab; import java.awt.Color; import java.awt.Component; diff --git a/src/main/java/burp/tab/MessageEditorController.java b/src/main/java/burp/tab/MessageEditorController.java new file mode 100644 index 0000000..14b2bd2 --- /dev/null +++ b/src/main/java/burp/tab/MessageEditorController.java @@ -0,0 +1,36 @@ +package burp.tab; + +import burp.BurpExtender; +import burp.IHttpRequestResponse; +import burp.IHttpService; +import burp.IHttpServiceImpl; +import burp.IMessageEditor; +import burp.IMessageEditorController; +import burp.IRequestInfo; + +public class MessageEditorController implements IMessageEditorController { + + private IHttpRequestResponse request; + private IMessageEditor messageEditor; + + public MessageEditorController(IHttpRequestResponse request, IMessageEditor messageEditor) { + this.request = request; + this.messageEditor = messageEditor; + } + + @Override + public IHttpService getHttpService() { + IRequestInfo analyzeRequest = BurpExtender.getBurpExtenderCallbacks().getHelpers().analyzeRequest(this.request); + return new IHttpServiceImpl(analyzeRequest); + } + + @Override + public byte[] getRequest() { + return messageEditor.getMessage(); + } + + @Override + public byte[] getResponse() { + return this.request.getResponse(); + } +} diff --git a/src/main/java/burp/tab/POCTypesComboBox.java b/src/main/java/burp/tab/POCTypesComboBox.java new file mode 100644 index 0000000..4a3f8df --- /dev/null +++ b/src/main/java/burp/tab/POCTypesComboBox.java @@ -0,0 +1,43 @@ +package burp.tab; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Iterator; + +import javax.swing.JComboBox; +import javax.swing.JOptionPane; + +import burp.IHttpRequestResponse; +import burp.ITextEditor; +import burp.pocs.IPoc; +import burp.pocs.Pocs; + +public class POCTypesComboBox extends JComboBox implements ItemListener { + + private static final long serialVersionUID = 1L; + private IHttpRequestResponse request; + private ITextEditor textEditor; + + public POCTypesComboBox(ITextEditor textEditor, IHttpRequestResponse request) { + this.textEditor = textEditor; + this.request = request; + Iterator pocKeys = Pocs.getPocKeys(); + while (pocKeys.hasNext()) { + addItem(pocKeys.next()); + } + addItemListener(this); + } + + @Override + public void itemStateChanged(ItemEvent e) { + String selectedItem = getSelectedItem().toString(); + IPoc poc = Pocs.getPoc(selectedItem); + try { + byte[] pocContent = poc.getPoc(this.request); + this.textEditor.setText(pocContent); + } catch (Exception ex) { + JOptionPane.showMessageDialog(this, ex, "Error", JOptionPane.ERROR_MESSAGE); + } + } + +} diff --git a/src/main/java/burp/tab/PocCreatorTab.java b/src/main/java/burp/tab/PocCreatorTab.java new file mode 100644 index 0000000..f13ad20 --- /dev/null +++ b/src/main/java/burp/tab/PocCreatorTab.java @@ -0,0 +1,75 @@ + +package burp.tab; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import burp.BurpExtender; +import burp.IHttpRequestResponse; +import burp.IMessageEditor; +import burp.ITextEditor; +import burp.tab.buttons.CopyPOCButton; +import burp.tab.buttons.SavePOCButton; + +/** + * POC Creator tab + * + * @author Joaquin R. Martinez + */ +public class PocCreatorTab extends JPanel { + + private static final long serialVersionUID = 1L; + private final ITextEditor textEditor; + private IMessageEditor messageEditor; + private POCTypesComboBox pocTypesCombo; + + /** + * Creates pocString new tab for pocString poc + * + * @param request the request to show on the left + * @param poc the poc code + */ + public PocCreatorTab(IHttpRequestResponse request, byte[] poc) { + super(new BorderLayout(10, 10)); + this.textEditor = BurpExtender.getBurpExtenderCallbacks().createTextEditor(); + this.pocTypesCombo = new POCTypesComboBox(textEditor, request); + + /* Making our message editor great with burp normal popup menu */ + this.messageEditor = BurpExtender.getBurpExtenderCallbacks() + .createMessageEditor(new MessageEditorController(request, messageEditor), true); +; + this.add(BorderLayout.CENTER, createEditorSplitPane()); + this.add(BorderLayout.SOUTH, createButtonsPanel()); + this.textEditor.setText(poc); + this.messageEditor.setMessage(request.getRequest(), true); + BurpExtender.getBurpExtenderCallbacks().customizeUiComponent(PocCreatorTab.this);// burp lookandfeel + } + + /** + * Sets the selected poc item. + * + * @param key the item. + */ + public void setSelectedItem(String key) { + this.pocTypesCombo.setSelectedItem(key); + } + + private JSplitPane createEditorSplitPane() { + JSplitPane editorArea = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + editorArea.add(this.messageEditor.getComponent()); + editorArea.add(this.textEditor.getComponent()); + return editorArea; + } + + private JPanel createButtonsPanel() { + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonsPanel.add(new JLabel("PoC type: ")); + buttonsPanel.add(pocTypesCombo); + buttonsPanel.add(new CopyPOCButton(textEditor)); + buttonsPanel.add(new SavePOCButton(textEditor)); + return buttonsPanel; + } + +} diff --git a/src/main/java/burp/burptab/PocTabManager.java b/src/main/java/burp/tab/PocTabManager.java similarity index 57% rename from src/main/java/burp/burptab/PocTabManager.java rename to src/main/java/burp/tab/PocTabManager.java index a1c8985..bbe8e68 100644 --- a/src/main/java/burp/burptab/PocTabManager.java +++ b/src/main/java/burp/tab/PocTabManager.java @@ -1,5 +1,5 @@ -package burp.burptab; +package burp.tab; import java.awt.Dimension; import javax.swing.JButton; @@ -24,19 +24,33 @@ public class PocTabManager extends JTabbedPane { public void addTab(final String title, final PocCreatorTab pocCreatorTab) { super.addTab(title, pocCreatorTab); int index = getTabCount() - 1; + JPanel tabContainer = createTabContainer(title); + setTabComponentAt(index, tabContainer); + } + + private JPanel createTabContainer(String title) { JPanel tabContainer = new JPanel(); tabContainer.setOpaque(false); tabContainer.add(new JLabel(title)); + JButton closeTabButton = createTabButton(title); + tabContainer.add(closeTabButton); + return tabContainer; + } + + private JButton createTabButton(String title) { CloseIcon closeIcon = new CloseIcon(); JButton closeTabButton = new JButton(closeIcon); - closeTabButton.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight())); - closeTabButton.addActionListener(e -> { - int indexOfTab = indexOfTab(title); //tabs title does not change - if (indexOfTab != -1) { - removeTabAt(indexOfTab); - } - }); - tabContainer.add(closeTabButton); - setTabComponentAt(index, tabContainer); + Dimension closeIconDimension = new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()); + closeTabButton.setPreferredSize(closeIconDimension); + closeTabButton.addActionListener(e -> removeTab(title)); + return closeTabButton; } + + private void removeTab(String title) { + int indexOfTab = indexOfTab(title); //tabs title does not change + if (indexOfTab != -1) { + removeTabAt(indexOfTab); + } + } + } diff --git a/src/main/java/burp/burptab/ITabImpl.java b/src/main/java/burp/tab/TabImpl.java similarity index 74% rename from src/main/java/burp/burptab/ITabImpl.java rename to src/main/java/burp/tab/TabImpl.java index 188f5e1..f854235 100644 --- a/src/main/java/burp/burptab/ITabImpl.java +++ b/src/main/java/burp/tab/TabImpl.java @@ -1,5 +1,5 @@ -package burp.burptab; +package burp.tab; import burp.ITab; import java.awt.Component; @@ -7,17 +7,17 @@ * * @author Joaquin R. Martinez */ -public class ITabImpl implements ITab { +public class TabImpl implements ITab { private final Component contentComponent; private final String tabString; /** - * Creates a new ITabImpl object with the given title and component. + * Creates a new TabImpl object with the given title and component. * @param tabstring the title of the tab. * @param ui the component shown on this tab. */ - public ITabImpl(String tabstring, Component ui) { + public TabImpl(String tabstring, Component ui) { this.contentComponent = ui; this.tabString = tabstring; } diff --git a/src/main/java/burp/tab/buttons/CopyPOCButton.java b/src/main/java/burp/tab/buttons/CopyPOCButton.java new file mode 100644 index 0000000..f965f6f --- /dev/null +++ b/src/main/java/burp/tab/buttons/CopyPOCButton.java @@ -0,0 +1,33 @@ +package burp.tab.buttons; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import burp.BurpExtender; +import burp.IExtensionHelpers; +import burp.ITextEditor; + +public class CopyPOCButton extends JButton implements ActionListener{ + + private static final long serialVersionUID = 1L; + + private ITextEditor textEditor; + + public CopyPOCButton(ITextEditor textEditor) { + super("copy"); + this.textEditor = textEditor; + addActionListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + IExtensionHelpers helpers = BurpExtender.getBurpExtenderCallbacks().getHelpers(); + String bytesToString = helpers.bytesToString(this.textEditor.getText()); + Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + systemClipboard.setContents(new StringSelection(bytesToString), null); + } + +} diff --git a/src/main/java/burp/tab/buttons/SavePOCButton.java b/src/main/java/burp/tab/buttons/SavePOCButton.java new file mode 100644 index 0000000..a5da017 --- /dev/null +++ b/src/main/java/burp/tab/buttons/SavePOCButton.java @@ -0,0 +1,50 @@ +package burp.tab.buttons; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; + +import burp.BurpExtender; +import burp.ITextEditor; + +public class SavePOCButton extends JButton implements ActionListener { + + private static final long serialVersionUID = 1L; + private static final JFileChooser saveFileDialog = new JFileChooser();; + private ITextEditor textEditor; + + public SavePOCButton(ITextEditor textEditor) { + super("save to file"); + this.textEditor = textEditor; + setForeground(Color.blue); + addActionListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + int showSaveDialog = saveFileDialog.showSaveDialog(this.textEditor.getComponent()); + if (showSaveDialog == JFileChooser.APPROVE_OPTION) { + File file = saveFileDialog.getSelectedFile(); + writeFileContents(file, this.textEditor.getText()); + } + } + + private void writeFileContents(File file, byte[] text) { + try (FileWriter fileWriter = new FileWriter(file); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { + bufferedWriter.write(BurpExtender.getBurpExtenderCallbacks().getHelpers().bytesToString(text)); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, ex, "Error", JOptionPane.ERROR_MESSAGE); + } + + } + +}