Skip to content

Commit

Permalink
Added new Then action: Then Evaluate. Changed Then Run Rule to use a …
Browse files Browse the repository at this point in the history
…dropdown to select a Rule to run. Added URL setter in Then Send Request and Then Build Http Message. Added right-click menu with Copy & Paste and an option to insert variable tags into text fields. Improved the default sizing of the When Wizard dialog.
  • Loading branch information
ddwightx committed Mar 20, 2022
1 parent 80d95ed commit 611c16f
Show file tree
Hide file tree
Showing 101 changed files with 2,129 additions and 318 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
}

group 'com.synfron.reshaper.burp'
version '1.7.0'
version '1.8.0'

targetCompatibility = '15'
sourceCompatibility = '15'
Expand Down
2 changes: 2 additions & 0 deletions docs/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Run Rules - Run a specific rule or all auto-run rules

Run Script - Execute a JavaScript script

Evaluate - Perform operations on values

Set Event Direction - Change whether to send a request or to send a response at the end of processing

Set Encoding - Set the encoding used to read and write bytes of the HTTP request or response body
Expand Down
22 changes: 18 additions & 4 deletions docs/Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ Script - The text of the JavaScript script to run.

Max Execution (secs) - Terminate long-running scripts after this time.

### Evaluate

Perform operations on values

#### Fields

X - First value. Supports variable tags.

Operation - `Add`, `Subtract`, `Multiply`, `Divide By`, `Increment`, `Decrement`, `Mod`, `Abs`, `Round`, `Equals`, `Greater Than`, `Greater Than Or Equals`, `Less Than`, or `Less Than Or Equals`

Y - Second value. Only available for certain operations. Supports variable tags.

### Set Event Direction

Change whether to send a request or to send a response at the end of processing
Expand Down Expand Up @@ -398,13 +410,15 @@ Send a separate HTTP request.

#### Fields

Protocol - `http` or `https`. Supports variable tags.
Request - The HTTP request message to send. Uses the value from the current event if left blank. Supports variable tags.

URL - The URL of the request. If this is set, it overrides the Host request header, the request message URI, protocol, address, and port. Supports variable tags.

Address - Host name without port. Example: `www.example.com`. Supports variable tags.
Protocol - `http` or `https`. If this is set, it overrides the values from the URL (if set) or the current event. Supports variable tags.

Port - Example: `80`. Supports variable tags.
Address - Hostname without port. If this is set, it overrides the values from the URL (if set) or the current event. Example: `www.example.com`. Supports variable tags.

Request - The HTTP request message to send. Supports variable tags.
Port - Example: `80`. If this is set, it overrides the values from the URL (if set) or the current event. Supports variable tags.

Wait for Completion - Wait for a response before continuing.

Expand Down
4 changes: 2 additions & 2 deletions docs/Variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Special character variables provide access to special characters which typically

## Variable Tags

Variables can be read by Whens and Thens when a variable tag is specified in supporting text fields.
Variables can be read by Whens and Thens when a variable tag is specified in supporting text fields. Variable tags can be typed in manually or inserted via the right-click menu for those text fields.
{% raw %}

**Event Variable Tag (event, e):** `{{event:MyVariableName}}`
Expand All @@ -35,7 +35,7 @@ For example, if Global variable named `firstName` has the value `John` and varia

**Special Character Tag (special, s):** `{{s:specialCharacterSequences}}`. Examples: `{{s:n}}` (new line), `{{s:rn}}` (carriage return + new line), `{{s:u00A9}}` (Copyright symbol)

**Cookie Jar Tag (cookiejar, cj):** `{{cookiejar:domain}}` or `{{cookiejar:domain:path}}`. Example: `{{cookiejar:example.com:/}}`
**Cookie Jar Tag (cookiejar, cj):** `{{cookiejar:domain:name}}` or `{{cookiejar:domain:name:path}}`. Example: `{{cookiejar:example.com:tracker:/}}`


{% endraw %}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ public Encoder(String encoding) {
setEncoding(encoding, true);
}

