From 0b0da49cb468e07fa98d38d3c17c8f74a6f6f5d1 Mon Sep 17 00:00:00 2001 From: Corey <1339555+CoreyD97@users.noreply.github.com> Date: Fri, 2 Dec 2022 08:45:18 +0000 Subject: [PATCH] Upgrade to Montoya API --- build.gradle | 29 +- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/burp/BurpExtender.java | 23 -- .../LoggerContextMenuFactory.java | 72 +++-- .../loggerplusplus/LoggerPlusPlus.java | 157 ++++------ .../loggerplusplus/MainViewController.java | 16 +- .../exports/AutomaticLogExporter.java | 2 - .../exports/Base64Exporter.java | 6 +- .../exports/CSVExporterControlPanel.java | 3 +- .../exports/ElasticExporter.java | 12 +- .../exports/ElasticExporterConfigDialog.java | 3 +- .../exports/ExportController.java | 10 +- .../exports/HARExporterControlPanel.java | 3 +- .../loggerplusplus/exports/HarSerializer.java | 105 +++---- .../loggerplusplus/exports/JSONExporter.java | 3 +- .../exports/JSONExporterControlPanel.java | 3 +- .../filter/colorfilter/ColorFilter.java | 1 - .../loggerplusplus/filter/parser/Filter.jj | 3 +- .../loggerplusplus/filter/parser/Filter.jjt | 2 +- .../FilterLibraryController.java | 24 +- .../filterlibrary/FilterLibraryPanel.java | 1 - .../FilterLibraryTableModel.java | 5 +- .../grepper/GrepResultsTable.java | 3 +- .../grepper/GrepperController.java | 34 +-- .../loggerplusplus/grepper/GrepperPanel.java | 5 +- .../imports/ImportRequestResponse.java | 136 --------- .../loggerplusplus/imports/LoggerImport.java | 60 ++-- .../loggerplusplus/logentry/LogEntry.java | 283 +++++++++--------- .../logentry/LogEntryFieldSerializer.java | 4 - .../loggerplusplus/logging/BurpAppender.java | 40 +++ .../logging/JTextAreaAppender.java | 88 ------ .../logging/LoggingController.java | 49 +-- .../logview/LogViewController.java | 43 +-- .../logview/MultipleLogEntryMenu.java | 59 +++- .../logview/SingleLogEntryMenu.java | 60 +++- .../entryviewer/RequestViewerController.java | 80 ++--- .../entryviewer/RequestViewerPanel.java | 4 +- .../logview/logtable/LogTableColumn.java | 1 - .../logview/logtable/LogTableColumnModel.java | 1 - .../logview/logtable/TableHeader.java | 1 - .../logview/processor/EntryImportWorker.java | 51 +++- .../logview/processor/LogProcessor.java | 268 +++++++++++------ .../logview/processor/LogProcessorHelper.java | 20 +- .../preferences/LoggerPreferenceFactory.java | 12 +- .../preferences/PreferencesController.java | 42 ++- .../preferences/PreferencesPanel.java | 18 +- .../reflection/ReflectionController.java | 24 +- .../reflection/filter/BlacklistFilter.java | 8 +- .../reflection/filter/LengthFilter.java | 14 +- .../reflection/filter/ParameterFilter.java | 4 +- .../transformer/Base64EncodeTransformer.java | 1 - .../transformer/HTMLEscapeTransformer.java | 4 - .../transformer/HexEncodeTransformer.java | 1 - .../transformer/URLDecodeTransformer.java | 1 - .../nccgroup/loggerplusplus/util/Globals.java | 4 +- .../loggerplusplus/util/MoreHelp.java | 22 +- src/main/resources/log4j2.xml | 14 + src/test/java/Test.java | 5 + 58 files changed, 859 insertions(+), 1090 deletions(-) delete mode 100644 src/main/java/burp/BurpExtender.java delete mode 100644 src/main/java/com/nccgroup/loggerplusplus/imports/ImportRequestResponse.java create mode 100644 src/main/java/com/nccgroup/loggerplusplus/logging/BurpAppender.java delete mode 100644 src/main/java/com/nccgroup/loggerplusplus/logging/JTextAreaAppender.java create mode 100644 src/main/resources/log4j2.xml create mode 100644 src/test/java/Test.java diff --git a/build.gradle b/build.gradle index 9ca949e6..2b8bf9ff 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,11 @@ -apply plugin: 'java' +plugins { + id 'java' + id "io.freefair.lombok" version "6.5.1" +} + +sourceCompatibility = JavaVersion.VERSION_17 +targetCompatibility = JavaVersion.VERSION_17 -sourceCompatibility = 15 -targetCompatibility = 15 repositories { mavenCentral() @@ -11,18 +15,15 @@ repositories { } dependencies { - compileOnly 'net.portswigger.burp.extender:burp-extender-api:2.3' -// compileOnly 'net.portswigger.burp.extender:montoya-api:0.9.5' - compileOnly 'org.projectlombok:lombok:1.18.24' - annotationProcessor 'org.projectlombok:lombok:1.18.24' - + implementation 'net.portswigger.burp.extensions:montoya-api:0.10.1' implementation 'org.swinglabs:swingx:1.6.1' - implementation 'com.github.CoreyD97:BurpExtenderUtilities:e800fd2d' - implementation 'com.google.code.gson:gson:2.8.2' - implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.5.2' - implementation 'org.apache.httpcomponents:httpclient:4.5.6' - implementation 'org.apache.commons:commons-text:1.7' - implementation 'org.apache.logging.log4j:log4j-core:2.17.1' + implementation 'com.github.CoreyD97:BurpExtenderUtilities:896a540db7' + implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.15.2' + implementation 'org.apache.httpcomponents:httpclient:4.5.13' + implementation 'org.apache.commons:commons-text:1.10.0' + + implementation 'org.apache.logging.log4j:log4j-core:2.19.0' + testCompileOnly files("${System.properties['user.home']}/BurpSuitePro/burpsuite_pro.jar") } jar { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a25..ae04661e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java deleted file mode 100644 index c44293da..00000000 --- a/src/main/java/burp/BurpExtender.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// Burp Suite Logger++ -// -// Released as open source by NCC Group Plc - https://www.nccgroup.trust/ -// -// Developed by Soroush Dalili (@irsdl) -// -// Project link: http://www.github.com/nccgroup/BurpSuiteLoggerPlusPlus -// -// Released under AGPL see LICENSE for more information -// - -package burp; - -import com.nccgroup.loggerplusplus.LoggerPlusPlus; - - -public class BurpExtender extends LoggerPlusPlus -{ - public static void main(String [] args){ - System.out.println("You have built the Logger++. You shall play with the jar file now!"); - } -} diff --git a/src/main/java/com/nccgroup/loggerplusplus/LoggerContextMenuFactory.java b/src/main/java/com/nccgroup/loggerplusplus/LoggerContextMenuFactory.java index 1c462756..27d78531 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/LoggerContextMenuFactory.java +++ b/src/main/java/com/nccgroup/loggerplusplus/LoggerContextMenuFactory.java @@ -1,7 +1,10 @@ package com.nccgroup.loggerplusplus; -import burp.IContextMenuFactory; -import burp.IContextMenuInvocation; +import burp.api.montoya.core.Range; +import burp.api.montoya.http.message.HttpMessage; +import burp.api.montoya.ui.contextmenu.ContextMenuEvent; +import burp.api.montoya.ui.contextmenu.ContextMenuItemsProvider; +import burp.api.montoya.ui.contextmenu.MessageEditorHttpRequestResponse; import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter; import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter; import com.nccgroup.loggerplusplus.filter.parser.ParseException; @@ -19,53 +22,50 @@ import static com.nccgroup.loggerplusplus.util.Globals.PREF_COLOR_FILTERS; -public class LoggerContextMenuFactory implements IContextMenuFactory { - - private final LoggerPlusPlus loggerPlusPlus; +public class LoggerContextMenuFactory implements ContextMenuItemsProvider { - public LoggerContextMenuFactory(LoggerPlusPlus loggerPlusPlus){ - this.loggerPlusPlus = loggerPlusPlus; + public LoggerContextMenuFactory(){ } - + @Override - public List createMenuItems(IContextMenuInvocation invocation) { - if(invocation == null) return null; + public List provideMenuItems(ContextMenuEvent event) { JMenuItem filterMenu = new JMenu("Logger++"); - if (invocation.getSelectedMessages().length == 0 || - invocation.getSelectionBounds()[0] == invocation.getSelectionBounds()[1]) { - return null; - } + //We're handling a message editor context menu + //And we have a selection + MessageEditorHttpRequestResponse requestResponse = event.messageEditorRequestResponse().orElseThrow(); + Range selectedRange = requestResponse.selectionOffsets().orElseThrow(); + HttpMessage target; final LogEntryField context; final byte[] selectedBytes; - switch (invocation.getInvocationContext()){ - case IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST: - case IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_REQUEST: { + switch (event.invocationType()){ + case MESSAGE_EDITOR_REQUEST: + case MESSAGE_VIEWER_REQUEST: { + target = requestResponse.getRequestResponse().httpRequest(); try { - byte[] msg = invocation.getSelectedMessages()[0].getRequest(); - if (LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(msg).getBodyOffset() > invocation.getSelectionBounds()[0]) { + if (selectedRange.startIndexInclusive() <= target.bodyOffset()) { context = LogEntryField.REQUEST_HEADERS; } else { context = LogEntryField.REQUEST_BODY; } - selectedBytes = Arrays.copyOfRange(invocation.getSelectedMessages()[0].getRequest(), - invocation.getSelectionBounds()[0],invocation.getSelectionBounds()[1]); + selectedBytes = Arrays.copyOfRange(target.asBytes().getBytes(), selectedRange.startIndexInclusive(), + selectedRange.endIndexExclusive()); }catch (NullPointerException nPException){ return null; } break; } - case IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_RESPONSE: - case IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_RESPONSE: { + case MESSAGE_EDITOR_RESPONSE: + case MESSAGE_VIEWER_RESPONSE: { + target = requestResponse.getRequestResponse().httpResponse(); try { - byte[] msg = invocation.getSelectedMessages()[0].getResponse(); - if (LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(msg).getBodyOffset() > invocation.getSelectionBounds()[0]) { + if (selectedRange.startIndexInclusive() <= target.bodyOffset()) { context = LogEntryField.RESPONSE_HEADERS; } else { context = LogEntryField.RESPONSE_BODY; } - selectedBytes = Arrays.copyOfRange(invocation.getSelectedMessages()[0].getResponse(), - invocation.getSelectionBounds()[0], invocation.getSelectionBounds()[1]); + selectedBytes = Arrays.copyOfRange(target.asBytes().getBytes(), selectedRange.startIndexInclusive(), + selectedRange.endIndexExclusive()); } catch (NullPointerException nPException) { return null; } @@ -75,15 +75,13 @@ public List createMenuItems(IContextMenuInvocation invocation) { return null; } - if (selectedBytes != null) System.out.println(new String(selectedBytes)); - - final LogTable logTable = loggerPlusPlus.getLogViewController().getLogTableController().getLogTable(); + final LogTable logTable = LoggerPlusPlus.instance.getLogViewController().getLogTableController().getLogTable(); String selectedText = StringEscapeUtils.escapeJava(new String(selectedBytes)); JMenuItem useAsFilter = new JMenuItem(new AbstractAction("Use Selection As LogFilter") { @Override public void actionPerformed(ActionEvent actionEvent) { - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(context.getFullLabel() + + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(context.getFullLabel() + " CONTAINS \"" + selectedText + "\""); } }); @@ -95,7 +93,7 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem andFilter = new JMenuItem(new AbstractAction("AND") { @Override public void actionPerformed(ActionEvent actionEvent) { - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && " + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && " + "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\""); } }); @@ -103,7 +101,7 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem andNotFilter = new JMenuItem(new AbstractAction("AND NOT") { @Override public void actionPerformed(ActionEvent actionEvent) { - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && !(" + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && !(" + "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\")"); } }); @@ -111,7 +109,7 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem orFilter = new JMenuItem(new AbstractAction("OR") { @Override public void actionPerformed(ActionEvent actionEvent) { - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " || " + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " || " + context.getFullLabel() + " CONTAINS \"" + selectedText + "\""); } }); @@ -126,11 +124,11 @@ public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) { try { ColorFilter colorFilter = new ColorFilter(); - colorFilter.setFilter(new LogFilter(loggerPlusPlus.getLibraryController(), + colorFilter.setFilter(new LogFilter(LoggerPlusPlus.instance.getLibraryController(), context.getFullLabel() + " CONTAINS \"" + selectedText + "\"")); - HashMap colorFilters = loggerPlusPlus.getPreferencesController().getPreferences().getSetting(PREF_COLOR_FILTERS); + HashMap colorFilters = LoggerPlusPlus.instance.getPreferencesController().getPreferences().getSetting(PREF_COLOR_FILTERS); colorFilters.put(colorFilter.getUUID(), colorFilter); - new ColorFilterDialog(loggerPlusPlus.getLibraryController()).setVisible(true); + new ColorFilterDialog(LoggerPlusPlus.instance.getLibraryController()).setVisible(true); } catch (ParseException e) { return; } diff --git a/src/main/java/com/nccgroup/loggerplusplus/LoggerPlusPlus.java b/src/main/java/com/nccgroup/loggerplusplus/LoggerPlusPlus.java index 3702d89f..6d913370 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/LoggerPlusPlus.java +++ b/src/main/java/com/nccgroup/loggerplusplus/LoggerPlusPlus.java @@ -1,8 +1,7 @@ package com.nccgroup.loggerplusplus; -import burp.IBurpExtender; -import burp.IBurpExtenderCallbacks; -import burp.IExtensionStateListener; +import burp.api.montoya.BurpExtension; +import burp.api.montoya.MontoyaApi; import com.coreyd97.BurpExtenderUtilities.DefaultGsonProvider; import com.coreyd97.BurpExtenderUtilities.IGsonProvider; import com.nccgroup.loggerplusplus.exports.ExportController; @@ -16,11 +15,12 @@ import com.nccgroup.loggerplusplus.reflection.ReflectionController; import com.nccgroup.loggerplusplus.util.Globals; import com.nccgroup.loggerplusplus.util.userinterface.LoggerMenu; +import lombok.Getter; +import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.Level; import javax.swing.*; import java.awt.*; -import java.net.URL; import java.util.Arrays; import java.util.List; @@ -29,12 +29,17 @@ /** * Created by corey on 07/09/17. */ -public class LoggerPlusPlus implements IBurpExtender, IExtensionStateListener { +@Log4j2 +@Getter +public class LoggerPlusPlus implements BurpExtension { + + private static String NAME = "Logger++"; + + public static LoggingController loggingController; public static LoggerPlusPlus instance; - public static IBurpExtenderCallbacks callbacks; + public static MontoyaApi montoya; + public static IGsonProvider gsonProvider = new DefaultGsonProvider(); - private final IGsonProvider gsonProvider; - private LoggingController loggingController; private LogProcessor logProcessor; private ExportController exportController; private PreferencesController preferencesController; @@ -48,70 +53,56 @@ public class LoggerPlusPlus implements IBurpExtender, IExtensionStateListener { //UX private LoggerMenu loggerMenu; - - public LoggerPlusPlus(){ - this.gsonProvider = new DefaultGsonProvider(); + public LoggerPlusPlus() { + LoggerPlusPlus.instance = this; } @Override - public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) - { - - //Fix Darcula's issue with JSpinner UI. - try { - Class spinnerUI = Class.forName("com.bulenkov.darcula.ui.DarculaSpinnerUI"); - UIManager.put("com.bulenkov.darcula.ui.DarculaSpinnerUI", spinnerUI); - Class sliderUI = Class.forName("com.bulenkov.darcula.ui.DarculaSliderUI"); - UIManager.put("com.bulenkov.darcula.ui.DarculaSliderUI", sliderUI); - } catch (ClassNotFoundException e) { - //Darcula is not installed. - } + public void initialize(MontoyaApi montoya) { + //Woohoo! Montoya! + LoggerPlusPlus.montoya = montoya; + montoya.extension().setName(NAME); + montoya.extension().registerUnloadingHandler(this::unloadExtension); - //Burp Specific - LoggerPlusPlus.instance = this; - LoggerPlusPlus.callbacks = callbacks; - callbacks.setExtensionName("Logger++"); - LoggerPlusPlus.callbacks.registerExtensionStateListener(LoggerPlusPlus.this); + //TODO Set Logging Level from prefs + loggingController = new LoggingController(gsonProvider, montoya); + log.info("Logging configured"); - loggingController = new LoggingController(gsonProvider); - preferencesController = new PreferencesController(this); + preferencesController = new PreferencesController(montoya); preferencesController.getPreferences().addSettingListener((source, settingName, newValue) -> { if (settingName.equals(Globals.PREF_LOG_LEVEL)) { loggingController.setLogLevel((Level) newValue); } }); reflectionController = new ReflectionController(preferencesController.getPreferences()); - exportController = new ExportController(this, preferencesController.getPreferences()); - libraryController = new FilterLibraryController(this, preferencesController); - logViewController = new LogViewController(this, libraryController); - logProcessor = new LogProcessor(this, logViewController.getLogTableController(), exportController); - grepperController = new GrepperController(this, logViewController.getLogTableController(), preferencesController); - contextMenuFactory = new LoggerContextMenuFactory(this); - - mainViewController = new MainViewController(this); - - LoggerPlusPlus.callbacks.registerContextMenuFactory(contextMenuFactory); - - - SwingUtilities.invokeLater(() -> { - - LoggerPlusPlus.callbacks.addSuiteTab(mainViewController); - - //Add menu item to Burp's frame menu. - JFrame rootFrame = (JFrame) SwingUtilities.getWindowAncestor(mainViewController.getUiComponent()); - try{ - JMenuBar menuBar = rootFrame.getJMenuBar(); - loggerMenu = new LoggerMenu(LoggerPlusPlus.this); - menuBar.add(loggerMenu, menuBar.getMenuCount() - 1); - }catch (NullPointerException nPException){ - loggerMenu = null; - } - }); + exportController = new ExportController(preferencesController.getPreferences()); + libraryController = new FilterLibraryController(preferencesController); + logViewController = new LogViewController(libraryController); + logProcessor = new LogProcessor(logViewController.getLogTableController(), exportController); + grepperController = new GrepperController(logViewController.getLogTableController(), preferencesController); + contextMenuFactory = new LoggerContextMenuFactory(); + mainViewController = new MainViewController(); + + + montoya.userInterface().registerContextMenuItemsProvider(contextMenuFactory); + montoya.userInterface().registerSuiteTab(NAME, mainViewController.getUiComponent()); + + montoya.http().registerHttpHandler(logProcessor.getHttpHandler()); + montoya.proxy().registerResponseHandler(logProcessor.getProxyHttpResponseHandler()); + + //Add menu item to Burp's frame menu. + JFrame rootFrame = (JFrame) SwingUtilities.getWindowAncestor(mainViewController.getUiComponent()); + try{ + JMenuBar menuBar = rootFrame.getJMenuBar(); + loggerMenu = new LoggerMenu(LoggerPlusPlus.this); + menuBar.add(loggerMenu, menuBar.getMenuCount() - 1); + }catch (NullPointerException nPException){ + loggerMenu = null; + } } - @Override - public void extensionUnloaded() { + public void unloadExtension() { if(loggerMenu != null && loggerMenu.getParent() != null){ loggerMenu.getParent().remove(loggerMenu); } @@ -127,63 +118,17 @@ public void extensionUnloaded() { //Null out static variables so not leftover. LoggerPlusPlus.instance = null; - LoggerPlusPlus.callbacks = null; } - public static boolean isUrlInScope(URL url){ + public static boolean isUrlInScope(String url){ return (!(Boolean) instance.getPreferencesController().getPreferences().getSetting(PREF_RESTRICT_TO_SCOPE) - || callbacks.isInScope(url)); - } - - - public LogViewController getLogViewController() { - return logViewController; - } - - public IGsonProvider getGsonProvider() { - return gsonProvider; - } - - public GrepperController getGrepperController() { - return grepperController; - } - - public MainViewController getMainViewController() { - return mainViewController; - } - - public FilterLibraryController getLibraryController() { - return libraryController; - } - - public LoggingController getLoggingController() { - return loggingController; - } - - public PreferencesController getPreferencesController() { - return preferencesController; - } - - public LogProcessor getLogProcessor() { - return logProcessor; - } - - public ReflectionController getReflectionController() { - return reflectionController; - } - - public LoggerMenu getLoggerMenu() { - return loggerMenu; + || montoya.scope().isInScope(url)); } public List getLogEntries(){ return logViewController.getLogTableController().getLogTableModel().getData(); } - public ExportController getExportController() { - return exportController; - } - public Frame getLoggerFrame() { if (mainViewController == null) { return Arrays.stream(JFrame.getFrames()).filter(frame -> { diff --git a/src/main/java/com/nccgroup/loggerplusplus/MainViewController.java b/src/main/java/com/nccgroup/loggerplusplus/MainViewController.java index 7bba5682..f7c7ccd5 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/MainViewController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/MainViewController.java @@ -1,6 +1,5 @@ package com.nccgroup.loggerplusplus; -import burp.ITab; import com.coreyd97.BurpExtenderUtilities.PopOutPanel; import com.nccgroup.loggerplusplus.about.AboutPanel; import com.nccgroup.loggerplusplus.help.HelpPanel; @@ -9,15 +8,14 @@ import javax.swing.*; import java.awt.*; -public class MainViewController implements ITab { - - private final LoggerPlusPlus loggerPlusPlus; +public class MainViewController { + private final JTabbedPane tabbedPane; private final PopOutPanel popOutWrapper; - public MainViewController(LoggerPlusPlus loggerPlusPlus) { - this.loggerPlusPlus = loggerPlusPlus; + public MainViewController() { this.tabbedPane = new JTabbedPane(); + LoggerPlusPlus loggerPlusPlus = LoggerPlusPlus.instance; tabbedPane.addTab("View Logs", null, loggerPlusPlus.getLogViewController().getLogViewPanel(), null); tabbedPane.addTab("Filter Library", null, loggerPlusPlus.getLibraryController().getFilterLibraryPanel(), null); tabbedPane.addTab("Grep Values", null, loggerPlusPlus.getGrepperController().getGrepperPanel(), null); @@ -27,12 +25,6 @@ public MainViewController(LoggerPlusPlus loggerPlusPlus) { this.popOutWrapper = new PopOutPanel(tabbedPane, Globals.APP_NAME); } - @Override - public String getTabCaption() { - return Globals.APP_NAME; - } - - @Override public Component getUiComponent() { return popOutWrapper; } diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/AutomaticLogExporter.java b/src/main/java/com/nccgroup/loggerplusplus/exports/AutomaticLogExporter.java index 6e1d077c..f2649ff3 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/AutomaticLogExporter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/AutomaticLogExporter.java @@ -3,8 +3,6 @@ import com.coreyd97.BurpExtenderUtilities.Preferences; import com.nccgroup.loggerplusplus.logentry.LogEntry; -import javax.swing.*; - public abstract class AutomaticLogExporter extends LogExporter { protected AutomaticLogExporter(ExportController exportController, Preferences preferences){ diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/Base64Exporter.java b/src/main/java/com/nccgroup/loggerplusplus/exports/Base64Exporter.java index 7b3262e8..e83b9d1c 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/Base64Exporter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/Base64Exporter.java @@ -39,19 +39,19 @@ public void exportEntries(List entries, boolean includeRequest, boolea protected Void doInBackground() throws Exception { super.doInBackground(); try (FileWriter fileWriter = new FileWriter(file, false)) { - Gson gson = exportController.getLoggerPlusPlus().getGsonProvider().getGson(); + Gson gson = LoggerPlusPlus.gsonProvider.getGson(); ArrayList jsonEntries = new ArrayList<>(); Base64.Encoder encoder = Base64.getEncoder(); for (LogEntry entry : entries) { JsonObject jsonEntry = new JsonObject(); if (includeRequest) { jsonEntry.addProperty("request", - encoder.encodeToString(entry.getRequest())); + encoder.encodeToString(entry.getRequestBytes())); } if (includeResponse) { jsonEntry.addProperty("response", - encoder.encodeToString(entry.getResponse())); + encoder.encodeToString(entry.getResponseBytes())); } jsonEntries.add(jsonEntry); } diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporterControlPanel.java b/src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporterControlPanel.java index 283cabbf..56b57079 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporterControlPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporterControlPanel.java @@ -2,6 +2,7 @@ import com.coreyd97.BurpExtenderUtilities.Alignment; import com.coreyd97.BurpExtenderUtilities.PanelBuilder; +import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import javax.swing.*; @@ -19,7 +20,7 @@ public class CSVExporterControlPanel extends JPanel { JButton manualSaveButton = new JButton("Export as CSV"); manualSaveButton.addActionListener(actionEvent -> { - final List entries = csvExporter.getExportController().getLoggerPlusPlus().getLogEntries(); + final List entries = LoggerPlusPlus.instance.getLogEntries(); csvExporter.exportEntries(entries); }); diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java b/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java index 565c7923..52a79fd1 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java @@ -8,6 +8,7 @@ import com.nccgroup.loggerplusplus.logentry.LogEntryField; import com.nccgroup.loggerplusplus.logentry.Status; import com.nccgroup.loggerplusplus.util.Globals; +import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; import org.apache.http.HttpHost; @@ -40,6 +41,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +@Log4j2 public class ElasticExporter extends AutomaticLogExporter implements ExportPanelProvider, ContextMenuExportProvider { RestHighLevelClient httpClient; @@ -95,7 +97,7 @@ void setup() throws Exception { if (!StringUtils.isBlank(filterString)) { try { - logFilter = new LogFilter(exportController.getLoggerPlusPlus().getLibraryController(), filterString); + logFilter = new LogFilter(LoggerPlusPlus.instance.getLibraryController(), filterString); } catch (ParseException ex) { logger.error("The log filter configured for the Elastic exporter is invalid!", ex); } @@ -197,8 +199,8 @@ public IndexRequest buildIndexRequest(LogEntry logEntry) throws IOException { builder.field(field.getFullLabel(), value); } }catch (Exception e){ - LoggerPlusPlus.callbacks.printError("ElasticExporter: " + value); - LoggerPlusPlus.callbacks.printError("ElasticExporter: " + e.getMessage()); + log.error("ElasticExporter: " + value); + log.error("ElasticExporter: " + e.getMessage()); throw e; } } @@ -224,7 +226,7 @@ private void indexPendingEntries(){ IndexRequest request = buildIndexRequest(logEntry); httpBulkBuilder.add(request); } catch (Exception e) { - LoggerPlusPlus.callbacks.printError("Could not build elastic export request for entry: " + e.getMessage()); + log.error("Could not build elastic export request for entry: " + e.getMessage()); //Could not build index request. Ignore it? } } @@ -233,7 +235,7 @@ private void indexPendingEntries(){ BulkResponse bulkResponse = httpClient.bulk(httpBulkBuilder, RequestOptions.DEFAULT); if (bulkResponse.hasFailures()) { for (BulkItemResponse bulkItemResponse : bulkResponse.getItems()) { - LoggerPlusPlus.callbacks.printError(bulkItemResponse.getFailureMessage()); + log.error(bulkItemResponse.getFailureMessage()); } } connectFailedCounter = 0; diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporterConfigDialog.java b/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporterConfigDialog.java index a43e93b2..ced2aedc 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporterConfigDialog.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporterConfigDialog.java @@ -221,8 +221,7 @@ public void windowClosing(WindowEvent e) { String logFilter = preferences.getSetting(PREF_ELASTIC_FILTER); if (!StringUtils.isBlank(logFilter)) { - FilterLibraryController libraryController = elasticExporter.getExportController() - .getLoggerPlusPlus().getLibraryController(); + FilterLibraryController libraryController = LoggerPlusPlus.instance.getLibraryController(); try { new LogFilter(libraryController, logFilter); } catch (ParseException ex) { diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/ExportController.java b/src/main/java/com/nccgroup/loggerplusplus/exports/ExportController.java index 70b68d43..2d77bb65 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/ExportController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/ExportController.java @@ -1,7 +1,6 @@ package com.nccgroup.loggerplusplus.exports; import com.coreyd97.BurpExtenderUtilities.Preferences; -import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import java.util.ArrayList; @@ -10,14 +9,11 @@ import java.util.List; public class ExportController { - - private final LoggerPlusPlus loggerPlusPlus; private final Preferences preferences; private final HashMap, LogExporter> exporters; private final List enabledExporters; - public ExportController(LoggerPlusPlus loggerPlusPlus, Preferences preferences) { - this.loggerPlusPlus = loggerPlusPlus; + public ExportController(Preferences preferences) { this.preferences = preferences; this.exporters = new HashMap<>(); @@ -63,8 +59,4 @@ public void exportUpdatedEntry(LogEntry logEntry) { exporter.exportUpdatedEntry(logEntry); } } - - public LoggerPlusPlus getLoggerPlusPlus() { - return loggerPlusPlus; - } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/HARExporterControlPanel.java b/src/main/java/com/nccgroup/loggerplusplus/exports/HARExporterControlPanel.java index e43203f4..c7c8e3fd 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/HARExporterControlPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/HARExporterControlPanel.java @@ -2,6 +2,7 @@ import com.coreyd97.BurpExtenderUtilities.Alignment; import com.coreyd97.BurpExtenderUtilities.PanelBuilder; +import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import javax.swing.*; @@ -14,7 +15,7 @@ public class HARExporterControlPanel extends JPanel { JButton manualSaveButton = new JButton("Export as HAR"); manualSaveButton.addActionListener(actionEvent -> { - final List entries = harExporter.getExportController().getLoggerPlusPlus().getLogEntries(); + final List entries = LoggerPlusPlus.instance.getLogEntries(); harExporter.exportEntries(entries); }); diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/HarSerializer.java b/src/main/java/com/nccgroup/loggerplusplus/exports/HarSerializer.java index 942d05f1..9fdee06c 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/HarSerializer.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/HarSerializer.java @@ -1,13 +1,13 @@ package com.nccgroup.loggerplusplus.exports; -import burp.ICookie; -import burp.IParameter; -import burp.IRequestInfo; -import burp.IResponseInfo; +import burp.api.montoya.http.message.cookies.Cookie; +import burp.api.montoya.http.message.headers.HttpHeader; +import burp.api.montoya.http.message.params.HttpParameter; +import burp.api.montoya.http.message.params.HttpParameterType; +import burp.api.montoya.http.message.requests.HttpRequest; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import com.nccgroup.loggerplusplus.logentry.LogEntryField; @@ -60,43 +60,37 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti writer.name("time").value(time); writer.name("request").beginObject(); writer.name("method").value(logEntry.getMethod()); - writer.name("url").value(logEntry.getUrl().toString()); + writer.name("url").value(logEntry.getUrlString().toString()); writer.name("httpVersion").value(logEntry.getRequestHttpVersion()); writer.name("origin").value(logEntry.getOrigin()); writer.name("cookies").beginArray(); if (logEntry.isHasCookieParam()) { - List cookies = getRequestParametersByType(logEntry.getRequest(), - IParameter.PARAM_COOKIE); - for (IParameter cookie : cookies) { + List cookies = getRequestParametersByType(logEntry.getRequest(), HttpParameterType.COOKIE); + for (HttpParameter cookie : cookies) { writer.beginObject(); - writer.name("name").value(cookie.getName()); - writer.name("value").value(cookie.getValue()); + writer.name("name").value(cookie.name()); + writer.name("value").value(cookie.value()); writer.endObject(); } } writer.endArray(); // end request cookies array writer.name("headers").beginArray(); - for (String headerString : logEntry.getRequestHeaders()) { - if (headerString.contains(":")) { - writer.beginObject(); - String headerArray[] = headerString.split(":", 2); - writer.name("name").value(headerArray[0]); - writer.name("value").value(headerArray[1].trim()); - writer.endObject(); - } + for (HttpHeader header : logEntry.getRequestHeaders()) { + writer.beginObject(); + writer.name("name").value(header.name()); + writer.name("value").value(header.value()); + writer.endObject(); } writer.endArray(); // end request headers array writer.name("queryString").beginArray(); if (logEntry.getUrl().getQuery() != null) { - List queryParams = getRequestParametersByType(logEntry.getRequest(), - IParameter.PARAM_URL); - for (IParameter queryParam : queryParams) { + for (HttpParameter queryParam : getRequestParametersByType(logEntry.getRequest(), HttpParameterType.URL)) { writer.beginObject(); - writer.name("name").value(queryParam.getName()); - writer.name("value").value(queryParam.getValue()); + writer.name("name").value(queryParam.name()); + writer.name("value").value(queryParam.value()); writer.endObject(); } } @@ -105,12 +99,11 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti if (logEntry.isHasBodyParam()) { writer.name("postData").beginObject(); writer.name("mimeType").value(logEntry.getRequestContentType()); - List bodyParams = getRequestBodyParameters(logEntry.getRequest()); writer.name("params").beginArray(); - for (IParameter bodyParam : bodyParams) { + for (HttpParameter bodyParam : getRequestParametersByType(logEntry.getRequest(), HttpParameterType.BODY)) { writer.beginObject(); - writer.name("name").value(bodyParam.getName()); - writer.name("value").value(bodyParam.getValue()); + writer.name("name").value(bodyParam.name()); + writer.name("value").value(bodyParam.value()); writer.endObject(); } writer.endArray(); // end params array @@ -118,7 +111,7 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti writer.endObject(); // end postData object } - writer.name("headersSize").value(logEntry.getRequest().length - logEntry.getRequestBodyLength()); + writer.name("headersSize").value(logEntry.getRequestBytes().length - logEntry.getRequestBodyLength()); writer.name("bodySize").value(logEntry.getRequestBodyLength()); writer.endObject(); // end request object @@ -130,14 +123,14 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti writer.name("cookies").beginArray(); if (logEntry.isHasSetCookies()) { - List cookies = getResponseCookies(logEntry.getResponse()); + List cookies = logEntry.getResponse().cookies(); - for (ICookie cookie : cookies) { + for (Cookie cookie : cookies) { writer.beginObject(); - writer.name("name").value(cookie.getName()); - writer.name("value").value(cookie.getValue()); - writer.name("path").value(cookie.getPath()); - writer.name("domain").value(cookie.getDomain()); + writer.name("name").value(cookie.name()); + writer.name("value").value(cookie.value()); + writer.name("path").value(cookie.path()); + writer.name("domain").value(cookie.domain()); writer.endObject(); } } @@ -145,21 +138,18 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti writer.name("headers").beginArray(); if (logEntry.getResponseHeaders() != null) { - for (String headerString : logEntry.getResponseHeaders()) { - if (headerString.contains(":")) { - writer.beginObject(); - String headerArray[] = headerString.split(":", 2); - writer.name("name").value(headerArray[0]); - writer.name("value").value(headerArray[1].trim()); - writer.endObject(); - } + for (HttpHeader header : logEntry.getResponseHeaders()) { + writer.beginObject(); + writer.name("name").value(header.name()); + writer.name("value").value(header.value()); + writer.endObject(); } } writer.endArray(); // end response headers array writer.name("redirectURL").value(String.valueOf(logEntry.getValueByKey(LogEntryField.REDIRECT_URL))); - if (logEntry.getResponse() != null) { - writer.name("headersSize").value(logEntry.getResponse().length - logEntry.getResponseBodyLength()); + if (logEntry.getResponseBytes() != null) { + writer.name("headersSize").value(logEntry.getResponseBytes().length - logEntry.getResponseBodyLength()); writer.name("bodySize").value(logEntry.getResponseBodyLength()); } else { writer.name("headersSize").value(0); @@ -169,7 +159,7 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti writer.name("content").beginObject(); // start content object writer.name("size").value(logEntry.getResponseBodyLength()); - writer.name("mimeType").value(logEntry.getResponseMimeType()); + writer.name("mimeType").value(logEntry.getResponseContentType()); writer.name("text").value(String.valueOf(logEntry.getValueByKey(LogEntryField.RESPONSE_BODY))); writer.endObject(); //end content object @@ -195,32 +185,17 @@ public void write(JsonWriter writer, List logEntries) throws IOExcepti } - private List getRequestParametersByType(byte[] request, byte paramType) { - IRequestInfo tempAnalyzedReq = LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(request); - List params = tempAnalyzedReq.getParameters().stream() - .filter(iParameter -> iParameter.getType() == paramType).collect(Collectors.toList()); - return params; - } - - private List getRequestBodyParameters(byte[] request) { - IRequestInfo tempAnalyzedReq = LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(request); - List params = tempAnalyzedReq.getParameters().stream() - .filter(iParameter -> iParameter.getType() != IParameter.PARAM_COOKIE - && iParameter.getType() != IParameter.PARAM_URL) + private List getRequestParametersByType(HttpRequest request, HttpParameterType paramType) { + return request.parameters().stream() + .filter(iParameter -> iParameter.type().equals(paramType)) .collect(Collectors.toList()); - return params; } + @Override public List read(JsonReader reader) throws IOException { // TODO Implement HAR Import logic return null; } - private List getResponseCookies(byte[] responseMessage) { - IResponseInfo tempAnalyzedResp = LoggerPlusPlus.callbacks.getHelpers().analyzeResponse(responseMessage); - - return tempAnalyzedResp.getCookies(); - } - } diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporter.java b/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporter.java index 52967d35..69a67da5 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporter.java @@ -2,6 +2,7 @@ import com.coreyd97.BurpExtenderUtilities.Preferences; import com.google.gson.Gson; +import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import com.nccgroup.loggerplusplus.util.MoreHelp; import com.nccgroup.loggerplusplus.util.SwingWorkerWithProgressDialog; @@ -41,7 +42,7 @@ public void exportEntries(List entries) { protected Void doInBackground() throws Exception { super.doInBackground(); try(FileWriter fileWriter = new FileWriter(file, false)) { - Gson gson = exportController.getLoggerPlusPlus().getGsonProvider().getGson(); + Gson gson = LoggerPlusPlus.gsonProvider.getGson(); gson.toJson(entries, fileWriter); } diff --git a/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporterControlPanel.java b/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporterControlPanel.java index 3a18f41d..4df2f260 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporterControlPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporterControlPanel.java @@ -2,6 +2,7 @@ import com.coreyd97.BurpExtenderUtilities.Alignment; import com.coreyd97.BurpExtenderUtilities.PanelBuilder; +import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import javax.swing.*; @@ -15,7 +16,7 @@ public class JSONExporterControlPanel extends JPanel { JButton manualSaveButton = new JButton("Export as JSON"); manualSaveButton.addActionListener(actionEvent -> { - final List entries = jsonExporter.getExportController().getLoggerPlusPlus().getLogEntries(); + final List entries = LoggerPlusPlus.instance.getLogEntries(); jsonExporter.exportEntries(entries); }); diff --git a/src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/ColorFilter.java b/src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/ColorFilter.java index 34587874..645257f3 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/ColorFilter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/ColorFilter.java @@ -1,7 +1,6 @@ package com.nccgroup.loggerplusplus.filter.colorfilter; import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter; -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilterController; import com.nccgroup.loggerplusplus.filter.parser.ParseException; import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController; diff --git a/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jj b/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jj index 177cda81..da4eaa6f 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jj +++ b/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jj @@ -12,7 +12,7 @@ PARSER_BEGIN(FilterParser) package com.nccgroup.loggerplusplus.filter.parser; -import com.nccgroup.loggerplusplus.filter.ComparisonOperator;import com.nccgroup.loggerplusplus.filter.LogicalOperator; +import com.nccgroup.loggerplusplus.filter.LogicalOperator; import com.nccgroup.loggerplusplus.filter.ComparisonOperator; import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController; import java.io.StringReader; @@ -50,6 +50,7 @@ public class FilterParser/*@bgen(jjtree)*/implements FilterParserTreeConstants/* private static void throwOperatorAmbiguityException(LogicalOperator op, LogicalOperator other) throws ParseException { throw new ParseException(String.format("Cannot mix operators %s, %s. Please use parenthesis to remove ambiguity.", op.getLabel(), other.getLabel())); } +}} } PARSER_END(FilterParser) diff --git a/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jjt b/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jjt index b86eccbb..756879d3 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jjt +++ b/src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jjt @@ -12,7 +12,6 @@ options { PARSER_BEGIN(FilterParser) package com.nccgroup.loggerplusplus.filter.parser; import com.nccgroup.loggerplusplus.filter.ComparisonOperator;import com.nccgroup.loggerplusplus.filter.LogicalOperator; -import com.nccgroup.loggerplusplus.filter.ComparisonOperator; import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController; import java.io.StringReader; import java.math.BigDecimal; @@ -46,6 +45,7 @@ public class FilterParser { private static void throwOperatorAmbiguityException(LogicalOperator op, LogicalOperator other) throws ParseException { throw new ParseException(String.format("Cannot mix operators %s, %s. Please use parenthesis to remove ambiguity.", op.getLabel(), other.getLabel())); } +}} } PARSER_END(FilterParser) diff --git a/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryController.java b/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryController.java index e2cff819..dc67760f 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryController.java @@ -10,6 +10,7 @@ import com.nccgroup.loggerplusplus.filter.tag.TagListener; import com.nccgroup.loggerplusplus.preferences.PreferencesController; import com.nccgroup.loggerplusplus.util.Globals; +import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -18,9 +19,9 @@ import java.util.HashMap; import java.util.UUID; +@Log4j2 public class FilterLibraryController { - private final LoggerPlusPlus loggerPlusPlus; private final Preferences preferences; private final FilterLibraryPanel panel; private final ArrayList listeners; @@ -30,10 +31,7 @@ public class FilterLibraryController { private final HashMap tagFilters; private final ArrayList tagListeners; - Logger logger = LogManager.getRootLogger(); - - public FilterLibraryController(LoggerPlusPlus loggerPlusPlus, PreferencesController preferencesController) { - this.loggerPlusPlus = loggerPlusPlus; + public FilterLibraryController(PreferencesController preferencesController) { this.preferences = preferencesController.getPreferences(); this.listeners = new ArrayList<>(); this.colorFilterListeners = new ArrayList<>(); @@ -44,10 +42,6 @@ public FilterLibraryController(LoggerPlusPlus loggerPlusPlus, PreferencesControl this.panel = new FilterLibraryPanel(this); } - public LoggerPlusPlus getLoggerPlusPlus() { - return loggerPlusPlus; - } - public FilterLibraryPanel getFilterLibraryPanel() { return panel; } @@ -119,7 +113,7 @@ public void addColorFilter(ColorFilter colorFilter){ try { colorFilterListener.onColorFilterAdd(colorFilter); } catch (Exception e) { - logger.error(e); + log.error(e); } } saveColorFilters(); @@ -133,7 +127,7 @@ public void removeColorFilter(ColorFilter colorFilter){ try{ listener.onColorFilterRemove(colorFilter); }catch (Exception e){ - logger.error(e); + log.error(e); } } saveColorFilters(); @@ -145,7 +139,7 @@ public void updateColorFilter(ColorFilter colorFilter){ try{ listener.onColorFilterChange(colorFilter); }catch (Exception e){ - logger.error(e); + log.error(e); } } saveColorFilters(); @@ -174,7 +168,7 @@ public void addTag(Tag tag) { try { listener.onTagAdd(tag); } catch (Exception error) { - logger.error(error); + log.error(error); } } saveTags(); @@ -188,7 +182,7 @@ public void removeTag(Tag tag) { try { listener.onTagRemove(tag); } catch (Exception error) { - logger.error(error); + log.error(error); } } saveTags(); @@ -200,7 +194,7 @@ public void updateTag(Tag tag) { try { listener.onTagChange(tag); } catch (Exception e) { - logger.error(e); + log.error(e); } } saveTags(); diff --git a/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryPanel.java b/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryPanel.java index b2d5b752..52ec15b5 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryPanel.java @@ -1,6 +1,5 @@ package com.nccgroup.loggerplusplus.filterlibrary; -import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.filter.parser.ParseException; import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter; import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer; diff --git a/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryTableModel.java b/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryTableModel.java index 7285e2da..a9b1ebaf 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryTableModel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryTableModel.java @@ -1,6 +1,5 @@ package com.nccgroup.loggerplusplus.filterlibrary; -import burp.BurpExtender; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter; import com.nccgroup.loggerplusplus.filter.parser.ParseException; @@ -90,8 +89,8 @@ public void onClick(int row, int col) { if(row < 0 || row >= controller.getSavedFilters().size()) return; SavedFilter savedFilter = controller.getSavedFilters().get(row); if(col == 2){ - controller.getLoggerPlusPlus().getLogViewController().getLogFilterController().setFilter(savedFilter.getFilterString()); - controller.getLoggerPlusPlus().getMainViewController().getTabbedPanel().setSelectedIndex(0); + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(savedFilter.getFilterString()); + LoggerPlusPlus.instance.getMainViewController().getTabbedPanel().setSelectedIndex(0); return; } if(col == 3){ diff --git a/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepResultsTable.java b/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepResultsTable.java index 6e263b9a..cc3da9b1 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepResultsTable.java +++ b/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepResultsTable.java @@ -1,5 +1,6 @@ package com.nccgroup.loggerplusplus.grepper; +import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logview.logtable.LogTable; import org.jdesktop.swingx.JXTree; import org.jdesktop.swingx.JXTreeTable; @@ -51,7 +52,7 @@ public void mouseReleased(MouseEvent e) { public void actionPerformed(ActionEvent actionEvent) { LogTable table = controller.getLogTableController().getLogTable(); table.changeSelection(table.convertRowIndexToView(index), 1, false, false); - controller.getLoggerPlusPlus().getMainViewController().getTabbedPanel().setSelectedIndex(0); + LoggerPlusPlus.instance.getMainViewController().getTabbedPanel().setSelectedIndex(0); } }); menu.add(viewInLogs); diff --git a/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperController.java b/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperController.java index 09128b1b..95cbb5bd 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperController.java @@ -1,7 +1,9 @@ package com.nccgroup.loggerplusplus.grepper; -import burp.IHttpRequestResponse; -import burp.IHttpRequestResponseWithMarkers; +import burp.api.montoya.core.Annotations; +import burp.api.montoya.core.Range; +import burp.api.montoya.http.message.HttpRequestResponse; +import burp.api.montoya.http.message.MarkedHttpRequestResponse; import com.coreyd97.BurpExtenderUtilities.Preferences; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; @@ -20,7 +22,6 @@ public class GrepperController { - private final LoggerPlusPlus loggerPlusPlus; private final LogTableController logTableController; private final Preferences preferences; private final GrepperPanel grepPanel; @@ -29,8 +30,7 @@ public class GrepperController { private ExecutorService searchExecutor; - public GrepperController(LoggerPlusPlus loggerPlusPlus, LogTableController logTableController, PreferencesController preferencesController){ - this.loggerPlusPlus = loggerPlusPlus; + public GrepperController(LogTableController logTableController, PreferencesController preferencesController){ this.logTableController = logTableController; this.preferences = preferencesController.getPreferences(); this.listeners = new ArrayList<>(); @@ -38,10 +38,6 @@ public GrepperController(LoggerPlusPlus loggerPlusPlus, LogTableController logTa this.grepPanel = new GrepperPanel(this, preferences); } - public LoggerPlusPlus getLoggerPlusPlus() { - return loggerPlusPlus; - } - public LogTableController getLogTableController() { return logTableController; } @@ -64,15 +60,15 @@ public void reset() { //TODO SwingWorker } } - public IHttpRequestResponseWithMarkers addMarkers(IHttpRequestResponse requestResponse, List matches) { - List requestMarkers = new ArrayList<>(), responseMarkers = new ArrayList<>(); + public MarkedHttpRequestResponse addMarkers(HttpRequestResponse requestResponse, List matches) { + List requestMarkers = new ArrayList<>(), responseMarkers = new ArrayList<>(); for (GrepResults.Match match : matches) { - int[] marker = new int[]{match.startIndex, match.endIndex}; + Range marker = Range.range(match.startIndex, match.endIndex); if (match.isRequest) requestMarkers.add(marker); else responseMarkers.add(marker); } - return LoggerPlusPlus.callbacks.applyMarkers(requestResponse, requestMarkers, responseMarkers); + return requestResponse.withMarkers(requestMarkers, responseMarkers); } public void beginSearch(final Pattern pattern, final boolean inScopeOnly, final boolean searchRequests, final boolean searchResponses) { @@ -80,7 +76,7 @@ public void beginSearch(final Pattern pattern, final boolean inScopeOnly, final this.searchExecutor = Executors.newFixedThreadPool(searchThreads, new NamedThreadFactory("LPP-Grepper")); new Thread(() -> { - ArrayList logEntries = new ArrayList<>(loggerPlusPlus.getLogViewController().getLogTableController().getLogTableModel().getData()); + ArrayList logEntries = new ArrayList<>(LoggerPlusPlus.instance.getLogViewController().getLogTableController().getLogTableModel().getData()); remainingEntries.getAndSet(logEntries.size()); this.listeners.forEach(listener -> { @@ -97,11 +93,11 @@ private GrepResults processEntry(LogEntry entry, Pattern pattern, final boolean GrepResults grepResults = null; if (entry != null) { grepResults = new GrepResults(entry); - if (entry.getRequest() != null && searchRequests) { - processMatches(grepResults, pattern, entry.getRequest(), true); + if (entry.getRequestBytes() != null && searchRequests) { + processMatches(grepResults, pattern, entry.getRequestBytes(), true); } - if (entry.getResponse() != null && searchResponses) { - processMatches(grepResults, pattern, entry.getResponse(), false); + if (entry.getResponseBytes() != null && searchResponses) { + processMatches(grepResults, pattern, entry.getResponseBytes(), false); } } return grepResults; @@ -128,7 +124,7 @@ private Runnable createProcessThread(final LogEntry logEntry, final Pattern patt return () -> { if (Thread.currentThread().isInterrupted()) return; GrepResults grepResults = null; - if (!inScopeOnly || LoggerPlusPlus.callbacks.isInScope(logEntry.getUrl())) { + if (!inScopeOnly || LoggerPlusPlus.isUrlInScope(logEntry.getUrlString())) { grepResults = processEntry(logEntry, pattern, searchRequests, searchResponses); } for (GrepperListener listener : this.listeners) { diff --git a/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperPanel.java b/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperPanel.java index 98159d68..d9e4359f 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperPanel.java @@ -3,6 +3,7 @@ import com.coreyd97.BurpExtenderUtilities.HistoryField; import com.coreyd97.BurpExtenderUtilities.PanelBuilder; import com.coreyd97.BurpExtenderUtilities.Preferences; +import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; import com.nccgroup.loggerplusplus.logview.entryviewer.RequestViewerController; import com.nccgroup.loggerplusplus.util.Globals; @@ -72,7 +73,7 @@ public void actionPerformed(ActionEvent e) { }); this.grepResultsTable = new GrepResultsTable(controller); - this.requestViewerController = new RequestViewerController(preferences, false, false); + this.requestViewerController = new RequestViewerController(preferences); grepResultsTable.addTreeSelectionListener(treeSelectionEvent -> { TreePath selectedPath = treeSelectionEvent.getPath(); @@ -137,7 +138,7 @@ private void startSearch() { try { pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE); } catch (PatternSyntaxException e) { - JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(controller.getLoggerPlusPlus().getMainViewController().getUiComponent()), "Pattern Syntax Invalid", "Invalid Pattern", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(LoggerPlusPlus.instance.getMainViewController().getUiComponent()), "Pattern Syntax Invalid", "Invalid Pattern", JOptionPane.ERROR_MESSAGE); return; } diff --git a/src/main/java/com/nccgroup/loggerplusplus/imports/ImportRequestResponse.java b/src/main/java/com/nccgroup/loggerplusplus/imports/ImportRequestResponse.java deleted file mode 100644 index 7e829699..00000000 --- a/src/main/java/com/nccgroup/loggerplusplus/imports/ImportRequestResponse.java +++ /dev/null @@ -1,136 +0,0 @@ -// -// Burp Suite Logger++ -// -// Released as open source by NCC Group Plc - https://www.nccgroup.trust/ -// -// Originally Developed by Soroush Dalili (@irsdl) -// Maintained by Corey Arthur (@CoreyD97) -// -// Project link: http://www.github.com/nccgroup/BurpSuiteLoggerPlusPlus -// -// Released under AGPL see LICENSE for more information -// - -package com.nccgroup.loggerplusplus.imports; - -import java.net.URL; - -import com.nccgroup.loggerplusplus.LoggerPlusPlus; - -import burp.IHttpRequestResponse; -import burp.IHttpService; - -class ImportRequestResponse implements IHttpRequestResponse { - - private IHttpService service; - private byte[] request; - private byte[] response; - private String comment; - private String highlight; - - ImportRequestResponse(String url, byte[] req, byte[] res) { - LoggerHttpService srv = new LoggerHttpService(url); - setHttpService(srv); - setRequest(req); - setResponse(res); - } - - @Override - public byte[] getRequest() { - return request; - } - - @Override - public void setRequest(byte[] message) { - request = message; - } - - @Override - public byte[] getResponse() { - return response; - } - - @Override - public void setResponse(byte[] message) { - response = message; - } - - @Override - public String getComment() { - return comment; - } - - @Override - public void setComment(String c) { - comment = c; - } - - @Override - public String getHighlight() { - return highlight; - } - - @Override - public void setHighlight(String color) { - highlight = color; - } - - @Override - public IHttpService getHttpService() { - return service; - } - - @Override - public void setHttpService(IHttpService httpService) { - service = httpService; - } - - private static class LoggerHttpService implements IHttpService { - - private String host; - private int port; - private String protocol; - - LoggerHttpService(String urlS) { - URL url; - try { - url = new URL(urlS); - } catch (Exception e) { - LoggerPlusPlus.callbacks.printError("LoggerHttpService: Error Parsing URL: " + urlS); - LoggerPlusPlus.callbacks.printError(e.toString()); - return; - } - - host = url.getHost(); - protocol = url.getProtocol(); - port = url.getPort(); - - if ( port < 1 ) { - switch (protocol) { - case "http": - port = 80; - break; - case "https": - port = 443; - break; - } - } - } - - @Override - public String getHost() { - return host; - } - - @Override - public int getPort() { - return port; - } - - @Override - public String getProtocol() { - return protocol; - } - - } -} \ No newline at end of file diff --git a/src/main/java/com/nccgroup/loggerplusplus/imports/LoggerImport.java b/src/main/java/com/nccgroup/loggerplusplus/imports/LoggerImport.java index 022fc9d8..c3d42c19 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/imports/LoggerImport.java +++ b/src/main/java/com/nccgroup/loggerplusplus/imports/LoggerImport.java @@ -13,11 +13,15 @@ package com.nccgroup.loggerplusplus.imports; -import burp.IBurpExtenderCallbacks; -import burp.IExtensionHelpers; -import burp.IHttpRequestResponse; +import burp.api.montoya.core.ByteArray; +import burp.api.montoya.core.ToolType; +import burp.api.montoya.http.HttpService; +import burp.api.montoya.http.message.HttpRequestResponse; +import burp.api.montoya.http.message.requests.HttpRequest; +import burp.api.montoya.http.message.responses.HttpResponse; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logview.processor.EntryImportWorker; +import lombok.extern.log4j.Log4j2; import javax.swing.*; import java.io.BufferedReader; @@ -26,8 +30,10 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Base64; import java.util.Iterator; +@Log4j2 public class LoggerImport { public static String getLoadFile() { @@ -50,7 +56,7 @@ public static ArrayList readFile(String filename) { try { reader = new BufferedReader(new FileReader(filename)); } catch (FileNotFoundException e) { - LoggerPlusPlus.callbacks.printError("LoggerImport-readFile: Error Opening File " + filename); + log.error("LoggerImport-readFile: Error Opening File " + filename); return new ArrayList(); } try { @@ -59,17 +65,16 @@ public static ArrayList readFile(String filename) { lines.add(line); } } catch (IOException e) { - LoggerPlusPlus.callbacks.printError("LoggerImport-readFile: Error Reading Line"); + log.error("LoggerImport-readFile: Error Reading Line"); return new ArrayList(); } return lines; } - public static ArrayList importWStalker() { + public static ArrayList importWStalker() { ArrayList lines; - ArrayList requests = new ArrayList<>(); - IExtensionHelpers helpers = LoggerPlusPlus.callbacks.getHelpers(); + ArrayList requests = new ArrayList<>(); String filename = getLoadFile(); if ( filename.length() == 0 ) { // exit if no file selected @@ -84,30 +89,31 @@ public static ArrayList importWStalker() { String line = i.next(); String[] v = line.split(","); // Format: "base64(request),base64(response),url" - byte[] request = helpers.base64Decode(v[0]); - byte[] response = helpers.base64Decode(v[1]); String url = v[3]; + Base64.Decoder b64Decoder = LoggerPlusPlus.montoya.utilities().base64Utils().getDecoder(); + HttpService httpService = HttpService.httpService(url); + HttpRequest httpRequest = HttpRequest.httpRequest(httpService, ByteArray.byteArray(b64Decoder.decode(v[0]))); + HttpResponse httpResponse = HttpResponse.httpResponse(ByteArray.byteArray(b64Decoder.decode(v[1]))); + HttpRequestResponse requestResponse = HttpRequestResponse.httpRequestResponse(httpRequest, httpResponse); - ImportRequestResponse x = new ImportRequestResponse(url, request, response); - requests.add(x); + requests.add(requestResponse); } catch (Exception e) { - LoggerPlusPlus.callbacks.printError("LoggerImport-importWStalker: Error Parsing Content"); - return new ArrayList(); + log.error("LoggerImport-importWStalker: Error Parsing Content"); + return new ArrayList<>(); } } return requests; } - public static ArrayList importZAP() { + public static ArrayList importZAP() { ArrayList lines = new ArrayList(); - ArrayList requests = new ArrayList(); - IExtensionHelpers helpers = LoggerPlusPlus.callbacks.getHelpers(); + ArrayList requests = new ArrayList(); String filename = getLoadFile(); if ( filename.length() == 0 ) { // exit if no file selected - return new ArrayList(); + return new ArrayList(); } lines = readFile(filename); @@ -139,12 +145,12 @@ public static ArrayList importZAP() { if ( line.matches(reSeparator) || !i.hasNext() ) { // TODO: Remove one or two \n at the end of requestBuffer - byte[] req = helpers.stringToBytes(requestBuffer); - byte[] res = helpers.stringToBytes(responseBuffer); + HttpService httpService = HttpService.httpService(url); + HttpRequest httpRequest = HttpRequest.httpRequest(httpService, requestBuffer); + HttpResponse httpResponse = HttpResponse.httpResponse(responseBuffer); + HttpRequestResponse requestResponse = HttpRequestResponse.httpRequestResponse(httpRequest, httpResponse); - // Add IHttpRequestResponse Object - ImportRequestResponse x = new ImportRequestResponse(url, req, res); - requests.add(x); + requests.add(requestResponse); // Reset content isRequest = true; @@ -167,7 +173,7 @@ public static ArrayList importZAP() { line = x[0] + " " + path + " " + x[2]; // fix the path in the request } catch (Exception e) { - LoggerPlusPlus.callbacks.printError("importZAP: Wrong Path Format"); + log.error("importZAP: Wrong Path Format"); return new ArrayList<>(); } } @@ -190,10 +196,10 @@ public static ArrayList importZAP() { return requests; } - public static boolean loadImported(ArrayList requests, Boolean sendToAutoExporters) { + public static boolean loadImported(ArrayList requests, Boolean sendToAutoExporters) { EntryImportWorker importWorker = LoggerPlusPlus.instance.getLogProcessor().createEntryImportBuilder() - .setOriginatingTool(IBurpExtenderCallbacks.TOOL_EXTENDER) - .setEntries(requests) + .setOriginatingTool(ToolType.EXTENSIONS) + .setHttpEntries(requests) .setInterimConsumer(integers -> { //Optional //Outputs chunks of integers representing imported indices diff --git a/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java b/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java index 2f39de78..83ca33a5 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java @@ -13,12 +13,19 @@ package com.nccgroup.loggerplusplus.logentry; -import burp.*; +import burp.api.montoya.core.ToolType; +import burp.api.montoya.http.HttpService; +import burp.api.montoya.http.MimeType; +import burp.api.montoya.http.message.cookies.Cookie; +import burp.api.montoya.http.message.headers.HttpHeader; +import burp.api.montoya.http.message.params.HttpParameter; +import burp.api.montoya.http.message.params.HttpParameterType; +import burp.api.montoya.http.message.requests.HttpRequest; +import burp.api.montoya.http.message.responses.HttpResponse; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter; import com.nccgroup.loggerplusplus.filter.tag.Tag; import com.nccgroup.loggerplusplus.logview.processor.LogProcessor; -import com.nccgroup.loggerplusplus.logview.processor.LogProcessorHelper; import com.nccgroup.loggerplusplus.reflection.ReflectionController; import com.nccgroup.loggerplusplus.util.Globals; import lombok.AccessLevel; @@ -27,8 +34,8 @@ import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; +import java.net.MalformedURLException; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.*; import java.util.regex.Matcher; @@ -41,17 +48,17 @@ public class LogEntry { Status previousStatus; Status status = Status.UNPROCESSED; - @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) - private IHttpRequestResponse requestResponse; //Only used for request, comment and HTTP Service. - private byte[] response; + private HttpRequest request; + @Setter(AccessLevel.NONE) + private HttpResponse response; private Integer identifier; - private int tool; - private String toolName; + private ToolType tool; private String hostname = ""; private String host = ""; // TODO better name? private String method = ""; + private String urlString; private URL url; private boolean params = false; private Short responseStatus = -1; @@ -60,7 +67,8 @@ public class LogEntry { private boolean hasBodyParam = false; private boolean hasCookieParam = false; private String title = ""; - private String newCookies = ""; + private String comment; + private List newCookies = new ArrayList<>(); private String sentCookies = ""; private String listenerInterface = ""; private boolean isSSL = false; @@ -74,8 +82,8 @@ public class LogEntry { private String clientIP = ""; private boolean hasSetCookies = false; private String formattedResponseTime = ""; - private String responseMimeType = ""; - private String responseInferredMimeType = ""; + private MimeType responseMimeType; + private MimeType responseInferredMimeType; private int responseBodyLength = -1; private String responseContentType = ""; private boolean complete = false; @@ -92,63 +100,67 @@ public class LogEntry { private Date responseDateTime = new Date(0); //Zero epoch dates to prevent null. Response date pulled from response headers private Date requestDateTime = new Date(0); //Zero epoch dates to prevent null. Response date pulled from response headers private int requestResponseDelay = -1; - private List responseHeaders; - private List requestHeaders; - private List tempParameters; + private List responseHeaders; + private List requestHeaders; private List parameters; private List reflectedParameters; private LogEntry() { - this.matchingColorFilters = Collections.synchronizedList(new ArrayList()); - this.matchingTags = Collections.synchronizedList(new ArrayList()); + this.matchingColorFilters = Collections.synchronizedList(new ArrayList<>()); + this.matchingTags = Collections.synchronizedList(new ArrayList<>()); } - public LogEntry(int tool, IHttpRequestResponse requestResponse) { + public LogEntry(ToolType tool, HttpRequest request) { this(); this.tool = tool; - this.toolName = LoggerPlusPlus.callbacks.getToolName(tool); - this.requestResponse = requestResponse; - this.response = requestResponse.getResponse(); + this.request = request; + } + + public LogEntry(ToolType tool, HttpRequest request, HttpResponse response){ + this(tool, request); + this.response = response; } /** * Create new entry and specify arrival time. - * + * * @param tool + * @param request * @param formattedRequestTime - * @param requestResponse */ - public LogEntry(int tool, Date formattedRequestTime, IHttpRequestResponse requestResponse) { - this(tool, requestResponse); + public LogEntry(ToolType tool, HttpRequest request, Date formattedRequestTime) { + this(tool, request); this.setReqestTime(formattedRequestTime); } - public void process() { - // TODO Move into separate processing class + public boolean process() { previousStatus = this.status; switch (this.status) { case UNPROCESSED: { this.status = processRequest(); - // If the entry should be ignored, break here. + // If the entry should be ignored, stop here. if (this.status == Status.IGNORED) - break; + return true; // Else continue, fall through to process response } case AWAITING_RESPONSE: { if (this.response == null) { this.status = Status.AWAITING_RESPONSE; - break; + return false; } processResponse(); this.status = Status.PROCESSED; + return true; } case IGNORED: case PROCESSED: { // Nothing to do, we're done! - break; + return true; } + + default: return false; } } @@ -166,69 +178,69 @@ public Status getPreviousStatus() { } private Status processRequest() { - IRequestInfo tempAnalyzedReq = LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(this.requestResponse); - URL uUrl = tempAnalyzedReq.getUrl(); - if (!LoggerPlusPlus.isUrlInScope(uUrl)) - return Status.IGNORED; - requestHeaders = tempAnalyzedReq.getHeaders(); + + requestHeaders = request.headers(); // Get HTTP Version, which would be the last token in "GET /admin/login/?next\u003d/admin/ HTTP/1.1" - String[] httpRequestTokens = requestHeaders.get(0).split(" "); + String[] httpRequestTokens = requestHeaders.get(0).value().split(" "); this.requestHttpVersion = httpRequestTokens[httpRequestTokens.length - 1]; - this.tempParameters = tempAnalyzedReq.getParameters().stream() - .filter(iParameter -> iParameter.getType() != IParameter.PARAM_COOKIE).collect(Collectors.toList()); - this.parameters = tempParameters.stream().map(IParameter::getName).collect(Collectors.toList()); + this.parameters = request.parameters().stream() + .filter(param -> param.type() != HttpParameterType.COOKIE) + .map(HttpParameter::name) + .collect(Collectors.toList()); - this.url = tempAnalyzedReq.getUrl(); - this.hostname = this.requestResponse.getHttpService().getHost(); - this.protocol = this.requestResponse.getHttpService().getProtocol(); - this.isSSL = this.protocol.equals("https"); - this.targetPort = this.requestResponse.getHttpService().getPort(); + this.urlString = request.url(); + this.hostname = this.request.httpService().host(); + this.protocol = this.request.httpService().secure() ? "https" : "http"; + this.isSSL = this.request.httpService().secure(); + this.targetPort = this.request.httpService().port(); boolean isDefaultPort = (this.protocol.equals("https") && this.targetPort == 443) || (this.protocol.equals("http") && this.targetPort == 80); this.host = this.protocol + "://" + this.hostname + (isDefaultPort ? "" : ":" + this.targetPort); - this.method = tempAnalyzedReq.getMethod(); + this.method = request.method(); + this.requestBodyLength = this.getRequestBytes().length - request.bodyOffset(); + this.hasBodyParam = requestBodyLength > 0; + try { + this.url = new URL(request.url()); + // I don't want to delete special characters such as ; or : from the extension // as it may really be part of the extension! (burp proxy log ignores them) - String tempPath = this.url.getPath().replaceAll("\\\\", "/"); + String tempPath = url.getPath().replaceAll("\\\\", "/"); tempPath = tempPath.substring(tempPath.lastIndexOf("/")); int tempPathDotLocation = tempPath.lastIndexOf("."); - if (tempPathDotLocation >= 0) + if (tempPathDotLocation >= 0) { this.urlExtension = tempPath.substring(tempPathDotLocation + 1); - } catch (Exception e) { - this.urlExtension = ""; - } + } + this.params = url.getQuery() != null || this.hasBodyParam; + } catch (MalformedURLException ignored) {} + + - this.requestBodyLength = this.getRequest().length - tempAnalyzedReq.getBodyOffset(); - this.hasBodyParam = requestBodyLength > 0; - this.params = this.url.getQuery() != null || this.hasBodyParam; - this.hasCookieParam = false; // reading request headers like a boss! - for (String item : requestHeaders) { - if (item.contains(":")) { - String[] headerItem = item.split(":\\s", 2); - if (headerItem[0].equalsIgnoreCase("cookie")) { - this.sentCookies = headerItem[1]; + for (HttpHeader header : requestHeaders) { +// if (header.contains(":")) { + if (header.name().equalsIgnoreCase("cookie")) { + this.sentCookies = header.value(); if (!this.sentCookies.isEmpty()) { this.hasCookieParam = true; this.sentCookies += ";"; // we need to ad this to search it in cookie Jar! // Check to see if it uses cookie Jars! - List cookieJars = LoggerPlusPlus.callbacks.getCookieJarContents(); + List cookiesInJar = LoggerPlusPlus.montoya.http().cookieJar().cookies(); boolean oneNotMatched = false; boolean anyParamMatched = false; - for (ICookie cookieItem : cookieJars) { - if (cookieItem.getDomain().equals(this.hostname)) { + for (Cookie cookieItem : cookiesInJar) { + if (cookieItem.domain().equals(this.hostname)) { // now we want to see if any of these cookies have been set here! - String currentCookieJarParam = cookieItem.getName() + "=" + cookieItem.getValue() + ";"; + String currentCookieJarParam = cookieItem.name() + "=" + cookieItem.value() + ";"; if (this.sentCookies.contains(currentCookieJarParam)) { anyParamMatched = true; } else { @@ -245,14 +257,14 @@ private Status processRequest() { this.usesCookieJar = CookieJarStatus.YES; } } - } else if (headerItem[0].equalsIgnoreCase("referer")) { - this.referrerURL = headerItem[1]; - } else if (headerItem[0].equalsIgnoreCase("content-type")) { - this.requestContentType = headerItem[1]; - } else if (headerItem[0].equalsIgnoreCase("origin")) { - this.origin = headerItem[1]; + } else if (header.name().equalsIgnoreCase("referer")) { + this.referrerURL = header.value(); + } else if (header.name().equalsIgnoreCase("content-type")) { + this.requestContentType = header.value(); + } else if (header.name().equalsIgnoreCase("origin")) { + this.origin = header.value(); } - } +// } } return Status.AWAITING_RESPONSE; @@ -303,7 +315,7 @@ private Status processRequest() { //// this.regexAllReq[i] = allMatches.toString(); // // }catch(Exception e){ - // LoggerPlusPlus.callbacks.printError("Error in regular expression: " + + // LoggerPlusPlus.montoya.printError("Error in regular expression: " + // regexString); // } // @@ -317,64 +329,54 @@ private Status processRequest() { * @param requestResponse * @param arrivalTime */ - public void addResponse(IHttpRequestResponse requestResponse, Date arrivalTime) { + public void addResponse(HttpResponse requestResponse, Date arrivalTime) { this.responseDateTime = arrivalTime; //IHttpRequestResponse objects received by the proxy listener do not contain the latest request. //So we must store the content separately. - this.response = requestResponse.getResponse(); - this.setComment(requestResponse.getComment()); //Update the comment with the current comment + this.response = requestResponse; +// this.setComment(requestResponse.getComment()); //Update the comment with the current comment } private Status processResponse() { reflectedParameters = new ArrayList<>(); - IResponseInfo tempAnalyzedResp = LoggerPlusPlus.callbacks.getHelpers() - .analyzeResponse(response); +// IResponseInfo tempAnalyzedResp = LoggerPlusPlus.montoya.getHelpers() +// .analyzeResponse(response); - this.responseStatus = tempAnalyzedResp.getStatusCode(); - this.responseBodyLength = response.length - tempAnalyzedResp.getBodyOffset(); - this.responseMimeType = tempAnalyzedResp.getStatedMimeType(); - this.responseInferredMimeType = tempAnalyzedResp.getInferredMimeType(); + this.responseStatus = response.statusCode(); + this.responseBodyLength = response.body().length(); + this.responseMimeType = response.statedMimeType(); + this.responseInferredMimeType = response.inferredMimeType(); /************************************** ************HEADER PROCESSING********* **************************************/ - //Fancy handling to combine duplicate headers into CSVs. - Map headers = tempAnalyzedResp.getHeaders().stream().filter(s -> s.contains(":")) - .collect(Collectors.toMap(s -> { - String[] split = s.split(": ", 2); - return split.length > 0 ? split[0] : ""; - }, s -> { - String[] split = s.split(": ", 2); - if (split.length > 1) { - return split[1]; - } - return ""; - }, (s, s2) -> { + Map headers = response.headers().stream() + .collect(Collectors.toMap(HttpHeader::name, HttpHeader::value, (s, s2) -> { s += ", " + s2; return s; }, () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER))); - responseHeaders = tempAnalyzedResp.getHeaders(); + responseHeaders = response.headers(); if (headers.containsKey("Location")) { this.redirectURL = headers.get("Location"); } // Extract HTTP Status message - String[] httpStatusTokens = responseHeaders.get(0).split(" "); - this.responseStatusText = httpStatusTokens[httpStatusTokens.length - 1]; - this.responseHttpVersion = httpStatusTokens[0]; + HttpHeader httpStatusTokens = response.headers().get(0); + //TODO FixMe +// this.responseStatusText = httpStatusTokens[httpStatusTokens.length - 1]; +// this.responseHttpVersion = httpStatusTokens[0]; + if (headers.containsKey("content-type")) { this.responseContentType = headers.get("content-type"); } //Cookies - for (ICookie cookieItem : tempAnalyzedResp.getCookies()) { - this.newCookies += cookieItem.getName() + "=" + cookieItem.getValue() + "; "; //TODO convert to map, and add filter support for maps - } + this.newCookies = response.cookies().stream().map(cookie -> String.format("%s=%s", cookie.name(), cookie.value())).collect(Collectors.toList()); this.hasSetCookies = !newCookies.isEmpty(); @@ -408,40 +410,35 @@ private Status processResponse() { **************************************/ Long maxRespSize = ((Integer) LoggerPlusPlus.instance.getPreferencesController().getPreferences().getSetting(Globals.PREF_MAX_RESP_SIZE)) * 1000000L; - int bodyOffset = response.length - responseBodyLength; + int bodyOffset = response.bodyOffset(); if (responseBodyLength < maxRespSize) { //Only title match HTML files. Prevents expensive regex running on e.g. binary downloads. - if (this.responseInferredMimeType.equalsIgnoreCase("HTML")) { - String strFullResponse = new String(response); - Matcher titleMatcher = Globals.HTML_TITLE_PATTERN.matcher(strFullResponse); + if (this.responseInferredMimeType == MimeType.HTML) { + Matcher titleMatcher = Globals.HTML_TITLE_PATTERN.matcher(response.bodyAsString()); if (titleMatcher.find()) { this.title = titleMatcher.group(1); } } - String responseBody = new String(response, bodyOffset, responseBodyLength); ReflectionController reflectionController = LoggerPlusPlus.instance.getReflectionController(); - reflectedParameters = tempParameters.parallelStream() - .filter(iParameter -> !reflectionController.isParameterFiltered(iParameter) - && reflectionController.validReflection(responseBody, iParameter)) - .map(IParameter::getName).collect(Collectors.toList()); + reflectedParameters = request.parameters().parallelStream() + .filter(parameter -> !reflectionController.isParameterFiltered(parameter) && reflectionController.validReflection(response.bodyAsString(), parameter)) + .map(HttpParameter::name).collect(Collectors.toList()); -// this.requestResponse = LoggerPlusPlus.callbacks.saveBuffersToTempFiles(requestResponse); +// this.requestResponse = LoggerPlusPlus.montoya.saveBuffersToTempFiles(requestResponse); } else { //Just look for reflections in the headers. ReflectionController reflectionController = LoggerPlusPlus.instance.getReflectionController(); - reflectedParameters = tempParameters.parallelStream() - .filter(iParameter -> !reflectionController.isParameterFiltered(iParameter) - && reflectionController.validReflection(new String(response, 0, bodyOffset), iParameter)) - .map(IParameter::getName).collect(Collectors.toList()); + reflectedParameters = request.parameters().parallelStream() + .filter(parameter -> !reflectionController.isParameterFiltered(parameter) + && reflectionController.validReflection(new String(response.asBytes().getBytes(), 0, bodyOffset), parameter)) + .map(HttpParameter::name).collect(Collectors.toList()); //Trim the response down to a maximum size, but at least keep the headers! - this.response = (new String(this.response, 0, bodyOffset) + "Response body trimmed by Logger++. To prevent this, increase \"Maximum Response Size\" in the Logger++ options.").getBytes(StandardCharsets.UTF_8); + //TODO Fix response trimming? +// this.response = (new String(this.response, 0, bodyOffset) + "Response body trimmed by Logger++. To prevent this, increase \"Maximum Response Size\" in the Logger++ options.").getBytes(StandardCharsets.UTF_8); } - - tempParameters = null; // We're done with these. Allow them to be cleaned. - this.complete = true; return Status.PROCESSED; @@ -487,7 +484,7 @@ private Status processResponse() { // this.regexAllResp[i] = allMatches.toString(); // // }catch(Exception e){ - // LoggerPlusPlus.callbacks.printError("Error in regular expression: " + + // LoggerPlusPlus.montoya.printError("Error in regular expression: " + // regexString); // } // @@ -501,12 +498,12 @@ private Status processResponse() { // } } - public byte[] getRequest() { - return this.requestResponse.getRequest(); + public byte[] getRequestBytes() { + return this.request.asBytes().getBytes(); } - public byte[] getResponse() { - return response; + public byte[] getResponseBytes() { + return response.asBytes().getBytes(); } public void setReqestTime(Date requestTime) { @@ -520,11 +517,11 @@ public void setResponseTime(Date responseTime) { } public void setComment(String comment) { - this.requestResponse.setComment(comment); + this.comment = comment; } public String getComment() { - return this.requestResponse.getComment(); + return this.comment; } @@ -534,15 +531,15 @@ public Object getValueByKey(LogEntryField columnName) { switch (columnName) { case PROXY_TOOL: case REQUEST_TOOL: - return getToolName(); + return tool.toolName(); case TAGS: return this.matchingTags.stream().map(Tag::getName).collect(Collectors.toList()); case URL: - return this.url; + return this.urlString; case PATH: - return this.url.getPath(); + return (this.url != null ? this.url.getPath() : ""); case QUERY: - return this.url.getQuery(); + return (this.url != null ? this.url.getQuery() : ""); case STATUS: return this.responseStatus; case STATUS_TEXT: @@ -568,7 +565,7 @@ public Object getValueByKey(LogEntryField columnName) { case RESPONSE_TIME: return this.responseDateTime; case COMMENT: - return this.requestResponse.getComment(); + return this.comment; case REQUEST_CONTENT_TYPE: return this.requestContentType; case REQUEST_HTTP_VERSION: @@ -582,7 +579,7 @@ public Object getValueByKey(LogEntryField columnName) { case PARAMETER_COUNT: return this.parameters.size(); case HASGETPARAM: - return this.url.getQuery() != null; + return this.url != null && this.url.getQuery() != null; case HASPOSTPARAM: return this.hasBodyParam; case HASCOOKIEPARAM: @@ -641,24 +638,22 @@ public Object getValueByKey(LogEntryField columnName) { return reflectedParameters.size(); case REQUEST_BODY: // request if (requestBodyLength == 0) return ""; - return new String(getRequest(), getRequest().length - requestBodyLength, requestBodyLength); + return new String(getRequestBytes(), getRequestBytes().length - requestBodyLength, requestBodyLength); // .substring(request.length - requestBodyLength); case RESPONSE_BODY: // response - if (responseBodyLength == 0) return ""; - return new String(response, response.length - responseBodyLength, responseBodyLength); -// .substring(response.length - responseBodyLength); + return response.bodyAsString(); case RTT: return requestResponseDelay; case REQUEST_HEADERS: - return requestHeaders != null ? String.join("\r\n", requestHeaders) : ""; + return requestHeaders != null ? requestHeaders.stream().map(HttpHeader::toString).collect(Collectors.joining("\r\n")) : ""; case RESPONSE_HEADERS: - return responseHeaders != null ? String.join("\r\n", responseHeaders) : ""; + return responseHeaders != null ? responseHeaders.stream().map(HttpHeader::toString).collect(Collectors.joining("\r\n")) : ""; case REDIRECT_URL: return redirectURL; case BASE64_REQUEST: - return Base64.getEncoder().encodeToString(this.getRequest()); + return Base64.getEncoder().encodeToString(this.getRequestBytes()); case BASE64_RESPONSE: - return Base64.getEncoder().encodeToString(response); + return Base64.getEncoder().encodeToString(this.getResponseBytes()); case RESPONSE_HASH: { if (responseHash == null) { responseHash = DigestUtils @@ -682,8 +677,8 @@ public List getMatchingTags() { return matchingTags; } - public IHttpService getHttpService() { - return this.requestResponse.getHttpService(); + public HttpService getHttpService() { + return this.request.httpService(); } public enum CookieJarStatus { @@ -763,10 +758,10 @@ public boolean testTag(Tag tag, boolean retest) { @Override public String toString() { - return this.url.toString(); + return this.urlString.toString(); } - public static Integer extractAndRemoveIdentifierFromComment(LogEntry logEntry) { - return LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(logEntry.requestResponse); - } +// public static Integer extractAndRemoveIdentifierFromComment(LogEntry logEntry) { +// return LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(logEntry.request); +// } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntryFieldSerializer.java b/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntryFieldSerializer.java index b93b6aa6..9d996a21 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntryFieldSerializer.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntryFieldSerializer.java @@ -3,10 +3,6 @@ import com.google.gson.*; import java.lang.reflect.Type; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; public class LogEntryFieldSerializer implements JsonSerializer, JsonDeserializer { diff --git a/src/main/java/com/nccgroup/loggerplusplus/logging/BurpAppender.java b/src/main/java/com/nccgroup/loggerplusplus/logging/BurpAppender.java new file mode 100644 index 00000000..84469af6 --- /dev/null +++ b/src/main/java/com/nccgroup/loggerplusplus/logging/BurpAppender.java @@ -0,0 +1,40 @@ +package com.nccgroup.loggerplusplus.logging; + +import com.nccgroup.loggerplusplus.LoggerPlusPlus; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Core; +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.appender.AbstractAppender; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginElement; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.core.layout.PatternLayout; + +@Plugin(name="BurpAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) +public class BurpAppender extends AbstractAppender { + + public BurpAppender(String name, Filter filter){ + super(name, filter, PatternLayout.createDefaultLayout(), false, null); + System.out.println("Created appender"); + } + + @PluginFactory + public static BurpAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filter") Filter filter) { + return new BurpAppender(name, filter); + } + + @Override + public void append(LogEvent event) { + String message = new String(this.getLayout().toByteArray(event)); + if(LoggerPlusPlus.montoya == null) return; + + if (event.getLevel().isInRange(Level.WARN, Level.FATAL)) { + LoggerPlusPlus.montoya.logging().logToError(message); + } else { + LoggerPlusPlus.montoya.logging().logToOutput(message); + } + } +} diff --git a/src/main/java/com/nccgroup/loggerplusplus/logging/JTextAreaAppender.java b/src/main/java/com/nccgroup/loggerplusplus/logging/JTextAreaAppender.java deleted file mode 100644 index 59482b62..00000000 --- a/src/main/java/com/nccgroup/loggerplusplus/logging/JTextAreaAppender.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.nccgroup.loggerplusplus.logging; - -import org.apache.logging.log4j.core.*; -import org.apache.logging.log4j.core.appender.AbstractAppender; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.config.plugins.PluginAttribute; -import org.apache.logging.log4j.core.config.plugins.PluginElement; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; - -import javax.swing.*; -import java.util.ArrayList; - -import static javax.swing.SwingUtilities.invokeLater; -import static org.apache.logging.log4j.core.config.Property.EMPTY_ARRAY; -import static org.apache.logging.log4j.core.layout.PatternLayout.createDefaultLayout; - -/** - * JTextAreaAppender - https://stackoverflow.com/a/29736246 - * Credit to https://stackoverflow.com/users/4544015/vshiro - */ - -@Plugin(name = "JTextAreaAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) -public class JTextAreaAppender extends AbstractAppender { - private static volatile ArrayList textAreas = new ArrayList<>(); - - private int maxLines; - - private JTextAreaAppender(String name, Layout layout, Filter filter, int maxLines, boolean ignoreExceptions) { - super(name, filter, layout, ignoreExceptions, EMPTY_ARRAY); - this.maxLines = maxLines; - } - - @SuppressWarnings("unused") - @PluginFactory - public static JTextAreaAppender createAppender(@PluginAttribute("name") String name, - @PluginAttribute("maxLines") int maxLines, - @PluginAttribute("ignoreExceptions") boolean ignoreExceptions, - @PluginElement("Layout") Layout layout, - @PluginElement("Filters") Filter filter) { - if (name == null) { - LOGGER.error("No name provided for JTextAreaAppender"); - return null; - } - - if (layout == null) { - layout = createDefaultLayout(); - } - return new JTextAreaAppender(name, layout, filter, maxLines, ignoreExceptions); - } - - // Add the target JTextArea to be populated and updated by the logging information. - public static void addLog4j2TextAreaAppender(final JTextArea textArea) { - JTextAreaAppender.textAreas.add(textArea); - } - - @Override - public void append(LogEvent event) { - String message = new String(this.getLayout().toByteArray(event)); - - // Append formatted message to text area using the Thread. - try { - invokeLater(() -> - { - for (JTextArea textArea : textAreas) { - try { - if (textArea != null) { - if (textArea.getText().length() == 0) { - textArea.setText(message); - } else { - textArea.append("\n" + message); - if (maxLines > 0 & textArea.getLineCount() > maxLines + 1) { - int endIdx = textArea.getDocument().getText(0, textArea.getDocument().getLength()).indexOf("\n"); - textArea.getDocument().remove(0, endIdx + 1); - } - } - String content = textArea.getText(); - textArea.setText(content.substring(0, content.length() - 1)); - } - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - }); - } catch (IllegalStateException exception) { - exception.printStackTrace(); - } - } -} diff --git a/src/main/java/com/nccgroup/loggerplusplus/logging/LoggingController.java b/src/main/java/com/nccgroup/loggerplusplus/logging/LoggingController.java index 1675372e..c5de5d33 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logging/LoggingController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logging/LoggingController.java @@ -1,60 +1,23 @@ package com.nccgroup.loggerplusplus.logging; -import burp.IBurpExtenderCallbacks; +import burp.api.montoya.MontoyaApi; import com.coreyd97.BurpExtenderUtilities.IGsonProvider; -import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.util.Globals; +import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.appender.AbstractAppender; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.layout.PatternLayout; +@Log4j2 public class LoggingController { private final IGsonProvider gsonProvider; - private IBurpExtenderCallbacks callbacks; private Level logLevel; - public LoggingController(IGsonProvider gsonProvider) { + public LoggingController(IGsonProvider gsonProvider, MontoyaApi montoyaApi) { this.gsonProvider = gsonProvider; - this.callbacks = LoggerPlusPlus.callbacks; - configureLogger(); - } - - private void configureLogger() { - logLevel = gsonProvider.getGson().fromJson(callbacks.loadExtensionSetting(Globals.PREF_LOG_LEVEL), Level.class); - - if (logLevel == null) { //Handle change from debug boolean to log level. - logLevel = Level.INFO; - callbacks.saveExtensionSetting(Globals.PREF_LOG_LEVEL, gsonProvider.getGson().toJson(logLevel)); - } - - LoggerContext context = (LoggerContext) LogManager.getContext(false); - Configuration config = context.getConfiguration(); - PatternLayout logLayout = PatternLayout.newBuilder() - .withConfiguration(config) - .withPattern("[%-5level] %d{yyyy-MM-dd HH:mm:ss} %msg%n") - .build(); - - Appender burpAppender = new AbstractAppender("Burp Appender", null, logLayout, false, null) { - @Override - public void append(LogEvent event) { - String message = new String(this.getLayout().toByteArray(event)); - if (event.getLevel().isMoreSpecificThan(Level.INFO)) { - callbacks.printError(message); - } else { - callbacks.printOutput(message); - } - } - }; - burpAppender.start(); - - context.getConfiguration().getRootLogger().addAppender(burpAppender, logLevel, null); - context.updateLoggers(); + logLevel = gsonProvider.getGson().fromJson(montoyaApi.persistence().preferences().getString(Globals.PREF_LOG_LEVEL), Level.class); + setLogLevel(logLevel); } public void setLogLevel(Level logLevel) { diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/LogViewController.java b/src/main/java/com/nccgroup/loggerplusplus/logview/LogViewController.java index 283f47c0..7b0bba23 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/LogViewController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/LogViewController.java @@ -7,26 +7,35 @@ import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController; import com.nccgroup.loggerplusplus.logview.entryviewer.RequestViewerController; import com.nccgroup.loggerplusplus.logview.logtable.LogTableController; +import lombok.Getter; public class LogViewController { - private final LoggerPlusPlus loggerPlusPlus; + @Getter private final FilterLibraryController filterLibraryController; + + @Getter private final Preferences preferences; + + @Getter private final LogFilterController logFilterController; + + @Getter private final LogTableController logTableController; + + @Getter private final RequestViewerController requestViewerController; + @Getter private final LogViewPanel logViewPanel; - public LogViewController(LoggerPlusPlus loggerPlusPlus, FilterLibraryController filterLibraryController){ - this.loggerPlusPlus = loggerPlusPlus; + public LogViewController(FilterLibraryController filterLibraryController){ this.filterLibraryController = filterLibraryController; - this.preferences = loggerPlusPlus.getPreferencesController().getPreferences(); + this.preferences = LoggerPlusPlus.instance.getPreferencesController().getPreferences(); this.logTableController = new LogTableController(this, filterLibraryController); this.logFilterController = new LogFilterController(this); - this.requestViewerController = new RequestViewerController(preferences, false, false); + this.requestViewerController = new RequestViewerController(preferences); //Build UI this.logViewPanel = new LogViewPanel(this); @@ -39,28 +48,4 @@ public void setPanelLayout(VariableViewPanel.View view){ public void setEntryViewerLayout(VariableViewPanel.View view){ this.logViewPanel.getRequestViewerPanel().getVariableViewPanel().setView(view); } - - public LoggerPlusPlus getLoggerPlusPlus() { - return loggerPlusPlus; - } - - public LogViewPanel getLogViewPanel() { - return logViewPanel; - } - - public LogFilterController getLogFilterController() { - return logFilterController; - } - - public LogTableController getLogTableController() { - return logTableController; - } - - public RequestViewerController getRequestViewerController() { - return requestViewerController; - } - - public Preferences getPreferences() { - return preferences; - } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/MultipleLogEntryMenu.java b/src/main/java/com/nccgroup/loggerplusplus/logview/MultipleLogEntryMenu.java index 015bd619..eafabc80 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/MultipleLogEntryMenu.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/MultipleLogEntryMenu.java @@ -1,5 +1,10 @@ package com.nccgroup.loggerplusplus.logview; +import burp.api.montoya.core.BurpSuiteEdition; +import burp.api.montoya.http.message.HttpRequestResponse; +import burp.api.montoya.scanner.BuiltInScanConfiguration; +import burp.api.montoya.scanner.InvalidLauncherConfigurationException; +import burp.api.montoya.scanner.Scan; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.exports.ContextMenuExportProvider; import com.nccgroup.loggerplusplus.exports.ExportController; @@ -7,6 +12,7 @@ import com.nccgroup.loggerplusplus.logentry.LogEntry; import com.nccgroup.loggerplusplus.logview.logtable.LogTable; import com.nccgroup.loggerplusplus.logview.logtable.LogTableController; +import lombok.extern.log4j.Log4j2; import javax.swing.*; import java.awt.datatransfer.Clipboard; @@ -21,11 +27,12 @@ /** * Created by corey on 24/08/17. */ +@Log4j2 public class MultipleLogEntryMenu extends JPopupMenu { public MultipleLogEntryMenu(final LogTableController logTableController, final List selectedEntries){ final LogTable logTable = logTableController.getLogTable(); - final boolean isPro = LoggerPlusPlus.callbacks.getBurpVersion()[0].equals("Burp Suite Professional"); + final boolean isPro = LoggerPlusPlus.montoya.burpSuite().version().edition() == BurpSuiteEdition.PROFESSIONAL; this.add(new JMenuItem(selectedEntries.size() + " items")); this.add(new Separator()); @@ -76,7 +83,7 @@ public void actionPerformed(ActionEvent actionEvent) { this.add(copySelectedUrls); JMenu exportMenu = new JMenu("Export entries as..."); - ExportController exportController = logTableController.getLogViewController().getLoggerPlusPlus().getExportController(); + ExportController exportController = LoggerPlusPlus.instance.getExportController(); for (LogExporter exporter : exportController.getExporters().values()) { if (exporter instanceof ContextMenuExportProvider) { JMenuItem item = ((ContextMenuExportProvider) exporter).getExportEntriesMenuItem(selectedEntries); @@ -91,21 +98,38 @@ public void actionPerformed(ActionEvent actionEvent) { this.add(new Separator()); - JMenuItem spider = new JMenuItem(new AbstractAction("Spider selected " + selectedEntries.size() + " urls") { + JMenuItem scanner = new JMenuItem(new AbstractAction("Crawl selected " + selectedEntries.size() + " urls") { @Override public void actionPerformed(ActionEvent actionEvent) { + Scan scan = LoggerPlusPlus.montoya.scanner().createScan(); + for (LogEntry entry : selectedEntries) { - LoggerPlusPlus.callbacks.sendToSpider(entry.getUrl()); + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse())); + } + + try { + scan.startCrawl(); + } catch (InvalidLauncherConfigurationException e) { + log.error(e); } } }); - this.add(spider); + this.add(scanner); JMenuItem activeScan = new JMenuItem(new AbstractAction("Active scan selected " + selectedEntries.size() + " urls") { @Override public void actionPerformed(ActionEvent actionEvent) { + Scan scan = LoggerPlusPlus.montoya.scanner().createScan(); + scan.addConfiguration(BuiltInScanConfiguration.ACTIVE_AUDIT_CHECKS); + for (LogEntry entry : selectedEntries) { - LoggerPlusPlus.callbacks.doActiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest()); + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse())); + } + + try { + scan.startAudit(); + } catch (InvalidLauncherConfigurationException e) { + log.error(e); } } }); @@ -115,10 +139,17 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem passiveScan = new JMenuItem(new AbstractAction("Passive scan selected " + selectedEntries.size() + " urls") { @Override public void actionPerformed(ActionEvent actionEvent) { + Scan scan = LoggerPlusPlus.montoya.scanner().createScan(); + scan.addConfiguration(BuiltInScanConfiguration.PASSIVE_AUDIT_CHECKS); + for (LogEntry entry : selectedEntries) { - if (entry.isComplete()) { //Cannot scan entries without response - LoggerPlusPlus.callbacks.doPassiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), entry.getResponse()); - } + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse())); + } + + try { + scan.startAudit(); + } catch (InvalidLauncherConfigurationException e) { + log.error(e); } } }); @@ -131,7 +162,7 @@ public void actionPerformed(ActionEvent actionEvent) { @Override public void actionPerformed(ActionEvent actionEvent) { for (LogEntry entry : selectedEntries) { - LoggerPlusPlus.callbacks.sendToRepeater(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), "L++"); + LoggerPlusPlus.montoya.repeater().sendToRepeater(entry.getRequest()); } } }); @@ -141,7 +172,7 @@ public void actionPerformed(ActionEvent actionEvent) { @Override public void actionPerformed(ActionEvent actionEvent) { for (LogEntry entry : selectedEntries) { - LoggerPlusPlus.callbacks.sendToIntruder(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest()); + LoggerPlusPlus.montoya.intruder().sendToIntruder(entry.getRequest()); } } }); @@ -152,7 +183,7 @@ public void actionPerformed(ActionEvent actionEvent) { @Override public void actionPerformed(ActionEvent actionEvent) { for (LogEntry entry : selectedEntries) { - LoggerPlusPlus.callbacks.sendToComparer(entry.getRequest()); + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getRequest().asBytes()); } } }); @@ -162,7 +193,7 @@ public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) { for (LogEntry entry : selectedEntries) { if (entry.isComplete()) { //Do not add entries without a response - LoggerPlusPlus.callbacks.sendToComparer(entry.getResponse()); + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getResponse().asBytes()); } } } @@ -193,7 +224,7 @@ private void copySelected(List items, Scope scope, boolean onlyUnique) for (LogEntry item : items) { switch (scope) { case URL: - values.add(String.valueOf(item.getUrl())); + values.add(String.valueOf(item.getUrlString())); break; case PATH: values.add(item.getUrl().getPath()); diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/SingleLogEntryMenu.java b/src/main/java/com/nccgroup/loggerplusplus/logview/SingleLogEntryMenu.java index 84ff316c..5b122528 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/SingleLogEntryMenu.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/SingleLogEntryMenu.java @@ -1,5 +1,10 @@ package com.nccgroup.loggerplusplus.logview; +import burp.api.montoya.core.BurpSuiteEdition; +import burp.api.montoya.http.message.HttpRequestResponse; +import burp.api.montoya.scanner.BuiltInScanConfiguration; +import burp.api.montoya.scanner.InvalidLauncherConfigurationException; +import burp.api.montoya.scanner.Scan; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.exports.ContextMenuExportProvider; import com.nccgroup.loggerplusplus.exports.ExportController; @@ -15,6 +20,7 @@ import com.nccgroup.loggerplusplus.logview.logtable.LogTableController; import com.nccgroup.loggerplusplus.logview.processor.LogProcessor; import com.nccgroup.loggerplusplus.util.userinterface.dialog.ColorFilterDialog; +import lombok.extern.log4j.Log4j2; import javax.swing.*; import java.awt.event.ActionEvent; @@ -26,6 +32,7 @@ /** * Created by corey on 24/08/17. */ +@Log4j2 public class SingleLogEntryMenu extends JPopupMenu { public SingleLogEntryMenu(final LogTableController logTableController, final LogEntry entry, final LogEntryField selectedField){ @@ -45,7 +52,7 @@ public SingleLogEntryMenu(final LogTableController logTableController, final Log columnValueString = "\"\""; } - final boolean isPro = LoggerPlusPlus.callbacks.getBurpVersion()[0].equals("Burp Suite Professional"); + final boolean isPro = LoggerPlusPlus.montoya.burpSuite().version().edition() == BurpSuiteEdition.PROFESSIONAL; String title = entry.getValueByKey(LogEntryField.URL).toString(); if(title.length() > 50) title = title.substring(0, 47) + "..."; this.add(new JMenuItem(title)); @@ -98,7 +105,7 @@ public void actionPerformed(ActionEvent actionEvent) { ColorFilter colorFilter = new ColorFilter(); colorFilter.setFilter(new LogFilter(LoggerPlusPlus.instance.getLibraryController(), columnName + " == " + columnValueString)); - logTableController.getLogViewController().getLoggerPlusPlus().getLibraryController().addColorFilter(colorFilter); + LoggerPlusPlus.instance.getLibraryController().addColorFilter(colorFilter); ColorFilterDialog colorFilterDialog = new ColorFilterDialog(LoggerPlusPlus.instance.getLibraryController()); colorFilterDialog.setVisible(true); } catch (ParseException e1) { @@ -110,7 +117,7 @@ public void actionPerformed(ActionEvent actionEvent) { } this.add(new JPopupMenu.Separator()); - final boolean inScope = LoggerPlusPlus.callbacks.isInScope(entry.getUrl()); + final boolean inScope = LoggerPlusPlus.isUrlInScope(entry.getUrlString()); JMenuItem scopeItem; if(!inScope){ scopeItem = new JMenu("Add to scope"); @@ -119,7 +126,7 @@ public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) { try { URL domainURL = new URL(entry.getProtocol(), entry.getHostname(), entry.getTargetPort(), ""); - LoggerPlusPlus.callbacks.includeInScope(domainURL); + LoggerPlusPlus.montoya.scope().includeInScope(domainURL.toExternalForm()); } catch (MalformedURLException e) { JOptionPane.showMessageDialog(scopeItem, "Could not build URL for scope entry. Sorry!", "Add to scope", JOptionPane.ERROR_MESSAGE); } @@ -128,21 +135,21 @@ public void actionPerformed(ActionEvent actionEvent) { scopeItem.add(new JMenuItem(new AbstractAction("Domain + Path") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.includeInScope(entry.getUrl()); + LoggerPlusPlus.montoya.scope().isInScope(entry.getUrlString()); } })); }else{ scopeItem = new JMenuItem(new AbstractAction("Remove from scope") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.excludeFromScope(entry.getUrl()); + LoggerPlusPlus.montoya.scope().excludeFromScope(entry.getUrlString()); } }); } this.add(scopeItem); JMenu exportMenu = new JMenu("Export as..."); - ExportController exportController = logTableController.getLogViewController().getLoggerPlusPlus().getExportController(); + ExportController exportController = LoggerPlusPlus.instance.getExportController(); for (LogExporter exporter : exportController.getExporters().values()) { if (exporter instanceof ContextMenuExportProvider) { JMenuItem item = ((ContextMenuExportProvider) exporter).getExportEntriesMenuItem(Collections.singletonList(entry)); @@ -157,10 +164,17 @@ public void actionPerformed(ActionEvent actionEvent) { this.add(new JPopupMenu.Separator()); - JMenuItem spider = new JMenuItem(new AbstractAction("Spider from here") { + JMenuItem spider = new JMenuItem(new AbstractAction("Crawl from here") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.sendToSpider(entry.getUrl()); + Scan scan = LoggerPlusPlus.montoya.scanner().createScan(); + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse())); + + try { + scan.startCrawl(); + } catch (InvalidLauncherConfigurationException e) { + log.error(e); + } } }); this.add(spider); @@ -168,7 +182,15 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem activeScan = new JMenuItem(new AbstractAction("Do an active scan") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.doActiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest()); + Scan scan = LoggerPlusPlus.montoya.scanner().createScan(); + scan.addConfiguration(BuiltInScanConfiguration.ACTIVE_AUDIT_CHECKS); + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse())); + + try { + scan.startAudit(); + } catch (InvalidLauncherConfigurationException e) { + log.error(e); + } } }); this.add(activeScan); @@ -177,7 +199,15 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem passiveScan = new JMenuItem(new AbstractAction("Do a passive scan") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.doPassiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), entry.getResponse()); + Scan scan = LoggerPlusPlus.montoya.scanner().createScan(); + scan.addConfiguration(BuiltInScanConfiguration.PASSIVE_AUDIT_CHECKS); + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse())); + + try { + scan.startAudit(); + } catch (InvalidLauncherConfigurationException e) { + log.error(e); + } } }); passiveScan.setEnabled(entry.isComplete() && isPro); @@ -188,7 +218,7 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem sendToRepeater = new JMenuItem(new AbstractAction("Send to Repeater") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.sendToRepeater(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), "L++"); + LoggerPlusPlus.montoya.repeater().sendToRepeater(entry.getRequest()); } }); this.add(sendToRepeater); @@ -196,7 +226,7 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem sendToIntruder = new JMenuItem(new AbstractAction("Send to Intruder") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.sendToIntruder(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest()); + LoggerPlusPlus.montoya.intruder().sendToIntruder(entry.getRequest()); } }); this.add(sendToIntruder); @@ -205,14 +235,14 @@ public void actionPerformed(ActionEvent actionEvent) { JMenuItem comparerRequest = new JMenuItem(new AbstractAction("Request") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.sendToComparer(entry.getRequest()); + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getRequest().asBytes()); } }); sendToComparer.add(comparerRequest); JMenuItem comparerResponse = new JMenuItem(new AbstractAction("Response") { @Override public void actionPerformed(ActionEvent actionEvent) { - LoggerPlusPlus.callbacks.sendToComparer(entry.getResponse()); + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getResponse().asBytes()); } }); sendToComparer.add(comparerResponse); diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerController.java b/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerController.java index 9001f530..3664fb48 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerController.java @@ -1,87 +1,47 @@ package com.nccgroup.loggerplusplus.logview.entryviewer; -import burp.IHttpService; -import burp.IMessageEditor; -import burp.IMessageEditorController; +import burp.api.montoya.ui.editor.EditorOptions; +import burp.api.montoya.ui.editor.HttpRequestEditor; +import burp.api.montoya.ui.editor.HttpResponseEditor; import com.coreyd97.BurpExtenderUtilities.Preferences; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.logentry.LogEntry; +import lombok.Getter; -public class RequestViewerController implements IMessageEditorController { +@Getter +public class RequestViewerController { private final Preferences preferences; - private final IMessageEditor requestEditor; - private final IMessageEditor responseEditor; + private final HttpRequestEditor requestEditor; + private final HttpResponseEditor responseEditor; private final RequestViewerPanel requestViewerPanel; private LogEntry currentEntry; - public RequestViewerController(Preferences preferences, boolean requestEditable, boolean responseEditable) { + public RequestViewerController(Preferences preferences) { this.preferences = preferences; - this.requestEditor = LoggerPlusPlus.callbacks.createMessageEditor(this, requestEditable); - this.responseEditor = LoggerPlusPlus.callbacks.createMessageEditor(this, responseEditable); + this.requestEditor = LoggerPlusPlus.montoya.userInterface().createHttpRequestEditor(EditorOptions.READ_ONLY); + this.responseEditor = LoggerPlusPlus.montoya.userInterface().createHttpResponseEditor(EditorOptions.READ_ONLY); this.requestViewerPanel = new RequestViewerPanel(this); } public void setDisplayedEntity(LogEntry logEntry) { this.currentEntry = logEntry; - if (logEntry == null) { - requestEditor.setMessage(new byte[0], true); - responseEditor.setMessage(new byte[0], false); - return; + if (logEntry == null || logEntry.getRequest() == null) { + requestEditor.setRequest(null); + }else{ + requestEditor.setRequest(logEntry.getRequest()); } - if (logEntry.getRequest() != null) { - requestEditor.setMessage(logEntry.getRequest(), true); - } else { - requestEditor.setMessage(new byte[0], true); + if (logEntry == null || logEntry.getResponse() == null) { + responseEditor.setResponse(null); + }else{ + responseEditor.setResponse(logEntry.getResponse()); } - - if (logEntry.getResponse() != null) { - responseEditor.setMessage(logEntry.getResponse(), false); - } else { - responseEditor.setMessage(new byte[0], false); - } - } - - public IMessageEditor getRequestEditor() { - return requestEditor; - } - - public IMessageEditor getResponseEditor() { - return responseEditor; - } - - public Preferences getPreferences() { - return preferences; } - public RequestViewerPanel getRequestViewerPanel() { - return requestViewerPanel; - } - - @Override - public byte[] getRequest() { - if (currentEntry != null && currentEntry.getRequest() != null) { - return currentEntry.getRequest(); - } else { - return new byte[0]; - } - } - - @Override - public byte[] getResponse() { - if (currentEntry != null && currentEntry.getResponse() != null) { - return currentEntry.getResponse(); - } else { - return new byte[0]; - } - } + public void setMarkers(){ - @Override - public IHttpService getHttpService() { - if (currentEntry == null) return null; - return currentEntry.getHttpService(); } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerPanel.java b/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerPanel.java index 3ef6244b..5e912ec0 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerPanel.java @@ -14,8 +14,8 @@ public RequestViewerPanel(RequestViewerController controller){ this.controller = controller; this.variableViewPanel = new VariableViewPanel(controller.getPreferences(), Globals.PREF_MESSAGE_VIEW_LAYOUT, - controller.getRequestEditor().getComponent(), "Request", - controller.getResponseEditor().getComponent(), "Response", + controller.getRequestEditor().uiComponent(), "Request", + controller.getResponseEditor().uiComponent(), "Response", VariableViewPanel.View.HORIZONTAL); this.setComponent(variableViewPanel); diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumn.java b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumn.java index 952fc6f0..0f115ce3 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumn.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumn.java @@ -19,7 +19,6 @@ import com.google.gson.*; import com.nccgroup.loggerplusplus.logentry.LogEntryField; -import com.nccgroup.loggerplusplus.util.userinterface.renderer.LeftTableCellRenderer; import javax.swing.table.TableColumn; import java.lang.reflect.Type; diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java index 4691e7b4..e7a1750f 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java @@ -13,7 +13,6 @@ package com.nccgroup.loggerplusplus.logview.logtable; import com.coreyd97.BurpExtenderUtilities.Preferences; -import com.nccgroup.loggerplusplus.logentry.LogEntryField; import com.nccgroup.loggerplusplus.util.Globals; import com.nccgroup.loggerplusplus.LoggerPlusPlus; diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeader.java b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeader.java index 258cdde6..00fad487 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeader.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeader.java @@ -2,7 +2,6 @@ import javax.swing.*; import javax.swing.table.JTableHeader; -import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/processor/EntryImportWorker.java b/src/main/java/com/nccgroup/loggerplusplus/logview/processor/EntryImportWorker.java index 3ae7c0be..63b1bead 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/processor/EntryImportWorker.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/processor/EntryImportWorker.java @@ -1,7 +1,10 @@ package com.nccgroup.loggerplusplus.logview.processor; -import burp.IBurpExtenderCallbacks; -import burp.IHttpRequestResponse; +import burp.api.montoya.core.ToolType; +import burp.api.montoya.http.message.HttpRequestResponse; +import burp.api.montoya.http.message.requests.HttpRequest; +import burp.api.montoya.http.message.responses.HttpResponse; +import burp.api.montoya.proxy.ProxyRequestResponse; import com.nccgroup.loggerplusplus.logentry.LogEntry; import javax.swing.*; @@ -13,8 +16,9 @@ public class EntryImportWorker extends SwingWorker { private final LogProcessor logProcessor; - private final int originatingTool; - private final List entries; + private final ToolType originatingTool; + private final List proxyEntries; + private final List httpEntries; private final Consumer> interimConsumer; private final Runnable callback; private final boolean sendToAutoExporters; @@ -22,7 +26,8 @@ public class EntryImportWorker extends SwingWorker { private EntryImportWorker(Builder builder){ this.logProcessor = builder.logProcessor; this.originatingTool = builder.originatingTool; - this.entries = builder.entries; + this.proxyEntries = builder.proxyEntries; + this.httpEntries = builder.httpEntries; this.interimConsumer = builder.interimConsumer; this.callback = builder.callback; this.sendToAutoExporters = builder.sendToAutoExporters; @@ -31,12 +36,24 @@ private EntryImportWorker(Builder builder){ @Override protected Void doInBackground() throws Exception { logProcessor.getEntryProcessExecutor().pause(); //Pause the processor, we don't want it mixing with our import. + boolean isProxyEntries = proxyEntries.size() > 0; + int count = isProxyEntries ? proxyEntries.size() : httpEntries.size(); - CountDownLatch countDownLatch = new CountDownLatch(entries.size()); + + CountDownLatch countDownLatch = new CountDownLatch(count); ThreadPoolExecutor entryImportExecutor = logProcessor.getEntryImportExecutor(); - for (int index = 0; index < entries.size(); index++) { + for (int index = 0; index < count; index++) { if(entryImportExecutor.isShutdown() || this.isCancelled()) return null; - final LogEntry logEntry = new LogEntry(originatingTool, entries.get(index)); + HttpRequest request; + HttpResponse response; + if(isProxyEntries){ + request = proxyEntries.get(index).finalRequest(); + response = proxyEntries.get(index).originalResponse(); + }else{ + request = httpEntries.get(index).httpRequest(); + response = httpEntries.get(index).httpResponse(); + } + final LogEntry logEntry = new LogEntry(originatingTool, request, response); int finalIndex = index; entryImportExecutor.submit(() -> { if(this.isCancelled()) return; @@ -68,8 +85,9 @@ protected void done() { public static class Builder { private final LogProcessor logProcessor; - private int originatingTool = IBurpExtenderCallbacks.TOOL_EXTENDER; - private List entries; + private ToolType originatingTool = ToolType.EXTENSIONS; + private List proxyEntries; + private List httpEntries; private Consumer> interimConsumer; private Runnable callback; private boolean sendToAutoExporters = false; @@ -78,13 +96,20 @@ public static class Builder { this.logProcessor = logProcessor; } - public Builder setOriginatingTool(int originatingTool){ + public Builder setOriginatingTool(ToolType originatingTool){ this.originatingTool = originatingTool; return this; } - public Builder setEntries(List entries) { - this.entries = entries; + public Builder setProxyEntries(List entries) { + this.proxyEntries.addAll(entries); + this.httpEntries.clear(); + return this; + } + + public Builder setHttpEntries(List entries) { + this.httpEntries.addAll(entries); + this.proxyEntries.clear(); return this; } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessor.java b/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessor.java index e476d310..70a57a11 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessor.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessor.java @@ -1,6 +1,14 @@ package com.nccgroup.loggerplusplus.logview.processor; -import burp.*; +import burp.api.montoya.core.Annotations; +import burp.api.montoya.core.ToolSource; +import burp.api.montoya.core.ToolType; +import burp.api.montoya.http.HttpHandler; +import burp.api.montoya.http.RequestResult; +import burp.api.montoya.http.ResponseResult; +import burp.api.montoya.http.message.requests.HttpRequest; +import burp.api.montoya.http.message.responses.HttpResponse; +import burp.api.montoya.proxy.*; import com.coreyd97.BurpExtenderUtilities.Preferences; import com.nccgroup.loggerplusplus.LoggerPlusPlus; import com.nccgroup.loggerplusplus.exports.ExportController; @@ -11,6 +19,8 @@ import com.nccgroup.loggerplusplus.logview.logtable.LogTableController; import com.nccgroup.loggerplusplus.util.NamedThreadFactory; import com.nccgroup.loggerplusplus.util.PausableThreadPoolExecutor; +import lombok.Getter; +import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -24,11 +34,10 @@ /** * Created by corey on 07/09/17. */ -public class LogProcessor implements IHttpListener, IProxyListener { +@Log4j2 +public class LogProcessor { public static final SimpleDateFormat LOGGER_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); public static final SimpleDateFormat SERVER_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz"); - - private final LoggerPlusPlus loggerPlusPlus; private final LogTableController logTableController; private final ExportController exportController; private final Preferences preferences; @@ -38,6 +47,11 @@ public class LogProcessor implements IHttpListener, IProxyListener { private final PausableThreadPoolExecutor entryImportExecutor; private final ScheduledExecutorService cleanupExecutor; + @Getter + private final HttpHandler httpHandler; + @Getter + private final ProxyHttpResponseHandler proxyHttpResponseHandler; + Logger logger = LogManager.getLogger(this); /** @@ -45,11 +59,10 @@ public class LogProcessor implements IHttpListener, IProxyListener { * Logic to allow requests independently and match them to responses once received. * TODO SQLite integration */ - public LogProcessor(LoggerPlusPlus loggerPlusPlus, LogTableController logTableController, ExportController exportController) { - this.loggerPlusPlus = loggerPlusPlus; + public LogProcessor(LogTableController logTableController, ExportController exportController) { this.logTableController = logTableController; this.exportController = exportController; - this.preferences = this.loggerPlusPlus.getPreferencesController().getPreferences(); + this.preferences = LoggerPlusPlus.instance.getPreferencesController().getPreferences(); this.entriesPendingProcessing = new ConcurrentHashMap<>(); this.entryProcessingFutures = new ConcurrentHashMap<>(); @@ -62,70 +75,150 @@ public LogProcessor(LoggerPlusPlus loggerPlusPlus, LogTableController logTableCo this.cleanupExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("LPP-LogManager-Cleanup")); this.cleanupExecutor.scheduleAtFixedRate(new AbandonedRequestCleanupRunnable(),30, 30, TimeUnit.SECONDS); - LoggerPlusPlus.callbacks.registerHttpListener(this); - LoggerPlusPlus.callbacks.registerProxyListener(this); + //TODO Enable new logging API when support for matching requests and their responses improves... + this.httpHandler = createHttpHandler(); + this.proxyHttpResponseHandler = createProxyResponseHandler(); } - /** - * Process messages from all tools. - * Adds to queue for later processing. - * Note: processProxyMessage runs *after* processHttpMessage, responses from the proxy tool are left for that method. - * - * @param toolFlag Tool used to make request - * @param isRequestOnly If the message is request only or complete with response - * @param httpMessage The request and potentially response received. - */ - @Override - public void processHttpMessage(final int toolFlag, final boolean isRequestOnly, final IHttpRequestResponse httpMessage) { - if (httpMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return; - Date arrivalTime = new Date(); - - if (isRequestOnly) { - //If we're handling a new request, create a log entry. - //We must also handle proxy messages here, since the HTTP listener operates after the proxy listener - final LogEntry logEntry = new LogEntry(toolFlag, arrivalTime, httpMessage); - - //Set the entry's identifier to the HTTP request's hashcode. - // For non-proxy messages, this doesn't change when we receive the response - logEntry.setIdentifier(System.identityHashCode(httpMessage.getRequest())); - //Submit a new task to process the entry - submitNewEntryProcessingRunnable(logEntry); - } else { - if (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY) { - //If the request came from the proxy, the response isn't final yet. - //Just tag the comment with the identifier so we can match it up later. - Integer identifier = System.identityHashCode(httpMessage.getRequest()); - LogProcessorHelper.addIdentifierInComment(identifier, httpMessage); - return; //Process proxy responses using processProxyMessage - } else { - //Otherwise, we have the final HTTP response, and can use the request hashcode to match it up with the log entry. - Integer identifier = System.identityHashCode(httpMessage.getRequest()); - updateRequestWithResponse(identifier, arrivalTime, httpMessage); + private HttpHandler createHttpHandler(){ + return new HttpHandler() { + @Override + public RequestResult handleHttpRequest(HttpRequest request, Annotations annotations, ToolSource toolSource) { + if (!(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolSource.toolType()) + || !LoggerPlusPlus.isUrlInScope(request.url())){ + return RequestResult.requestResult(request,annotations); + } + Date arrivalTime = new Date(); + + //If we're handling a new request, create a log entry. + //We must also handle proxy messages here, since the HTTP listener operates after the proxy listener + final LogEntry logEntry = new LogEntry(toolSource.toolType(), request, arrivalTime); + + //Set the entry's identifier to the HTTP request's hashcode. + // For non-proxy messages, this doesn't change when we receive the response + Integer identifier = System.identityHashCode(request.body()); + logEntry.setIdentifier(identifier); + annotations = LogProcessorHelper.addIdentifierInComment(identifier, annotations); + //Submit a new task to process the entry + submitNewEntryProcessingRunnable(logEntry); + + return RequestResult.requestResult(request, annotations); } - } + + @Override + public ResponseResult handleHttpResponse(HttpResponse response, HttpRequest initiatingRequest, Annotations annotations, ToolSource toolSource) { + if (!(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolSource.toolType()) + || !LoggerPlusPlus.isUrlInScope(initiatingRequest.url())){ + return ResponseResult.responseResult(response,annotations); + } + Date arrivalTime = new Date(); + + if (toolSource.isFromTool(ToolType.PROXY)) { + //If the request came from the proxy, the response isn't final yet. + //Just tag the comment with the identifier so we can match it up later. +// Integer identifier = System.identityHashCode(initiatingRequest); +// System.out.println("HTTP Response Proxy - Initiating Request: " + identifier); +// log.info("New Proxy Response: " + identifier); +// annotations = LogProcessorHelper.addIdentifierInComment(identifier, annotations); +// return ResponseResult.responseResult(response, annotations); //Process proxy responses using processProxyMessage + } else { + //Otherwise, we have the final HTTP response, and can use the request hashcode to match it up with the log entry. + Object[] identifierAndAnnotation = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(annotations); + Integer identifier = (Integer) identifierAndAnnotation[0]; //TODO Ew. + annotations = (Annotations) identifierAndAnnotation[1]; + updateRequestWithResponse(identifier, arrivalTime, response); + } + return ResponseResult.responseResult(response, annotations); + } + }; } - /** - * Since this method runs after processHttpMessage, we must use it to get the final response for proxy tool requests - * otherwise, changes to the message by other tools using processProxyMessage would not be seen! - * - * @param isRequestOnly - * @param proxyMessage - */ - @Override - public void processProxyMessage(final boolean isRequestOnly, final IInterceptedProxyMessage proxyMessage) { - final int toolFlag = IBurpExtenderCallbacks.TOOL_PROXY; - if (proxyMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return; - Date arrivalTime = new Date(); + private ProxyHttpResponseHandler createProxyResponseHandler(){ + return new ProxyHttpResponseHandler() { + @Override + public ResponseInitialInterceptResult handleReceivedResponse(InterceptedHttpResponse interceptedResponse, HttpRequest initiatingRequest, Annotations annotations) { + return ResponseInitialInterceptResult.followUserRules(interceptedResponse, annotations); //Do nothing + } - if (isRequestOnly) { + @Override + public ResponseFinalInterceptResult handleResponseToReturn(InterceptedHttpResponse interceptedResponse, HttpRequest initiatingRequest, Annotations annotations) { + if(!((boolean) preferences.getSetting(PREF_ENABLED)) || !((boolean) preferences.getSetting(PREF_LOG_PROXY)) + || !LoggerPlusPlus.isUrlInScope(initiatingRequest.url())) { + return ResponseFinalInterceptResult.continueWith(interceptedResponse, annotations); + } - } else { //We only want to handle responses. - Integer identifier = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(proxyMessage.getMessageInfo()); - updateRequestWithResponse(identifier, arrivalTime, proxyMessage.getMessageInfo()); - } + Date arrivalTime = new Date(); + Object[] identifierAndAnnotation = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(annotations); + Integer identifier = (Integer) identifierAndAnnotation[0]; //TODO Ew. + annotations = (Annotations) identifierAndAnnotation[1]; + + updateRequestWithResponse(identifier, arrivalTime, interceptedResponse); + return ResponseFinalInterceptResult.continueWith(interceptedResponse, annotations); + } + }; } + +// /** +// * Process messages from all tools. +// * Adds to queue for later processing. +// * Note: processProxyMessage runs *after* processHttpMessage, responses from the proxy tool are left for that method. +// * +// * @param toolFlag Tool used to make request +// * @param isRequestOnly If the message is request only or complete with response +// * @param httpMessage The request and potentially response received. +// */ +// @Override +// public void processHttpMessage(final int toolFlag, final boolean isRequestOnly, final IHttpRequestResponse httpMessage) { +// if (httpMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return; +// Date arrivalTime = new Date(); +// +// if (isRequestOnly) { +// //If we're handling a new request, create a log entry. +// //We must also handle proxy messages here, since the HTTP listener operates after the proxy listener +// final LogEntry logEntry = new LogEntry(toolFlag, arrivalTime, httpMessage); +// +// //Set the entry's identifier to the HTTP request's hashcode. +// // For non-proxy messages, this doesn't change when we receive the response +// logEntry.setIdentifier(System.identityHashCode(httpMessage.getRequest())); +// //Submit a new task to process the entry +// submitNewEntryProcessingRunnable(logEntry); +// } else { +// if (toolFlag == IBurpExtendermontoya.TOOL_PROXY) { +// //If the request came from the proxy, the response isn't final yet. +// //Just tag the comment with the identifier so we can match it up later. +// Integer identifier = System.identityHashCode(httpMessage.getRequest()); +// LogProcessorHelper.addIdentifierInComment(identifier, httpMessage); +// return; //Process proxy responses using processProxyMessage +// } else { +// //Otherwise, we have the final HTTP response, and can use the request hashcode to match it up with the log entry. +// Integer identifier = System.identityHashCode(httpMessage.getRequest()); +// updateRequestWithResponse(identifier, arrivalTime, httpMessage); +// } +// } +// } +// +// /** +// * Since this method runs after processHttpMessage, we must use it to get the final response for proxy tool requests +// * otherwise, changes to the message by other tools using processProxyMessage would not be seen! +// * +// * @param isRequestOnly +// * @param proxyMessage +// */ +// @Override +// public void processProxyMessage(final boolean isRequestOnly, final IInterceptedProxyMessage proxyMessage) { +// final int toolFlag = IBurpExtendermontoya.TOOL_PROXY; +// if (proxyMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return; +// Date arrivalTime = new Date(); +// +// if (isRequestOnly) { +// +// } else { //We only want to handle responses. +// Integer identifier = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(proxyMessage.getMessageInfo()); +// updateRequestWithResponse(identifier, arrivalTime, proxyMessage.getMessageInfo()); +// } +// } + /** * When a response comes in, determine if the request has already been processed or not. * If it has not yet been processed, add the response information to the entry and let the original job handle it. @@ -134,14 +227,14 @@ public void processProxyMessage(final boolean isRequestOnly, final IInterceptedP * * @param entryIdentifier The unique UUID for the log entry. * @param arrivalTime The arrival time of the response. - * @param requestResponse The HTTP request response object. + * @param response The HTTP request response object. */ - private void updateRequestWithResponse(Integer entryIdentifier, Date arrivalTime, IHttpRequestResponse requestResponse) { + private void updateRequestWithResponse(Integer entryIdentifier, Date arrivalTime, HttpResponse response) { if (entriesPendingProcessing.containsKey(entryIdentifier)) { //Not yet started processing the entry, we can add the response so it is processed in the first pass final LogEntry logEntry = entriesPendingProcessing.get(entryIdentifier); - //Update the requestResponse with the new one, and tell it when it arrived. - logEntry.addResponse(requestResponse, arrivalTime); + //Update the response with the new one, and tell it when it arrived. + logEntry.addResponse(response, arrivalTime); //Do nothing now, there's already a runnable submitted to process it somewhere in the queue. return; @@ -154,7 +247,7 @@ private void updateRequestWithResponse(Integer entryIdentifier, Date arrivalTime //Submit a job for the processing of its response. //This will block on the request finishing processing, then update the response and process it separately. - entryProcessExecutor.submit(createEntryUpdateRunnable(processingFuture, requestResponse, arrivalTime)); + entryProcessExecutor.submit(createEntryUpdateRunnable(processingFuture, response, arrivalTime)); } else { //Unknown Identifier. Potentially for a request which was ignored or cleaned up already? } @@ -216,7 +309,7 @@ LogEntry processEntry(final LogEntry logEntry){ } private RunnableFuture createEntryUpdateRunnable(final Future processingFuture, - final IHttpRequestResponse requestResponse, + final HttpResponse requestResponse, final Date arrivalTime){ return new FutureTask<>(() -> { //Block until initial processing is complete. @@ -247,30 +340,34 @@ public void importProxyHistory(boolean sendToAutoExporters) { //TODO Remove to more suitable UI class and show dialog //Build list of entries to import - IHttpRequestResponse[] proxyHistory = LoggerPlusPlus.callbacks.getProxyHistory(); + List proxyHistory = LoggerPlusPlus.montoya.proxy().history(); int maxEntries = preferences.getSetting(PREF_MAXIMUM_ENTRIES); - int startIndex = Math.max(proxyHistory.length - maxEntries, 0); - List entriesToImport = Arrays.asList(proxyHistory).subList(startIndex, proxyHistory.length); + int startIndex = Math.max(proxyHistory.size() - maxEntries, 0); + List entriesToImport = proxyHistory.subList(startIndex, proxyHistory.size()); //Build and start import worker EntryImportWorker importWorker = new EntryImportWorker.Builder(this) - .setOriginatingTool(IBurpExtenderCallbacks.TOOL_PROXY) - .setEntries(entriesToImport) + .setOriginatingTool(ToolType.PROXY) + .setProxyEntries(entriesToImport) .setSendToAutoExporters(sendToAutoExporters).build(); importWorker.execute(); } - private boolean isValidTool(int toolFlag){ - return ((Boolean) preferences.getSetting(PREF_LOG_GLOBAL) || - ((Boolean) preferences.getSetting(PREF_LOG_PROXY) && toolFlag== IBurpExtenderCallbacks.TOOL_PROXY) || - ((Boolean) preferences.getSetting(PREF_LOG_INTRUDER) && toolFlag== IBurpExtenderCallbacks.TOOL_INTRUDER) || - ((Boolean) preferences.getSetting(PREF_LOG_REPEATER) && toolFlag== IBurpExtenderCallbacks.TOOL_REPEATER) || - ((Boolean) preferences.getSetting(PREF_LOG_SCANNER) && toolFlag== IBurpExtenderCallbacks.TOOL_SCANNER) || - ((Boolean) preferences.getSetting(PREF_LOG_SEQUENCER) && toolFlag== IBurpExtenderCallbacks.TOOL_SEQUENCER) || - ((Boolean) preferences.getSetting(PREF_LOG_SPIDER) && toolFlag== IBurpExtenderCallbacks.TOOL_SPIDER) || - ((Boolean) preferences.getSetting(PREF_LOG_EXTENDER) && toolFlag == IBurpExtenderCallbacks.TOOL_EXTENDER) || - ((Boolean) preferences.getSetting(PREF_LOG_TARGET_TAB) && toolFlag == IBurpExtenderCallbacks.TOOL_TARGET)); + private boolean isValidTool(ToolType toolType){ + if(preferences.getSetting(PREF_LOG_GLOBAL)) return true; + + switch (toolType){ + case PROXY -> {return preferences.getSetting(PREF_LOG_PROXY);} + case INTRUDER -> {return preferences.getSetting(PREF_LOG_INTRUDER);} + case REPEATER -> {return preferences.getSetting(PREF_LOG_REPEATER);} + case EXTENSIONS -> {return preferences.getSetting(PREF_LOG_EXTENSIONS);} + case SCANNER -> {return preferences.getSetting(PREF_LOG_SCANNER);} + case SEQUENCER -> {return preferences.getSetting(PREF_LOG_SEQUENCER);} + case SUITE -> {return preferences.getSetting(PREF_LOG_SUITE);} + case RECORDED_LOGIN_REPLAYER -> {return preferences.getSetting(PREF_LOG_RECORDED_LOGINS);} + default -> {return false;} + } } public void shutdown() { @@ -332,9 +429,10 @@ public void run() { long responseTimeout = 1000 * ((Integer) preferences.getSetting(PREF_RESPONSE_TIMEOUT)).longValue(); if (timeNow - entryTime > responseTimeout) { iter.remove(); - if (logEntry.getTool() == IBurpExtenderCallbacks.TOOL_PROXY) { + if (logEntry.getTool() == ToolType.PROXY) { //Remove the identifier from the comment. - LogEntry.extractAndRemoveIdentifierFromComment(logEntry); + //TODO Fix Comment cleanup +// LogEntry.extractAndRemoveIdentifierFromComment(logEntry); } logEntry.setComment(logEntry.getComment() + " Timed Out"); } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessorHelper.java b/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessorHelper.java index 13d47b5c..2ba7755b 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessorHelper.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessorHelper.java @@ -1,27 +1,29 @@ package com.nccgroup.loggerplusplus.logview.processor; -import burp.IHttpRequestResponse; +import burp.api.montoya.core.Annotations; import com.nccgroup.loggerplusplus.util.Globals; +import org.apache.commons.lang3.StringUtils; import java.util.regex.Matcher; public class LogProcessorHelper { - public static void addIdentifierInComment(Integer identifier, IHttpRequestResponse requestResponse) { - String originalComment = requestResponse.getComment() != null ? requestResponse.getComment() : ""; - requestResponse.setComment(originalComment + "$LPP:" + identifier + "$"); + public static Annotations addIdentifierInComment(Integer identifier, Annotations annotations) { + String originalComment = annotations.comment() != null ? annotations.comment() : ""; + annotations = annotations.withComment(originalComment + "$LPP:" + identifier + "$"); + return annotations; } - public static Integer extractAndRemoveIdentifierFromRequestResponseComment(IHttpRequestResponse requestResponse) { + public static Object[] extractAndRemoveIdentifierFromRequestResponseComment(Annotations annotations) { Integer identifier = null; - if (requestResponse.getComment() != null) { - Matcher matcher = Globals.LOG_ENTRY_ID_PATTERN.matcher(requestResponse.getComment()); + if (!StringUtils.isEmpty(annotations.comment())) { + Matcher matcher = Globals.LOG_ENTRY_ID_PATTERN.matcher(annotations.comment()); if (matcher.find()) { identifier = Integer.parseInt(matcher.group(1)); - requestResponse.setComment(matcher.replaceAll("")); + annotations = annotations.withComment(matcher.replaceAll("")); } } - return identifier; + return new Object[]{identifier,annotations}; } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java b/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java index 88c91a1a..c52c9a9c 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java +++ b/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java @@ -1,6 +1,6 @@ package com.nccgroup.loggerplusplus.preferences; -import burp.IBurpExtenderCallbacks; +import burp.api.montoya.MontoyaApi; import com.coreyd97.BurpExtenderUtilities.IGsonProvider; import com.coreyd97.BurpExtenderUtilities.ILogProvider; import com.coreyd97.BurpExtenderUtilities.PreferenceFactory; @@ -29,12 +29,12 @@ public class LoggerPreferenceFactory extends PreferenceFactory { private ArrayList defaultlogTableColumns; private Set defaultBlacklistedReflections; - public LoggerPreferenceFactory(IGsonProvider gsonProvider, ILogProvider logProvider, IBurpExtenderCallbacks callbacks){ - super("LoggerPlusPlus", gsonProvider, logProvider, callbacks); + public LoggerPreferenceFactory(MontoyaApi montoya, IGsonProvider gsonProvider, ILogProvider logProvider){ + super(montoya, "LoggerPlusPlus", gsonProvider, logProvider); } - public LoggerPreferenceFactory(IGsonProvider gsonProvider, IBurpExtenderCallbacks callbacks){ - super("LoggerPlusPlus", gsonProvider, callbacks); + public LoggerPreferenceFactory(MontoyaApi montoya, IGsonProvider gsonProvider){ + super(montoya, "LoggerPlusPlus", gsonProvider); } @Override @@ -71,7 +71,7 @@ protected void registerSettings() { prefs.registerSetting(PREF_LOG_SCANNER, Boolean.class, true); prefs.registerSetting(PREF_LOG_REPEATER, Boolean.class, true); prefs.registerSetting(PREF_LOG_SEQUENCER, Boolean.class, true); - prefs.registerSetting(PREF_LOG_EXTENDER, Boolean.class, true); + prefs.registerSetting(PREF_LOG_EXTENSIONS, Boolean.class, true); prefs.registerSetting(PREF_LOG_TARGET_TAB, Boolean.class, true); prefs.registerSetting(PREF_MAX_RESP_SIZE, Integer.class, 10); //Default 10MB prefs.registerSetting(PREF_COLOR_FILTERS, new TypeToken>() { diff --git a/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesController.java b/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesController.java index 71d30426..6e7c895e 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesController.java @@ -1,57 +1,49 @@ package com.nccgroup.loggerplusplus.preferences; +import burp.api.montoya.MontoyaApi; import com.coreyd97.BurpExtenderUtilities.IGsonProvider; import com.coreyd97.BurpExtenderUtilities.ILogProvider; import com.coreyd97.BurpExtenderUtilities.Preferences; import com.nccgroup.loggerplusplus.LoggerPlusPlus; +import lombok.Getter; +import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +@Log4j2 public class PreferencesController { - private final LoggerPlusPlus loggerPlusPlus; + + @Getter private final IGsonProvider gsonProvider; + + @Getter private final Preferences preferences; private PreferencesPanel preferencesPanel; - private Logger logger = LogManager.getLogger(this.getClass()); - - public PreferencesController(LoggerPlusPlus loggerPlusPlus) { - this.loggerPlusPlus = loggerPlusPlus; - this.gsonProvider = loggerPlusPlus.getGsonProvider(); - this.preferences = new LoggerPreferenceFactory( + public PreferencesController(MontoyaApi montoya) { + this.gsonProvider = LoggerPlusPlus.gsonProvider; + this.preferences = new LoggerPreferenceFactory(montoya, gsonProvider, new ILogProvider() { @Override public void logOutput(String message) { - logger.debug(message); + log.debug(message); } @Override public void logError(String errorMessage) { - logger.error(errorMessage); + log.error(errorMessage); } - }, - LoggerPlusPlus.callbacks + } ).buildPreferences(); } public PreferencesPanel getPreferencesPanel() { - if(preferencesPanel == null) { - preferencesPanel = new PreferencesPanel(this); + if(this.preferencesPanel == null) { + this.preferencesPanel = new PreferencesPanel(this); } - return preferencesPanel; - } - public LoggerPlusPlus getLoggerPlusPlus() { - return loggerPlusPlus; - } - - public IGsonProvider getGsonProvider() { - return gsonProvider; - } - - public Preferences getPreferences() { - return preferences; + return preferencesPanel; } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java b/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java index 55555ffc..3965fdd4 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java @@ -12,7 +12,7 @@ package com.nccgroup.loggerplusplus.preferences; -import burp.IHttpRequestResponse; +import burp.api.montoya.http.message.HttpRequestResponse; import com.coreyd97.BurpExtenderUtilities.Alignment; import com.coreyd97.BurpExtenderUtilities.ComponentGroup; import com.coreyd97.BurpExtenderUtilities.ComponentGroup.Orientation; @@ -77,7 +77,7 @@ public void actionPerformed(ActionEvent e) { JCheckBox logSequencer = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_SEQUENCER, "Sequencer"); JCheckBox logProxy = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_PROXY, "Proxy"); JCheckBox logTarget = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_TARGET_TAB, "Target"); - JCheckBox logExtender = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_EXTENDER, "Extender"); + JCheckBox logExtender = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_EXTENSIONS, "Extender"); strutConstraints = logFromPanel.generateNextConstraints(true); strutConstraints.weighty = strutConstraints.weightx = 0; @@ -115,7 +115,7 @@ public void actionPerformed(ActionEvent e) { importGroup.add(new JButton(new AbstractAction("Import Burp Proxy History") { @Override public void actionPerformed(ActionEvent e) { - int historySize = LoggerPlusPlus.callbacks.getProxyHistory().length; + int historySize = LoggerPlusPlus.montoya.proxy().history().size(); int maxEntries = preferences.getSetting(PREF_MAXIMUM_ENTRIES); String message = "Import " + historySize + " items from burp suite proxy history? This will clear the current entries." @@ -137,7 +137,7 @@ public void actionPerformed(ActionEvent e) { sendToAutoExporters = res == JOptionPane.YES_OPTION; } - preferencesController.getLoggerPlusPlus().getLogProcessor().importProxyHistory(sendToAutoExporters); + LoggerPlusPlus.instance.getLogProcessor().importProxyHistory(sendToAutoExporters); } } })); @@ -145,7 +145,7 @@ public void actionPerformed(ActionEvent e) { importGroup.add(new JButton(new AbstractAction("Import From WStalker CSV") { @Override public void actionPerformed(ActionEvent e) { - ArrayList requests = LoggerImport.importWStalker(); + ArrayList requests = LoggerImport.importWStalker(); if (LoggerPlusPlus.instance.getExportController().getEnabledExporters().size() > 0) { int res = JOptionPane.showConfirmDialog(LoggerPlusPlus.instance.getLoggerFrame(), "One or more auto-exporters are currently enabled. " + @@ -161,7 +161,7 @@ public void actionPerformed(ActionEvent e) { importGroup.add(new JButton(new AbstractAction("Import From OWASP ZAP") { @Override public void actionPerformed(ActionEvent e) { - ArrayList requests = LoggerImport.importZAP(); + ArrayList requests = LoggerImport.importZAP(); if (LoggerPlusPlus.instance.getExportController().getEnabledExporters().size() > 0) { int res = JOptionPane.showConfirmDialog(LoggerPlusPlus.instance.getLoggerFrame(), @@ -176,7 +176,7 @@ public void actionPerformed(ActionEvent e) { })); ComponentGroup exportGroup = new ComponentGroup(Orientation.HORIZONTAL); - HashMap, LogExporter> exporters = preferencesController.getLoggerPlusPlus() + HashMap, LogExporter> exporters = LoggerPlusPlus.instance .getExportController().getExporters(); exportGroup.add(((ExportPanelProvider) exporters.get(CSVExporter.class)).getExportPanel()); exportGroup.add(((ExportPanelProvider) exporters.get(JSONExporter.class)).getExportPanel()); @@ -280,7 +280,7 @@ public void actionPerformed(ActionEvent e) { JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { preferences.resetSettings(preferences.getRegisteredSettings().keySet()); - preferencesController.getLoggerPlusPlus().getLogViewController().getLogTableController() + LoggerPlusPlus.instance.getLogViewController().getLogTableController() .reinitialize(); } } @@ -289,7 +289,7 @@ public void actionPerformed(ActionEvent e) { resetPanel.add(new JButton(new AbstractAction("Clear The Logs") { @Override public void actionPerformed(ActionEvent e) { - preferencesController.getLoggerPlusPlus().getLogViewController().getLogTableController().reset(); + LoggerPlusPlus.instance.getLogViewController().getLogTableController().reset(); } })); diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/ReflectionController.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/ReflectionController.java index 2960e9d5..de3d18db 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/ReflectionController.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/ReflectionController.java @@ -1,6 +1,6 @@ package com.nccgroup.loggerplusplus.reflection; -import burp.IParameter; +import burp.api.montoya.http.message.params.HttpParameter; import com.coreyd97.BurpExtenderUtilities.Alignment; import com.coreyd97.BurpExtenderUtilities.PanelBuilder; import com.coreyd97.BurpExtenderUtilities.Preferences; @@ -9,20 +9,16 @@ import com.nccgroup.loggerplusplus.reflection.filter.LengthFilter; import com.nccgroup.loggerplusplus.reflection.filter.ParameterFilter; import com.nccgroup.loggerplusplus.reflection.transformer.*; -import com.nccgroup.loggerplusplus.util.MoreHelp; import com.nccgroup.loggerplusplus.util.userinterface.renderer.BooleanRenderer; import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer; import javax.swing.*; -import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableModel; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; +import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; import java.util.regex.Pattern; public class ReflectionController { @@ -47,15 +43,15 @@ public ReflectionController(Preferences preferences){ transformerList.add(new XMLUnescapeTransformer(preferences)); } - public List filterParameters(List allParameters){ - List interestingParameters = new ArrayList<>(); - for (IParameter parameter : allParameters) { + public List filterParameters(List allParameters){ + List interestingParameters = new ArrayList<>(); + for (HttpParameter parameter : allParameters) { if(!isParameterFiltered(parameter)) interestingParameters.add(parameter); } return interestingParameters; } - public boolean isParameterFiltered(IParameter parameter){ + public boolean isParameterFiltered(HttpParameter parameter){ for (ParameterFilter filter : filterList) { if(!filter.isEnabled()) continue; if(filter.isFiltered(parameter)){ @@ -65,15 +61,15 @@ public boolean isParameterFiltered(IParameter parameter){ return false; } - public boolean validReflection(String responseBody, IParameter param){ - if(param.getName().isEmpty() || param.getValue().isEmpty()) return false; + public boolean validReflection(String responseBody, HttpParameter param){ + if(param.name().isEmpty() || param.value().isEmpty()) return false; - if(responseBody.contains(param.getValue())) return true; + if(responseBody.contains(param.value())) return true; for (ParameterValueTransformer transformer : transformerList) { try { if (transformer.isEnabled()){ - Pattern pattern = Pattern.compile("\\Q"+transformer.transform(param.getValue())+"\\E", Pattern.CASE_INSENSITIVE); + Pattern pattern = Pattern.compile("\\Q"+transformer.transform(param.value())+"\\E", Pattern.CASE_INSENSITIVE); if(pattern.matcher(responseBody).find()){ return true; } diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/BlacklistFilter.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/BlacklistFilter.java index 65fb2364..a50380ca 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/BlacklistFilter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/BlacklistFilter.java @@ -1,13 +1,11 @@ package com.nccgroup.loggerplusplus.reflection.filter; -import burp.IParameter; -import com.coreyd97.BurpExtenderUtilities.PanelBuilder; +import burp.api.montoya.http.message.params.HttpParameter; import com.coreyd97.BurpExtenderUtilities.Preferences; import com.google.gson.reflect.TypeToken; import com.nccgroup.loggerplusplus.util.MoreHelp; import org.apache.commons.lang3.StringUtils; -import javax.swing.*; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -28,8 +26,8 @@ public BlacklistFilter(Preferences preferences){ } @Override - public boolean isFiltered(IParameter parameter) { - return blacklist.contains(parameter.getValue()); + public boolean isFiltered(HttpParameter parameter) { + return blacklist.contains(parameter.value()); } @Override diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/LengthFilter.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/LengthFilter.java index f372c917..2508ea67 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/LengthFilter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/LengthFilter.java @@ -1,20 +1,12 @@ package com.nccgroup.loggerplusplus.reflection.filter; -import burp.IParameter; +import burp.api.montoya.http.message.params.HttpParameter; import com.coreyd97.BurpExtenderUtilities.Alignment; import com.coreyd97.BurpExtenderUtilities.PanelBuilder; import com.coreyd97.BurpExtenderUtilities.Preferences; -import com.google.gson.reflect.TypeToken; import com.nccgroup.loggerplusplus.LoggerPlusPlus; -import com.nccgroup.loggerplusplus.util.MoreHelp; -import org.apache.commons.lang3.StringUtils; import javax.swing.*; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.TreeSet; -import java.util.logging.Logger; public class LengthFilter extends ParameterFilter { @@ -33,8 +25,8 @@ public LengthFilter(Preferences preferences){ } @Override - public boolean isFiltered(IParameter parameter) { - int len = parameter.getValue().length(); + public boolean isFiltered(HttpParameter parameter) { + int len = parameter.value().length(); return len < min_length || len > max_length; } diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/ParameterFilter.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/ParameterFilter.java index a0cd29bd..0a16b78a 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/ParameterFilter.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/filter/ParameterFilter.java @@ -1,6 +1,6 @@ package com.nccgroup.loggerplusplus.reflection.filter; -import burp.IParameter; +import burp.api.montoya.http.message.params.HttpParameter; import com.coreyd97.BurpExtenderUtilities.Preferences; public abstract class ParameterFilter { @@ -31,7 +31,7 @@ public boolean isEnabled() { return enabled; } - public abstract boolean isFiltered(IParameter parameter); + public abstract boolean isFiltered(HttpParameter parameter); public abstract void showConfigDialog(); } diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/Base64EncodeTransformer.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/Base64EncodeTransformer.java index 5c779321..ba290615 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/Base64EncodeTransformer.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/Base64EncodeTransformer.java @@ -3,7 +3,6 @@ import com.coreyd97.BurpExtenderUtilities.Preferences; import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.Base64; public class Base64EncodeTransformer extends ParameterValueTransformer { diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HTMLEscapeTransformer.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HTMLEscapeTransformer.java index 87c5904a..4fdf31df 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HTMLEscapeTransformer.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HTMLEscapeTransformer.java @@ -1,12 +1,8 @@ package com.nccgroup.loggerplusplus.reflection.transformer; import com.coreyd97.BurpExtenderUtilities.Preferences; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; - public class HTMLEscapeTransformer extends ParameterValueTransformer { public HTMLEscapeTransformer(Preferences preferences){ diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HexEncodeTransformer.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HexEncodeTransformer.java index c620a0c9..38c4855d 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HexEncodeTransformer.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HexEncodeTransformer.java @@ -4,7 +4,6 @@ import org.apache.commons.codec.binary.Hex; import java.io.UnsupportedEncodingException; -import java.util.Base64; public class HexEncodeTransformer extends ParameterValueTransformer { diff --git a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/URLDecodeTransformer.java b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/URLDecodeTransformer.java index 17549975..4e2e773f 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/URLDecodeTransformer.java +++ b/src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/URLDecodeTransformer.java @@ -4,7 +4,6 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.net.URLEncoder; public class URLDecodeTransformer extends ParameterValueTransformer { diff --git a/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java b/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java index 6b23b0c2..ee2f6c93 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java +++ b/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java @@ -35,8 +35,10 @@ public class Globals { public static final String PREF_LOG_SCANNER = "logscanner"; public static final String PREF_LOG_REPEATER = "logrepeater"; public static final String PREF_LOG_SEQUENCER = "logsequencer"; - public static final String PREF_LOG_EXTENDER = "logextender"; + public static final String PREF_LOG_EXTENSIONS = "logextender"; public static final String PREF_LOG_TARGET_TAB = "logtargettab"; + public static final String PREF_LOG_RECORDED_LOGINS = "logrecordedlogins"; + public static final String PREF_LOG_SUITE = "logsuite"; public static final String PREF_COLOR_FILTERS = "colorfilters"; public static final String PREF_TAG_FILTERS = "tagfilters"; public static final String PREF_SAVED_FILTERS = "savedfilters"; diff --git a/src/main/java/com/nccgroup/loggerplusplus/util/MoreHelp.java b/src/main/java/com/nccgroup/loggerplusplus/util/MoreHelp.java index 5f051420..3bb4f889 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/util/MoreHelp.java +++ b/src/main/java/com/nccgroup/loggerplusplus/util/MoreHelp.java @@ -110,7 +110,7 @@ public static String[] getHeaderAndBody(byte[] fullMessage, String encoding) thr // public static void checkForUpdate(boolean showMessages) { // new Thread(() -> { - // IExtensionHelpers helper = LoggerPlusPlus.callbacks.getHelpers(); + // IExtensionHelpers helper = LoggerPlusPlus.montoya.getHelpers(); // Double currenVersion = Globals.VERSION; // Double latestVersion = 0.0; // int updateStatus = -1; @@ -120,7 +120,7 @@ public static String[] getHeaderAndBody(byte[] fullMessage, String encoding) thr // URL changeLogURL = new URL(Globals.CHANGELOG); // byte[] request = helper.buildHttpRequest(changeLogURL); // byte[] response = - // LoggerPlusPlus.callbacks.makeHttpRequest(changeLogURL.getHost(), 443, true, + // LoggerPlusPlus.montoya.makeHttpRequest(changeLogURL.getHost(), 443, true, // request); // // if (response != null) { @@ -148,27 +148,27 @@ public static String[] getHeaderAndBody(byte[] fullMessage, String encoding) thr // // } // } catch (Exception e) { - // LoggerPlusPlus.callbacks.printError(e.getMessage()); + // LoggerPlusPlus.montoya.printError(e.getMessage()); // } // // switch (updateStatus) { // case -1: // updateMessage = "Check for update failed: Could not get a proper response // from " + Globals.CHANGELOG; - // LoggerPlusPlus.callbacks.printError(updateMessage); + // LoggerPlusPlus.montoya.printError(updateMessage); // break; // case 0: // updateMessage = "This version is up to date."; - // LoggerPlusPlus.callbacks.printOutput(updateMessage); + // LoggerPlusPlus.montoya.printOutput(updateMessage); // break; // case 1: // updateMessage = "Version " + latestVersion.toString() + " is available via // GitHub. Visit the extension homepage."; - // if (LoggerPlusPlus.callbacks.isExtensionBapp()) { + // if (LoggerPlusPlus.montoya.isExtensionBapp()) { // updateMessage += "\nAs you are using BApp Store, you have to remove it first // and download the Jar file from the GitHub repository. "; // } else { - // if (LoggerPlusPlus.callbacks.getExtensionFilename() != null) { + // if (LoggerPlusPlus.montoya.getExtensionFilename() != null) { // int res = MoreHelp.askConfirmMessage("Update Available", "An update is // available. Would you like to update now?", new String[]{"Yes", "No"}); // if (res == JOptionPane.OK_OPTION) { @@ -176,7 +176,7 @@ public static String[] getHeaderAndBody(byte[] fullMessage, String encoding) thr // //TODO FIXME // URL updateUrl = new URL(Globals.UPDATE_URL); // InputStream input = updateUrl.openStream(); - // Path outputPath = Paths.get(LoggerPlusPlus.callbacks.getExtensionFilename()); + // Path outputPath = Paths.get(LoggerPlusPlus.montoya.getExtensionFilename()); // Files.copy(input, outputPath, StandardCopyOption.REPLACE_EXISTING); // } catch (Exception e) { // MoreHelp.showMessage("Could not update the plugin. Please visit the extension @@ -185,17 +185,17 @@ public static String[] getHeaderAndBody(byte[] fullMessage, String encoding) thr // } // MoreHelp.showMessage("Update complete. Re-enable the plugin in the extensions // tab to continue."); - // LoggerPlusPlus.callbacks.unloadExtension(); + // LoggerPlusPlus.montoya.unloadExtension(); // return; // } // } // } - // LoggerPlusPlus.callbacks.printOutput(updateMessage); + // LoggerPlusPlus.montoya.printOutput(updateMessage); // break; // case 2: // updateMessage = "This version is more up to date than the GitHub version! Are // you a time traveler? or just a keen ninja? ;)"; - // LoggerPlusPlus.callbacks.printOutput(updateMessage); + // LoggerPlusPlus.montoya.printOutput(updateMessage); // break; // } // if (!showMessages) return; diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 00000000..ec2de4f4 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/Test.java b/src/test/java/Test.java new file mode 100644 index 00000000..998ff084 --- /dev/null +++ b/src/test/java/Test.java @@ -0,0 +1,5 @@ +public class Test { + public static void main(String[] args) { + burp.StartBurp.main(args); + } +}