diff --git a/pom.xml b/pom.xml
index b67f97f..e506451 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.codemagi
burp-suite-utils
- 1.2.4
+ 1.2.5
jar
Burp Suite Utils
The Burp Suite Utils project provides developers with APIs for building Burp Suite Extensions.
diff --git a/src/main/java/com/codemagi/burp/Offsets.java b/src/main/java/com/codemagi/burp/Offsets.java
new file mode 100644
index 0000000..ee4a5c5
--- /dev/null
+++ b/src/main/java/com/codemagi/burp/Offsets.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 augustd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.codemagi.burp;
+
+/**
+ *
+ * @author August Detlefsen [augustd at codemagi dot com]
+ */
+public class Offsets {
+ private Integer start;
+ private Integer end;
+
+ public Offsets(Integer start, Integer end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ public Integer getStart() {
+ return start;
+ }
+
+ public void setStart(Integer start) {
+ this.start = start;
+ }
+
+ public Integer getEnd() {
+ return end;
+ }
+
+ public void setEnd(Integer end) {
+ this.end = end;
+ }
+
+ /**
+ * Return true if this set of Offsets overlaps the other set passed in.
+ *
+ * @param other Another Offsets instance to compare against
+ * @return true if this set of Offsets overlaps the other set passed in.
+ */
+ public boolean overlaps(Offsets other) {
+ if (other == null) return false;
+
+ return (this.start <= other.getEnd() && other.getStart() <= this.end);
+ }
+
+ /**
+ * Combine two sets of Offsets into one overlapping set.
+ *
+ * @param other Another Offsets instance to combine with
+ * @return An Offsets instance which combines the start/stop points of both instances
+ */
+ public Offsets combine(Offsets other) {
+ if (other == null) return this;
+
+ return new Offsets(Math.min(start, other.getStart()), Math.max(end, other.getEnd()));
+ }
+
+ /**
+ * Retrieve the start/stop points as an int[] array.
+ *
+ * @return An array of int suitable for passing into a Burp IScanIssue
+ */
+ public int[] toArray() {
+ int[] output = {start, end};
+ return output;
+ }
+}
diff --git a/src/main/java/com/codemagi/burp/PassiveScan.java b/src/main/java/com/codemagi/burp/PassiveScan.java
index 66e50d4..69c3043 100644
--- a/src/main/java/com/codemagi/burp/PassiveScan.java
+++ b/src/main/java/com/codemagi/burp/PassiveScan.java
@@ -7,6 +7,7 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
@@ -157,15 +158,28 @@ protected List processIssues(List matches, IHttpReques
if (!matches.isEmpty()) {
Collections.sort(matches); //matches must be in order
//get the offsets of scanner matches
- List startStop = new ArrayList<>(1);
+ LinkedList offsets = new LinkedList<>();
for (ScannerMatch match : matches) {
callbacks.printOutput("Processing match: " + match);
callbacks.printOutput(" start: " + match.getStart() + " end: " + match.getEnd() + " full match: " + match.getFullMatch() + " group: " + match.getMatchGroup());
//add a marker for code highlighting
- startStop.add(new int[]{match.getStart(), match.getEnd()});
+ //startStop.add(new int[]{match.getStart(), match.getEnd()});
+ Offsets matchOffsets = match.getOffsets();
+ if (!matchOffsets.overlaps(offsets.peekLast())) {
+ offsets.add(match.getOffsets());
+ } else {
+ //if the new offsets overlap, combine them into one and add them to the list
+ Offsets combinedOffsets = matchOffsets.combine(offsets.pop());
+ offsets.add(combinedOffsets);
+ }
}
+ List startStop = new ArrayList<>(1);
+ for (Offsets os : offsets) {
+ startStop.add(os.toArray());
+ }
issues.add(getScanIssue(baseRequestResponse, matches, startStop));
callbacks.printOutput("issues: " + issues.size());
+ callbacks.printOutput("offsets: " + offsets.size());
}
return issues;
diff --git a/src/main/java/com/codemagi/burp/ScanIssue.java b/src/main/java/com/codemagi/burp/ScanIssue.java
index e01cd2a..a826bd2 100644
--- a/src/main/java/com/codemagi/burp/ScanIssue.java
+++ b/src/main/java/com/codemagi/burp/ScanIssue.java
@@ -59,7 +59,7 @@ public ScanIssue(
this.severity = severity;
this.confidence = confidence;
}
-
+
public ScanIssue(IScanIssue existing) {
this.httpService = existing.getHttpService();
this.url = existing.getUrl();
diff --git a/src/main/java/com/codemagi/burp/ScannerMatch.java b/src/main/java/com/codemagi/burp/ScannerMatch.java
index b2d92dd..c739707 100644
--- a/src/main/java/com/codemagi/burp/ScannerMatch.java
+++ b/src/main/java/com/codemagi/burp/ScannerMatch.java
@@ -8,33 +8,29 @@
*/
public class ScannerMatch implements Comparable {
- private Integer start;
- private int end;
private String fullMatch;
private String matchGroup;
private String type;
private ScanIssueSeverity severity;
private ScanIssueConfidence confidence;
private MatchRule rule;
+ private Offsets offsets;
public ScannerMatch(int start, int end, String match, String type) {
- this.start = start;
- this.end = end;
+ offsets = new Offsets(start, end);
this.matchGroup = match;
this.type = type;
}
public ScannerMatch(Integer start, int end, String match, String type, ScanIssueSeverity severity) {
- this.start = start;
- this.end = end;
+ offsets = new Offsets(start, end);
this.matchGroup = match;
this.type = type;
this.severity = severity;
}
public ScannerMatch(Integer start, int end, String match, MatchRule rule) {
- this.start = start;
- this.end = end;
+ offsets = new Offsets(start, end);
this.matchGroup = match;
this.rule = rule;
this.type = rule.getType();
@@ -43,8 +39,7 @@ public ScannerMatch(Integer start, int end, String match, MatchRule rule) {
}
public ScannerMatch(Integer start, int end, String fullMatch, String matchGroup, MatchRule rule) {
- this.start = start;
- this.end = end;
+ offsets = new Offsets(start, end);
this.fullMatch = fullMatch;
this.matchGroup = matchGroup;
this.rule = rule;
@@ -53,12 +48,12 @@ public ScannerMatch(Integer start, int end, String fullMatch, String matchGroup,
this.confidence = rule.getConfidence();
}
- public int getStart() {
- return start;
+ public Integer getStart() {
+ return offsets.getStart();
}
- public int getEnd() {
- return end;
+ public Integer getEnd() {
+ return offsets.getEnd();
}
public String getFullMatch() {
@@ -73,9 +68,9 @@ public MatchRule getRule() {
return rule;
}
- public Pattern getPattern() {
- return rule.getPattern();
- }
+ public Pattern getPattern() {
+ return rule.getPattern();
+ }
public String getType() {
return type;
@@ -91,7 +86,11 @@ public ScanIssueConfidence getConfidence() {
@Override
public int compareTo(ScannerMatch m) {
- return start.compareTo(m.getStart());
+ return this.getStart().compareTo(m.getStart());
}
+ public Offsets getOffsets() {
+ return offsets;
+ }
+
}
diff --git a/src/test/java/com/codemagi/burp/OffsetsTest.java b/src/test/java/com/codemagi/burp/OffsetsTest.java
new file mode 100644
index 0000000..8da8108
--- /dev/null
+++ b/src/test/java/com/codemagi/burp/OffsetsTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 august.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.codemagi.burp;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author august
+ */
+public class OffsetsTest {
+
+ Offsets a = new Offsets(10, 15);
+ Offsets b = new Offsets(20, 25);
+ Offsets c = new Offsets(12, 17);
+ Offsets d = new Offsets(8, 13);
+ Offsets e = new Offsets(5, 20);
+
+ public OffsetsTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testOverlap() {
+ assertFalse(a.overlaps(b));
+ assertFalse(b.overlaps(a));
+
+ assertTrue(a.overlaps(c));
+ assertTrue(c.overlaps(a));
+
+ assertTrue(a.overlaps(d));
+ assertTrue(d.overlaps(a));
+
+ assertTrue(a.overlaps(e));
+ assertTrue(e.overlaps(a));
+
+ assertTrue(b.overlaps(e));
+ assertTrue(e.overlaps(b));
+ }
+
+ @Test
+ public void testCombine() {
+ Offsets product = a.combine(c);
+ assertEquals(new Integer(10), product.getStart());
+ assertEquals(new Integer(17), product.getEnd());
+ }
+}