Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.20.1 Release #204

Merged
merged 23 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
14ac567
Fixes #183
CoreyD97 Aug 3, 2023
6f39503
Fix Grep results toString.
CoreyD97 Aug 3, 2023
dd09c15
Implement #186
CoreyD97 Aug 3, 2023
12ad2fa
Additional logging when preference deserialization fails. Closes #188
CoreyD97 Aug 3, 2023
0497c55
Add import from exported json button & the import function logic
blackphreak Oct 18, 2023
3dcf9a4
Fix typo
blackphreak Oct 18, 2023
46f34a7
Merge branch 'nccgroup:master' into feature-import-from-json
blackphreak Oct 18, 2023
8b9781a
Implements #157
CoreyD97 Oct 19, 2023
1a7e505
Small cleanup
CoreyD97 Oct 19, 2023
05fa4c0
Upgrade Montoya API version
CoreyD97 Oct 19, 2023
f6970e4
Integrate JavaCC plugin
CoreyD97 Oct 20, 2023
4ae99b7
Partial implementation for #109. Thanks to @justinsteven.
CoreyD97 Oct 26, 2023
a208679
Merge branch 'feature-import-from-json' of https://github.com/blackph…
CoreyD97 Oct 26, 2023
19aefdf
Fixes to #PR195
CoreyD97 Oct 26, 2023
9330879
Merge pull request #195 from blackphreak/feature-import-from-json
CoreyD97 Oct 26, 2023
02373ad
Merge remote-tracking branch 'origin/develop' into develop
CoreyD97 Oct 26, 2023
76e7fc6
Fixes #196
CoreyD97 Dec 5, 2023
589e5f5
Prevent imports being forced to auto exporters
CoreyD97 Dec 5, 2023
b630d53
Display message on successful/failed ZAP import
CoreyD97 Dec 5, 2023
bc8a894
Fix request line not being included in request headers
CoreyD97 Dec 5, 2023
b44e7c8
Fixes #202
CoreyD97 Dec 5, 2023
7ea57cd
Fix InScope Column Title
CoreyD97 Dec 5, 2023
6217398
Increment version
CoreyD97 Dec 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions BappManifest.bmf
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ Uuid: 470b7057b86f41c396a97903377f3d81
ExtensionType: 1
Name: Logger++
RepoName: logger-plus-plus
ScreenVersion: 3.20.0
SerialVersion: 20
ScreenVersion: 3.20.1
SerialVersion: 21
MinPlatformVersion: 0
ProOnly: False
Author: Corey Arthur, NCC Group
Expand Down
24 changes: 19 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'java'
id "io.freefair.lombok" version "6.5.1"
id "org.javacc.javacc" version "3.0.0"
}

sourceCompatibility = JavaVersion.VERSION_17
Expand All @@ -14,16 +15,29 @@ repositories {
}

dependencies {
implementation 'net.portswigger.burp.extensions:montoya-api:2023.5'
implementation 'net.portswigger.burp.extensions:montoya-api:2023.10.4'
implementation 'org.swinglabs:swingx:1.6.1'
implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:234d21d'
// implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.17.9'
implementation 'co.elastic.clients:elasticsearch-java:8.6.2'
implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:54678c64'
implementation 'co.elastic.clients:elasticsearch-java:8.8.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
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'

testRuntimeOnly files("${System.properties['user.home']}/BurpSuitePro/burpsuite_pro.jar")
testRuntimeOnly files("${System.properties['user.home']}/BurpSuiteCommunity/burpsuite_community.jar")
}

sourceSets {
main {
java {
srcDir compileJavacc.outputDirectory
srcDir compileJjtree.outputDirectory
}
}
}

compileJjtree {
include '**/*.java'
}

