Skip to content

Commit

Permalink
Merge pull request #4 from CompassSecurity/extension_rewrite
Browse files Browse the repository at this point in the history
Refactor and update
  • Loading branch information
dcaluzi authored May 16, 2024
2 parents c4bf152 + 91122b8 commit 043fc63
Show file tree
Hide file tree
Showing 10 changed files with 429 additions and 306 deletions.
37 changes: 13 additions & 24 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.compass-security</groupId>
<artifactId>JWT-scanner</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0.4</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
Expand All @@ -17,37 +17,34 @@
<dependency>
<groupId>net.portswigger.burp.extensions</groupId>
<artifactId>montoya-api</artifactId>
<version>2023.3</version>
<version>2023.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.5.0-M1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<version>0.12.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
<version>0.12.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<version>0.12.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.57</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
<version>20231013</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
Expand All @@ -57,14 +54,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
Expand Down
10 changes: 2 additions & 8 deletions src/main/java/BurpExtension/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,16 @@

import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.logging.Logging;

//Burp will auto-detect and load any class that extends BurpExtension.
public class BurpExtender implements BurpExtension
{
@Override
public void initialize(MontoyaApi api)
{
// set extension name
api.extension().setName("JWT-scanner");
api.userInterface().registerContextMenuItemsProvider(new ContextMenu(api));

Logging logging = api.logging();
logging.raiseInfoEvent("JWT-scanner loaded.");

api.scanner().registerScanCheck(new JWTScanCheck(api));

api.scanner().registerScanCheck(new JwtScanCheck(api));
api.scanner().registerInsertionPointProvider(new JwtInsertionPointProvider(api));
}
}
85 changes: 53 additions & 32 deletions src/main/java/BurpExtension/ContextMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@
package BurpExtension;

import burp.api.montoya.MontoyaApi;
import burp.api.montoya.core.Range;
import burp.api.montoya.core.ToolType;
import burp.api.montoya.http.Http;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.scanner.Scanner;
import burp.api.montoya.ui.Selection;
import burp.api.montoya.scanner.audit.insertionpoint.AuditInsertionPoint;
import burp.api.montoya.ui.contextmenu.ContextMenuEvent;
import burp.api.montoya.ui.contextmenu.ContextMenuItemsProvider;
import burp.api.montoya.ui.contextmenu.MessageEditorHttpRequestResponse;
import burp.api.montoya.ui.editor.HttpRequestEditor;
import burp.api.montoya.scanner.AuditResult;
import burp.api.montoya.scanner.audit.issues.AuditIssue;

import javax.swing.*;
import java.awt.*;
Expand All @@ -27,68 +24,92 @@
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.apache.commons.collections4.IterableUtils;

