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
14 changes: 10 additions & 4 deletions src/main/java/burp/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public void initialize(MontoyaApi api) {
api.extension().setName(extensionName);
api.userInterface().registerContextMenuItemsProvider(new CstcContextMenuItemsProvider(api, view));
api.http().registerHttpHandler(new CstcHttpHandler(view));
api.proxy().registerRequestHandler(new CstcProxyRequestHandler(view));
api.proxy().registerResponseHandler(new CstcProxyResponseHandler(view));
api.userInterface().registerSuiteTab(extensionName, view);
api.userInterface().registerHttpRequestEditorProvider(new MyHttpRequestEditorProvider(view));
api.userInterface().registerHttpRequestEditorProvider(new MyHttpRequestEditorProviderFormatting(view));
Expand All @@ -41,8 +43,10 @@ public void initialize(MontoyaApi api) {
private void restoreInput(PersistedObject persistence) {
try {
this.view.getFormatRecipePanel().restoreInput(persistence.getString(BurpOperation.FORMAT + "Input"));
this.view.getIncomingRecipePanel().restoreInput(persistence.getString(BurpOperation.INCOMING + "Input"));
this.view.getOutgoingRecipePanel().restoreInput(persistence.getString(BurpOperation.OUTGOING + "Input"));
this.view.getIncomingProxyRequestRecipePanel().restoreInput(persistence.getString(BurpOperation.INCOMING_PROXY_REQUEST + "Input"));
this.view.getOutgoingHttpRequestRecipePanel().restoreInput(persistence.getString(BurpOperation.OUTGOING_HTTP_REQUEST + "Input"));
this.view.getIncomingHttpResponseRecipePanel().restoreInput(persistence.getString(BurpOperation.INCOMING_HTTP_RESPONSE + "Input"));
this.view.getOutgoingProxyResponseRecipePanel().restoreInput(persistence.getString(BurpOperation.OUTGOING_PROXY_RESPONSE + "Input"));
} catch (Exception e) {
Logger.getInstance().log(
"Could not restore the input for one or multiple panels. If this is the first time using CSTC in a project, you can ignore this message.");
Expand All @@ -52,8 +56,10 @@ private void restoreInput(PersistedObject persistence) {
private void restoreRecipe(PersistedObject persistence) {
try {
this.view.getFormatRecipePanel().restoreState(persistence.getString(BurpOperation.FORMAT + "Recipe"));
this.view.getIncomingRecipePanel().restoreState(persistence.getString(BurpOperation.INCOMING + "Recipe"));
this.view.getOutgoingRecipePanel().restoreState(persistence.getString(BurpOperation.OUTGOING + "Recipe"));
this.view.getIncomingHttpResponseRecipePanel().restoreState(persistence.getString(BurpOperation.INCOMING_HTTP_RESPONSE + "Recipe"));
this.view.getIncomingProxyRequestRecipePanel().restoreState(persistence.getString(BurpOperation.INCOMING_PROXY_REQUEST + "Recipe"));
this.view.getOutgoingHttpRequestRecipePanel().restoreState(persistence.getString(BurpOperation.OUTGOING_HTTP_REQUEST + "Recipe"));
this.view.getOutgoingProxyResponseRecipePanel().restoreState(persistence.getString(BurpOperation.OUTGOING_PROXY_RESPONSE + "Recipe"));
} catch (Exception e) {
Logger.getInstance().log(
"Could not restore the recipe for one or multiple panels. If this is the first time using CSTC in a project, you can ignore this message.");
Expand Down
38 changes: 28 additions & 10 deletions src/main/java/burp/CstcContextMenuItemsProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,45 @@ public CstcContextMenuItemsProvider(MontoyaApi api, View view)
public List<Component> provideMenuItems(ContextMenuEvent event) {

List<Component> menuItems = new ArrayList<>();
JMenuItem incomingMenu = new JMenuItem("Send to CSTC (Incoming)");
JMenuItem outgoingMenu = new JMenuItem("Send to CSTC (Outgoing)");
JMenuItem incomingReqFormatMenu = new JMenuItem("Send request to CSTC (Formatting)");
JMenuItem incomingResFormatMenu = new JMenuItem("Send response to CSTC (Formatting)");
JMenuItem incomingHttpResponseMenu = new JMenuItem("Send to Incoming HTTP Responses");
JMenuItem incomingProxyRequestMenu = new JMenuItem("Send to Incoming Proxy Requests");
JMenuItem outgoingHttpRequestMenu = new JMenuItem("Send to Outgoing HTTP Requests");
JMenuItem outgoingProxyResponseMenu = new JMenuItem("Send to Outgoing Proxy Responses");
JMenuItem incomingReqFormatMenu = new JMenuItem("Send request to Formatting");
JMenuItem incomingResFormatMenu = new JMenuItem("Send response to Formatting");

menuItems.add(outgoingMenu);
menuItems.add(incomingMenu);
menuItems.add(outgoingHttpRequestMenu);
menuItems.add(outgoingProxyResponseMenu);
menuItems.add(incomingHttpResponseMenu);
menuItems.add(incomingProxyRequestMenu);
menuItems.add(incomingReqFormatMenu);
menuItems.add(incomingResFormatMenu);

incomingMenu.addActionListener(new ActionListener() {
incomingHttpResponseMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
view.getIncomingRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0));
view.getIncomingHttpResponseRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0));
}
});

incomingProxyRequestMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
view.getIncomingProxyRequestRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0));
}
});

