Skip to content

Commit 785c85e

Browse files
authored
Merge pull request #204 from nccgroup/develop
v3.20.1 Release
2 parents 100137b + 6217398 commit 785c85e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+310
-4645
lines changed

BappManifest.bmf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ Uuid: 470b7057b86f41c396a97903377f3d81
22
ExtensionType: 1
33
Name: Logger++
44
RepoName: logger-plus-plus
5-
ScreenVersion: 3.20.0
6-
SerialVersion: 20
5+
ScreenVersion: 3.20.1
6+
SerialVersion: 21
77
MinPlatformVersion: 0
88
ProOnly: False
99
Author: Corey Arthur, NCC Group

build.gradle

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
plugins {
22
id 'java'
33
id "io.freefair.lombok" version "6.5.1"
4+
id "org.javacc.javacc" version "3.0.0"
45
}
56

67
sourceCompatibility = JavaVersion.VERSION_17
@@ -14,16 +15,29 @@ repositories {
1415
}
1516

1617
dependencies {
17-
implementation 'net.portswigger.burp.extensions:montoya-api:2023.5'
18+
implementation 'net.portswigger.burp.extensions:montoya-api:2023.10.4'
1819
implementation 'org.swinglabs:swingx:1.6.1'
19-
implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:234d21d'
20-
// implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.17.9'
21-
implementation 'co.elastic.clients:elasticsearch-java:8.6.2'
20+
implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:54678c64'
21+
implementation 'co.elastic.clients:elasticsearch-java:8.8.2'
22+
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
2223
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
2324
implementation 'org.apache.commons:commons-text:1.10.0'
2425
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
2526

26-
testRuntimeOnly files("${System.properties['user.home']}/BurpSuitePro/burpsuite_pro.jar")
27+
testRuntimeOnly files("${System.properties['user.home']}/BurpSuiteCommunity/burpsuite_community.jar")
28+
}
29+
30+
sourceSets {
31+
main {
32+
java {
33+
srcDir compileJavacc.outputDirectory
34+
srcDir compileJjtree.outputDirectory
35+
}
36+
}
37+
}
38+
39+
compileJjtree {
40+
include '**/*.java'
2741
}
2842

