Skip to content

Commit

Permalink
Implements the feature asked in #9
Browse files Browse the repository at this point in the history
  • Loading branch information
righettod committed Aug 25, 2019
1 parent 348d837 commit b8f769e
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 45 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ The extension is referenced [here](https://portswigger.net/bappstore/d916d945067

# Change log

**1.0.8**

Under active development, see the associated [milestone](https://github.com/righettod/log-requests-to-sqlite/milestone/5) for details.

**1.0.7**

* Upgrade the version of the third party library used to handle the work with the SQLite DB in order to fix exposure to [CVE-2018-20505](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20505).
Expand Down
44 changes: 24 additions & 20 deletions src/burp/ActivityHttpListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,32 @@ private boolean mustLogRequest(IRequestInfo reqInfo) {
//By default: Request is logged
boolean mustLogRequest = true;

//First: We check if we must apply restriction about image resource
if (ConfigMenu.EXCLUDE_IMAGE_RESOURCE_REQUESTS) {
//Get the file extension of the current URL and remove the parameters from the URL
String filename = reqInfo.getUrl().getFile();
if (filename != null && filename.indexOf('?') != -1) {
filename = filename.substring(0, filename.indexOf('?')).trim();
}
if (filename != null && filename.indexOf('#') != -1) {
filename = filename.substring(0, filename.indexOf('#')).trim();
}
if (filename != null && filename.lastIndexOf('.') != -1) {
String extension = filename.substring(filename.lastIndexOf('.') + 1).trim().toLowerCase(Locale.US);
if (ConfigMenu.IMAGE_RESOURCE_EXTENSIONS.contains(extension)) {
mustLogRequest = false;
//Initially we check the pause state
if (ConfigMenu.IS_LOGGING_PAUSED) {
mustLogRequest = false;
} else {
//First: We check if we must apply restriction about image resource
if (ConfigMenu.EXCLUDE_IMAGE_RESOURCE_REQUESTS) {
//Get the file extension of the current URL and remove the parameters from the URL
String filename = reqInfo.getUrl().getFile();
if (filename != null && filename.indexOf('?') != -1) {
filename = filename.substring(0, filename.indexOf('?')).trim();
}
if (filename != null && filename.indexOf('#') != -1) {
filename = filename.substring(0, filename.indexOf('#')).trim();
}
if (filename != null && filename.lastIndexOf('.') != -1) {
String extension = filename.substring(filename.lastIndexOf('.') + 1).trim().toLowerCase(Locale.US);
if (ConfigMenu.IMAGE_RESOURCE_EXTENSIONS.contains(extension)) {
mustLogRequest = false;
}
}
}
}

//Secondly: We check if we must apply restriction about the URL scope
//Configuration restrictions options are applied in sequence so we only work here if the request is marked to be logged
if (mustLogRequest && ConfigMenu.ONLY_INCLUDE_REQUESTS_FROM_SCOPE && !this.callbacks.isInScope(reqInfo.getUrl())) {
mustLogRequest = false;
//Secondly: We check if we must apply restriction about the URL scope
//Configuration restrictions options are applied in sequence so we only work here if the request is marked to be logged
if (mustLogRequest && ConfigMenu.ONLY_INCLUDE_REQUESTS_FROM_SCOPE && !this.callbacks.isInScope(reqInfo.getUrl())) {
mustLogRequest = false;
}
}

return mustLogRequest;
Expand Down
59 changes: 40 additions & 19 deletions src/burp/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,53 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
//Extension init.
callbacks.setExtensionName(extensionName);
Trace trace = new Trace(callbacks);
//Ask to the user if he want to continue to log the events in the current DB file
//If the logging is not paused then ask to the user if he want to continue to log the events in the current DB file or pause the logging
String defaultStoreFileName = new File(System.getProperty("user.home"), extensionName + ".db").getAbsolutePath().replaceAll("\\\\", "/");
String customStoreFileName = callbacks.loadExtensionSetting(ConfigMenu.DB_FILE_CUSTOM_LOCATION_CFG_KEY);
if (customStoreFileName == null) {
customStoreFileName = defaultStoreFileName;
}
int loggingQuestionReply = JOptionPane.showConfirmDialog(burpFrame, "Continue to log events into the following database file?\n\r" + customStoreFileName, extensionName, JOptionPane.YES_NO_OPTION);
if (loggingQuestionReply == JOptionPane.NO_OPTION) {
JFileChooser customStoreFileNameFileChooser = new JFileChooser();
customStoreFileNameFileChooser.setDialogTitle(extensionName + " - Select the DB file to use...");
customStoreFileNameFileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
customStoreFileNameFileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
customStoreFileNameFileChooser.setDragEnabled(false);
customStoreFileNameFileChooser.setMultiSelectionEnabled(false);
customStoreFileNameFileChooser.setAcceptAllFileFilterUsed(false);
customStoreFileNameFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
customStoreFileNameFileChooser.setFileHidingEnabled(true);
int dbFileSelectionReply = customStoreFileNameFileChooser.showDialog(burpFrame, "Use");
if (dbFileSelectionReply == JFileChooser.APPROVE_OPTION) {
customStoreFileName = customStoreFileNameFileChooser.getSelectedFile().getAbsolutePath().replaceAll("\\\\", "/");
} else {
JOptionPane.showMessageDialog(burpFrame, "The following database file will continue to be used:\n\r" + customStoreFileName, extensionName, JOptionPane.INFORMATION_MESSAGE);
boolean isLoggingPaused = Boolean.parseBoolean(callbacks.loadExtensionSetting(ConfigMenu.PAUSE_LOGGING_CFG_KEY));
if (!isLoggingPaused) {
Object[] options = {"Keep the DB file", "Change the DB file", "Pause the logging"};
String msg = "Continue to log events into the following database file?\n\r" + customStoreFileName;
//Mapping of the buttons with the dialog: options[0] => YES / options[1] => NO / options[2] => CANCEL
int loggingQuestionReply = JOptionPane.showOptionDialog(burpFrame, msg, extensionName, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null);
//Case for YES is already handled, use the stored file
if (loggingQuestionReply == JOptionPane.YES_OPTION) {
callbacks.saveExtensionSetting(ConfigMenu.PAUSE_LOGGING_CFG_KEY, Boolean.FALSE.toString());
callbacks.issueAlert("Logging is enabled.");
}
//Case for the NO => Change DB file
if (loggingQuestionReply == JOptionPane.NO_OPTION) {
JFileChooser customStoreFileNameFileChooser = new JFileChooser();
customStoreFileNameFileChooser.setDialogTitle(extensionName + " - Select the DB file to use...");
customStoreFileNameFileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
customStoreFileNameFileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
customStoreFileNameFileChooser.setDragEnabled(false);
customStoreFileNameFileChooser.setMultiSelectionEnabled(false);
customStoreFileNameFileChooser.setAcceptAllFileFilterUsed(false);
customStoreFileNameFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
customStoreFileNameFileChooser.setFileHidingEnabled(true);
int dbFileSelectionReply = customStoreFileNameFileChooser.showDialog(burpFrame, "Use");
if (dbFileSelectionReply == JFileChooser.APPROVE_OPTION) {
customStoreFileName = customStoreFileNameFileChooser.getSelectedFile().getAbsolutePath().replaceAll("\\\\", "/");
} else {
JOptionPane.showMessageDialog(burpFrame, "The following database file will continue to be used:\n\r" + customStoreFileName, extensionName, JOptionPane.INFORMATION_MESSAGE);
}
callbacks.saveExtensionSetting(ConfigMenu.PAUSE_LOGGING_CFG_KEY, Boolean.FALSE.toString());
callbacks.issueAlert("Logging is enabled.");
}
//Case for the CANCEL => Pause the logging
if (loggingQuestionReply == JOptionPane.CANCEL_OPTION) {
callbacks.saveExtensionSetting(ConfigMenu.PAUSE_LOGGING_CFG_KEY, Boolean.TRUE.toString());
callbacks.issueAlert("Logging is paused.");
}
//Save the location of the database file chosen by the user
callbacks.saveExtensionSetting(ConfigMenu.DB_FILE_CUSTOM_LOCATION_CFG_KEY, customStoreFileName);
} else {
callbacks.issueAlert("Logging is paused.");
}
//Save the location of the database file chosen by the user
callbacks.saveExtensionSetting(ConfigMenu.DB_FILE_CUSTOM_LOCATION_CFG_KEY, customStoreFileName);
//Init logger and HTTP listener
ActivityLogger activityLogger = new ActivityLogger(customStoreFileName, callbacks, trace);
ActivityHttpListener activityHttpListener = new ActivityHttpListener(activityLogger, trace, callbacks);
Expand Down
39 changes: 33 additions & 6 deletions src/burp/ConfigMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class ConfigMenu implements Runnable, IExtensionStateListener {
*/
static final List<String> IMAGE_RESOURCE_EXTENSIONS = new ArrayList<>();

/**
* Expose the configuration option to allow the user to pause the logging.
*/
static volatile boolean IS_LOGGING_PAUSED = Boolean.FALSE;

/**
* Option configuration key for the restriction of the logging of requests in defined target scope.
*/
Expand All @@ -50,6 +55,11 @@ class ConfigMenu implements Runnable, IExtensionStateListener {
*/
public static final String DB_FILE_CUSTOM_LOCATION_CFG_KEY = "DB_FILE_CUSTOM_LOCATION";

/**
* Option configuration key to allow the user to pause the logging.
*/
public static final String PAUSE_LOGGING_CFG_KEY = "PAUSE_LOGGING";

/**
* Extension root configuration menu.
*/
Expand Down Expand Up @@ -91,13 +101,11 @@ class ConfigMenu implements Runnable, IExtensionStateListener {
}
//Load the save state of the options
value = this.callbacks.loadExtensionSetting(ONLY_INCLUDE_REQUESTS_FROM_SCOPE_CFG_KEY);
if (value != null) {
ONLY_INCLUDE_REQUESTS_FROM_SCOPE = Boolean.parseBoolean(value);
}
ONLY_INCLUDE_REQUESTS_FROM_SCOPE = Boolean.parseBoolean(value);
value = this.callbacks.loadExtensionSetting(ONLY_INCLUDE_REQUESTS_FROM_SCOPE_CFG_KEY);
if (value != null) {
EXCLUDE_IMAGE_RESOURCE_REQUESTS = Boolean.parseBoolean(value);
}
EXCLUDE_IMAGE_RESOURCE_REQUESTS = Boolean.parseBoolean(value);
value = this.callbacks.loadExtensionSetting(PAUSE_LOGGING_CFG_KEY);
IS_LOGGING_PAUSED = Boolean.parseBoolean(value);
}

/**
Expand Down Expand Up @@ -141,6 +149,25 @@ public void actionPerformed(ActionEvent e) {
}
});
this.cfgMenu.add(subMenuExcludeImageResources);
//Add the menu to pause the logging
menuText = "Pause the logging";
final JCheckBoxMenuItem subMenuPauseTheLogging = new JCheckBoxMenuItem(menuText, IS_LOGGING_PAUSED);
subMenuPauseTheLogging.addActionListener(new AbstractAction(menuText) {
public void actionPerformed(ActionEvent e) {
if (subMenuPauseTheLogging.isSelected()) {
ConfigMenu.this.callbacks.saveExtensionSetting(PAUSE_LOGGING_CFG_KEY, Boolean.TRUE.toString());
ConfigMenu.IS_LOGGING_PAUSED = Boolean.TRUE;
ConfigMenu.this.trace.writeLog("From now, logging is paused.");
} else {
ConfigMenu.this.callbacks.saveExtensionSetting(PAUSE_LOGGING_CFG_KEY, Boolean.FALSE.toString());
ConfigMenu.IS_LOGGING_PAUSED = Boolean.FALSE;
String dbPath = callbacks.loadExtensionSetting(ConfigMenu.DB_FILE_CUSTOM_LOCATION_CFG_KEY);
String msg = "From now, logging is enabled and stored in database file '" + dbPath + "'.";
ConfigMenu.this.trace.writeLog(msg);
}
}
});
this.cfgMenu.add(subMenuPauseTheLogging);
//Add the sub menu to get statistics about the DB.
menuText = "Get statistics about the logged events";
final JMenuItem subMenuDBStatsMenuItem = new JMenuItem(menuText);
Expand Down

0 comments on commit b8f769e

Please sign in to comment.