outgoingMenu.addActionListener(new ActionListener() {
outgoingHttpRequestMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
view.getOutgoingHttpRequestRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0));
}
});

outgoingProxyResponseMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
view.getOutgoingRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0));
view.getOutgoingProxyResponseRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0));
}
});

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/burp/CstcHttpHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent reque
return continueWith(request, Annotations.annotations("CSTC"));
}

if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.OUTGOING, requestToBeSent.toolSource().toolType())) {
if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.OUTGOING_HTTP_REQUEST, requestToBeSent.toolSource().toolType())) {

ByteArray request = requestToBeSent.toByteArray();
ByteArray modifiedRequest = view.getOutgoingRecipePanel().bake(request, null);
ByteArray modifiedRequest = view.getOutgoingHttpRequestRecipePanel().bake(request, null);
return continueWith(HttpRequest.httpRequest(modifiedRequest).withService(requestToBeSent.httpService()));
}
else{
Expand All @@ -45,12 +45,12 @@ public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent reque

@Override
public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) {
if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.INCOMING, responseReceived.toolSource().toolType())) {
if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.INCOMING_HTTP_RESPONSE, responseReceived.toolSource().toolType())) {
if(responseReceived.annotations().hasNotes() && responseReceived.annotations().notes().equals("CSTC")) {
return continueWith(responseReceived);
}
ByteArray response = responseReceived.toByteArray();
ByteArray modifiedResponse = view.getIncomingRecipePanel().bake(response, responseReceived.initiatingRequest().toByteArray());
ByteArray modifiedResponse = view.getIncomingHttpResponseRecipePanel().bake(response, responseReceived.initiatingRequest().toByteArray());
return continueWith(HttpResponse.httpResponse(modifiedResponse));
}
else{
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/burp/CstcProxyRequestHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package burp;

import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.ToolType;
import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.proxy.http.InterceptedRequest;
import burp.api.montoya.proxy.http.ProxyRequestHandler;
import burp.api.montoya.proxy.http.ProxyRequestReceivedAction;
import burp.api.montoya.proxy.http.ProxyRequestToBeSentAction;
import de.usd.cstchef.view.View;
import de.usd.cstchef.view.filter.FilterState;

import static burp.api.montoya.proxy.http.ProxyRequestReceivedAction.continueWith;

public class CstcProxyRequestHandler implements ProxyRequestHandler {

private View view;

public CstcProxyRequestHandler(View view) {
this.view = view;
}

@Override
public ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest interceptedRequest) {
if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.INCOMING_PROXY_REQUEST, ToolType.PROXY)) {
ByteArray request = interceptedRequest.toByteArray();
ByteArray modifiedRequest = view.getIncomingProxyRequestRecipePanel().bake(request, null);
return continueWith(HttpRequest.httpRequest(modifiedRequest).withService(interceptedRequest.httpService()));
}
else{
return continueWith(interceptedRequest);
}
}

