diff --git a/README.md b/README.md index 48d6587..b203676 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,11 @@ Small Burp Suite Extension to generate multiple scan reports by host with just a 9. Select the output directory for the reports by clicking the "Select folder ..." button and selecting a directory. If the selected directory does not yet exist, it will be created when the reports are generated. 10. Select whether to append the date to the report filenames, and choose the desired date from the dropdown box. The report filenames will be in the following format: ```[FILENAME]-[DATE_FORMAT].[FORMAT]```. 1. The following date formats are available: MMDDYYYY, DDMMYYYY, YYYYMMDD, MMDDYY, DDMMYY, YYMMDD -11. Select whether to save generated reports to sub-directories by host (named after host). +11. Select whether to save generated reports to sub-directories by host (named after host and created when the reports are generated). 12. Once all options have been set, click the "Generate Report(s)" button to start report generation. 1. The status of the report generation will be displayed next to the button and will be updated in real time. 2. A more verbose status of the generation will be printed in the Extender->Output tab for the Extension. This will include a list of the absolute paths to every report file that is successfully generated. + 3. Any errors encountered during report generation will be printed to the Extender->Errors tab for the Extension. # Building Requires Java Development Kit 8 or higher, and Gradle 4 or higher. diff --git a/burp/BurpExtender.java b/burp/BurpExtender.java index 33aa18f..682cb03 100644 --- a/burp/BurpExtender.java +++ b/burp/BurpExtender.java @@ -1,7 +1,7 @@ /* BurpExtender.java - v0.3 (6/XX/2022) + v0.3 (6/24/2022) Small Burp Suite Extension to generate multiple scan reports by host with just a few clicks. Works with Burp Suite Professional only. */ @@ -18,6 +18,7 @@ import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JButton; +import javax.swing.JOptionPane; import javax.swing.SwingConstants; import java.awt.Component; import java.awt.GridLayout; @@ -35,7 +36,7 @@ import java.net.URL; import java.text.SimpleDateFormat; -public class BurpExtender implements IBurpExtender,ITab,ActionListener { +public class BurpExtender implements IBurpExtender,ITab,IExtensionStateListener,ActionListener { private IBurpExtenderCallbacks callbacks; private IExtensionHelpers helpers; private String name; @@ -48,11 +49,12 @@ public class BurpExtender implements IBurpExtender,ITab,ActionListener { private boolean mergeHttps; //merge http:80 and https:443 into one report private boolean mergeAll; //merge all protocols and ports into 1 report private File destDir; - private boolean fileDate; //append generation date to filename in format MMDDYYYY + private int fileDate; //append generation date to filename (if -1, then do not append; if >-1, append using format from DATE_FORMATS index) private boolean createSubDirectories; //create sub-directory for each report (named after host) //UI fields private JPanel component; + private JButton defaultSettingsButton; private JRadioButton htmlButton; private JRadioButton xmlButton; private JCheckBox includeHighSeverityCheck; @@ -77,7 +79,8 @@ public class BurpExtender implements IBurpExtender,ITab,ActionListener { //constants private static final String VERSION = "0.3"; - private static final String[] dateFormats = {"MMddyyyy","ddMMyyyy","yyyyMMdd","MMddyy","ddMMyy","yyMMdd"}; + private static final String[] DATE_FORMATS = {"MMddyyyy","ddMMyyyy","yyyyMMdd","MMddyy","ddMMyy","yyMMdd"}; + private static final String OPTION_PREFIX = "bort.batchreport"; //IBurpExtender methods @Override @@ -87,18 +90,45 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks cb) { name = "Batch Scan Report Generator"; callbacks.setExtensionName(name+" v"+VERSION); - //initialized default settings - reportFormat = "HTML"; - severities = new boolean[] {true,true,true,true,false}; - confidences = new boolean[] {true,true,true}; - inscopeOnly = true; - mergeHttps = true; - mergeAll = false; - destDir = new File(System.getProperty("java.io.tmpdir")); - fileDate = false; - createSubDirectories = false; + //initialize default settings, then restore saved settings (if any) + setDefaultOptions(); + String savedOption = callbacks.loadExtensionSetting(OPTION_PREFIX+".reportFormat"); + if(savedOption != null) reportFormat = savedOption; + savedOption = callbacks.loadExtensionSetting(OPTION_PREFIX+".severities"); + if(savedOption != null) { + String[] optionSplit = savedOption.split(","); + for(int i=0;i(); - for(int i=0;i reportFilenames = reportIssues.keySet(); if(reportFilenames.size()==0) { callbacks.printOutput("No reports generated: Sites matching requirements contained no issues to report!\n"); - callbacks.printError("No reports generated: Sites matching requirements contained no issues to report!"); + callbacks.printError("No reports generated: Sites matching requirements contained no issues to report!\n"); statusLabel.setText("No reports generated: Sites matching requirements contained no issues to report!"); reEnableUiElements(); return; @@ -505,9 +590,9 @@ public void run() { callbacks.printOutput("Generating report "+Integer.toString(count)+" of "+Integer.toString(reportFilenames.size())); statusLabel.setText("Generating report "+Integer.toString(count)+" of "+Integer.toString(reportFilenames.size())+"..."); IScanIssue[] issueList = reportIssues.get(filename); - if(fileDate) { + if(fileDate>-1) { filename = filename.substring(0,filename.length()-(reportFormat.toLowerCase().length()+1))+"-"; - SimpleDateFormat sdf = new SimpleDateFormat(dateFormats[dateFormatChooser.getSelectedIndex()]); + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMATS[fileDate]); filename += sdf.format(new Date())+"."+reportFormat.toLowerCase(); } File reportFile = null; @@ -542,7 +627,7 @@ public void run() { } else { callbacks.printOutput("No reports generated: No sites match requirements for report generation!\n"); - callbacks.printError("No reports generated: No sites match requirements for report generation!"); + callbacks.printError("No reports generated: No sites match requirements for report generation!\n"); statusLabel.setText("No reports generated: No sites match requirements for report generation!"); } @@ -553,6 +638,7 @@ public void run() { private void reEnableUiElements() { generateButton.setEnabled(true); generateButton.setText("Generate Report(s)"); + defaultSettingsButton.setEnabled(true); htmlButton.setEnabled(true); xmlButton.setEnabled(true); includeHighSeverityCheck.setEnabled(true); @@ -568,9 +654,40 @@ private void reEnableUiElements() { mergeAllCheck.setEnabled(true); destDirButton.setEnabled(true); filenameDateCheck.setEnabled(true); - dateFormatChooser.setEnabled(fileDate); + if(fileDate>-1) dateFormatChooser.setEnabled(true); createSubDirectoriesCheck.setEnabled(true); return; } } + + + //private "Default Settings Resetter" class + private class ResetSettingsThread implements Runnable { + @Override + public void run() { + int result = JOptionPane.showConfirmDialog(null,"Restore Batch Report Generation Settings to Defaults?","Restore Default Settings",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE); + if(result == JOptionPane.YES_OPTION) { + setDefaultOptions(); + htmlButton.setSelected(true); + xmlButton.setSelected(false); + includeHighSeverityCheck.setSelected(true); + includeMediumSeverityCheck.setSelected(true); + includeLowSeverityCheck.setSelected(true); + includeInformationSeverityCheck.setSelected(true); + includeFalsePositiveSeverityCheck.setSelected(false); + includeCertainConfidenceCheck.setSelected(true); + includeFirmConfidenceCheck.setSelected(true); + includeTentativeConfidenceCheck.setSelected(true); + inscopeCheck.setSelected(true); + httpsCheck.setSelected(true); + httpsCheck.setEnabled(true); + mergeAllCheck.setSelected(false); + destDirLabel.setText(destDir.getAbsolutePath()); + filenameDateCheck.setSelected(false); + dateFormatChooser.setSelectedIndex(0); + createSubDirectoriesCheck.setSelected(false); + callbacks.printOutput("Default settings restored."); + } + } + } } diff --git a/extender-snapshot.png b/extender-snapshot.png index d320b02..0acac30 100644 Binary files a/extender-snapshot.png and b/extender-snapshot.png differ