public class ContextMenu implements ContextMenuItemsProvider
{

private final MontoyaApi api;
private Scanner scanner;
private final Executor executor = Executors.newSingleThreadExecutor();

private final JwtAuditIssueEquator jwtAuditIssueEquator = new JwtAuditIssueEquator();

public ContextMenu(MontoyaApi api)
{

this.api = api;
scanner = api.scanner();
}

@Override
public List<Component> provideMenuItems(ContextMenuEvent event)
{
if (event.isFromTool(ToolType.PROXY, ToolType.REPEATER, ToolType.TARGET, ToolType.LOGGER, ToolType.INTRUDER))
{
MessageEditorHttpRequestResponse editorHttpRequestResponse = null;
List<Component> menuItemList = new ArrayList<>();

HttpRequestResponse requestResponse;

// determine if context menu is triggered on message editor
boolean editorIsPresent = event.messageEditorRequestResponse().isPresent();

List<Component> menuItemList = new ArrayList<>();

if (editorIsPresent) {
editorHttpRequestResponse = event.messageEditorRequestResponse().get();
requestResponse = editorHttpRequestResponse.requestResponse();
requestResponse = event.messageEditorRequestResponse().get().requestResponse();
} else {
List<HttpRequestResponse> selectedRequests = event.selectedRequestResponses();

// only 1 request is support at this time
// only 1 request is support at this time, otherwise no menu item is shown
if (selectedRequests.size() == 1) {
requestResponse = selectedRequests.get(0);
} else {
return null;
}
}

// Autodetect JWT
JMenuItem retrieveRequestItem = new JMenuItem("Autodetect JWT");
JwtScanCheck scan = new JwtScanCheck(api);
JwtInsertionPointProvider insertionPointProvider = new JwtInsertionPointProvider(api);

JWTScanCheck scan = new JWTScanCheck(api);
JwtInsertionPoint insertionPoint = new JwtInsertionPoint(api,requestResponse.request());
retrieveRequestItem.addActionListener(l -> SwingUtilities.invokeLater(() ->
this.executor.execute(() -> scan.activeAudit(requestResponse,insertionPoint)))
// Autodetect JWT
JMenuItem autodetectMenuItem = new JMenuItem("Autodetect JWT");
autodetectMenuItem.addActionListener(l -> SwingUtilities.invokeLater(() ->
this.executor.execute(() -> {
List<AuditInsertionPoint> auditInsertionPoints = insertionPointProvider.provideInsertionPoints(requestResponse);

for (AuditInsertionPoint insertionPoint : auditInsertionPoints) {
AuditResult auditResult = scan.activeAudit(requestResponse,insertionPoint,true);

for (AuditIssue issue : auditResult.auditIssues()) {
if (!IterableUtils.contains(api.siteMap().issues(), issue, jwtAuditIssueEquator)) {
api.siteMap().add(issue);
}
}
}
}))
);
menuItemList.add(retrieveRequestItem);
menuItemList.add(autodetectMenuItem);

// Selected JWT
if (editorIsPresent && editorHttpRequestResponse.selectionOffsets().isPresent()) {
JMenuItem retrieveSelectedRequestItem = new JMenuItem("Selected JWT");
if (editorIsPresent && event.messageEditorRequestResponse().get().selectionOffsets().isPresent()) {

int startindex = event.messageEditorRequestResponse().get().selectionOffsets().get().startIndexInclusive();
int endindex = event.messageEditorRequestResponse().get().selectionOffsets().get().endIndexExclusive();
JWTScanCheck scanSelected = new JWTScanCheck(api);
JwtInsertionPoint insertionPointSelected = new JwtInsertionPoint(api,requestResponse.request(),startindex,endindex);
retrieveSelectedRequestItem.addActionListener(l -> SwingUtilities.invokeLater(() ->
this.executor.execute(() -> scanSelected.activeAudit(requestResponse,insertionPointSelected)))
);

menuItemList.add(retrieveSelectedRequestItem);
List<AuditInsertionPoint> auditInsertionPoints = insertionPointProvider.provideInsertionPointsInSelection(requestResponse, startindex, endindex);

if (!auditInsertionPoints.isEmpty()) {
JMenuItem retrieveSelectedRequestItem = new JMenuItem("Selected JWT");
retrieveSelectedRequestItem.addActionListener(l -> SwingUtilities.invokeLater(() ->
this.executor.execute(() -> {
for (AuditInsertionPoint insertionPoint : auditInsertionPoints) {
AuditResult auditResult = scan.activeAudit(requestResponse,insertionPoint,true);

for (AuditIssue issue : auditResult.auditIssues()) {
if (!IterableUtils.contains(api.siteMap().issues(), issue, jwtAuditIssueEquator)) {
api.siteMap().add(issue);
}
}
}
}))
);

menuItemList.add(retrieveSelectedRequestItem);
}
}

return menuItemList;
Expand Down
128 changes: 0 additions & 128 deletions src/main/java/BurpExtension/JWTScanCheck.java

This file was deleted.

28 changes: 28 additions & 0 deletions src/main/java/BurpExtension/JwtAuditIssueEquator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package BurpExtension;

import burp.api.montoya.scanner.audit.issues.AuditIssue;
import org.apache.commons.collections4.Equator;
import org.apache.commons.collections4.functors.DefaultEquator;

public class JwtAuditIssueEquator implements Equator<AuditIssue> {

@Override
public boolean equate(AuditIssue auditIssue, AuditIssue t1) {
// name of issue needs to match
if (auditIssue.name().equals(t1.name())) {
// HTTP Service needs to match
if (auditIssue.httpService().equals(t1.httpService())) {
// path needs to match
if (auditIssue.requestResponses().get(0).request().path().equals(t1.requestResponses().get(0).request().path())) {
return true;
}
}
}
return false;
}

@Override
public int hash(AuditIssue auditIssue) {
return DefaultEquator.INSTANCE.hash(auditIssue);
}
}
Loading

0 comments on commit 043fc63

Please sign in to comment.