2943
jar {

src/main/java/com/nccgroup/loggerplusplus/LoggerContextMenuFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,23 @@ public void actionPerformed(ActionEvent actionEvent) {
9292
JMenuItem andFilter = new JMenuItem(new AbstractAction("AND") {
9393
@Override
9494
public void actionPerformed(ActionEvent actionEvent) {
95-
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && "
95+
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().getFilterExpression() + " && "
9696
+ "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
9797
}
9898
});
9999

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

108108
JMenuItem orFilter = new JMenuItem(new AbstractAction("OR") {
109109
@Override
110110
public void actionPerformed(ActionEvent actionEvent) {
111-
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " || "
111+
LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().getFilterExpression() + " || "
112112
+ context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
113113
}
114114
});

src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@
33
import co.elastic.clients.elasticsearch.ElasticsearchClient;
44
import co.elastic.clients.elasticsearch.core.BulkRequest;
55
import co.elastic.clients.elasticsearch.core.BulkResponse;
6-
import co.elastic.clients.elasticsearch.core.IndexRequest;
76
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
87
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
98
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
10-
import co.elastic.clients.elasticsearch.indices.GetIndexRequest;
11-
import co.elastic.clients.json.JsonData;
12-
import co.elastic.clients.json.jackson.JacksonJsonpGenerator;
139
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
1410
import co.elastic.clients.transport.ElasticsearchTransport;
1511
import co.elastic.clients.transport.endpoints.BooleanResponse;
1612
import co.elastic.clients.transport.rest_client.RestClientTransport;
1713
import com.coreyd97.BurpExtenderUtilities.Preferences;
18-
import com.google.gson.Gson;
19-
import com.google.gson.JsonObject;
14+
import com.fasterxml.jackson.core.JsonGenerator;
15+
import com.fasterxml.jackson.core.Version;
16+
import com.fasterxml.jackson.databind.ObjectMapper;
17+
import com.fasterxml.jackson.databind.SerializerProvider;
18+
import com.fasterxml.jackson.databind.module.SimpleModule;
19+
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
2020
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
2121
import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
2222
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
@@ -59,16 +59,20 @@ public class ElasticExporter extends AutomaticLogExporter implements ExportPanel
5959

6060
private final ScheduledExecutorService executorService;
6161
private final ElasticExporterControlPanel controlPanel;
62-
private final Gson gson;
62+
private final ObjectMapper mapper;
6363

6464
private Logger logger = LogManager.getLogger(this);
6565

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

71+
this.mapper = new ObjectMapper();
72+
SimpleModule module = new SimpleModule("LogEntry Serializer", new Version(0,1,0,"",null, null));
73+
module.addSerializer(LogEntry.class, new ElasticExporter.EntrySerializer(LogEntry.class));
74+
mapper.registerModule(module);
75+
7276
if ((boolean) preferences.getSetting(Globals.PREF_ELASTIC_AUTOSTART_GLOBAL)
7377
|| (boolean) preferences.getSetting(Globals.PREF_ELASTIC_AUTOSTART_PROJECT)) {
7478
//Autostart exporter.
@@ -91,22 +95,23 @@ void setup() throws Exception {
9195
String projectPreviousFilterString = preferences.getSetting(Globals.PREF_ELASTIC_FILTER_PROJECT_PREVIOUS);
9296
String filterString = preferences.getSetting(Globals.PREF_ELASTIC_FILTER);
9397

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

105109
if (!StringUtils.isBlank(filterString)) {
106110
try {
107111
logFilter = new LogTableFilter(filterString);
108112
} catch (ParseException ex) {
109113
logger.error("The log filter configured for the Elastic exporter is invalid!", ex);
114+
throw new Exception("The log filter configured for the Elastic exporter is invalid!", ex);
110115
}
111116
}
112117

@@ -140,7 +145,7 @@ void setup() throws Exception {
140145
}
141146

142147

143-
ElasticsearchTransport transport = new RestClientTransport(restClientBuilder.build(), new JacksonJsonpMapper());
148+
ElasticsearchTransport transport = new RestClientTransport(restClientBuilder.build(), new JacksonJsonpMapper(this.mapper));
144149

145150
elasticClient = new ElasticsearchClient(transport);
146151

@@ -195,21 +200,21 @@ private void createIndices() throws IOException {
195200
}
196201
}
197202

198-
public JsonObject serializeLogEntry(LogEntry logEntry) {
199-
//Todo Better serialization of entries
200-
JsonObject jsonObject = new JsonObject();
201-
for (LogEntryField field : this.fields) {
202-
Object value = formatValue(logEntry.getValueByKey(field));
203-
try {
204-
jsonObject.addProperty(field.getFullLabel(), gson.toJson(value));
205-
}catch (Exception e){
206-
log.error("ElasticExporter: " + value);
207-
log.error("ElasticExporter: " + e.getMessage());
208-
throw e;
209-
}
210-
}
211-
return jsonObject;
212-
}
203+
// public JsonObject serializeLogEntry(LogEntry logEntry) {
204+
// //Todo Better serialization of entries
205+
// JsonObject jsonObject = new JsonObject();
206+
// for (LogEntryField field : this.fields) {
207+
// Object value = formatValue(logEntry.getValueByKey(field));
208+
// try {
209+
// jsonObject.addProperty(field.getFullLabel(), gson.toJson(value));
210+
// }catch (Exception e){
211+
// log.error("ElasticExporter: " + value);
212+
// log.error("ElasticExporter: " + e.getMessage());
213+
// throw e;
214+
// }
215+
// }
216+
// return jsonObject;
217+
// }
213218

214219
private void indexPendingEntries(){
215220
try {
@@ -228,7 +233,7 @@ private void indexPendingEntries(){
228233
bulkBuilder.operations(op -> op
229234
.index(idx -> idx
230235
.index(this.indexName)
231-
.document(serializeLogEntry(logEntry))
236+
.document(logEntry)
232237
)
233238
);
234239

@@ -255,18 +260,13 @@ private void indexPendingEntries(){
255260
shutdown();
256261
}
257262
}catch (IOException e) {
258-
e.printStackTrace();
263+
log.error(e);
259264
}
260265
}catch (Exception e){
261-
e.printStackTrace();
266+
log.error(e);
262267
}
263268
}
264269

265-
private Object formatValue(Object value){
266-
if (value instanceof java.net.URL) return String.valueOf((java.net.URL) value);
267-
else return value;
268-
}
269-
270270
public ExportController getExportController() {
271271
return this.exportController;
272272
}
@@ -279,4 +279,34 @@ public void setFields(List<LogEntryField> fields) {
279279
preferences.setSetting(Globals.PREF_PREVIOUS_ELASTIC_FIELDS, fields);
280280
this.fields = fields;
281281
}
282+
283+
private class EntrySerializer extends StdSerializer<LogEntry> {
284+
285+
public EntrySerializer(Class<LogEntry> t) {
286+
super(t);
287+
}
288+
289+
@Override
290+
public void serialize(LogEntry logEntry, JsonGenerator gen, SerializerProvider provider) throws IOException {
291+
gen.writeStartObject();
292+
for (LogEntryField field : ElasticExporter.this.fields) {
293+
Object value = logEntry.getValueByKey(field);
294+
if(value == null) continue;
295+
try {
296+
switch (field.getType().getSimpleName()){
297+
case "Integer": gen.writeNumberField(field.getFullLabel(), (Integer) value); break;
298+
case "Short": gen.writeNumberField(field.getFullLabel(), (Short) value); break;
299+
case "Double": gen.writeNumberField(field.getFullLabel(), (Double) value); break;
300+
case "String": gen.writeStringField(field.getFullLabel(), value.toString()); break;
301+
case "Boolean": gen.writeBooleanField(field.getFullLabel(), (Boolean) value); break;
302+
case "Date": gen.writeNumberField(field.getFullLabel(), ((Date) value).getTime()); break;
303+
default: log.error("Unhandled field type: " + field.getType().getSimpleName());
304+
}
305+
}catch (Exception e){
306+
log.error("ElasticExporter: Couldn't serialize field. The field was ommitted from the export.");
307+
}
308+
}
309+
gen.writeEndObject();
310+
}
311+
}
282312
}

src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporterConfigDialog.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
88
import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
99
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
10-
import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
1110
import com.nccgroup.loggerplusplus.logentry.LogEntryField;
1211
import com.nccgroup.loggerplusplus.util.Globals;
1312
import com.nccgroup.loggerplusplus.util.MoreHelp;

src/main/java/com/nccgroup/loggerplusplus/exports/HARExporter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.nccgroup.loggerplusplus.util.Globals;
99
import com.nccgroup.loggerplusplus.util.MoreHelp;
1010
import com.nccgroup.loggerplusplus.util.SwingWorkerWithProgressDialog;
11+
import lombok.extern.log4j.Log4j2;
1112

1213
import javax.swing.*;
1314
import java.awt.event.ActionEvent;
@@ -16,6 +17,7 @@
1617
import java.lang.reflect.Type;
1718
import java.util.List;
1819

20+
@Log4j2
1921
public class HARExporter extends LogExporter implements ExportPanelProvider, ContextMenuExportProvider {
2022

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

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

6468
} catch (Exception e) {
6569
// Cancelled.
70+
log.error(e);
6671
}
6772
}
6873

src/main/java/com/nccgroup/loggerplusplus/exports/HarSerializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public void write(JsonWriter writer, List<LogEntry> logEntries) throws IOExcepti
148148
writer.endArray(); // end response headers array
149149

150150
writer.name("redirectURL").value(String.valueOf(logEntry.getValueByKey(LogEntryField.REDIRECT_URL)));
151-
if (logEntry.getResponseBytes() != null) {
151+
if (logEntry.getResponse() != null) {
152152
writer.name("headersSize").value(logEntry.getResponseBytes().length - logEntry.getResponseBodyLength());
153153
writer.name("bodySize").value(logEntry.getResponseBodyLength());
154154
} else {

src/main/java/com/nccgroup/loggerplusplus/filter/FilterExpression.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.nccgroup.loggerplusplus.filter;
22

33
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
4-
import com.nccgroup.loggerplusplus.filter.parser.*;
4+
import com.nccgroup.loggerplusplus.filter.parser.ASTExpression;
5+
import com.nccgroup.loggerplusplus.filter.parser.FilterEvaluationVisitor;
6+
import com.nccgroup.loggerplusplus.filter.parser.FilterParser;
7+
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
58
import com.nccgroup.loggerplusplus.logentry.FieldGroup;
69
import com.nccgroup.loggerplusplus.logentry.LogEntry;
710
import com.nccgroup.loggerplusplus.logentry.LogEntryField;

src/main/java/com/nccgroup/loggerplusplus/filter/logfilter/LogFilterController.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.coreyd97.BurpExtenderUtilities.HistoryField;
44
import com.coreyd97.BurpExtenderUtilities.Preferences;
5-
import com.nccgroup.loggerplusplus.LoggerPlusPlus;
65
import com.nccgroup.loggerplusplus.filter.parser.ParseException;
76
import com.nccgroup.loggerplusplus.logentry.FieldGroup;
87
import com.nccgroup.loggerplusplus.logentry.LogEntryField;

src/main/java/com/nccgroup/loggerplusplus/filter/logfilter/LogTableFilter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ public boolean include(RowFilter.Entry entry) {
3232
}
3333
return false;
3434
}
35+
36+
@Override
37+
public String toString() {
38+
return getFilterExpression().toString();
39+
}
3540
}

0 commit comments

Comments
 (0)