@Override
public ProxyRequestToBeSentAction handleRequestToBeSent(InterceptedRequest interceptedRequest) {
return ProxyRequestToBeSentAction.continueWith(interceptedRequest);
}
}
39 changes: 39 additions & 0 deletions src/main/java/burp/CstcProxyResponseHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package burp;

import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.ToolType;
import burp.api.montoya.http.message.responses.HttpResponse;
import burp.api.montoya.proxy.http.InterceptedResponse;
import burp.api.montoya.proxy.http.ProxyResponseHandler;
import burp.api.montoya.proxy.http.ProxyResponseReceivedAction;
import burp.api.montoya.proxy.http.ProxyResponseToBeSentAction;
import de.usd.cstchef.view.View;
import de.usd.cstchef.view.filter.FilterState;

import static burp.api.montoya.proxy.http.ProxyResponseToBeSentAction.continueWith;

public class CstcProxyResponseHandler implements ProxyResponseHandler {

private View view;

public CstcProxyResponseHandler(View view) {
this.view = view;
}

@Override
public ProxyResponseReceivedAction handleResponseReceived(InterceptedResponse interceptedResponse) {
return ProxyResponseReceivedAction.continueWith(interceptedResponse);
}

@Override
public ProxyResponseToBeSentAction handleResponseToBeSent(InterceptedResponse interceptedResponse) {
if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.OUTGOING_PROXY_RESPONSE, ToolType.PROXY)) {
ByteArray response = interceptedResponse.toByteArray();
ByteArray modifiedResponse = view.getOutgoingProxyResponseRecipePanel().bake(response, interceptedResponse.request().toByteArray());
return continueWith(HttpResponse.httpResponse(modifiedResponse));
}
else{
return continueWith(interceptedResponse);
}
}
}
4 changes: 2 additions & 2 deletions src/main/java/burp/MyExtensionProvidedHttpRequestEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public HttpRequest getRequest()
@Override
public void setRequestResponse(HttpRequestResponse requestResponse)
{
ByteArray result = view.getOutgoingRecipePanel().bake(requestResponse.request().toByteArray(), requestResponse.request().toByteArray());
ByteArray result = view.getOutgoingHttpRequestRecipePanel().bake(requestResponse.request().toByteArray(), requestResponse.request().toByteArray());
this.requestEditor.setContents(result);
}