jar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,23 @@ public void actionPerformed(ActionEvent actionEvent) {
JMenuItem andFilter = new JMenuItem(new AbstractAction("AND") {
@Override
public void actionPerformed(ActionEvent actionEvent) {
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && "
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().getFilterExpression() + " && "
+ "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
}
});

JMenuItem andNotFilter = new JMenuItem(new AbstractAction("AND NOT") {
@Override
public void actionPerformed(ActionEvent actionEvent) {
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && !("
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().getFilterExpression() + " && !("
+ "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\")");
}
});

JMenuItem orFilter = new JMenuItem(new AbstractAction("OR") {
@Override
public void actionPerformed(ActionEvent actionEvent) {
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " || "
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().getFilterExpression() + " || "
+ context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
}
});
Expand Down
114 changes: 72 additions & 42 deletions src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
import co.elastic.clients.elasticsearch.indices.GetIndexRequest;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.jackson.JacksonJsonpGenerator;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.coreyd97.BurpExtenderUtilities.Preferences;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
Expand Down Expand Up @@ -59,16 +59,20 @@ public class ElasticExporter extends AutomaticLogExporter implements ExportPanel

private final ScheduledExecutorService executorService;
private final ElasticExporterControlPanel controlPanel;
private final Gson gson;
private final ObjectMapper mapper;

private Logger logger = LogManager.getLogger(this);

protected ElasticExporter(ExportController exportController, Preferences preferences) {
super(exportController, preferences);
this.fields = new ArrayList<>(preferences.getSetting(Globals.PREF_PREVIOUS_ELASTIC_FIELDS));
this.gson = LoggerPlusPlus.gsonProvider.getGson();
executorService = Executors.newScheduledThreadPool(1);

this.mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("LogEntry Serializer", new Version(0,1,0,"",null, null));
module.addSerializer(LogEntry.class, new ElasticExporter.EntrySerializer(LogEntry.class));
mapper.registerModule(module);

if ((boolean) preferences.getSetting(Globals.PREF_ELASTIC_AUTOSTART_GLOBAL)
|| (boolean) preferences.getSetting(Globals.PREF_ELASTIC_AUTOSTART_PROJECT)) {
//Autostart exporter.
Expand All @@ -91,22 +95,23 @@ void setup() throws Exception {
String projectPreviousFilterString = preferences.getSetting(Globals.PREF_ELASTIC_FILTER_PROJECT_PREVIOUS);
String filterString = preferences.getSetting(Globals.PREF_ELASTIC_FILTER);

if (!Objects.equals(projectPreviousFilterString, filterString)) {
//The current filter isn't what we used to export last time.
int res = JOptionPane.showConfirmDialog(LoggerPlusPlus.instance.getLoggerFrame(),
"Heads up! Looks like the filter being used to select which logs to export to " +
"ElasticSearch has changed since you last ran the exporter for this project.\n" +
"Do you want to continue?", "ElasticSearch Export Log Filter", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (res == JOptionPane.NO_OPTION) {
throw new Exception("Export cancelled.");
}
}
// if (!Objects.equals(projectPreviousFilterString, filterString)) {
// //The current filter isn't what we used to export last time.
// int res = JOptionPane.showConfirmDialog(LoggerPlusPlus.instance.getLoggerFrame(),
// "Heads up! Looks like the filter being used to select which logs to export to " +
// "ElasticSearch has changed since you last ran the exporter for this project.\n" +
// "Do you want to continue?", "ElasticSearch Export Log Filter", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
// if (res == JOptionPane.NO_OPTION) {
// throw new Exception("Export cancelled.");
// }
// }

if (!StringUtils.isBlank(filterString)) {
try {
logFilter = new LogTableFilter(filterString);
} catch (ParseException ex) {
logger.error("The log filter configured for the Elastic exporter is invalid!", ex);
throw new Exception("The log filter configured for the Elastic exporter is invalid!", ex);
}
}

Expand Down Expand Up @@ -140,7 +145,7 @@ void setup() throws Exception {
}


ElasticsearchTransport transport = new RestClientTransport(restClientBuilder.build(), new JacksonJsonpMapper());
ElasticsearchTransport transport = new RestClientTransport(restClientBuilder.build(), new JacksonJsonpMapper(this.mapper));

elasticClient = new ElasticsearchClient(transport);

Expand Down Expand Up @@ -195,21 +200,21 @@ private void createIndices() throws IOException {
}
}

public JsonObject serializeLogEntry(LogEntry logEntry) {
//Todo Better serialization of entries
JsonObject jsonObject = new JsonObject();
for (LogEntryField field : this.fields) {
Object value = formatValue(logEntry.getValueByKey(field));
try {
jsonObject.addProperty(field.getFullLabel(), gson.toJson(value));
}catch (Exception e){
log.error("ElasticExporter: " + value);
log.error("ElasticExporter: " + e.getMessage());
throw e;
}
}
return jsonObject;
}
// public JsonObject serializeLogEntry(LogEntry logEntry) {
// //Todo Better serialization of entries
// JsonObject jsonObject = new JsonObject();
// for (LogEntryField field : this.fields) {
// Object value = formatValue(logEntry.getValueByKey(field));
// try {
// jsonObject.addProperty(field.getFullLabel(), gson.toJson(value));
// }catch (Exception e){
// log.error("ElasticExporter: " + value);
// log.error("ElasticExporter: " + e.getMessage());
// throw e;
// }
// }
// return jsonObject;
// }

private void indexPendingEntries(){
try {
Expand All @@ -228,7 +233,7 @@ private void indexPendingEntries(){
bulkBuilder.operations(op -> op
.index(idx -> idx
.index(this.indexName)
.document(serializeLogEntry(logEntry))
.document(logEntry)
)
);

Expand All @@ -255,18 +260,13 @@ private void indexPendingEntries(){
shutdown();
}
}catch (IOException e) {
e.printStackTrace();
log.error(e);
}
}catch (Exception e){
e.printStackTrace();
log.error(e);
}
}

private Object formatValue(Object value){
if (value instanceof java.net.URL) return String.valueOf((java.net.URL) value);
else return value;
}

public ExportController getExportController() {
return this.exportController;
}
Expand All @@ -279,4 +279,34 @@ public void setFields(List<LogEntryField> fields) {
preferences.setSetting(Globals.PREF_PREVIOUS_ELASTIC_FIELDS, fields);
this.fields = fields;
}

private class EntrySerializer extends StdSerializer<LogEntry> {

public EntrySerializer(Class<LogEntry> t) {
super(t);
}

@Override
public void serialize(LogEntry logEntry, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
for (LogEntryField field : ElasticExporter.this.fields) {
Object value = logEntry.getValueByKey(field);
if(value == null) continue;
try {
switch (field.getType().getSimpleName()){
case "Integer": gen.writeNumberField(field.getFullLabel(), (Integer) value); break;
case "Short": gen.writeNumberField(field.getFullLabel(), (Short) value); break;
case "Double": gen.writeNumberField(field.getFullLabel(), (Double) value); break;
case "String": gen.writeStringField(field.getFullLabel(), value.toString()); break;
case "Boolean": gen.writeBooleanField(field.getFullLabel(), (Boolean) value); break;
case "Date": gen.writeNumberField(field.getFullLabel(), ((Date) value).getTime()); break;
default: log.error("Unhandled field type: " + field.getType().getSimpleName());
}
}catch (Exception e){
log.error("ElasticExporter: Couldn't serialize field. The field was ommitted from the export.");
}
}
gen.writeEndObject();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
import com.nccgroup.loggerplusplus.logentry.LogEntryField;
import com.nccgroup.loggerplusplus.util.Globals;
import com.nccgroup.loggerplusplus.util.MoreHelp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.nccgroup.loggerplusplus.util.Globals;
import com.nccgroup.loggerplusplus.util.MoreHelp;
import com.nccgroup.loggerplusplus.util.SwingWorkerWithProgressDialog;
import lombok.extern.log4j.Log4j2;

import javax.swing.*;
import java.awt.event.ActionEvent;
Expand All @@ -16,6 +17,7 @@
import java.lang.reflect.Type;
import java.util.List;

@Log4j2
public class HARExporter extends LogExporter implements ExportPanelProvider, ContextMenuExportProvider {

private final HARExporterControlPanel controlPanel;
Expand Down Expand Up @@ -46,6 +48,8 @@ protected Void doInBackground() throws Exception {
Type logEntryListType = new TypeToken<List<LogEntry>>(){}.getType();
Gson gson = new GsonBuilder().registerTypeAdapter(logEntryListType, new HarSerializer(String.valueOf(Globals.VERSION), "LoggerPlusPlus")).create();
gson.toJson(entries, logEntryListType, fileWriter);
}catch (Exception e){
log.error(e);
}

return null;
Expand All @@ -63,6 +67,7 @@ protected void done() {

} catch (Exception e) {
// Cancelled.
log.error(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void write(JsonWriter writer, List<LogEntry> logEntries) throws IOExcepti
writer.endArray(); // end response headers array

writer.name("redirectURL").value(String.valueOf(logEntry.getValueByKey(LogEntryField.REDIRECT_URL)));
if (logEntry.getResponseBytes() != null) {
if (logEntry.getResponse() != null) {
writer.name("headersSize").value(logEntry.getResponseBytes().length - logEntry.getResponseBodyLength());
writer.name("bodySize").value(logEntry.getResponseBodyLength());
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.nccgroup.loggerplusplus.filter;

import com.nccgroup.loggerplusplus.LoggerPlusPlus;
import com.nccgroup.loggerplusplus.filter.parser.*;
import com.nccgroup.loggerplusplus.filter.parser.ASTExpression;
import com.nccgroup.loggerplusplus.filter.parser.FilterEvaluationVisitor;
import com.nccgroup.loggerplusplus.filter.parser.FilterParser;
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
import com.nccgroup.loggerplusplus.logentry.FieldGroup;
import com.nccgroup.loggerplusplus.logentry.LogEntry;
import com.nccgroup.loggerplusplus.logentry.LogEntryField;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.coreyd97.BurpExtenderUtilities.HistoryField;
import com.coreyd97.BurpExtenderUtilities.Preferences;
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
import com.nccgroup.loggerplusplus.logentry.FieldGroup;
import com.nccgroup.loggerplusplus.logentry.LogEntryField;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ public boolean include(RowFilter.Entry entry) {
}
return false;
}

@Override
public String toString() {
return getFilterExpression().toString();
}
}
Loading
Loading