Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ repositories {
}

dependencies {
implementation 'net.portswigger.burp.extensions:montoya-api:2023.10.4'
// implementation 'net.portswigger.burp.extensions:montoya-api:2023.10.4'
implementation 'net.portswigger.burp.extensions:montoya-api:2024.12'
implementation 'org.swinglabs:swingx:1.6.1'
implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:54678c64'
implementation 'co.elastic.clients:elasticsearch-java:8.8.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import java.text.SimpleDateFormat;

@Log4j2
public class ElasticExporter extends AutomaticLogExporter implements ExportPanelProvider, ContextMenuExportProvider {

Expand Down Expand Up @@ -289,6 +291,7 @@ public EntrySerializer(Class<LogEntry> t) {
@Override
public void serialize(LogEntry logEntry, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
String stamp = null;
for (LogEntryField field : ElasticExporter.this.fields) {
Object value = logEntry.getValueByKey(field);
if(value == null) continue;
Expand All @@ -299,13 +302,24 @@ public void serialize(LogEntry logEntry, JsonGenerator gen, SerializerProvider p
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;
case "Date":
String label = field.getFullLabel();
if(label.equals("Request.Time")){
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
simpleDate.setTimeZone(TimeZone.getTimeZone("UTC"));
stamp = simpleDate.format(((Date) value));
}
gen.writeStringField(field.getFullLabel(), ((Date) value).toLocaleString());
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.");
}
}
if(stamp != null){
gen.writeStringField("@timestamp", stamp);
}
gen.writeEndObject();
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ public class LogEntry {
private List<UUID> matchingColorFilters;
private List<Tag> matchingTags;
private String formattedRequestTime;
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 Date responseDateTime = null; // If null, gets pulled from the response
private Date requestDateTime = null; // If null, becomes epoch start time
private int requestResponseDelay = -1;
private List<HttpHeader> responseHeaders;
private List<HttpHeader> requestHeaders;
Expand All @@ -121,6 +121,14 @@ public LogEntry(ToolType tool, HttpRequest request) {
public LogEntry(ToolType tool, HttpRequest request, HttpResponse response){
this(tool, request);
this.response = response;
this.requestDateTime = new Date(0);
}

public LogEntry(ToolType tool, HttpRequest request, HttpResponse response, Date requestTime, Date responseTime){
this(tool, request);
this.response = response;
this.requestDateTime = requestTime;
this.responseDateTime = responseTime;
}

/**
Expand Down Expand Up @@ -314,7 +322,7 @@ private Status processResponse() {
this.newCookies = response.cookies().stream().map(cookie -> String.format("%s=%s", cookie.name(), cookie.value())).collect(Collectors.toList());
this.hasSetCookies = !newCookies.isEmpty();


// If response date isn't set, pull it from response headers
if (this.responseDateTime == null) {
// If it didn't have an arrival time set, parse the response for it.
if (headers.get("date") != null && !StringUtils.isBlank(headers.get("date"))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Consumer;
import java.util.Date;
import java.time.ZonedDateTime;
import java.time.Instant;
import burp.api.montoya.http.handler.TimingData;

public class EntryImportWorker extends SwingWorker<Void, Integer> {

Expand Down Expand Up @@ -47,14 +51,28 @@ protected Void doInBackground() throws Exception {
if(entryImportExecutor.isShutdown() || this.isCancelled()) return null;
HttpRequest request;
HttpResponse response;
Date requestTime = null;
Date responseTime = null;
if(isProxyEntries){
request = proxyEntries.get(index).finalRequest();
response = proxyEntries.get(index).originalResponse();

TimingData timingData = proxyEntries.get(index).timingData();
requestTime = Date.from(timingData.timeRequestSent().toInstant());
responseTime = Date.from(timingData.timeRequestSent().plusNanos(timingData.timeBetweenRequestSentAndEndOfResponse().getNano()).toInstant());
}else{
request = httpEntries.get(index).request();
response = httpEntries.get(index).response();
TimingData timingData = httpEntries.get(index).timingData().orElse(null);
if(timingData != null){
requestTime = Date.from(timingData.timeRequestSent().toInstant());
responseTime = Date.from(timingData.timeRequestSent().plusNanos(timingData.timeBetweenRequestSentAndEndOfResponse().getNano()).toInstant());
}else{
//Zero epoch date to prevent null. Response date pulled from response headers
requestTime = new Date(0);
}
}
final LogEntry logEntry = new LogEntry(originatingTool, request, response);
final LogEntry logEntry = new LogEntry(originatingTool, request, response, requestTime, responseTime);
int finalIndex = index;
entryImportExecutor.submit(() -> {
if(this.isCancelled()) return;
Expand Down