Expand Down Expand Up @@ -69,4 +69,4 @@ public boolean isModified()
{
return requestEditor.isModified();
}
}
}
156 changes: 78 additions & 78 deletions src/main/java/de/usd/cstchef/operations/dataformat/FromDecimal.java
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,78 +1,78 @@
package de.usd.cstchef.operations.dataformat;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Set;
import javax.swing.JComboBox;
import burp.api.montoya.core.ByteArray;
import de.usd.cstchef.operations.Operation;
import de.usd.cstchef.operations.Operation.OperationInfos;
import de.usd.cstchef.operations.OperationCategory;
import de.usd.cstchef.operations.dataformat.ToHex.Delimiter;
@OperationInfos(name = "From Decimal", category = OperationCategory.DATAFORMAT, description = "Converts an integer array back into its raw form.")
public class FromDecimal extends Operation {
static HashMap<String, Delimiter> delimiters = new HashMap<String, Delimiter>() {
{
put("Space", new Delimiter(" "));
put("Comma", new Delimiter(","));
put("Semi-colon", new Delimiter(";"));
put("Colon", new Delimiter(":"));
put("Line feed", new Delimiter("\n"));
put("CRLF", new Delimiter("\r\n"));
}
};
private JComboBox<String> delimiterBox;
@Override
protected ByteArray perform(ByteArray input) throws Exception {
if(input.length() == 0) {
return input;
}
String selectedKey = (String) this.delimiterBox.getSelectedItem();
Delimiter delimiter = ToHex.delimiters.get(selectedKey);
String delimString = new String(delimiter.value, StandardCharsets.UTF_8);
String[] parts = input.toString().trim().split(delimString);
byte[] decodedBytes = new byte[parts.length];
for (int i = 0; i < parts.length; i++) {
try {
decodedBytes[i] = (byte) Integer.parseInt(parts[i]);
}
catch(NumberFormatException e) {
if(e.getMessage().split("\\s+")[0].equals("For")) {
if(parts[i].length() < 100) {
throw new IllegalArgumentException("Cannot parse string \"" + parts[i] + "\" to an integer.");
}
else {
throw new IllegalArgumentException("Cannot parse parts of the string to an integer.");
}
}
else {
throw new IllegalArgumentException("Please ensure that the input only contains parsable integers and delimiters.");
}
}
}
String output = new String(decodedBytes, StandardCharsets.UTF_8);
return factory.createByteArray(output);
}
@Override
public void createUI() {
Set<String> choices = FromDecimal.delimiters.keySet();
delimiterBox = new JComboBox<String>(choices.toArray(new String[choices.size()]));
delimiterBox.setSelectedIndex(0);
this.addUIElement("Delimiter", delimiterBox);
}
}
package de.usd.cstchef.operations.dataformat;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Set;

import javax.swing.JComboBox;

import burp.api.montoya.core.ByteArray;
import de.usd.cstchef.operations.Operation;
import de.usd.cstchef.operations.Operation.OperationInfos;
import de.usd.cstchef.operations.OperationCategory;
import de.usd.cstchef.operations.dataformat.ToHex.Delimiter;

@OperationInfos(name = "From Decimal", category = OperationCategory.DATAFORMAT, description = "Converts an integer array back into its raw form.")
public class FromDecimal extends Operation {

static HashMap<String, Delimiter> delimiters = new HashMap<String, Delimiter>() {
{
put("Space", new Delimiter(" "));
put("Comma", new Delimiter(","));
put("Semi-colon", new Delimiter(";"));
put("Colon", new Delimiter(":"));
put("Line feed", new Delimiter("\n"));
put("CRLF", new Delimiter("\r\n"));
}
};

private JComboBox<String> delimiterBox;

@Override
protected ByteArray perform(ByteArray input) throws Exception {

if(input.length() == 0) {
return input;
}

String selectedKey = (String) this.delimiterBox.getSelectedItem();
Delimiter delimiter = ToHex.delimiters.get(selectedKey);
String delimString = new String(delimiter.value, StandardCharsets.UTF_8);

String[] parts = input.toString().trim().split(delimString);

byte[] decodedBytes = new byte[parts.length];

for (int i = 0; i < parts.length; i++) {
try {
decodedBytes[i] = (byte) Integer.parseInt(parts[i]);
}
catch(NumberFormatException e) {
if(e.getMessage().split("\\s+")[0].equals("For")) {
if(parts[i].length() < 100) {
throw new IllegalArgumentException("Cannot parse string \"" + parts[i] + "\" to an integer.");
}
else {
throw new IllegalArgumentException("Cannot parse parts of the string to an integer.");
}
}
else {
throw new IllegalArgumentException("Please ensure that the input only contains parsable integers and delimiters.");
}
}
}

String output = new String(decodedBytes, StandardCharsets.UTF_8);

return factory.createByteArray(output);
}

@Override
public void createUI() {
Set<String> choices = FromDecimal.delimiters.keySet();
delimiterBox = new JComboBox<String>(choices.toArray(new String[choices.size()]));
delimiterBox.setSelectedIndex(0);

this.addUIElement("Delimiter", delimiterBox);
}
}
Loading