public String getEncoding() {
if (useAutoDetect) {
return autoDetectEncoderName;
} else if (useDefault) {
return defaultEncoderName;
}
return charset.displayName();
}

public void setEncoding(String encoding, boolean autoSet) {
useDefault = false;
useAutoDetect = false;
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/synfron/reshaper/burp/core/messages/EventInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import burp.BurpExtender;
import burp.IHttpRequestResponse;
import burp.IInterceptedProxyMessage;
import lombok.Data;
import lombok.Getter;
import synfron.reshaper.burp.core.BurpTool;
import synfron.reshaper.burp.core.exceptions.WrappedException;
Expand Down Expand Up @@ -74,6 +75,20 @@ public EventInfo(DataDirection dataDirection, BurpTool burpTool, IHttpRequestRes
proxyName = null;
}

public EventInfo(IEventInfo sourceEventInfo) {
this.burpTool = sourceEventInfo.getBurpTool();
this.dataDirection = sourceEventInfo.getDataDirection();
this.requestResponse = null;
this.encoder.setEncoding(sourceEventInfo.getEncoder().getEncoding(), sourceEventInfo.getEncoder().isAutoSet());
httpRequestMessage = new HttpRequestMessage(sourceEventInfo.getHttpRequestMessage().getValue(), encoder);
httpResponseMessage = new HttpResponseMessage(sourceEventInfo.getHttpResponseMessage().getValue(), encoder);
httpProtocol = sourceEventInfo.getHttpProtocol();
sourceAddress = sourceEventInfo.getSourceAddress();
destinationPort = sourceEventInfo.getDestinationPort();
destinationAddress = sourceEventInfo.getDestinationAddress();
proxyName = sourceEventInfo.getProxyName();
}

@Override
public void setDataDirection(DataDirection dataDirection) {
this.dataDirection = dataDirection;
Expand Down Expand Up @@ -123,8 +138,7 @@ public void setUrl(String urlStr) {
setHttpProtocol(url.getProtocol());
setDestinationAddress(url.getHost());
setDestinationPort(url.getPort() > 0 ? url.getPort() : url.getDefaultPort());
getHttpRequestMessage().getStatusLine().setUrl(url.getFile().startsWith("/") ? url.getFile() : "/" + url.getFile());
getHttpRequestMessage().getHeaders().setHeader("Host", url.getAuthority(), SetItemPlacement.Only);
getHttpRequestMessage().setUrl(url);
} catch (MalformedURLException e) {
throw new WrappedException(e);
}
Expand Down Expand Up @@ -162,4 +176,5 @@ public String getUrl() {
}
return url;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

public enum MessageValue {
SourceAddress("Source Address", null, true, false),
DestinationAddress("Destination Address", null, true, false),
DestinationPort("Destination Port", null, true, false),
HttpProtocol("Protocol", null, true, false),
Url("URL", null, true, false),
HttpRequestMessage("Request Message", DataDirection.Request, true, false),
DestinationAddress("Destination Address", DataDirection.Request, true, false),
DestinationPort("Destination Port", DataDirection.Request, true, false),
HttpProtocol("Protocol", DataDirection.Request, true, false),
Url("URL", DataDirection.Request, true, false, true, false),
HttpRequestMessage("Request Message", DataDirection.Request, true, true, false, false),
HttpRequestStatusLine("Request Status Line", DataDirection.Request, false, false),
HttpRequestMethod("Request Method", DataDirection.Request, false, false),
HttpRequestUri("Request URI", DataDirection.Request, false, false),
Expand All @@ -19,7 +19,7 @@ public enum MessageValue {
HttpRequestHeader("Request Header", DataDirection.Request, false, true),
HttpRequestCookie("Request Cookie", DataDirection.Request, false, true),
HttpRequestBody("Request Body", DataDirection.Request, false, false),
HttpResponseMessage("Response Message", DataDirection.Response, true, false),
HttpResponseMessage("Response Message", DataDirection.Response, true, true, false, false),
HttpResponseStatusLine("Response Status Line", DataDirection.Response, false, false),
HttpResponseStatusCode("Response Status Code", DataDirection.Response, false, false),
HttpResponseStatusMessage("Response Status Message", DataDirection.Response, false, false),
Expand All @@ -35,12 +35,27 @@ public enum MessageValue {
@Getter
private final boolean topLevel;
@Getter
private final boolean messageGettable;
@Getter
private final boolean messageSettable;
@Getter
private final boolean identifierRequired;

MessageValue(String name, DataDirection dataDirection, boolean topLevel, boolean identifierRequired) {
this.name = name;
this.dataDirection = dataDirection;
this.topLevel = topLevel;
this.messageGettable = !topLevel;
this.messageSettable = !topLevel;
this.identifierRequired = identifierRequired;
}

MessageValue(String name, DataDirection dataDirection, boolean topLevel, boolean messageGettable, boolean messageSettable, boolean identifierRequired) {
this.name = name;
this.dataDirection = dataDirection;
this.topLevel = topLevel;
this.messageGettable = messageGettable;
this.messageSettable = messageSettable;
this.identifierRequired = identifierRequired;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public class MessageValueHandler {
public static String getValue(IEventInfo eventInfo, MessageValue messageValue, VariableString identifier, GetItemPlacement itemPlacement)
{
String value;
if (messageValue.getDataDirection() == DataDirection.Request) {
if (!messageValue.isTopLevel() && messageValue.getDataDirection() == DataDirection.Request) {
value = getRequestValue(eventInfo, eventInfo.getHttpRequestMessage(), messageValue, identifier, itemPlacement);
} else if (messageValue.getDataDirection() == DataDirection.Response) {
} else if (!messageValue.isTopLevel() && messageValue.getDataDirection() == DataDirection.Response) {
value = getResponseValue(eventInfo, eventInfo.getHttpResponseMessage(), messageValue, identifier, itemPlacement);
} else {
value = switch (messageValue) {
Expand All @@ -27,6 +27,8 @@ public static String getValue(IEventInfo eventInfo, MessageValue messageValue, V
case SourceAddress -> eventInfo.getSourceAddress();
case DestinationPort -> Integer.toString(eventInfo.getDestinationPort());
case DestinationAddress -> eventInfo.getDestinationAddress();
case HttpRequestMessage -> eventInfo.getHttpRequestMessage().getText();
case HttpResponseMessage -> eventInfo.getHttpResponseMessage().getText();
default -> throw new UnsupportedOperationException(String.format("Cannot get message value '%s'", messageValue));
};
}
Expand Down Expand Up @@ -67,9 +69,9 @@ public static String getResponseValue(IEventInfo eventInfo, HttpResponseMessage


public static void setValue(IEventInfo eventInfo, MessageValue messageValue, VariableString identifier, SetItemPlacement itemPlacement, String replacementText) {
if (messageValue.getDataDirection() == DataDirection.Request && !messageValue.isTopLevel()) {
if (!messageValue.isTopLevel() && messageValue.getDataDirection() == DataDirection.Request) {
setRequestValue(eventInfo, eventInfo.getHttpRequestMessage(), messageValue, identifier,itemPlacement, replacementText);
} else if (messageValue.getDataDirection() == DataDirection.Response && !messageValue.isTopLevel()) {
} else if (!messageValue.isTopLevel() && messageValue.getDataDirection() == DataDirection.Response) {
setResponseValue(eventInfo, eventInfo.getHttpResponseMessage(), messageValue, identifier, itemPlacement, replacementText);
} else {
switch (messageValue) {
Expand All @@ -92,11 +94,11 @@ public static void setRequestValue(IEventInfo eventInfo, HttpRequestMessage requ
case HttpRequestStatusLine -> requestMessage.setStatusLine(replacementText);
case HttpRequestCookie -> requestMessage.getHeaders().getCookies().setCookie(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpRequestUri -> requestMessage.getStatusLine().setUrl(replacementText);
case HttpRequestMessage -> eventInfo.setHttpRequestMessage(eventInfo.getEncoder().encode(replacementText));
case HttpRequestMethod -> requestMessage.getStatusLine().setMethod(replacementText);
case HttpRequestUriPath -> requestMessage.getStatusLine().getUrl().setPath(StringUtils.defaultString(replacementText));
case HttpRequestUriQueryParameter -> requestMessage.getStatusLine().getUrl().getQueryParams().setQueryParameter(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpRequestUriQueryParameters -> requestMessage.getStatusLine().getUrl().setQueryParametersText(StringUtils.defaultString(replacementText));
case Url -> requestMessage.setUrl(StringUtils.defaultString(replacementText));
}
}

Expand All @@ -107,7 +109,6 @@ public static void setResponseValue(IEventInfo eventInfo, HttpResponseMessage re
case HttpResponseBody -> responseMessage.setBody(StringUtils.defaultString(replacementText));
case HttpResponseStatusLine -> responseMessage.setStatusLine(replacementText);
case HttpResponseCookie -> responseMessage.getHeaders().getCookies().setCookie(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpResponseMessage -> eventInfo.setHttpResponseMessage(eventInfo.getEncoder().encode(replacementText));
case HttpResponseStatusCode -> responseMessage.getStatusLine().setCode(replacementText);
case HttpResponseStatusMessage -> responseMessage.getStatusLine().setMessage(StringUtils.defaultString(replacementText));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import burp.BurpExtender;
import burp.IRequestInfo;
import org.apache.commons.lang3.StringUtils;
import synfron.reshaper.burp.core.exceptions.WrappedException;
import synfron.reshaper.burp.core.messages.ContentType;
import synfron.reshaper.burp.core.messages.Encoder;
import synfron.reshaper.burp.core.utils.CollectionUtils;
import synfron.reshaper.burp.core.utils.SetItemPlacement;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -87,6 +91,20 @@ public void setBody(String body) {
changed = true;
}

public void setUrl(String urlStr) {
try {
URL url = new URL(urlStr);
setUrl(url);
} catch (MalformedURLException e) {
throw new WrappedException(e);
}
}

public void setUrl(URL url) {
getStatusLine().setUrl(url.getFile().startsWith("/") ? url.getFile() : "/" + url.getFile());
getHeaders().setHeader("Host", url.getAuthority(), SetItemPlacement.Only);
}

public byte[] getValue() {
return !isChanged() ?
getAdjustedRequest(request) :
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/synfron/reshaper/burp/core/rules/Rule.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class Rule implements Serializable {
@Getter
private final transient PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent();
@Getter @Setter
private List<When<?>> whens = new ArrayList<>();
private When<?>[] whens = new When<?>[0];
@Getter @Setter
private List<Then<?>> thens = new ArrayList<>();
private Then<?>[] thens = new Then<?>[0];
@Getter
private boolean enabled = true;
@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class RulesEngine {
@Getter
private final RulesRegistry rulesRegistry = new RulesRegistry();

private boolean match(List<When<?>> whens, IEventInfo eventInfo)
private boolean match(When<?>[] whens, IEventInfo eventInfo)
{
boolean isMatch = true;
boolean first = true;
Expand All @@ -37,7 +37,7 @@ private boolean match(List<When<?>> whens, IEventInfo eventInfo)
return isMatch;
}

private RuleResponse perform(List<Then<?>> thens, IEventInfo eventInfo)
private RuleResponse perform(Then<?>[] thens, IEventInfo eventInfo)
{
RuleResponse thenResult = RuleResponse.Continue;
for (Then<?> then : thens)
Expand All @@ -54,7 +54,7 @@ private RuleResponse perform(List<Then<?>> thens, IEventInfo eventInfo)

public RuleResponse run(IEventInfo eventInfo)
{
List<Rule> rules = rulesRegistry.getRules();
Rule[] rules = rulesRegistry.getRules();
try {
if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logStart(eventInfo);
for (Rule rule : rules) {
Expand Down
Loading

0 comments on commit 611c16f

Please sign in to comment.