├── .gitignore ├── settings.gradle ├── libs └── htmlchardet-1.0.2.1.jar ├── src └── main │ └── java │ ├── synfron │ └── reshaper │ │ └── burp │ │ ├── core │ │ ├── utils │ │ │ ├── IValue.java │ │ │ ├── GetItemPlacement.java │ │ │ ├── DeleteItemPlacement.java │ │ │ ├── SetItemPlacement.java │ │ │ ├── Select.java │ │ │ ├── Value.java │ │ │ ├── Mapped.java │ │ │ ├── CaseInsensitiveString.java │ │ │ ├── IItemPlacement.java │ │ │ └── ObjectUtils.java │ │ ├── events │ │ │ ├── MessageEvent.java │ │ │ ├── IEventListener.java │ │ │ ├── PropertyChangedEvent.java │ │ │ ├── CollectionChangedEvent.java │ │ │ ├── CollectionChangedAction.java │ │ │ ├── PropertyChangedArgs.java │ │ │ ├── MessageArgs.java │ │ │ ├── message │ │ │ │ ├── Message.java │ │ │ │ ├── PromptCancelMessage.java │ │ │ │ ├── MessageType.java │ │ │ │ ├── PromptResponseMessage.java │ │ │ │ ├── PromptRequestMessage.java │ │ │ │ └── MessageWaiter.java │ │ │ ├── CollectionChangedArgs.java │ │ │ └── Event.java │ │ ├── messages │ │ │ ├── DataDirection.java │ │ │ ├── entities │ │ │ │ ├── HttpEntity.java │ │ │ │ ├── HttpRequestHeaders.java │ │ │ │ ├── HttpResponseHeaders.java │ │ │ │ ├── HttpBody.java │ │ │ │ ├── HttpResponseStatusLine.java │ │ │ │ ├── HttpRequestQueryParams.java │ │ │ │ └── HttpRequestStatusLine.java │ │ │ ├── MessageValueType.java │ │ │ └── IEventInfo.java │ │ ├── exceptions │ │ │ └── WrappedException.java │ │ ├── rules │ │ │ ├── thens │ │ │ │ ├── entities │ │ │ │ │ ├── sendto │ │ │ │ │ │ └── SendToOption.java │ │ │ │ │ ├── savefile │ │ │ │ │ │ └── FileExistsAction.java │ │ │ │ │ ├── evaluate │ │ │ │ │ │ └── Operation.java │ │ │ │ │ ├── buildhttpmessage │ │ │ │ │ │ └── MessageValueSetter.java │ │ │ │ │ ├── script │ │ │ │ │ │ └── ConsoleObj.java │ │ │ │ │ └── parsehttpmessage │ │ │ │ │ │ └── MessageValueGetter.java │ │ │ │ ├── ThenBreak.java │ │ │ │ ├── ThenDrop.java │ │ │ │ ├── ThenSetEventDirection.java │ │ │ │ ├── ThenComment.java │ │ │ │ ├── ThenLog.java │ │ │ │ ├── ThenSetEncoding.java │ │ │ │ ├── ThenDelay.java │ │ │ │ ├── ThenHighlight.java │ │ │ │ ├── ThenDeleteVariable.java │ │ │ │ ├── ThenDeleteValue.java │ │ │ │ ├── ThenRunScript.java │ │ │ │ └── Then.java │ │ │ ├── IRuleOperation.java │ │ │ ├── diagnostics │ │ │ │ ├── DiagnosticRecord.java │ │ │ │ ├── DiagnosticEntityType.java │ │ │ │ └── IDiagnostics.java │ │ │ ├── MatchType.java │ │ │ ├── RuleOperationType.java │ │ │ ├── whens │ │ │ │ ├── WhenFromTool.java │ │ │ │ ├── WhenProxyName.java │ │ │ │ ├── WhenEventDirection.java │ │ │ │ ├── WhenMimeType.java │ │ │ │ ├── WhenContentType.java │ │ │ │ ├── WhenInScope.java │ │ │ │ ├── When.java │ │ │ │ └── WhenType.java │ │ │ ├── RuleResponse.java │ │ │ └── Rule.java │ │ ├── settings │ │ │ ├── ExportSettings.java │ │ │ ├── Storage.java │ │ │ └── GeneralSettings.java │ │ ├── BurpTool.java │ │ └── vars │ │ │ ├── Variable.java │ │ │ ├── GlobalVariables.java │ │ │ ├── VariableSource.java │ │ │ ├── Variables.java │ │ │ └── VariableSourceEntry.java │ │ └── ui │ │ ├── utils │ │ ├── IPrompter.java │ │ ├── ListCellRenderer.java │ │ ├── TableCellRenderer.java │ │ ├── ActionPerformedListener.java │ │ ├── IPrompterModel.java │ │ ├── FocusActionListener.java │ │ ├── ForegroundColorListCellRenderer.java │ │ ├── DocumentActionListener.java │ │ ├── ContextMenuHandler.java │ │ ├── UiMessageHandler.java │ │ └── ComponentVisibilityManager.java │ │ ├── models │ │ └── rules │ │ │ ├── thens │ │ │ ├── IVariableCreator.java │ │ │ ├── VariableCreatorRegistry.java │ │ │ ├── ThenDropModel.java │ │ │ ├── ThenHighlightModel.java │ │ │ ├── ThenBreakModel.java │ │ │ ├── ThenSetEventDirectionModel.java │ │ │ ├── ThenLogModel.java │ │ │ ├── ThenCommentModel.java │ │ │ ├── ThenModel.java │ │ │ ├── ThenDelayModel.java │ │ │ ├── ThenSetEncodingModel.java │ │ │ ├── ThenRunRulesModel.java │ │ │ ├── ThenRunScriptModel.java │ │ │ └── ThenDeleteVariableModel.java │ │ │ ├── wizard │ │ │ ├── vars │ │ │ │ ├── IVariableTagWizardModel.java │ │ │ │ ├── FileVariableTagWizardModel.java │ │ │ │ ├── MessageVariableTagWizardModel.java │ │ │ │ ├── EventVariableTagWizardModel.java │ │ │ │ └── GlobalVariableTagWizardModel.java │ │ │ └── whens │ │ │ │ └── WhenWizardMatchType.java │ │ │ ├── RuleOperationModelType.java │ │ │ ├── whens │ │ │ ├── WhenFromToolModel.java │ │ │ ├── WhenMimeTypeModel.java │ │ │ ├── WhenContentTypeModel.java │ │ │ ├── WhenEventDirectionModel.java │ │ │ ├── WhenInScopeModel.java │ │ │ ├── WhenProxyNameModel.java │ │ │ ├── WhenHasEntityModel.java │ │ │ ├── WhenModelType.java │ │ │ └── WhenModel.java │ │ │ └── RuleOperationModel.java │ │ ├── components │ │ ├── rules │ │ │ ├── RuleContainerComponent.java │ │ │ ├── thens │ │ │ │ ├── ThenComponent.java │ │ │ │ ├── ThensComponent.java │ │ │ │ ├── ThenDropComponent.java │ │ │ │ ├── ThenLogComponent.java │ │ │ │ ├── ThenCommentComponent.java │ │ │ │ ├── ThenDelayComponent.java │ │ │ │ ├── ThenHighlightComponent.java │ │ │ │ ├── ThenSetEncodingComponent.java │ │ │ │ ├── ThenBreakComponent.java │ │ │ │ ├── ThenSetEventDirectionComponent.java │ │ │ │ ├── ThenListComponent.java │ │ │ │ ├── ThenDeleteVariableComponent.java │ │ │ │ ├── ThenSetVariableComponent.java │ │ │ │ ├── ThenRunScriptComponent.java │ │ │ │ └── ThenRunRulesComponent.java │ │ │ ├── RulesTabComponent.java │ │ │ ├── whens │ │ │ │ ├── WhensComponent.java │ │ │ │ ├── WhenInScopeComponent.java │ │ │ │ ├── WhenFromToolComponent.java │ │ │ │ ├── WhenProxyNameComponent.java │ │ │ │ ├── WhenEventDirectionComponent.java │ │ │ │ ├── WhenListComponent.java │ │ │ │ ├── WhenContainerComponent.java │ │ │ │ ├── WhenComponent.java │ │ │ │ └── WhenHasEntityComponent.java │ │ │ ├── RuleOperationContainerComponent.java │ │ │ ├── wizard │ │ │ │ └── vars │ │ │ │ │ ├── EventVariableTagWizardComponent.java │ │ │ │ │ ├── GlobalVariableTagWizardComponent.java │ │ │ │ │ ├── VariableTagWizardContainerComponent.java │ │ │ │ │ ├── MessageVariableTagWizardComponent.java │ │ │ │ │ └── SpecialVariableTagWizardComponent.java │ │ │ ├── RuleOperationsContainerComponent.java │ │ │ ├── RuleOperationsComponent.java │ │ │ └── RuleOperationComponent.java │ │ ├── vars │ │ │ ├── VariableContainerComponent.java │ │ │ └── VariablesTabComponent.java │ │ ├── LogsComponent.java │ │ └── ReshaperComponent.java │ │ └── Window.java │ └── burp │ └── BurpExtender.java ├── docs ├── _config.yml └── Variables.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | .idea/ 3 | build/ 4 | gradle/ 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'reshaper-for-burp' 2 | 3 | -------------------------------------------------------------------------------- /libs/htmlchardet-1.0.2.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/githubmaidou/ReshaperForBurp/release/libs/htmlchardet-1.0.2.1.jar -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/IValue.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | public interface IValue { 4 | T getValue(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/MessageEvent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | public class MessageEvent extends Event { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/IEventListener.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | public interface IEventListener { 4 | void invoke(T args); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/DataDirection.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages; 2 | 3 | public enum DataDirection { 4 | Request, 5 | Response 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/IPrompter.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | public interface IPrompter { 4 | void open(T model); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/PropertyChangedEvent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | public class PropertyChangedEvent extends Event { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/CollectionChangedEvent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | public class CollectionChangedEvent extends Event { 4 | } 5 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | title: Reshaper for Burp 3 | description: Trigger actions and reshape HTTP request and response traffic using configurable rules 4 | kramdown: 5 | auto_ids: true 6 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/GetItemPlacement.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | public enum GetItemPlacement implements IItemPlacement { 4 | First, 5 | Last 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpEntity.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | public abstract class HttpEntity { 4 | public abstract boolean isChanged(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/DeleteItemPlacement.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | public enum DeleteItemPlacement implements IItemPlacement { 4 | First, 5 | Last, 6 | All 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/CollectionChangedAction.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | public enum CollectionChangedAction { 4 | Add, 5 | Move, 6 | Update, 7 | Remove, 8 | Reset 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/SetItemPlacement.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | public enum SetItemPlacement implements IItemPlacement { 4 | First, 5 | Last, 6 | New, 7 | All, 8 | Only 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/exceptions/WrappedException.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.exceptions; 2 | 3 | public class WrappedException extends RuntimeException { 4 | public WrappedException(Exception e) { 5 | super(e); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/entities/sendto/SendToOption.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens.entities.sendto; 2 | 3 | public enum SendToOption { 4 | Comparer, 5 | Intruder, 6 | Repeater, 7 | Spider, 8 | Browser 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/IRuleOperation.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules; 2 | 3 | import java.io.Serializable; 4 | 5 | public interface IRuleOperation> extends Serializable { 6 | RuleOperationType getType(); 7 | 8 | T copy(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/entities/savefile/FileExistsAction.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens.entities.savefile; 2 | 3 | import com.jayway.jsonpath.internal.function.json.Append; 4 | 5 | public enum FileExistsAction { 6 | None, 7 | Append, 8 | Overwrite 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/ListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import javax.swing.*; 4 | 5 | public class ListCellRenderer extends DefaultListCellRenderer { 6 | 7 | public ListCellRenderer() { 8 | putClientProperty("html.disable", Boolean.TRUE); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/IVariableCreator.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.vars.VariableSourceEntry; 4 | 5 | import java.util.List; 6 | 7 | public interface IVariableCreator { 8 | List getVariableEntries(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpRequestHeaders.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | import java.util.List; 4 | 5 | public class HttpRequestHeaders extends HttpHeaders { 6 | public HttpRequestHeaders(List headerLines) { 7 | super(headerLines, "Cookie"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpResponseHeaders.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | import java.util.List; 4 | 5 | public class HttpResponseHeaders extends HttpHeaders { 6 | public HttpResponseHeaders(List headerLines) { 7 | super(headerLines, "Set-Cookie"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/diagnostics/DiagnosticRecord.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.diagnostics; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | @Data 7 | @AllArgsConstructor 8 | public class DiagnosticRecord { 9 | private DiagnosticEntityType entityType; 10 | private String log; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/TableCellRenderer.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import javax.swing.table.DefaultTableCellRenderer; 4 | 5 | public class TableCellRenderer extends DefaultTableCellRenderer { 6 | 7 | public TableCellRenderer() { 8 | putClientProperty("html.disable", Boolean.TRUE); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/PropertyChangedArgs.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | @Data 7 | @AllArgsConstructor 8 | public class PropertyChangedArgs { 9 | private final Object source; 10 | private final String name; 11 | private final Object value; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/MessageArgs.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import synfron.reshaper.burp.core.events.message.Message; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | public class MessageArgs { 10 | private final Object source; 11 | private final Message data; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/message/Message.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events.message; 2 | 3 | import lombok.Getter; 4 | 5 | public abstract class Message { 6 | @Getter 7 | private final String messageId; 8 | 9 | protected Message(String messageId) { 10 | this.messageId = messageId; 11 | } 12 | public abstract MessageType getMessageType(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/message/PromptCancelMessage.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events.message; 2 | 3 | public class PromptCancelMessage extends Message { 4 | 5 | public PromptCancelMessage(String messageId) { 6 | super(messageId); 7 | } 8 | 9 | @Override 10 | public MessageType getMessageType() { 11 | return MessageType.PromptCancel; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/settings/ExportSettings.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.settings; 2 | 3 | import lombok.Data; 4 | import synfron.reshaper.burp.core.rules.Rule; 5 | import synfron.reshaper.burp.core.vars.Variable; 6 | 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | @Data 11 | public class ExportSettings { 12 | private List rules = Collections.emptyList(); 13 | private List variables = Collections.emptyList(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/wizard/vars/IVariableTagWizardModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.wizard.vars; 2 | 3 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 4 | import synfron.reshaper.burp.core.vars.VariableSource; 5 | 6 | import java.util.List; 7 | 8 | public interface IVariableTagWizardModel { 9 | String getTag(); 10 | List validate(); 11 | VariableSource getVariableSource(); 12 | PropertyChangedEvent getPropertyChangedEvent(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/MessageValueType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages; 2 | 3 | import lombok.Getter; 4 | 5 | public enum MessageValueType { 6 | Text("Text"), 7 | Json("JSON"), 8 | Html("HTML"), 9 | Params("Params"); 10 | 11 | @Getter 12 | private final String name; 13 | 14 | MessageValueType(String name) { 15 | this.name = name; 16 | } 17 | 18 | 19 | @Override 20 | public String toString() { 21 | return name; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/message/MessageType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events.message; 2 | 3 | import lombok.Getter; 4 | 5 | public enum MessageType { 6 | PromptRequest(PromptRequestMessage.class), 7 | PromptResponse(PromptResponseMessage.class), 8 | PromptCancel(PromptCancelMessage.class); 9 | 10 | @Getter 11 | private final Class dataClass; 12 | 13 | MessageType(Class dataClass) { 14 | this.dataClass = dataClass; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/MatchType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules; 2 | 3 | import lombok.Getter; 4 | 5 | public enum MatchType { 6 | Equals("Equals"), 7 | Contains("Contains"), 8 | BeginsWith("Begins With"), 9 | EndsWith("Ends With"), 10 | Regex("Regex"); 11 | 12 | @Getter 13 | private final String name; 14 | 15 | MatchType(String name) { 16 | this.name = name; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return name; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/RuleOperationType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules; 2 | 3 | import lombok.Getter; 4 | 5 | public abstract class RuleOperationType> { 6 | @Getter 7 | private final String name; 8 | @Getter 9 | private final Class type; 10 | 11 | protected RuleOperationType(String name, Class type) { 12 | this.name = name; 13 | this.type = type; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/message/PromptResponseMessage.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events.message; 2 | 3 | import lombok.Getter; 4 | 5 | public class PromptResponseMessage extends Message { 6 | 7 | @Getter 8 | private final String response; 9 | 10 | public PromptResponseMessage(String messageId, String response) { 11 | super(messageId); 12 | this.response = response; 13 | } 14 | 15 | @Override 16 | public MessageType getMessageType() { 17 | return MessageType.PromptResponse; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/diagnostics/DiagnosticEntityType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.diagnostics; 2 | 3 | import lombok.Getter; 4 | 5 | public enum DiagnosticEntityType { 6 | StartEvent(0, 1), 7 | EndEvent(0, -1), 8 | StartRule(1, 1), 9 | EndRule(1, -1), 10 | When(2, 1), 11 | Then(2, 1); 12 | 13 | @Getter 14 | private final int level; 15 | @Getter 16 | private final int levelChange; 17 | 18 | DiagnosticEntityType(int level, int levelChange) { 19 | this.level = level; 20 | this.levelChange = levelChange; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/ActionPerformedListener.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import javax.swing.*; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | 7 | public class ActionPerformedListener extends AbstractAction { 8 | 9 | private final ActionListener actionListener; 10 | 11 | public ActionPerformedListener(ActionListener actionListener) { 12 | this.actionListener = actionListener; 13 | } 14 | 15 | @Override 16 | public void actionPerformed(ActionEvent e) { 17 | actionListener.actionPerformed(e); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/Select.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | public class Select { 10 | 11 | @Getter 12 | private final List options; 13 | @Getter @Setter 14 | private T selectedOption; 15 | 16 | public Select(List options, T selectedOption) { 17 | this.options = Collections.unmodifiableList(options); 18 | this.selectedOption = selectedOption != null ? selectedOption : options.stream().findFirst().orElse(null); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/message/PromptRequestMessage.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events.message; 2 | 3 | import lombok.Getter; 4 | 5 | public class PromptRequestMessage extends Message { 6 | 7 | @Getter 8 | private final String description; 9 | @Getter 10 | private final String text; 11 | 12 | public PromptRequestMessage(String messageId, String description, String text) { 13 | super(messageId); 14 | this.description = description; 15 | this.text = text; 16 | } 17 | 18 | @Override 19 | public MessageType getMessageType() { 20 | return MessageType.PromptRequest; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/IPrompterModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import synfron.reshaper.burp.core.events.IEventListener; 4 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 5 | 6 | public interface IPrompterModel> { 7 | 8 | T withListener(IEventListener listener); 9 | 10 | void resetPropertyChangedListener(); 11 | 12 | void setModalPrompter(ModalPrompter modalPrompter); 13 | 14 | ModalPrompter getModalPrompter(); 15 | 16 | boolean isInvalidated(); 17 | 18 | boolean isDismissed(); 19 | 20 | void setDismissed(boolean dismissed); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/RuleContainerComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules; 2 | 3 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | 8 | public class RuleContainerComponent extends JPanel { 9 | 10 | public RuleContainerComponent() { 11 | initComponent(); 12 | } 13 | 14 | private void initComponent() { 15 | setLayout(new BorderLayout()); 16 | } 17 | 18 | public void setModel(RuleModel model) { 19 | removeAll(); 20 | if (model != null) { 21 | add(new RuleComponent(model)); 22 | } 23 | revalidate(); 24 | repaint(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/Value.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | import java.util.Objects; 4 | 5 | public class Value implements IValue { 6 | 7 | private final T value; 8 | 9 | public Value(T value) { 10 | this.value = value; 11 | } 12 | 13 | public T getValue() { 14 | return value; 15 | } 16 | 17 | @Override 18 | public int hashCode() { 19 | return Objects.hashCode(getValue()); 20 | } 21 | 22 | @Override 23 | public boolean equals(Object obj) { 24 | return Objects.equals(getValue(), obj); 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return TextUtils.toString(getValue()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/vars/VariableContainerComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.vars; 2 | 3 | import synfron.reshaper.burp.ui.models.vars.VariableModel; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | 8 | public class VariableContainerComponent extends JPanel { 9 | 10 | public VariableContainerComponent() { 11 | initComponent(); 12 | } 13 | 14 | private void initComponent() { 15 | setLayout(new BorderLayout()); 16 | } 17 | 18 | public void setModel(VariableModel model) { 19 | removeAll(); 20 | if (model != null) { 21 | add(new VariableComponent(model)); 22 | } 23 | revalidate(); 24 | repaint(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/wizard/whens/WhenWizardMatchType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.wizard.whens; 2 | 3 | import lombok.Getter; 4 | 5 | public enum WhenWizardMatchType { 6 | Exists("Exists", false), 7 | Equals("Equals", true), 8 | Contains("Contains", true), 9 | BeginsWith("Begins With", true), 10 | EndsWith("Ends With", true), 11 | Regex("Regex", true); 12 | 13 | @Getter 14 | private final String name; 15 | @Getter 16 | private final boolean matcher; 17 | 18 | WhenWizardMatchType(String name, boolean matcher) { 19 | this.name = name; 20 | this.matcher = matcher; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return name; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/settings/Storage.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.settings; 2 | 3 | import burp.BurpExtender; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import synfron.reshaper.burp.core.utils.Serializer; 6 | 7 | public class Storage { 8 | 9 | public static void store(String storageKey, Object value) { 10 | BurpExtender.getCallbacks().saveExtensionSetting(storageKey, Serializer.serialize(value, false)); 11 | } 12 | 13 | public static T get(String storageKey, TypeReference typeReference) { 14 | String json = BurpExtender.getCallbacks().loadExtensionSetting(storageKey); 15 | if (json == null) { 16 | return null; 17 | } 18 | return Serializer.deserialize(json, typeReference); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/Mapped.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | import java.util.Objects; 4 | import java.util.function.Supplier; 5 | 6 | public class Mapped implements IValue { 7 | 8 | private final Supplier supplier; 9 | 10 | public Mapped(Supplier supplier) { 11 | this.supplier = supplier; 12 | } 13 | 14 | public T getValue() { 15 | return supplier.get(); 16 | } 17 | 18 | @Override 19 | public int hashCode() { 20 | return Objects.hashCode(getValue()); 21 | } 22 | 23 | @Override 24 | public boolean equals(Object obj) { 25 | return Objects.equals(getValue(), obj); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return TextUtils.toString(getValue()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.Then; 4 | import synfron.reshaper.burp.ui.components.rules.RuleOperationComponent; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenModel; 6 | 7 | import javax.swing.*; 8 | import javax.swing.border.CompoundBorder; 9 | 10 | public abstract class ThenComponent

, T extends Then> extends RuleOperationComponent { 11 | 12 | public ThenComponent(P model) { 13 | super(model); 14 | setBorder(new CompoundBorder( 15 | BorderFactory.createTitledBorder(String.format("Then %s", model.getType().getName())), 16 | BorderFactory.createEmptyBorder(4,4,4,4)) 17 | ); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/vars/VariablesTabComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.vars; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | 6 | public class VariablesTabComponent extends JPanel { 7 | 8 | public VariablesTabComponent() { 9 | initComponent(); 10 | } 11 | 12 | private void initComponent() { 13 | setLayout(new BorderLayout()); 14 | 15 | VariableListComponent variablesList = new VariableListComponent(); 16 | VariableContainerComponent variableContainer = new VariableContainerComponent(); 17 | variablesList.setSelectionContainer(variableContainer); 18 | 19 | JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, variablesList, variableContainer); 20 | splitPane.setDividerSize(3); 21 | 22 | add(splitPane); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenBreak.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | 9 | public class ThenBreak extends Then { 10 | @Getter 11 | @Setter 12 | private RuleResponse breakType = RuleResponse.BreakThens; 13 | 14 | @Override 15 | public RuleResponse perform(IEventInfo eventInfo) { 16 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, false, breakType); 17 | return breakType; 18 | } 19 | 20 | @Override 21 | public RuleOperationType getType() { 22 | return ThenType.Break; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenDrop.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | 9 | public class ThenDrop extends Then { 10 | @Getter @Setter 11 | private boolean dropMessage = true; 12 | 13 | public RuleResponse perform(IEventInfo eventInfo) { 14 | eventInfo.setShouldDrop(dropMessage); 15 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, false, dropMessage); 16 | return RuleResponse.Continue; 17 | } 18 | 19 | @Override 20 | public RuleOperationType getType() { 21 | return ThenType.Drop; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/RulesTabComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | 6 | public class RulesTabComponent extends JPanel { 7 | 8 | public RulesTabComponent() { 9 | initComponent(); 10 | } 11 | 12 | private void initComponent() { 13 | setLayout(new BorderLayout()); 14 | 15 | RuleListComponent ruleList = new RuleListComponent(); 16 | RuleContainerComponent ruleContainer = new RuleContainerComponent(); 17 | ruleList.setSelectionContainer(ruleContainer); 18 | 19 | JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, ruleList, ruleContainer); 20 | splitPane.setDividerLocation(ruleList.getPreferredSize().width); 21 | splitPane.setDividerSize(3); 22 | 23 | add(splitPane); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/FocusActionListener.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import java.awt.event.ActionEvent; 4 | import java.awt.event.ActionListener; 5 | import java.awt.event.FocusEvent; 6 | import java.awt.event.FocusListener; 7 | 8 | public class FocusActionListener implements FocusListener { 9 | private final ActionListener actionListener; 10 | 11 | public FocusActionListener(ActionListener actionListener) { 12 | this.actionListener = actionListener; 13 | } 14 | 15 | @Override 16 | public void focusGained(FocusEvent e) { 17 | actionListener.actionPerformed(new ActionEvent(e.getSource(), FocusEvent.FOCUS_GAINED, null)); 18 | } 19 | 20 | @Override 21 | public void focusLost(FocusEvent e) { 22 | actionListener.actionPerformed(new ActionEvent(e.getSource(), FocusEvent.FOCUS_LOST, null)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/RuleOperationModelType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.rules.IRuleOperation; 5 | import synfron.reshaper.burp.core.rules.RuleOperationType; 6 | 7 | public class RuleOperationModelType

, T extends IRuleOperation> { 8 | @Getter 9 | private final String name; 10 | @Getter 11 | private final Class

type; 12 | @Getter 13 | private final RuleOperationType ruleOperationType; 14 | 15 | protected RuleOperationModelType(String name, Class

type, RuleOperationType ruleOperationType) { 16 | this.name = name; 17 | this.type = type; 18 | this.ruleOperationType = ruleOperationType; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return name; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/BurpTool.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core; 2 | 3 | import burp.IBurpExtenderCallbacks; 4 | import lombok.Getter; 5 | 6 | import java.util.Arrays; 7 | 8 | public enum BurpTool { 9 | Proxy(IBurpExtenderCallbacks.TOOL_PROXY), 10 | Repeater(IBurpExtenderCallbacks.TOOL_REPEATER), 11 | Intruder(IBurpExtenderCallbacks.TOOL_INTRUDER), 12 | Target(IBurpExtenderCallbacks.TOOL_TARGET), 13 | Spider(IBurpExtenderCallbacks.TOOL_SPIDER), 14 | Scanner(IBurpExtenderCallbacks.TOOL_SCANNER), 15 | Extender(IBurpExtenderCallbacks.TOOL_EXTENDER), 16 | Session(null); 17 | 18 | @Getter 19 | private final Integer id; 20 | 21 | BurpTool(Integer id) { 22 | this.id = id; 23 | } 24 | 25 | public static BurpTool getById(int id) { 26 | return Arrays.stream(values()).filter(tool -> tool.getId() == id).findFirst().orElse(null); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpBody.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | import synfron.reshaper.burp.core.messages.Encoder; 4 | 5 | public class HttpBody extends HttpEntity { 6 | 7 | private String text; 8 | private final byte[] rawBytes; 9 | private final Encoder encoder; 10 | 11 | public HttpBody(byte[] rawBytes, Encoder encoder) { 12 | this.rawBytes = rawBytes; 13 | this.encoder = encoder; 14 | } 15 | 16 | public byte[] getValue() { 17 | return rawBytes; 18 | } 19 | 20 | public boolean hasValue() { 21 | return rawBytes.length > 0; 22 | } 23 | 24 | public String getText() { 25 | if (text == null) { 26 | text = encoder.decode(rawBytes); 27 | } 28 | return text; 29 | } 30 | 31 | @Override 32 | public boolean isChanged() { 33 | return false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThensComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.ui.components.rules.RuleOperationListComponent; 4 | import synfron.reshaper.burp.ui.components.rules.RuleOperationsComponent; 5 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 6 | import synfron.reshaper.burp.ui.models.rules.thens.ThenModel; 7 | 8 | public class ThensComponent extends RuleOperationsComponent> { 9 | public ThensComponent(RuleModel model) { 10 | super(model); 11 | } 12 | 13 | @Override 14 | protected RuleOperationListComponent> getOperationList() { 15 | ThenListComponent component = new ThenListComponent(model); 16 | component.setSelectionContainer(new ThenContainerComponent()); 17 | return component; 18 | } 19 | 20 | @Override 21 | protected String getHeaderText() { 22 | return "Thens"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhensComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.ui.components.rules.RuleOperationListComponent; 4 | import synfron.reshaper.burp.ui.components.rules.RuleOperationsComponent; 5 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 6 | import synfron.reshaper.burp.ui.models.rules.whens.WhenModel; 7 | 8 | public class WhensComponent extends RuleOperationsComponent> { 9 | public WhensComponent(RuleModel model) { 10 | super(model); 11 | } 12 | 13 | @Override 14 | protected RuleOperationListComponent> getOperationList() { 15 | WhenListComponent component = new WhenListComponent(model); 16 | component.setSelectionContainer(new WhenContainerComponent()); 17 | return component; 18 | } 19 | 20 | @Override 21 | protected String getHeaderText() { 22 | return "Whens"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenFromTool.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.BurpTool; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.rules.MatchType; 8 | import synfron.reshaper.burp.core.rules.RuleOperationType; 9 | 10 | public class WhenFromTool extends When { 11 | @Getter 12 | @Setter 13 | private BurpTool tool = BurpTool.Proxy; 14 | 15 | @Override 16 | public boolean isMatch(IEventInfo eventInfo) { 17 | boolean isMatch = eventInfo.getBurpTool() == tool; 18 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logCompare(this, null, MatchType.Equals, tool, eventInfo.getBurpTool(), isMatch); 19 | return isMatch; 20 | } 21 | 22 | @Override 23 | public RuleOperationType getType() { 24 | return WhenType.FromTool; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/CollectionChangedArgs.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class CollectionChangedArgs { 7 | private final Object source; 8 | private final CollectionChangedAction action; 9 | private final Object key; 10 | private final Object newKey; 11 | private final Object item; 12 | 13 | public CollectionChangedArgs(Object source, CollectionChangedAction action) { 14 | this(source, action, null, null, null); 15 | } 16 | 17 | public CollectionChangedArgs(Object source, CollectionChangedAction action, Object key, Object item) { 18 | this(source, action, key, key, item); 19 | } 20 | 21 | public CollectionChangedArgs(Object source, CollectionChangedAction action, Object key, Object newKey, Object item) { 22 | this.source = source; 23 | this.action = action; 24 | this.key = key; 25 | this.newKey = newKey; 26 | this.item = item; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/Window.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package synfron.reshaper.burp.ui; 7 | 8 | import synfron.reshaper.burp.ui.components.ReshaperComponent; 9 | 10 | import javax.swing.*; 11 | import java.awt.*; 12 | 13 | public class Window extends JFrame { 14 | 15 | public static void main(String[] args) { 16 | new Window().setVisible(true); 17 | } 18 | 19 | public Window() { 20 | super("Reshaper"); 21 | initComponents(); 22 | Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); 23 | setSize(dimension.width / 2, dimension.height / 2); 24 | setExtendedState(JFrame.MAXIMIZED_BOTH); 25 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 26 | } 27 | 28 | private void initComponents() { 29 | add(new ReshaperComponent()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/entities/evaluate/Operation.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens.entities.evaluate; 2 | 3 | import lombok.Getter; 4 | 5 | public enum Operation { 6 | Add("Add", 2), 7 | Subtract("Subtract", 2), 8 | Multiply("Multiply", 2), 9 | DivideBy("Divide By", 2), 10 | Increment("Increment", 1), 11 | Decrement("Decrement", 1), 12 | Mod("Mod", 2), 13 | Abs("Abs", 1), 14 | Round("Round", 1), 15 | Equals("Equals", 2), 16 | GreaterThan("Greater Than", 2), 17 | GreaterThanOrEquals("Greater Than Or Equals", 2), 18 | LessThan("Less Than", 2), 19 | LessThanOrEquals("Less Than Or Equals", 2); 20 | 21 | @Getter 22 | private final String name; 23 | @Getter 24 | private final int inputs; 25 | 26 | Operation(String name, int inputs) { 27 | this.name = name; 28 | this.inputs = inputs; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return name; 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenProxyName.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.apache.commons.lang3.StringUtils; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.rules.MatchType; 8 | import synfron.reshaper.burp.core.rules.RuleOperationType; 9 | 10 | public class WhenProxyName extends When { 11 | @Getter @Setter 12 | private String proxyName; 13 | 14 | @Override 15 | public boolean isMatch(IEventInfo eventInfo) { 16 | boolean isMatch = StringUtils.equalsIgnoreCase(eventInfo.getProxyName(), proxyName); 17 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logCompare(this, null, MatchType.Equals, proxyName, eventInfo.getProxyName(), isMatch); 18 | return isMatch; 19 | } 20 | 21 | @Override 22 | public RuleOperationType getType() { 23 | return WhenType.ProxyName; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/CaseInsensitiveString.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | import lombok.Getter; 4 | 5 | import java.io.Serializable; 6 | 7 | public class CaseInsensitiveString implements Serializable { 8 | @Getter 9 | private final String value; 10 | @Getter 11 | private final String compareValue; 12 | 13 | public CaseInsensitiveString(String value) { 14 | this.value = value; 15 | this.compareValue = value.toLowerCase(); 16 | } 17 | 18 | @Override 19 | public int hashCode() { 20 | return compareValue.hashCode(); 21 | } 22 | 23 | @Override 24 | public boolean equals(Object obj) { 25 | return obj instanceof CaseInsensitiveString ? equals((CaseInsensitiveString)obj) : value.equals(obj); 26 | } 27 | 28 | public boolean equals(CaseInsensitiveString str) { 29 | return compareValue.equals(str.getCompareValue()); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return value; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenSetEventDirection.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.DataDirection; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.rules.RuleOperationType; 8 | import synfron.reshaper.burp.core.rules.RuleResponse; 9 | 10 | public class ThenSetEventDirection extends Then { 11 | @Getter 12 | @Setter 13 | private DataDirection dataDirection = DataDirection.Request; 14 | 15 | @Override 16 | public RuleResponse perform(IEventInfo eventInfo) { 17 | eventInfo.setDataDirection(dataDirection); 18 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, false, dataDirection); 19 | return RuleResponse.Continue; 20 | } 21 | 22 | @Override 23 | public RuleOperationType getType() { 24 | return ThenType.SetEventDirection; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/ForegroundColorListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.util.function.BiFunction; 6 | 7 | public class ForegroundColorListCellRenderer extends DefaultListCellRenderer { 8 | 9 | private final BiFunction colorProvider; 10 | 11 | public ForegroundColorListCellRenderer(BiFunction colorProvider) { 12 | this.colorProvider = colorProvider; 13 | putClientProperty("html.disable", Boolean.TRUE); 14 | } 15 | 16 | @Override 17 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 18 | Component cell = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 19 | Color newColor = colorProvider.apply(value, cell.getForeground()); 20 | if (newColor != null) { 21 | cell.setForeground(newColor); 22 | } 23 | return cell; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenEventDirection.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.DataDirection; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.rules.MatchType; 8 | import synfron.reshaper.burp.core.rules.RuleOperationType; 9 | 10 | public class WhenEventDirection extends When { 11 | @Getter @Setter 12 | private DataDirection dataDirection = DataDirection.Request; 13 | 14 | @Override 15 | public boolean isMatch(IEventInfo eventInfo) { 16 | boolean isMatch = eventInfo.getDataDirection() == dataDirection; 17 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logCompare(this, null, MatchType.Equals, dataDirection, eventInfo.getDataDirection(), isMatch); 18 | return isMatch; 19 | } 20 | 21 | @Override 22 | public RuleOperationType getType() { 23 | return WhenType.EventDirection; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenDropComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenDrop; 4 | import synfron.reshaper.burp.ui.models.rules.thens.ThenDropModel; 5 | 6 | import javax.swing.*; 7 | import java.awt.event.ActionEvent; 8 | 9 | public class ThenDropComponent extends ThenComponent { 10 | private JCheckBox dropMessage; 11 | 12 | public ThenDropComponent(ThenDropModel then) { 13 | super(then); 14 | initComponent(); 15 | } 16 | 17 | private void initComponent() { 18 | dropMessage = new JCheckBox("Drop Message"); 19 | 20 | dropMessage.setSelected(model.isDropMessage()); 21 | 22 | dropMessage.addActionListener(this::onDropMessageChanged); 23 | 24 | mainContainer.add(dropMessage, "wrap"); 25 | mainContainer.add(getPaddedButton(validate)); 26 | } 27 | 28 | private void onDropMessageChanged(ActionEvent actionEvent) { 29 | model.setDropMessage(dropMessage.isSelected()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/entities/buildhttpmessage/MessageValueSetter.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens.entities.buildhttpmessage; 2 | 3 | import lombok.Data; 4 | import synfron.reshaper.burp.core.messages.DataDirection; 5 | import synfron.reshaper.burp.core.messages.MessageValue; 6 | import synfron.reshaper.burp.core.utils.GetItemPlacement; 7 | import synfron.reshaper.burp.core.utils.SetItemPlacement; 8 | import synfron.reshaper.burp.core.vars.VariableString; 9 | 10 | import java.io.Serializable; 11 | 12 | @Data 13 | public class MessageValueSetter implements Serializable { 14 | private MessageValue destinationMessageValue; 15 | private VariableString destinationIdentifier; 16 | private SetItemPlacement destinationIdentifierPlacement = SetItemPlacement.Only; 17 | private VariableString sourceText; 18 | 19 | public MessageValueSetter() {} 20 | 21 | public MessageValueSetter(DataDirection dataDirection) { 22 | destinationMessageValue = dataDirection == DataDirection.Request ? MessageValue.HttpRequestBody : MessageValue.HttpResponseBody; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/IItemPlacement.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | public interface IItemPlacement { 4 | 5 | static DeleteItemPlacement toDelete(SetItemPlacement itemPlacement) { 6 | return switch (itemPlacement) { 7 | case First -> DeleteItemPlacement.First; 8 | case Last -> DeleteItemPlacement.Last; 9 | case All -> DeleteItemPlacement.All; 10 | default -> null; 11 | }; 12 | } 13 | 14 | static GetItemPlacement toGet(SetItemPlacement itemPlacement) { 15 | return switch (itemPlacement) { 16 | case First -> GetItemPlacement.First; 17 | case Last, Only, All, New -> GetItemPlacement.Last; 18 | default -> null; 19 | }; 20 | } 21 | 22 | static SetItemPlacement toSet(DeleteItemPlacement itemPlacement) { 23 | return switch (itemPlacement) { 24 | case First -> SetItemPlacement.First; 25 | case Last -> SetItemPlacement.Last; 26 | case All -> SetItemPlacement.All; 27 | default -> null; 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Daquanne Dwight 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/entities/script/ConsoleObj.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens.entities.script; 2 | 3 | import org.mozilla.javascript.ScriptableObject; 4 | import synfron.reshaper.burp.core.utils.Log; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.Objects; 9 | import java.util.stream.Collectors; 10 | 11 | public class ConsoleObj { 12 | public void log(Object... args) { 13 | List values = getConsoleWritable(args); 14 | Log.get().withMessage("Script Log").withPayload(values.size() == 1 ? values.get(0) : values).log(); 15 | } 16 | 17 | public void error(Object... args) { 18 | List values = getConsoleWritable(args); 19 | Log.get().withMessage("Script Log").withPayload(values.size() == 1 ? values.get(0) : values).logErr(); 20 | } 21 | 22 | private List getConsoleWritable(Object[] values) { 23 | return Arrays.stream(values) 24 | .map(value -> value instanceof ScriptableObject ? Objects.toString(value) : value) 25 | .collect(Collectors.toList()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/DocumentActionListener.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import javax.swing.event.DocumentEvent; 4 | import javax.swing.event.DocumentListener; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | 8 | public class DocumentActionListener implements DocumentListener { 9 | private final ActionListener actionListener; 10 | 11 | public DocumentActionListener(ActionListener actionListener) { 12 | this.actionListener = actionListener; 13 | } 14 | 15 | @Override 16 | public void insertUpdate(DocumentEvent e) { 17 | actionListener.actionPerformed(new ActionEvent(e.getDocument(), ActionEvent.ACTION_PERFORMED, null)); 18 | } 19 | 20 | @Override 21 | public void removeUpdate(DocumentEvent e) { 22 | actionListener.actionPerformed(new ActionEvent(e.getDocument(), ActionEvent.ACTION_PERFORMED, null)); 23 | } 24 | 25 | @Override 26 | public void changedUpdate(DocumentEvent e) { 27 | actionListener.actionPerformed(new ActionEvent(e.getDocument(), ActionEvent.ACTION_PERFORMED, null)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenLogComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenLog; 4 | import synfron.reshaper.burp.ui.models.rules.thens.ThenLogModel; 5 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class ThenLogComponent extends ThenComponent { 11 | private JTextField text; 12 | 13 | public ThenLogComponent(ThenLogModel then) { 14 | super(then); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | text = createTextField(true); 20 | 21 | text.setText(model.getText()); 22 | 23 | text.getDocument().addDocumentListener(new DocumentActionListener(this::onTextChanged)); 24 | 25 | mainContainer.add(getLabeledField("Text *", text), "wrap"); 26 | mainContainer.add(getPaddedButton(validate)); 27 | } 28 | 29 | private void onTextChanged(ActionEvent actionEvent) { 30 | model.setText(text.getText()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenComment.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | import synfron.reshaper.burp.core.vars.VariableString; 9 | 10 | public class ThenComment extends Then { 11 | 12 | @Getter @Setter 13 | private VariableString text; 14 | 15 | @Override 16 | public RuleResponse perform(IEventInfo eventInfo) { 17 | boolean hasError = true; 18 | try { 19 | eventInfo.getRequestResponse().setComment(text.getText(eventInfo)); 20 | hasError = false; 21 | } finally { 22 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, hasError, VariableString.getTextOrDefault(eventInfo, text, null)); 23 | } 24 | return RuleResponse.Continue; 25 | } 26 | 27 | @Override 28 | public RuleOperationType getType() { 29 | return ThenType.Comment; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenCommentComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenComment; 4 | import synfron.reshaper.burp.ui.models.rules.thens.ThenCommentModel; 5 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class ThenCommentComponent extends ThenComponent { 11 | private JTextField text; 12 | 13 | public ThenCommentComponent(ThenCommentModel then) { 14 | super(then); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | text = createTextField(true); 20 | 21 | text.setText(model.getText()); 22 | 23 | text.getDocument().addDocumentListener(new DocumentActionListener(this::onTextChanged)); 24 | 25 | mainContainer.add(getLabeledField("Text *", text), "wrap"); 26 | mainContainer.add(getPaddedButton(validate)); 27 | } 28 | 29 | private void onTextChanged(ActionEvent actionEvent) { 30 | model.setText(text.getText()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenMimeType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.DataDirection; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.messages.MimeType; 8 | import synfron.reshaper.burp.core.rules.MatchType; 9 | import synfron.reshaper.burp.core.rules.RuleOperationType; 10 | 11 | public class WhenMimeType extends When { 12 | @Getter @Setter 13 | private MimeType mimeType = MimeType.Html; 14 | 15 | @Override 16 | public boolean isMatch(IEventInfo eventInfo) { 17 | MimeType eventMimeType = eventInfo.getHttpResponseMessage().getMimeType(); 18 | boolean isMatch = eventMimeType != null && this.mimeType.hasFlags(eventMimeType); 19 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logCompare(this, null, MatchType.Contains, mimeType, eventMimeType, isMatch); 20 | return isMatch; 21 | } 22 | 23 | @Override 24 | public RuleOperationType getType() { 25 | return WhenType.MimeType; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenDelayComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenDelay; 4 | import synfron.reshaper.burp.ui.models.rules.thens.ThenDelayModel; 5 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class ThenDelayComponent extends ThenComponent { 11 | private JTextField delay; 12 | 13 | public ThenDelayComponent(ThenDelayModel then) { 14 | super(then); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | delay = createTextField(true); 20 | 21 | delay.setText(model.getDelay()); 22 | 23 | delay.getDocument().addDocumentListener(new DocumentActionListener(this::onDelayChanged)); 24 | 25 | mainContainer.add(getLabeledField("Delay (milliseconds) *", delay), "wrap"); 26 | mainContainer.add(getPaddedButton(validate)); 27 | } 28 | 29 | private void onDelayChanged(ActionEvent actionEvent) { 30 | model.setDelay(delay.getText()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenLog.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | import synfron.reshaper.burp.core.utils.Log; 9 | import synfron.reshaper.burp.core.vars.VariableString; 10 | 11 | public class ThenLog extends Then { 12 | @Getter 13 | @Setter 14 | private VariableString text; 15 | 16 | @Override 17 | public RuleResponse perform(IEventInfo eventInfo) { 18 | boolean hasError = true; 19 | try { 20 | Log.get().withMessage(text.getText(eventInfo)).log(); 21 | hasError = false; 22 | } finally { 23 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, hasError, VariableString.getTextOrDefault(eventInfo, text, null)); 24 | } 25 | return RuleResponse.Continue; 26 | } 27 | 28 | @Override 29 | public RuleOperationType getType() { 30 | return ThenType.Log; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/LogsComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components; 2 | 3 | import burp.BurpExtender; 4 | import burp.ITextEditor; 5 | 6 | import javax.swing.*; 7 | import java.awt.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class LogsComponent extends JPanel { 11 | 12 | private final ITextEditor textEditor = BurpExtender.getLogTextEditor(); 13 | 14 | public LogsComponent() { 15 | initComponents(); 16 | } 17 | 18 | private void initComponents() { 19 | setLayout(new BorderLayout()); 20 | if (textEditor != null) { 21 | add(textEditor.getComponent(), BorderLayout.CENTER); 22 | add(getActionBar(), BorderLayout.PAGE_END); 23 | } 24 | } 25 | 26 | private Component getActionBar() { 27 | JPanel actionBar = new JPanel(new FlowLayout(FlowLayout.LEFT)); 28 | 29 | JButton clear = new JButton("Clear"); 30 | 31 | clear.addActionListener(this::onClear); 32 | 33 | actionBar.add(clear); 34 | return actionBar; 35 | } 36 | 37 | private void onClear(ActionEvent actionEvent) { 38 | textEditor.setText(new byte[0]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenHighlightComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenHighlight; 4 | import synfron.reshaper.burp.ui.models.rules.thens.ThenHighlightModel; 5 | 6 | import javax.swing.*; 7 | import java.awt.event.ActionEvent; 8 | 9 | public class ThenHighlightComponent extends ThenComponent { 10 | private JComboBox color; 11 | 12 | public ThenHighlightComponent(ThenHighlightModel then) { 13 | super(then); 14 | initComponent(); 15 | } 16 | 17 | private void initComponent() { 18 | color = createComboBox(ThenHighlight.HighlightColor.values()); 19 | 20 | color.setSelectedItem(model.getColor()); 21 | 22 | color.addActionListener(this::onColorChanged); 23 | 24 | mainContainer.add(getLabeledField("Color", color), "wrap"); 25 | mainContainer.add(getPaddedButton(validate)); 26 | } 27 | 28 | private void onColorChanged(ActionEvent actionEvent) { 29 | model.setColor((ThenHighlight.HighlightColor) color.getSelectedItem()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenContentType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.ContentType; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.messages.ContentType; 8 | import synfron.reshaper.burp.core.rules.MatchType; 9 | import synfron.reshaper.burp.core.rules.RuleOperationType; 10 | 11 | public class WhenContentType extends When { 12 | @Getter @Setter 13 | private ContentType contentType = ContentType.Json; 14 | 15 | @Override 16 | public boolean isMatch(IEventInfo eventInfo) { 17 | ContentType eventContentType = eventInfo.getHttpRequestMessage().getContentType(); 18 | boolean isMatch = eventContentType != null && this.contentType.hasFlags(eventContentType); 19 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logCompare(this, null, MatchType.Contains, contentType, eventContentType, isMatch); 20 | return isMatch; 21 | } 22 | 23 | @Override 24 | public RuleOperationType getType() { 25 | return WhenType.ContentType; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenInScope.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import burp.BurpExtender; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.rules.RuleOperationType; 8 | import synfron.reshaper.burp.core.vars.VariableString; 9 | 10 | import java.net.MalformedURLException; 11 | import java.net.URL; 12 | 13 | public class WhenInScope extends When { 14 | 15 | 16 | @Getter 17 | @Setter 18 | private VariableString url; 19 | 20 | @Override 21 | public boolean isMatch(IEventInfo eventInfo) { 22 | boolean isMatch = false; 23 | String url = VariableString.getTextOrDefault(eventInfo, this.url, eventInfo.getUrl()); 24 | try { 25 | isMatch = BurpExtender.getCallbacks().isInScope(new URL(url)); 26 | } catch (Exception ignored) { 27 | } 28 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, isMatch, url); 29 | return isMatch; 30 | } 31 | 32 | @Override 33 | public RuleOperationType getType() { 34 | return WhenType.InScope; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/entities/parsehttpmessage/MessageValueGetter.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens.entities.parsehttpmessage; 2 | 3 | import lombok.Data; 4 | import synfron.reshaper.burp.core.messages.DataDirection; 5 | import synfron.reshaper.burp.core.messages.MessageValue; 6 | import synfron.reshaper.burp.core.utils.GetItemPlacement; 7 | import synfron.reshaper.burp.core.utils.SetItemPlacement; 8 | import synfron.reshaper.burp.core.vars.VariableSource; 9 | import synfron.reshaper.burp.core.vars.VariableString; 10 | 11 | import java.io.Serializable; 12 | 13 | @Data 14 | public class MessageValueGetter implements Serializable { 15 | private MessageValue sourceMessageValue; 16 | private VariableString sourceIdentifier; 17 | private GetItemPlacement sourceIdentifierPlacement = GetItemPlacement.Last; 18 | private VariableSource destinationVariableSource = VariableSource.Global; 19 | private VariableString destinationVariableName; 20 | 21 | public MessageValueGetter() {} 22 | 23 | public MessageValueGetter(DataDirection dataDirection) { 24 | sourceMessageValue = dataDirection == DataDirection.Request ? MessageValue.HttpRequestBody : MessageValue.HttpResponseBody; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/utils/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.utils; 2 | 3 | import synfron.reshaper.burp.core.exceptions.WrappedException; 4 | 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.net.MalformedURLException; 7 | import java.net.URL; 8 | import java.util.Objects; 9 | import java.util.stream.Stream; 10 | 11 | public class ObjectUtils { 12 | public static Object construct(Class clazz, Object... args) { 13 | try { 14 | return clazz.getDeclaredConstructor( 15 | Stream.of(args).map(Object::getClass).toArray(Class[]::new) 16 | ).newInstance(args); 17 | } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { 18 | throw new WrappedException(e); 19 | } 20 | } 21 | 22 | public static URL getUrl(String protocol, String host, int port, String path) throws MalformedURLException { 23 | return new URL( 24 | protocol, 25 | host, 26 | (Objects.equals(protocol, "http") && port == 80) || (Objects.equals(protocol, "https") && port == 443) ? -1 : port, 27 | path 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenInScopeComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.rules.whens.WhenInScope; 4 | import synfron.reshaper.burp.ui.models.rules.whens.WhenInScopeModel; 5 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class WhenInScopeComponent extends WhenComponent { 11 | private JTextField url; 12 | 13 | public WhenInScopeComponent(WhenInScopeModel when) { 14 | super(when); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | url = createTextField(true); 20 | 21 | url.setText(model.getUrl()); 22 | 23 | url.getDocument().addDocumentListener(new DocumentActionListener(this::onUrlChanged)); 24 | 25 | mainContainer.add(getLabeledField("URL", url), "wrap"); 26 | getDefaultComponents().forEach(component -> mainContainer.add(component, "wrap")); 27 | mainContainer.add(getPaddedButton(validate)); 28 | } 29 | 30 | private void onUrlChanged(ActionEvent actionEvent) { 31 | model.setUrl(url.getText()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenFromToolComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.BurpTool; 4 | import synfron.reshaper.burp.core.rules.whens.WhenFromTool; 5 | import synfron.reshaper.burp.ui.models.rules.whens.WhenFromToolModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class WhenFromToolComponent extends WhenComponent { 11 | private JComboBox tool; 12 | 13 | public WhenFromToolComponent(WhenFromToolModel when) { 14 | super(when); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | tool = createComboBox(BurpTool.values()); 20 | 21 | tool.setSelectedItem(model.getTool()); 22 | 23 | tool.addActionListener(this::onToolChanged); 24 | 25 | mainContainer.add(getLabeledField("Tool", tool), "wrap"); 26 | getDefaultComponents().forEach(component -> mainContainer.add(component, "wrap")); 27 | mainContainer.add(getPaddedButton(validate)); 28 | } 29 | 30 | private void onToolChanged(ActionEvent actionEvent) { 31 | model.setTool((BurpTool)tool.getSelectedItem()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenSetEncodingComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.messages.Encoder; 4 | import synfron.reshaper.burp.core.rules.thens.ThenSetEncoding; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenSetEncodingModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class ThenSetEncodingComponent extends ThenComponent { 11 | private JComboBox encoding; 12 | 13 | public ThenSetEncodingComponent(ThenSetEncodingModel then) { 14 | super(then); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | encoding = createComboBox(Encoder.getEncodings().toArray(new String[0])); 20 | 21 | encoding.setSelectedItem(model.getEncoding()); 22 | 23 | encoding.addActionListener(this::onEncodingChanged); 24 | 25 | mainContainer.add(getLabeledField("Encoding", encoding), "wrap"); 26 | mainContainer.add(getPaddedButton(validate)); 27 | } 28 | 29 | private void onEncodingChanged(ActionEvent actionEvent) { 30 | model.setEncoding((String) encoding.getSelectedItem()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/RuleOperationContainerComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules; 2 | 3 | import synfron.reshaper.burp.core.utils.ObjectUtils; 4 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModel; 5 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | import java.util.Map; 10 | 11 | public abstract class RuleOperationContainerComponent extends JPanel { 12 | 13 | public RuleOperationContainerComponent() { 14 | initComponent(); 15 | } 16 | 17 | private void initComponent() { 18 | setLayout(new BorderLayout()); 19 | } 20 | 21 | public void setModel(RuleOperationModel model) { 22 | removeAll(); 23 | if (model != null) { 24 | add(getComponent(model)); 25 | } 26 | revalidate(); 27 | repaint(); 28 | } 29 | 30 | private Component getComponent(RuleOperationModel model) { 31 | Class componentClass = getComponentMap().get(model.getType()); 32 | return (Component)ObjectUtils.construct(componentClass, model); 33 | } 34 | 35 | protected abstract Map, Class> getComponentMap(); 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenBreakComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.RuleResponse; 4 | import synfron.reshaper.burp.core.rules.thens.ThenBreak; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenBreakModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class ThenBreakComponent extends ThenComponent { 11 | private JComboBox breakType; 12 | 13 | public ThenBreakComponent(ThenBreakModel then) { 14 | super(then); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | breakType = createComboBox(RuleResponse.getValues().stream().skip(1).toArray(RuleResponse[]::new)); 20 | 21 | breakType.setSelectedItem(model.getBreakType()); 22 | 23 | breakType.addActionListener(this::onBreakTypeChanged); 24 | 25 | mainContainer.add(getLabeledField("Break Type", breakType), "wrap"); 26 | mainContainer.add(getPaddedButton(validate)); 27 | } 28 | 29 | private void onBreakTypeChanged(ActionEvent actionEvent) { 30 | model.setBreakType((RuleResponse)breakType.getSelectedItem()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/VariableCreatorRegistry.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.vars.VariableSourceEntry; 4 | 5 | import java.lang.ref.WeakReference; 6 | import java.util.ArrayList; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | public class VariableCreatorRegistry { 11 | 12 | private static final List> creators = new ArrayList<>(); 13 | 14 | public static synchronized void register(IVariableCreator variableCreator) { 15 | creators.add(new WeakReference<>(variableCreator)); 16 | } 17 | 18 | public static synchronized List getVariableEntries() { 19 | List entries = new ArrayList<>(creators.size() + 5); 20 | Iterator> iterator = creators.iterator(); 21 | while (iterator.hasNext()) { 22 | WeakReference listenerReference = iterator.next(); 23 | if (listenerReference.get() != null) { 24 | entries.addAll(listenerReference.get().getVariableEntries()); 25 | } else { 26 | iterator.remove(); 27 | } 28 | } 29 | return entries; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenSetEncoding.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import burp.BurpExtender; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import synfron.reshaper.burp.core.messages.IEventInfo; 7 | import synfron.reshaper.burp.core.rules.RuleOperationType; 8 | import synfron.reshaper.burp.core.rules.RuleResponse; 9 | import synfron.reshaper.burp.core.vars.VariableString; 10 | 11 | public class ThenSetEncoding extends Then { 12 | @Getter 13 | @Setter 14 | private VariableString encoding; 15 | 16 | @Override 17 | public RuleResponse perform(IEventInfo eventInfo) { 18 | boolean hasError = false; 19 | String encodingValue = encoding.getText(eventInfo); 20 | try { 21 | eventInfo.getEncoder().setEncoding(encodingValue, false); 22 | } catch (Exception e) { 23 | hasError = true; 24 | throw e; 25 | } finally { 26 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, hasError, encodingValue); 27 | } 28 | return RuleResponse.Continue; 29 | } 30 | 31 | @Override 32 | public RuleOperationType getType() { 33 | return ThenType.SetEncoding; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenProxyNameComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.rules.whens.WhenProxyName; 4 | import synfron.reshaper.burp.ui.models.rules.whens.WhenProxyNameModel; 5 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class WhenProxyNameComponent extends WhenComponent { 11 | private JTextField proxyName; 12 | 13 | public WhenProxyNameComponent(WhenProxyNameModel when) { 14 | super(when); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | proxyName = createTextField(false); 20 | 21 | proxyName.setText(model.getProxyName()); 22 | 23 | proxyName.getDocument().addDocumentListener(new DocumentActionListener(this::onProxyNameChanged)); 24 | 25 | mainContainer.add(getLabeledField("Proxy Name *", proxyName), "wrap"); 26 | getDefaultComponents().forEach(component -> mainContainer.add(component, "wrap")); 27 | mainContainer.add(getPaddedButton(validate)); 28 | } 29 | 30 | private void onProxyNameChanged(ActionEvent actionEvent) { 31 | model.setProxyName(proxyName.getText()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenFromToolModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.BurpTool; 5 | import synfron.reshaper.burp.core.rules.whens.WhenFromTool; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | public class WhenFromToolModel extends WhenModel { 9 | 10 | @Getter 11 | private BurpTool tool; 12 | 13 | public WhenFromToolModel(WhenFromTool when, Boolean isNew) { 14 | super(when, isNew); 15 | tool = when.getTool(); 16 | } 17 | 18 | public void setTool(BurpTool tool) { 19 | this.tool = tool; 20 | propertyChanged("tool", tool); 21 | } 22 | 23 | public boolean persist() { 24 | if (validate().size() != 0) { 25 | return false; 26 | } 27 | ruleOperation.setTool(tool); 28 | return super.persist(); 29 | } 30 | 31 | @Override 32 | public boolean record() { 33 | if (validate().size() != 0) { 34 | return false; 35 | } 36 | setValidated(true); 37 | return true; 38 | } 39 | 40 | @Override 41 | public RuleOperationModelType getType() { 42 | return WhenModelType.FromTool; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenDropModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.rules.thens.ThenDrop; 5 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 6 | 7 | public class ThenDropModel extends ThenModel { 8 | 9 | @Getter 10 | private boolean dropMessage; 11 | 12 | public ThenDropModel(ThenDrop then, Boolean isNew) { 13 | super(then, isNew); 14 | dropMessage = then.isDropMessage(); 15 | } 16 | 17 | public void setDropMessage(boolean dropMessage) { 18 | this.dropMessage = dropMessage; 19 | propertyChanged("dropMessage", dropMessage); 20 | } 21 | 22 | public boolean persist() { 23 | if (validate().size() != 0) { 24 | return false; 25 | } 26 | ruleOperation.setDropMessage(dropMessage); 27 | setValidated(true); 28 | return true; 29 | } 30 | 31 | @Override 32 | public boolean record() { 33 | if (validate().size() != 0) { 34 | return false; 35 | } 36 | setValidated(true); 37 | return true; 38 | } 39 | 40 | @Override 41 | public RuleOperationModelType getType() { 42 | return ThenModelType.Drop; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenSetEventDirectionComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.messages.DataDirection; 4 | import synfron.reshaper.burp.core.rules.thens.ThenSetEventDirection; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenSetEventDirectionModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class ThenSetEventDirectionComponent extends ThenComponent { 11 | private JComboBox dataDirection; 12 | 13 | public ThenSetEventDirectionComponent(ThenSetEventDirectionModel then) { 14 | super(then); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | dataDirection = createComboBox(DataDirection.values()); 20 | 21 | dataDirection.setSelectedItem(model.getDataDirection()); 22 | 23 | dataDirection.addActionListener(this::onSetEventDirectionChanged); 24 | 25 | mainContainer.add(getLabeledField("Event Direction", dataDirection), "wrap"); 26 | mainContainer.add(getPaddedButton(validate)); 27 | } 28 | 29 | private void onSetEventDirectionChanged(ActionEvent actionEvent) { 30 | model.setDataDirection((DataDirection) dataDirection.getSelectedItem()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/diagnostics/IDiagnostics.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.diagnostics; 2 | 3 | import org.apache.commons.lang3.tuple.Pair; 4 | import synfron.reshaper.burp.core.messages.IEventInfo; 5 | import synfron.reshaper.burp.core.rules.MatchType; 6 | import synfron.reshaper.burp.core.rules.Rule; 7 | import synfron.reshaper.burp.core.rules.thens.Then; 8 | import synfron.reshaper.burp.core.rules.whens.When; 9 | 10 | import java.io.Serializable; 11 | import java.util.List; 12 | 13 | public interface IDiagnostics { 14 | void logCompare(When when, List> properties, MatchType matchType, Object matcher, Object value, boolean result); 15 | 16 | void logHas(When when, Object value, Object subValue, boolean result); 17 | 18 | void logValue(When when, boolean result, Object... values); 19 | 20 | void logValue(Then then, boolean hasError, Object... values); 21 | 22 | void logProperties(Then then, boolean hasError, List> properties); 23 | 24 | void logStart(Rule rule); 25 | 26 | void logEnd(Rule rule); 27 | 28 | void logStart(IEventInfo eventInfo); 29 | 30 | void logEnd(IEventInfo eventInfo); 31 | 32 | String getLogs(); 33 | 34 | boolean isEnabled(); 35 | 36 | void setEnabled(boolean enabled); 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenHighlightModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.rules.thens.ThenHighlight; 5 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 6 | 7 | public class ThenHighlightModel extends ThenModel { 8 | 9 | @Getter 10 | private ThenHighlight.HighlightColor color; 11 | 12 | public ThenHighlightModel(ThenHighlight then, Boolean isNew) { 13 | super(then, isNew); 14 | color = then.getColor(); 15 | } 16 | 17 | public void setColor(ThenHighlight.HighlightColor color) { 18 | this.color = color; 19 | propertyChanged("color", color); 20 | } 21 | 22 | public boolean persist() { 23 | if (validate().size() != 0) { 24 | return false; 25 | } 26 | ruleOperation.setColor(color); 27 | setValidated(true); 28 | return true; 29 | } 30 | 31 | @Override 32 | public boolean record() { 33 | if (validate().size() != 0) { 34 | return false; 35 | } 36 | setValidated(true); 37 | return true; 38 | } 39 | 40 | @Override 41 | public RuleOperationModelType getType() { 42 | return ThenModelType.Highlight; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/wizard/vars/EventVariableTagWizardComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.wizard.vars; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | import synfron.reshaper.burp.ui.components.IFormComponent; 5 | import synfron.reshaper.burp.ui.models.rules.wizard.vars.EventVariableTagWizardModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class EventVariableTagWizardComponent extends JPanel implements IFormComponent { 11 | private final EventVariableTagWizardModel model; 12 | private JComboBox variableName; 13 | 14 | public EventVariableTagWizardComponent(EventVariableTagWizardModel model) { 15 | this.model = model; 16 | initComponent(); 17 | } 18 | 19 | private void initComponent() { 20 | setLayout(new MigLayout()); 21 | 22 | variableName = createComboBox(model.getVariableNames().toArray(new String[0]), true); 23 | 24 | variableName.setSelectedItem(model.getVariableNames().stream().findFirst().orElse("")); 25 | 26 | variableName.addActionListener(this::onVariableNameChanged); 27 | 28 | add(getLabeledField("Variable Name *", variableName)); 29 | } 30 | 31 | private void onVariableNameChanged(ActionEvent actionEvent) { 32 | model.setVariableName((String)variableName.getSelectedItem()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/wizard/vars/GlobalVariableTagWizardComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.wizard.vars; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | import synfron.reshaper.burp.ui.components.IFormComponent; 5 | import synfron.reshaper.burp.ui.models.rules.wizard.vars.GlobalVariableTagWizardModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class GlobalVariableTagWizardComponent extends JPanel implements IFormComponent { 11 | private final GlobalVariableTagWizardModel model; 12 | private JComboBox variableName; 13 | 14 | public GlobalVariableTagWizardComponent(GlobalVariableTagWizardModel model) { 15 | this.model = model; 16 | initComponent(); 17 | } 18 | 19 | private void initComponent() { 20 | setLayout(new MigLayout()); 21 | 22 | variableName = createComboBox(model.getVariableNames().toArray(new String[0]), true); 23 | 24 | variableName.setSelectedItem(model.getVariableNames().stream().findFirst().orElse("")); 25 | 26 | variableName.addActionListener(this::onVariableNameChanged); 27 | 28 | add(getLabeledField("Variable Name *", variableName)); 29 | } 30 | 31 | private void onVariableNameChanged(ActionEvent actionEvent) { 32 | model.setVariableName((String)variableName.getSelectedItem()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenMimeTypeModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.messages.MimeType; 5 | import synfron.reshaper.burp.core.rules.whens.WhenMimeType; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | public class WhenMimeTypeModel extends WhenModel { 9 | 10 | @Getter 11 | private MimeType mimeType; 12 | 13 | public WhenMimeTypeModel(WhenMimeType when, Boolean isNew) { 14 | super(when, isNew); 15 | mimeType = when.getMimeType(); 16 | } 17 | 18 | public void setMimeType(MimeType mimeType) { 19 | this.mimeType = mimeType; 20 | propertyChanged("mimeType", mimeType); 21 | } 22 | 23 | public boolean persist() { 24 | if (validate().size() != 0) { 25 | return false; 26 | } 27 | ruleOperation.setMimeType(mimeType); 28 | return super.persist(); 29 | } 30 | 31 | @Override 32 | public boolean record() { 33 | if (validate().size() != 0) { 34 | return false; 35 | } 36 | setValidated(true); 37 | return true; 38 | } 39 | 40 | @Override 41 | public RuleOperationModelType getType() { 42 | return WhenModelType.MimeType; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenBreakModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.rules.RuleResponse; 5 | import synfron.reshaper.burp.core.rules.thens.ThenBreak; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | public class ThenBreakModel extends ThenModel { 9 | 10 | @Getter 11 | private RuleResponse breakType; 12 | 13 | public ThenBreakModel(ThenBreak then, Boolean isNew) { 14 | super(then, isNew); 15 | breakType = then.getBreakType(); 16 | } 17 | 18 | public void setBreakType(RuleResponse breakType) { 19 | this.breakType = breakType; 20 | propertyChanged("breakType", breakType); 21 | } 22 | 23 | public boolean persist() { 24 | if (validate().size() != 0) { 25 | return false; 26 | } 27 | ruleOperation.setBreakType(breakType); 28 | setValidated(true); 29 | return true; 30 | } 31 | 32 | @Override 33 | public boolean record() { 34 | if (validate().size() != 0) { 35 | return false; 36 | } 37 | setValidated(true); 38 | return true; 39 | } 40 | 41 | @Override 42 | public RuleOperationModelType getType() { 43 | return ThenModelType.Break; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenEventDirectionComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.messages.DataDirection; 4 | import synfron.reshaper.burp.core.rules.whens.WhenEventDirection; 5 | import synfron.reshaper.burp.ui.models.rules.whens.WhenEventDirectionModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | public class WhenEventDirectionComponent extends WhenComponent { 11 | private JComboBox dataDirection; 12 | 13 | public WhenEventDirectionComponent(WhenEventDirectionModel when) { 14 | super(when); 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | dataDirection = createComboBox(DataDirection.values()); 20 | 21 | dataDirection.setSelectedItem(model.getDataDirection()); 22 | 23 | dataDirection.addActionListener(this::onDataDirectionChanged); 24 | 25 | mainContainer.add(getLabeledField("Event Direction", dataDirection), "wrap"); 26 | getDefaultComponents().forEach(component -> mainContainer.add(component, "wrap")); 27 | mainContainer.add(getPaddedButton(validate)); 28 | } 29 | 30 | private void onDataDirectionChanged(ActionEvent actionEvent) { 31 | model.setDataDirection((DataDirection)dataDirection.getSelectedItem()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/When.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes; 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import synfron.reshaper.burp.core.messages.IEventInfo; 8 | import synfron.reshaper.burp.core.messages.MimeType; 9 | import synfron.reshaper.burp.core.rules.IRuleOperation; 10 | import synfron.reshaper.burp.core.utils.Serializer; 11 | 12 | @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, property = "@class") 13 | @JsonSubTypes({ 14 | @JsonSubTypes.Type(value = WhenEventDirection.class), 15 | @JsonSubTypes.Type(value = WhenHasEntity.class), 16 | @JsonSubTypes.Type(value = WhenMatchesText.class), 17 | @JsonSubTypes.Type(value = WhenContentType.class), 18 | @JsonSubTypes.Type(value = WhenMimeType.class), 19 | @JsonSubTypes.Type(value = WhenProxyName.class), 20 | @JsonSubTypes.Type(value = WhenInScope.class) 21 | }) 22 | public abstract class When> implements IRuleOperation { 23 | 24 | @Getter @Setter 25 | private boolean negate; 26 | 27 | @Getter @Setter 28 | private boolean useOrCondition; 29 | 30 | public abstract boolean isMatch(IEventInfo eventInfo); 31 | 32 | @SuppressWarnings("unchecked") 33 | public T copy() { 34 | return (T) Serializer.copy(this); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenContentTypeModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.messages.ContentType; 5 | import synfron.reshaper.burp.core.rules.whens.WhenContentType; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | public class WhenContentTypeModel extends WhenModel { 9 | 10 | @Getter 11 | private ContentType contentType; 12 | 13 | public WhenContentTypeModel(WhenContentType when, Boolean isNew) { 14 | super(when, isNew); 15 | contentType = when.getContentType(); 16 | } 17 | 18 | public void setContentType(ContentType contentType) { 19 | this.contentType = contentType; 20 | propertyChanged("contentType", contentType); 21 | } 22 | 23 | public boolean persist() { 24 | if (validate().size() != 0) { 25 | return false; 26 | } 27 | ruleOperation.setContentType(contentType); 28 | return super.persist(); 29 | } 30 | 31 | @Override 32 | public boolean record() { 33 | if (validate().size() != 0) { 34 | return false; 35 | } 36 | setValidated(true); 37 | return true; 38 | } 39 | 40 | @Override 41 | public RuleOperationModelType getType() { 42 | return WhenModelType.ContentType; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/RuleOperationsContainerComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules; 2 | 3 | import synfron.reshaper.burp.ui.components.rules.thens.ThensComponent; 4 | import synfron.reshaper.burp.ui.components.rules.whens.WhensComponent; 5 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | 10 | public class RuleOperationsContainerComponent extends JPanel { 11 | private final RuleModel model; 12 | 13 | public RuleOperationsContainerComponent(RuleModel model) { 14 | this.model = model; 15 | initComponent(); 16 | } 17 | 18 | private void initComponent() { 19 | setLayout(new GridLayout(1, 2)); 20 | 21 | add(getWhens()); 22 | add(getThens()); 23 | } 24 | 25 | private Component getWhens() { 26 | JPanel container = new JPanel(new BorderLayout()); 27 | container.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); 28 | 29 | WhensComponent whens = new WhensComponent(model); 30 | 31 | container.add(whens); 32 | return container; 33 | } 34 | 35 | private Component getThens() { 36 | JPanel container = new JPanel(new BorderLayout()); 37 | container.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); 38 | 39 | ThensComponent thens = new ThensComponent(model); 40 | 41 | container.add(thens); 42 | return container; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/vars/Variable.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.vars; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.events.IEventListener; 5 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 6 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 7 | import synfron.reshaper.burp.core.utils.TextUtils; 8 | 9 | public class Variable { 10 | @Getter 11 | private final transient PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 12 | @Getter 13 | private boolean persistent; 14 | 15 | @Getter 16 | private Object value; 17 | 18 | @Getter 19 | private final String name; 20 | 21 | private Variable() { 22 | this(null); 23 | } 24 | 25 | public Variable(String name) { 26 | this.name = name; 27 | } 28 | 29 | public Variable withListener(IEventListener listener) { 30 | propertyChangedEvent.add(listener); 31 | return this; 32 | } 33 | 34 | public void setValue(Object value) { 35 | this.value = value; 36 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, "value", value)); 37 | } 38 | 39 | public void setPersistent(boolean persistent) { 40 | this.persistent = persistent; 41 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, "persistent", persistent)); 42 | } 43 | 44 | public String toString() { 45 | return TextUtils.toString(name); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/ReshaperComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package synfron.reshaper.burp.ui.components; 7 | 8 | import burp.ITab; 9 | import synfron.reshaper.burp.ui.components.rules.RulesTabComponent; 10 | import synfron.reshaper.burp.ui.components.settings.SettingsTabComponent; 11 | import synfron.reshaper.burp.ui.components.vars.VariablesTabComponent; 12 | 13 | import javax.swing.*; 14 | import java.awt.*; 15 | 16 | public class ReshaperComponent extends JPanel implements ITab { 17 | 18 | public ReshaperComponent() { 19 | initComponents(); 20 | } 21 | 22 | private void initComponents() { 23 | setLayout(new BorderLayout()); 24 | add(getTabs()); 25 | } 26 | 27 | private JTabbedPane getTabs() { 28 | JTabbedPane tabs = new JTabbedPane(); 29 | 30 | tabs.addTab("Rules", new RulesTabComponent()); 31 | tabs.addTab("Global Variables", new VariablesTabComponent()); 32 | tabs.addTab("Logs", new LogsComponent()); 33 | tabs.addTab("Settings", new SettingsTabComponent()); 34 | return tabs; 35 | } 36 | 37 | @Override 38 | public String getTabCaption() { 39 | return "Reshaper"; 40 | } 41 | 42 | @Override 43 | public Component getUiComponent() { 44 | return this; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenEventDirectionModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.messages.DataDirection; 5 | import synfron.reshaper.burp.core.rules.whens.WhenEventDirection; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | public class WhenEventDirectionModel extends WhenModel { 9 | 10 | @Getter 11 | private DataDirection dataDirection; 12 | 13 | public WhenEventDirectionModel(WhenEventDirection when, Boolean isNew) { 14 | super(when, isNew); 15 | dataDirection = when.getDataDirection(); 16 | } 17 | 18 | public void setDataDirection(DataDirection dataDirection) { 19 | this.dataDirection = dataDirection; 20 | propertyChanged("dataDirection", dataDirection); 21 | } 22 | 23 | public boolean persist() { 24 | if (validate().size() != 0) { 25 | return false; 26 | } 27 | ruleOperation.setDataDirection(dataDirection); 28 | return super.persist(); 29 | } 30 | 31 | @Override 32 | public boolean record() { 33 | if (validate().size() != 0) { 34 | return false; 35 | } 36 | setValidated(true); 37 | return true; 38 | } 39 | 40 | @Override 41 | public RuleOperationModelType getType() { 42 | return WhenModelType.EventDirection; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/wizard/vars/VariableTagWizardContainerComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.wizard.vars; 2 | 3 | import synfron.reshaper.burp.ui.models.rules.wizard.vars.*; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | 8 | public class VariableTagWizardContainerComponent extends JPanel { 9 | 10 | public VariableTagWizardContainerComponent() { 11 | initComponent(); 12 | } 13 | 14 | private void initComponent() { 15 | setLayout(new BorderLayout()); 16 | } 17 | 18 | public void setModel(IVariableTagWizardModel model) { 19 | removeAll(); 20 | if (model != null) { 21 | JPanel component = switch (model.getVariableSource()) { 22 | case Event -> new EventVariableTagWizardComponent((EventVariableTagWizardModel) model); 23 | case Global -> new GlobalVariableTagWizardComponent((GlobalVariableTagWizardModel) model); 24 | case Message -> new MessageVariableTagWizardComponent((MessageVariableTagWizardModel) model); 25 | case File -> new FileVariableTagWizardComponent((FileVariableTagWizardModel) model); 26 | case Special -> new SpecialVariableTagWizardComponent((SpecialVariableTagWizardModel) model); 27 | case CookieJar -> new CookieJarVariableTagWizardComponent((CookieJarVariableTagWizardModel) model); 28 | }; 29 | add(component); 30 | } 31 | revalidate(); 32 | repaint(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenListComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.IRuleOperation; 4 | import synfron.reshaper.burp.core.rules.thens.Then; 5 | import synfron.reshaper.burp.ui.components.rules.RuleOperationListComponent; 6 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | import synfron.reshaper.burp.ui.models.rules.thens.ThenModel; 9 | import synfron.reshaper.burp.ui.models.rules.thens.ThenModelType; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class ThenListComponent extends RuleOperationListComponent> { 15 | 16 | public ThenListComponent(RuleModel model) { 17 | super(model); 18 | } 19 | 20 | @Override 21 | protected List> getRuleOperations() { 22 | return model.getThens(); 23 | } 24 | 25 | @Override 26 | protected List> getRuleOperationModelTypes() { 27 | return Collections.unmodifiableList(ThenModelType.getTypes()); 28 | } 29 | 30 | @Override 31 | protected ThenModel getNewModel(RuleOperationModelType ruleOperationModelType) { 32 | return ThenModel.getNewModel(ruleOperationModelType); 33 | } 34 | 35 | @Override 36 | protected > ThenModel getModel(R then) { 37 | return ThenModel.getModel((Then)then); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenListComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.rules.IRuleOperation; 4 | import synfron.reshaper.burp.core.rules.whens.When; 5 | import synfron.reshaper.burp.ui.components.rules.RuleOperationListComponent; 6 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | import synfron.reshaper.burp.ui.models.rules.whens.WhenModel; 9 | import synfron.reshaper.burp.ui.models.rules.whens.WhenModelType; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class WhenListComponent extends RuleOperationListComponent> { 15 | 16 | public WhenListComponent(RuleModel model) { 17 | super(model); 18 | } 19 | 20 | @Override 21 | protected List> getRuleOperations() { 22 | return model.getWhens(); 23 | } 24 | 25 | @Override 26 | protected List> getRuleOperationModelTypes() { 27 | return Collections.unmodifiableList(WhenModelType.getTypes()); 28 | } 29 | 30 | @Override 31 | protected WhenModel getNewModel(RuleOperationModelType ruleOperationModelType) { 32 | return WhenModel.getNewModel(ruleOperationModelType); 33 | } 34 | 35 | @Override 36 | protected > WhenModel getModel(R when) { 37 | return WhenModel.getModel((When)when); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenInScopeModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.whens.WhenInScope; 6 | import synfron.reshaper.burp.core.vars.VariableString; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | 9 | import java.util.List; 10 | 11 | public class WhenInScopeModel extends WhenModel { 12 | 13 | @Getter 14 | private String url; 15 | 16 | public WhenInScopeModel(WhenInScope when, Boolean isNew) { 17 | super(when, isNew); 18 | url = VariableString.toString(when.getUrl(), url); 19 | } 20 | 21 | public void setUrl(String url) { 22 | this.url = url; 23 | propertyChanged("url", url); 24 | } 25 | 26 | public List validate() { 27 | return super.validate(); 28 | } 29 | 30 | public boolean persist() { 31 | if (validate().size() != 0) { 32 | return false; 33 | } 34 | ruleOperation.setUrl(VariableString.getAsVariableString(url)); 35 | return super.persist(); 36 | } 37 | 38 | @Override 39 | public boolean record() { 40 | if (validate().size() != 0) { 41 | return false; 42 | } 43 | setValidated(true); 44 | return true; 45 | } 46 | 47 | @Override 48 | public RuleOperationModelType getType() { 49 | return WhenModelType.InScope; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenContainerComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.ui.components.rules.RuleOperationContainerComponent; 4 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 5 | import synfron.reshaper.burp.ui.models.rules.whens.WhenContentTypeModel; 6 | import synfron.reshaper.burp.ui.models.rules.whens.WhenModelType; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | public class WhenContainerComponent extends RuleOperationContainerComponent { 12 | 13 | private final static Map, Class> componentMap; 14 | 15 | static { 16 | componentMap = new HashMap<>(); 17 | componentMap.put(WhenModelType.EventDirection, WhenEventDirectionComponent.class); 18 | componentMap.put(WhenModelType.HasEntity, WhenHasEntityComponent.class); 19 | componentMap.put(WhenModelType.MatchesText, WhenMatchesTextComponent.class); 20 | componentMap.put(WhenModelType.ContentType, WhenContentTypeComponent.class); 21 | componentMap.put(WhenModelType.MimeType, WhenMimeTypeComponent.class); 22 | componentMap.put(WhenModelType.ProxyName, WhenProxyNameComponent.class); 23 | componentMap.put(WhenModelType.FromTool, WhenFromToolComponent.class); 24 | componentMap.put(WhenModelType.InScope, WhenInScopeComponent.class); 25 | } 26 | 27 | @Override 28 | protected Map, Class> getComponentMap() { 29 | return componentMap; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenSetEventDirectionModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.messages.DataDirection; 5 | import synfron.reshaper.burp.core.rules.thens.ThenSetEventDirection; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | public class ThenSetEventDirectionModel extends ThenModel { 9 | 10 | @Getter 11 | private DataDirection dataDirection; 12 | 13 | public ThenSetEventDirectionModel(ThenSetEventDirection then, Boolean isNew) { 14 | super(then, isNew); 15 | dataDirection = then.getDataDirection(); 16 | } 17 | 18 | public void setDataDirection(DataDirection dataDirection) { 19 | this.dataDirection = dataDirection; 20 | propertyChanged("dataDirection", dataDirection); 21 | } 22 | 23 | public boolean persist() { 24 | if (validate().size() != 0) { 25 | return false; 26 | } 27 | ruleOperation.setDataDirection(dataDirection); 28 | setValidated(true); 29 | return true; 30 | } 31 | 32 | @Override 33 | public boolean record() { 34 | if (validate().size() != 0) { 35 | return false; 36 | } 37 | setValidated(true); 38 | return true; 39 | } 40 | 41 | @Override 42 | public RuleOperationModelType getType() { 43 | return ThenModelType.SetEventDirection; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/IEventInfo.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages; 2 | 3 | import synfron.reshaper.burp.core.rules.diagnostics.IDiagnostics; 4 | 5 | public interface IEventInfo { 6 | void setDataDirection(DataDirection dataDirection); 7 | 8 | void setHttpRequestMessage(byte[] request); 9 | 10 | void setHttpResponseMessage(byte[] response); 11 | 12 | void setDestinationAddress(String destinationAddress); 13 | 14 | void setDestinationPort(int destinationPort); 15 | 16 | void setHttpProtocol(String httpProtocol); 17 | 18 | void setShouldDrop(boolean shouldDrop); 19 | 20 | void setUrl(String urlStr); 21 | 22 | boolean isChanged(); 23 | 24 | boolean isRequestChanged(); 25 | 26 | boolean isResponseChanged(); 27 | 28 | String getUrl(); 29 | 30 | burp.IHttpRequestResponse getRequestResponse(); 31 | 32 | synfron.reshaper.burp.core.BurpTool getBurpTool(); 33 | 34 | DataDirection getDataDirection(); 35 | 36 | String getProxyName(); 37 | 38 | String getSourceAddress(); 39 | 40 | String getDestinationAddress(); 41 | 42 | Integer getDestinationPort(); 43 | 44 | String getHttpProtocol(); 45 | 46 | boolean isShouldDrop(); 47 | 48 | synfron.reshaper.burp.core.messages.entities.HttpRequestMessage getHttpRequestMessage(); 49 | 50 | synfron.reshaper.burp.core.messages.entities.HttpResponseMessage getHttpResponseMessage(); 51 | 52 | Encoder getEncoder(); 53 | 54 | synfron.reshaper.burp.core.vars.Variables getVariables(); 55 | 56 | IDiagnostics getDiagnostics(); 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/vars/GlobalVariables.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.vars; 2 | 3 | import org.apache.commons.lang3.ObjectUtils; 4 | import synfron.reshaper.burp.core.events.CollectionChangedAction; 5 | import synfron.reshaper.burp.core.events.CollectionChangedArgs; 6 | import synfron.reshaper.burp.core.utils.CaseInsensitiveString; 7 | 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | public class GlobalVariables extends Variables { 13 | 14 | private GlobalVariables() {} 15 | 16 | private static final GlobalVariables global = new GlobalVariables(); 17 | 18 | public static GlobalVariables get() { 19 | return global; 20 | } 21 | 22 | public List exportVariables() { 23 | return variables.values().stream() 24 | .filter(Variable::isPersistent) 25 | .collect(Collectors.toList()); 26 | } 27 | 28 | public void importVariables(List variables, boolean overwriteDuplicates) { 29 | variables = ObjectUtils.defaultIfNull(variables, Collections.emptyList()); 30 | variables.forEach(variable -> { 31 | if (overwriteDuplicates) { 32 | this.variables.put(new CaseInsensitiveString(variable.getName()), variable); 33 | } else { 34 | this.variables.computeIfAbsent(new CaseInsensitiveString(variable.getName()), name -> variable); 35 | } 36 | }); 37 | collectionChangedEvent.invoke(new CollectionChangedArgs(this, CollectionChangedAction.Reset)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenDelay.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.apache.commons.lang3.ObjectUtils; 6 | import org.apache.commons.lang3.tuple.Pair; 7 | import synfron.reshaper.burp.core.messages.IEventInfo; 8 | import synfron.reshaper.burp.core.rules.RuleOperationType; 9 | import synfron.reshaper.burp.core.rules.RuleResponse; 10 | import synfron.reshaper.burp.core.utils.Log; 11 | import synfron.reshaper.burp.core.vars.VariableString; 12 | 13 | import java.util.Arrays; 14 | 15 | public class ThenDelay extends Then { 16 | @Getter 17 | @Setter 18 | private VariableString delay; 19 | 20 | @Override 21 | public RuleResponse perform(IEventInfo eventInfo) { 22 | boolean hasError = false; 23 | try { 24 | Thread.sleep(ObjectUtils.defaultIfNull(delay.getInt(eventInfo), 0)); 25 | } catch (InterruptedException e) { 26 | Log.get().withMessage("Delay interrupted").withException(e).logErr(); 27 | hasError = true; 28 | } catch (Exception e) { 29 | hasError = true; 30 | throw e; 31 | } finally { 32 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logProperties(this, hasError, Arrays.asList(Pair.of("millis", VariableString.getTextOrDefault(eventInfo, delay, "0")))); 33 | } 34 | return RuleResponse.Continue; 35 | } 36 | 37 | @Override 38 | public RuleOperationType getType() { 39 | return ThenType.Delay; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/ContextMenuHandler.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import burp.IContextMenuFactory; 4 | import burp.IContextMenuInvocation; 5 | import synfron.reshaper.burp.core.messages.EventInfo; 6 | import synfron.reshaper.burp.core.utils.Log; 7 | import synfron.reshaper.burp.ui.components.rules.wizard.whens.WhenWizardOptionPane; 8 | import synfron.reshaper.burp.ui.models.rules.wizard.whens.WhenWizardModel; 9 | 10 | import javax.swing.*; 11 | import java.awt.event.ActionEvent; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public class ContextMenuHandler implements IContextMenuFactory { 16 | 17 | @Override 18 | public List createMenuItems(IContextMenuInvocation invocation) { 19 | JMenuItem menuItem = new JMenuItem("Create Rule"); 20 | menuItem.addActionListener(actionEvent -> onCreateRule(invocation, actionEvent)); 21 | return invocation.getSelectedMessages().length == 1 ? Collections.singletonList(menuItem) : Collections.emptyList(); 22 | } 23 | 24 | private void onCreateRule(IContextMenuInvocation invocation, ActionEvent actionEvent) { 25 | openWhenWizard(new WhenWizardModel(new EventInfo(null, null, invocation.getSelectedMessages()[0]))); 26 | } 27 | 28 | private void openWhenWizard(WhenWizardModel model) { 29 | try { 30 | ModalPrompter.open(model, ignored -> WhenWizardOptionPane.showDialog(model), true); 31 | } catch (Exception e) { 32 | Log.get().withMessage("Failed to create rule from content menu").withException(e).logErr(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenHighlight.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | 9 | public class ThenHighlight extends Then { 10 | @Getter 11 | @Setter 12 | private HighlightColor color = HighlightColor.None; 13 | 14 | @Override 15 | public RuleResponse perform(IEventInfo eventInfo) { 16 | eventInfo.getRequestResponse().setHighlight(color.getValue()); 17 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, false, color.getValue()); 18 | return RuleResponse.Continue; 19 | } 20 | 21 | @Override 22 | public RuleOperationType getType() { 23 | return ThenType.Highlight; 24 | } 25 | 26 | public enum HighlightColor { 27 | None(null), 28 | Red("red"), 29 | Orange("orange"), 30 | Yellow("yellow"), 31 | Green("green"), 32 | Cyan("cyan"), 33 | Blue("blue"), 34 | Pink("pink"), 35 | Magenta("magenta"), 36 | Gray("gray"); 37 | 38 | private final String value; 39 | 40 | HighlightColor(String value) { 41 | this.value = value; 42 | } 43 | 44 | public String getValue() { 45 | return this.value; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return this.name(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/UiMessageHandler.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import synfron.reshaper.burp.core.events.IEventListener; 4 | import synfron.reshaper.burp.core.events.MessageArgs; 5 | import synfron.reshaper.burp.core.events.MessageEvent; 6 | import synfron.reshaper.burp.core.events.message.PromptRequestMessage; 7 | import synfron.reshaper.burp.core.events.message.PromptResponseMessage; 8 | 9 | public class UiMessageHandler { 10 | private final MessageEvent messageEvent; 11 | private final IEventListener messageListener = this::onMessage; 12 | 13 | public UiMessageHandler(MessageEvent messageEvent) { 14 | this.messageEvent = messageEvent; 15 | messageEvent.add(messageListener); 16 | } 17 | 18 | private void onMessage(MessageArgs messageArgs) { 19 | switch (messageArgs.getData().getMessageType()) { 20 | case PromptRequest -> { 21 | PromptRequestMessage message = (PromptRequestMessage)messageArgs.getData(); 22 | ModalPrompter.createTextAreaDialog( 23 | message.getMessageId(), 24 | "Prompt", 25 | message.getDescription(), 26 | message.getText(), 27 | value -> messageEvent.invoke(new MessageArgs(this, new PromptResponseMessage( 28 | message.getMessageId(), 29 | value 30 | ))) 31 | ); 32 | } 33 | case PromptCancel -> ModalPrompter.dismiss(messageArgs.getData().getMessageId()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenProxyNameModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.whens.WhenProxyName; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | import java.util.List; 9 | 10 | public class WhenProxyNameModel extends WhenModel { 11 | 12 | @Getter 13 | private String proxyName; 14 | 15 | public WhenProxyNameModel(WhenProxyName when, Boolean isNew) { 16 | super(when, isNew); 17 | proxyName = when.getProxyName(); 18 | } 19 | 20 | public void setProxyName(String proxyName) { 21 | this.proxyName = proxyName; 22 | propertyChanged("proxyName", proxyName); 23 | } 24 | 25 | public List validate() { 26 | List errors = super.validate(); 27 | if (StringUtils.isEmpty(proxyName)) { 28 | errors.add("Proxy Name is required"); 29 | } 30 | return errors; 31 | } 32 | 33 | public boolean persist() { 34 | if (validate().size() != 0) { 35 | return false; 36 | } 37 | ruleOperation.setProxyName(proxyName); 38 | return super.persist(); 39 | } 40 | 41 | @Override 42 | public boolean record() { 43 | if (validate().size() != 0) { 44 | return false; 45 | } 46 | setValidated(true); 47 | return true; 48 | } 49 | 50 | @Override 51 | public RuleOperationModelType getType() { 52 | return WhenModelType.ProxyName; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenLogModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.thens.ThenLog; 6 | import synfron.reshaper.burp.core.vars.VariableString; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | 9 | import java.util.List; 10 | 11 | public class ThenLogModel extends ThenModel { 12 | 13 | @Getter 14 | private String text; 15 | 16 | public ThenLogModel(ThenLog then, Boolean isNew) { 17 | super(then, isNew); 18 | text = VariableString.toString(then.getText(), text); 19 | } 20 | 21 | public void setText(String text) { 22 | this.text = text; 23 | propertyChanged("text", text); 24 | } 25 | 26 | public List validate() { 27 | List errors = super.validate(); 28 | if (StringUtils.isEmpty(text)) { 29 | errors.add("Text is required"); 30 | } 31 | return errors; 32 | } 33 | 34 | public boolean persist() { 35 | if (validate().size() != 0) { 36 | return false; 37 | } 38 | ruleOperation.setText(VariableString.getAsVariableString(text)); 39 | setValidated(true); 40 | return true; 41 | } 42 | 43 | @Override 44 | public boolean record() { 45 | if (validate().size() != 0) { 46 | return false; 47 | } 48 | setValidated(true); 49 | return true; 50 | } 51 | 52 | @Override 53 | public RuleOperationModelType getType() { 54 | return ThenModelType.Log; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenCommentModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.thens.ThenComment; 6 | import synfron.reshaper.burp.core.vars.VariableString; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | 9 | import java.util.List; 10 | 11 | public class ThenCommentModel extends ThenModel { 12 | 13 | @Getter 14 | private String text; 15 | 16 | public ThenCommentModel(ThenComment then, Boolean isNew) { 17 | super(then, isNew); 18 | text = VariableString.toString(then.getText(), text); 19 | } 20 | 21 | public void setText(String text) { 22 | this.text = text; 23 | propertyChanged("text", text); 24 | } 25 | 26 | public List validate() { 27 | List errors = super.validate(); 28 | if (StringUtils.isEmpty(text)) { 29 | errors.add("Text is required"); 30 | } 31 | return errors; 32 | } 33 | 34 | public boolean persist() { 35 | if (validate().size() != 0) { 36 | return false; 37 | } 38 | ruleOperation.setText(VariableString.getAsVariableString(text)); 39 | setValidated(true); 40 | return true; 41 | } 42 | 43 | @Override 44 | public boolean record() { 45 | if (validate().size() != 0) { 46 | return false; 47 | } 48 | setValidated(true); 49 | return true; 50 | } 51 | 52 | @Override 53 | public RuleOperationModelType getType() { 54 | return ThenModelType.Comment; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.events.IEventListener; 4 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 5 | import synfron.reshaper.burp.core.rules.thens.Then; 6 | import synfron.reshaper.burp.core.utils.ObjectUtils; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModel; 8 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 9 | 10 | public abstract class ThenModel

, T extends Then> extends RuleOperationModel { 11 | 12 | public ThenModel(T ruleOperation, Boolean isNew) { 13 | super(ruleOperation, isNew); 14 | } 15 | 16 | public ThenModel withListener(IEventListener listener) { 17 | getPropertyChangedEvent().add(listener); 18 | return this; 19 | } 20 | 21 | public static ThenModel getNewModel(RuleOperationModelType ruleOperationProxyType) { 22 | return (ThenModel) ObjectUtils.construct( 23 | ruleOperationProxyType.getType(), 24 | ObjectUtils.construct( 25 | ruleOperationProxyType.getRuleOperationType().getType() 26 | ), 27 | true 28 | ); 29 | } 30 | 31 | public static ThenModel getModel(Then then) { 32 | return (ThenModel) ObjectUtils.construct( 33 | ThenModelType.getTypes().stream() 34 | .filter(type -> type.getRuleOperationType() == then.getType()) 35 | .findFirst() 36 | .get().getType(), 37 | then, 38 | false 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenDeleteVariable.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | import synfron.reshaper.burp.core.vars.GlobalVariables; 9 | import synfron.reshaper.burp.core.vars.VariableSource; 10 | import synfron.reshaper.burp.core.vars.VariableString; 11 | import synfron.reshaper.burp.core.vars.Variables; 12 | 13 | public class ThenDeleteVariable extends Then { 14 | 15 | @Getter @Setter 16 | private VariableSource targetSource = VariableSource.Global; 17 | @Getter @Setter 18 | private VariableString variableName; 19 | 20 | @Override 21 | public RuleResponse perform(IEventInfo eventInfo) { 22 | boolean hasError = false; 23 | try { 24 | Variables variables = switch (targetSource) { 25 | case Event -> eventInfo.getVariables(); 26 | case Global -> GlobalVariables.get(); 27 | default -> null; 28 | }; 29 | variables.remove(variableName.getText(eventInfo)); 30 | } catch (Exception e) { 31 | hasError = true; 32 | throw e; 33 | } finally { 34 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, hasError, targetSource, VariableString.getTextOrDefault(eventInfo, variableName, null)); 35 | } 36 | return RuleResponse.Continue; 37 | } 38 | 39 | @Override 40 | public RuleOperationType getType() { 41 | return ThenType.DeleteVariable; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/Event.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events; 2 | 3 | import java.lang.ref.WeakReference; 4 | import java.util.Iterator; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | public class Event { 9 | private List>> listeners; 10 | 11 | public synchronized void clearListeners() { 12 | if (listeners != null) { 13 | listeners.clear(); 14 | } 15 | } 16 | 17 | public synchronized void remove(IEventListener listener) { 18 | if (listeners != null) { 19 | listeners.removeIf(listenerReference -> listenerReference.get() == null || listenerReference.get().equals(listener)); 20 | if (listeners.size() == 0) { 21 | listeners = null; 22 | } 23 | } 24 | } 25 | 26 | public synchronized void add(IEventListener listener) { 27 | getListeners().add(new WeakReference<>(listener)); 28 | } 29 | 30 | public synchronized void invoke(A args) { 31 | if (listeners != null) { 32 | Iterator>> iterator = listeners.iterator(); 33 | while (iterator.hasNext()) { 34 | WeakReference> listenerReference = iterator.next(); 35 | if (listenerReference.get() != null) { 36 | listenerReference.get().invoke(args); 37 | } else { 38 | iterator.remove(); 39 | } 40 | } 41 | } 42 | } 43 | 44 | private List>> getListeners() { 45 | if (listeners == null) { 46 | listeners = new LinkedList<>(); 47 | } 48 | return listeners; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/RuleOperationModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 5 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 6 | import synfron.reshaper.burp.core.rules.IRuleOperation; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public abstract class RuleOperationModel

, T extends IRuleOperation> { 12 | @Getter 13 | protected final T ruleOperation; 14 | @Getter 15 | protected boolean validated; 16 | @Getter 17 | private final PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 18 | 19 | public RuleOperationModel(T ruleOperation, boolean isNew) { 20 | this.ruleOperation = ruleOperation; 21 | this.validated = !isNew; 22 | } 23 | 24 | public List validate() { 25 | return new ArrayList<>(); 26 | } 27 | 28 | protected void setValidated(boolean validated) { 29 | if (validated != this.validated) { 30 | this.validated = validated; 31 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, "validated", validated)); 32 | } 33 | } 34 | 35 | protected void propertyChanged(String name, Object value) { 36 | setValidated(false); 37 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, name, value)); 38 | } 39 | 40 | public abstract boolean persist(); 41 | 42 | public abstract boolean record(); 43 | 44 | @Override 45 | public String toString() { 46 | return ruleOperation.getType().getName() + (validated ? "" : " *"); 47 | } 48 | 49 | public abstract RuleOperationModelType getType(); 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenDeleteValue.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.MessageValue; 6 | import synfron.reshaper.burp.core.messages.MessageValueHandler; 7 | import synfron.reshaper.burp.core.messages.IEventInfo; 8 | import synfron.reshaper.burp.core.rules.RuleOperationType; 9 | import synfron.reshaper.burp.core.rules.RuleResponse; 10 | import synfron.reshaper.burp.core.utils.DeleteItemPlacement; 11 | import synfron.reshaper.burp.core.utils.IItemPlacement; 12 | import synfron.reshaper.burp.core.vars.VariableString; 13 | 14 | public class ThenDeleteValue extends Then { 15 | @Getter 16 | @Setter 17 | private MessageValue messageValue = MessageValue.HttpRequestBody; 18 | @Getter 19 | @Setter 20 | private VariableString identifier; 21 | @Getter 22 | @Setter 23 | private DeleteItemPlacement identifierPlacement = DeleteItemPlacement.Last; 24 | 25 | @Override 26 | public RuleResponse perform(IEventInfo eventInfo) { 27 | boolean hasError = false; 28 | try { 29 | MessageValueHandler.setValue(eventInfo, messageValue, identifier, IItemPlacement.toSet(identifierPlacement), null); 30 | } catch (Exception e) { 31 | hasError = true; 32 | throw e; 33 | } finally { 34 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, hasError, messageValue, VariableString.getTextOrDefault(eventInfo, identifier, null)); 35 | } 36 | return RuleResponse.Continue; 37 | } 38 | 39 | @Override 40 | public RuleOperationType getType() { 41 | return ThenType.DeleteValue; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/vars/VariableSource.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.vars; 2 | 3 | import lombok.Getter; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | @Getter 11 | public enum VariableSource { 12 | Event("e", false), 13 | Global("g", false), 14 | Message("m", true), 15 | File("f", true), 16 | Special("s", true), 17 | CookieJar("Cookie Jar", "cj", true); 18 | 19 | private final String displayName; 20 | private final String shortName; 21 | private final boolean accessor; 22 | 23 | VariableSource(String displayName, String shortName, boolean accessor) { 24 | this.displayName = displayName; 25 | this.shortName = shortName; 26 | this.accessor = accessor; 27 | } 28 | 29 | VariableSource(String shortName, boolean accessor) { 30 | this.displayName = this.name(); 31 | this.shortName = shortName; 32 | this.accessor = accessor; 33 | } 34 | 35 | public static List getSupportedNames() { 36 | return Stream.concat( 37 | Arrays.stream(VariableSource.values()).map(source -> source.name().toLowerCase()), 38 | Arrays.stream(VariableSource.values()).map(VariableSource::getShortName) 39 | ).collect(Collectors.toList()); 40 | } 41 | 42 | public static VariableSource get(String name) { 43 | return Arrays.stream(VariableSource.values()) 44 | .filter(source -> source.name().equalsIgnoreCase(name) || source.shortName.equalsIgnoreCase(name)) 45 | .findFirst() 46 | .orElse(null); 47 | } 48 | 49 | 50 | @Override 51 | public String toString() { 52 | return displayName; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/whens/WhenType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.whens; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import synfron.reshaper.burp.core.rules.RuleOperationType; 5 | 6 | import java.util.List; 7 | 8 | @EqualsAndHashCode(callSuper = true) 9 | public class WhenType> extends RuleOperationType { 10 | public static final WhenType EventDirection = new WhenType<>("Event Direction", WhenEventDirection.class); 11 | public static final WhenType HasEntity = new WhenType<>("Has Entity", WhenHasEntity.class); 12 | public static final WhenType MatchesText = new WhenType<>("Matches Text", WhenMatchesText.class); 13 | public static final WhenType ContentType = new WhenType<>("Content Type", WhenContentType.class); 14 | public static final WhenType MimeType = new WhenType<>("MIME Type", WhenMimeType.class); 15 | public static final WhenType ProxyName = new WhenType<>("Proxy Name", WhenProxyName.class); 16 | public static final WhenType FromTool = new WhenType<>("From Tool", WhenFromTool.class); 17 | public static final WhenType InScope = new WhenType<>("In Scope", WhenInScope.class); 18 | 19 | private WhenType() { 20 | this(null, null); 21 | } 22 | 23 | private WhenType(String name, Class type) { 24 | super(name, type); 25 | } 26 | 27 | public static List> getTypes() { 28 | return List.of( 29 | EventDirection, 30 | HasEntity, 31 | MatchesText, 32 | ContentType, 33 | MimeType, 34 | ProxyName, 35 | FromTool, 36 | InScope 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.rules.whens.When; 4 | import synfron.reshaper.burp.ui.components.rules.RuleOperationComponent; 5 | import synfron.reshaper.burp.ui.models.rules.whens.WhenModel; 6 | 7 | import javax.swing.*; 8 | import javax.swing.border.CompoundBorder; 9 | import java.awt.*; 10 | import java.awt.event.ActionEvent; 11 | import java.util.List; 12 | 13 | public abstract class WhenComponent

, T extends When> extends RuleOperationComponent { 14 | protected JCheckBox useOrCondition; 15 | protected JCheckBox negate; 16 | 17 | public WhenComponent(P model) { 18 | super(model); 19 | setBorder(new CompoundBorder( 20 | BorderFactory.createTitledBorder(String.format("When %s", model.getType().getName())), 21 | BorderFactory.createEmptyBorder(4,4,4,4)) 22 | ); 23 | } 24 | 25 | protected List getDefaultComponents() { 26 | useOrCondition = new JCheckBox("Use OR Condition"); 27 | negate = new JCheckBox("Negate Result"); 28 | 29 | useOrCondition.setSelected(model.isUseOrCondition()); 30 | negate.setSelected(model.isNegate()); 31 | 32 | useOrCondition.addActionListener(this::onUseOrConditionChanged); 33 | negate.addActionListener(this::onNegateChanged); 34 | 35 | return List.of( 36 | useOrCondition, 37 | negate 38 | ); 39 | } 40 | 41 | private void onNegateChanged(ActionEvent actionEvent) { 42 | model.setNegate(negate.isSelected()); 43 | } 44 | 45 | private void onUseOrConditionChanged(ActionEvent actionEvent) { 46 | model.setUseOrCondition(useOrCondition.isSelected()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenDelayModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.thens.ThenDelay; 6 | import synfron.reshaper.burp.core.vars.VariableString; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | 9 | import java.util.List; 10 | 11 | public class ThenDelayModel extends ThenModel { 12 | 13 | @Getter 14 | private String delay; 15 | 16 | public ThenDelayModel(ThenDelay then, Boolean isNew) { 17 | super(then, isNew); 18 | delay = VariableString.toString(then.getDelay(), delay); 19 | } 20 | 21 | public void setDelay(String delay) { 22 | this.delay = delay; 23 | propertyChanged("delay", delay); 24 | } 25 | 26 | public List validate() { 27 | List errors = super.validate(); 28 | if (StringUtils.isEmpty(delay)) { 29 | errors.add("Delay is required"); 30 | } else if (!VariableString.isPotentialInt(delay)) { 31 | errors.add("Delay must be an integer"); 32 | } 33 | return errors; 34 | } 35 | 36 | public boolean persist() { 37 | if (validate().size() != 0) { 38 | return false; 39 | } 40 | ruleOperation.setDelay(VariableString.getAsVariableString(delay)); 41 | setValidated(true); 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean record() { 47 | if (validate().size() != 0) { 48 | return false; 49 | } 50 | setValidated(true); 51 | return true; 52 | } 53 | 54 | @Override 55 | public RuleOperationModelType getType() { 56 | return ThenModelType.Delay; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/ThenRunScript.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.RuleOperationType; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | import synfron.reshaper.burp.core.rules.thens.entities.script.Dispatcher; 9 | import synfron.reshaper.burp.core.rules.thens.entities.script.Environment; 10 | 11 | 12 | public class ThenRunScript extends Then { 13 | @Getter @Setter 14 | private String script; 15 | @Getter @Setter 16 | private int maxExecutionSeconds = 10; 17 | 18 | public RuleResponse perform(IEventInfo eventInfo) { 19 | boolean hasError = false; 20 | RuleResponse ruleResponse = RuleResponse.Continue; 21 | try { 22 | Dispatcher dispatcher = new Dispatcher(); 23 | dispatcher.setMaxExecutionSeconds(maxExecutionSeconds); 24 | dispatcher.getDataBag().put("eventInfo", eventInfo); 25 | 26 | dispatcher.start(context -> context.evaluateString( 27 | Environment.getEventScope(context), 28 | Environment.scriptWithWindow(script), 29 | "", 30 | 1, 31 | null 32 | )); 33 | 34 | ruleResponse = (RuleResponse)dispatcher.getDataBag().getOrDefault("ruleResponse", ruleResponse); 35 | } catch (Exception e) { 36 | hasError = true; 37 | throw e; 38 | } finally { 39 | if (eventInfo.getDiagnostics().isEnabled()) eventInfo.getDiagnostics().logValue(this, hasError, script); 40 | } 41 | return ruleResponse; 42 | } 43 | 44 | @Override 45 | public RuleOperationType getType() { 46 | return ThenType.RunScript; 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenDeleteVariableComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenDeleteVariable; 4 | import synfron.reshaper.burp.core.vars.VariableSource; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenDeleteVariableModel; 6 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 7 | 8 | import javax.swing.*; 9 | import java.awt.event.ActionEvent; 10 | 11 | public class ThenDeleteVariableComponent extends ThenComponent { 12 | private JComboBox targetSource; 13 | private JTextField variableName; 14 | 15 | public ThenDeleteVariableComponent(ThenDeleteVariableModel then) { 16 | super(then); 17 | initComponent(); 18 | } 19 | 20 | private void initComponent() { 21 | targetSource = createComboBox(new VariableSource[] { VariableSource.Event, VariableSource.Global }); 22 | variableName = createTextField(true); 23 | 24 | targetSource.setSelectedItem(model.getTargetSource()); 25 | variableName.setText(model.getVariableName()); 26 | 27 | targetSource.addActionListener(this::onTargetSourceChanged); 28 | variableName.getDocument().addDocumentListener(new DocumentActionListener(this::onVariableNameChanged)); 29 | 30 | mainContainer.add(getLabeledField("Variable Source", targetSource), "wrap"); 31 | mainContainer.add(getLabeledField("Variable Name *", variableName), "wrap"); 32 | mainContainer.add(getPaddedButton(validate)); 33 | } 34 | 35 | private void onTargetSourceChanged(ActionEvent actionEvent) { 36 | model.setTargetSource((VariableSource) targetSource.getSelectedItem()); 37 | } 38 | 39 | private void onVariableNameChanged(ActionEvent actionEvent) { 40 | model.setVariableName(variableName.getText()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/burp/BurpExtender.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.Connector; 5 | import synfron.reshaper.burp.core.events.MessageEvent; 6 | import synfron.reshaper.burp.core.settings.GeneralSettings; 7 | import synfron.reshaper.burp.core.utils.Log; 8 | import synfron.reshaper.burp.ui.components.ReshaperComponent; 9 | import synfron.reshaper.burp.ui.utils.ContextMenuHandler; 10 | import synfron.reshaper.burp.ui.utils.UiMessageHandler; 11 | 12 | public class BurpExtender implements IBurpExtender { 13 | 14 | @Getter 15 | private static IBurpExtenderCallbacks callbacks; 16 | @Getter 17 | private final static Connector connector = new Connector(); 18 | @Getter 19 | private static ITextEditor logTextEditor; 20 | @Getter 21 | private static final GeneralSettings generalSettings = new GeneralSettings(); 22 | @Getter 23 | private static final MessageEvent messageEvent = new MessageEvent(); 24 | private static final UiMessageHandler uiMessageHandler = new UiMessageHandler(messageEvent); 25 | private static final ContextMenuHandler contextMenuHandler = new ContextMenuHandler(); 26 | 27 | @Override 28 | public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { 29 | BurpExtender.callbacks = callbacks; 30 | logTextEditor = callbacks.createTextEditor(); 31 | logTextEditor.setEditable(false); 32 | connector.init(); 33 | 34 | callbacks.addSuiteTab(new ReshaperComponent()); 35 | callbacks.setExtensionName("Reshaper"); 36 | callbacks.registerProxyListener(connector); 37 | callbacks.registerHttpListener(connector); 38 | callbacks.registerExtensionStateListener(connector); 39 | callbacks.registerSessionHandlingAction(connector); 40 | callbacks.registerContextMenuFactory(contextMenuHandler); 41 | 42 | Log.get().withMessage("Reshaper started").log(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/RuleOperationsComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModel; 5 | import synfron.reshaper.burp.ui.models.rules.RuleModel; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | 10 | public abstract class RuleOperationsComponent> extends JPanel { 11 | 12 | protected final RuleModel model; 13 | protected JPanel ruleOperationContainer; 14 | 15 | public RuleOperationsComponent(RuleModel model) { 16 | this.model = model; 17 | initComponent(); 18 | } 19 | 20 | protected void initComponent() { 21 | setLayout(new BorderLayout()); 22 | setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); 23 | 24 | add(getHeader(), BorderLayout.PAGE_START); 25 | add(getBody(), BorderLayout.CENTER); 26 | } 27 | 28 | private Component getHeader() { 29 | JPanel container = new JPanel(new FlowLayout(FlowLayout.LEFT)); 30 | 31 | JLabel header = new JLabel(getHeaderText()); 32 | 33 | container.add(header); 34 | return container; 35 | } 36 | 37 | private Component getBody() { 38 | JPanel container = new JPanel(new MigLayout()); 39 | 40 | ruleOperationContainer = new JPanel(new BorderLayout()); 41 | 42 | 43 | RuleOperationListComponent operationListComponent = getOperationList(); 44 | 45 | ruleOperationContainer.add(operationListComponent.getRuleOperationContainer()); 46 | 47 | container.add(operationListComponent, "width 100%, height 30%, wrap"); 48 | container.add(ruleOperationContainer, "width 100%, height 70%"); 49 | 50 | return container; 51 | } 52 | 53 | protected abstract RuleOperationListComponent getOperationList(); 54 | 55 | protected abstract String getHeaderText(); 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenSetVariableComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import synfron.reshaper.burp.core.rules.thens.ThenSetVariable; 4 | import synfron.reshaper.burp.core.vars.VariableSource; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenSetVariableModel; 6 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 7 | 8 | import javax.swing.*; 9 | import java.awt.*; 10 | import java.awt.event.ActionEvent; 11 | import java.util.List; 12 | 13 | public class ThenSetVariableComponent extends ThenSetComponent { 14 | 15 | private JComboBox targetSource; 16 | private JTextField variableName; 17 | 18 | public ThenSetVariableComponent(ThenSetVariableModel then) { 19 | super(then); 20 | } 21 | 22 | @Override 23 | protected List getExtendedComponents() { 24 | targetSource = createComboBox(new VariableSource[] { VariableSource.Event, VariableSource.Global }); 25 | variableName = createTextField(true); 26 | 27 | targetSource.setSelectedItem(model.getTargetSource()); 28 | variableName.setText(model.getVariableName()); 29 | 30 | targetSource.addActionListener(this::onTargetSourceChanged); 31 | variableName.getDocument().addDocumentListener(new DocumentActionListener(this::onVariableNameChanged)); 32 | 33 | return List.of( 34 | getLabeledField("Destination Variable Source", targetSource), 35 | getLabeledField("Destination Variable Name *", variableName) 36 | ); 37 | } 38 | 39 | private void onTargetSourceChanged(ActionEvent actionEvent) { 40 | model.setTargetSource((VariableSource) targetSource.getSelectedItem()); 41 | } 42 | 43 | private void onVariableNameChanged(ActionEvent actionEvent) { 44 | model.setVariableName(variableName.getText()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/RuleResponse.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.Getter; 5 | import synfron.reshaper.burp.core.messages.MimeType; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | @EqualsAndHashCode 11 | public class RuleResponse { 12 | public static final RuleResponse Continue = new RuleResponse("Continue", 1); 13 | public static final RuleResponse BreakThens = new RuleResponse("Skip Next Thens", 2); 14 | public static final RuleResponse BreakRules = new RuleResponse("Skip Next Rules", 4); 15 | 16 | private static final List values = List.of( 17 | Continue, 18 | BreakThens, 19 | BreakRules 20 | ); 21 | 22 | @Getter 23 | private final String name; 24 | private final int flags; 25 | 26 | private RuleResponse() { 27 | this(Continue.name, Continue.flags); 28 | } 29 | 30 | private RuleResponse(String name, int flags) { 31 | this.name = name; 32 | this.flags = flags; 33 | } 34 | 35 | private RuleResponse(int flags) { 36 | this(getValues().stream() 37 | .filter(ruleResponse -> ruleResponse.hasFlags(flags)) 38 | .map(RuleResponse::getName) 39 | .collect(Collectors.joining(", ")), flags); 40 | } 41 | 42 | public static List getValues() { 43 | return values; 44 | } 45 | 46 | public boolean hasFlags(RuleResponse ruleResponse) { 47 | return hasFlags(ruleResponse.flags); 48 | } 49 | 50 | private boolean hasFlags(int flags) { 51 | return (this.flags & flags) == flags; 52 | } 53 | 54 | public RuleResponse or(RuleResponse ruleResponse) { 55 | int newFlag = flags | ruleResponse.flags; 56 | return new RuleResponse(newFlag); 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return name; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/thens/Then.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules.thens; 2 | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes; 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 5 | import synfron.reshaper.burp.core.messages.IEventInfo; 6 | import synfron.reshaper.burp.core.rules.IRuleOperation; 7 | import synfron.reshaper.burp.core.rules.RuleResponse; 8 | import synfron.reshaper.burp.core.utils.Serializer; 9 | 10 | @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, property = "@class") 11 | @JsonSubTypes({ 12 | @JsonSubTypes.Type(value = ThenBreak.class), 13 | @JsonSubTypes.Type(value = ThenDelay.class), 14 | @JsonSubTypes.Type(value = ThenDeleteValue.class), 15 | @JsonSubTypes.Type(value = ThenDeleteVariable.class), 16 | @JsonSubTypes.Type(value = ThenDrop.class), 17 | @JsonSubTypes.Type(value = ThenHighlight.class), 18 | @JsonSubTypes.Type(value = ThenComment.class), 19 | @JsonSubTypes.Type(value = ThenLog.class), 20 | @JsonSubTypes.Type(value = ThenRunRules.class), 21 | @JsonSubTypes.Type(value = ThenRunScript.class), 22 | @JsonSubTypes.Type(value = ThenEvaluate.class), 23 | @JsonSubTypes.Type(value = ThenSendTo.class), 24 | @JsonSubTypes.Type(value = ThenSetEventDirection.class), 25 | @JsonSubTypes.Type(value = ThenSetValue.class), 26 | @JsonSubTypes.Type(value = ThenSetVariable.class), 27 | @JsonSubTypes.Type(value = ThenRunProcess.class), 28 | @JsonSubTypes.Type(value = ThenBuildHttpMessage.class), 29 | @JsonSubTypes.Type(value = ThenParseHttpMessage.class), 30 | @JsonSubTypes.Type(value = ThenSendRequest.class) 31 | }) 32 | public abstract class Then> implements IRuleOperation { 33 | public abstract RuleResponse perform(IEventInfo eventInfo); 34 | 35 | @SuppressWarnings("unchecked") 36 | public T copy() { 37 | return (T)Serializer.copy(this); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenSetEncodingModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.apache.http.util.CharsetUtils; 6 | import synfron.reshaper.burp.core.messages.Encoder; 7 | import synfron.reshaper.burp.core.rules.thens.ThenSetEncoding; 8 | import synfron.reshaper.burp.core.vars.VariableString; 9 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 10 | 11 | import java.util.List; 12 | 13 | public class ThenSetEncodingModel extends ThenModel { 14 | 15 | @Getter 16 | private String encoding; 17 | 18 | public ThenSetEncodingModel(ThenSetEncoding then, Boolean isNew) { 19 | super(then, isNew); 20 | encoding = VariableString.toString(then.getEncoding(), encoding); 21 | } 22 | 23 | public void setEncoding(String encoding) { 24 | this.encoding = encoding; 25 | propertyChanged("encoding", encoding); 26 | } 27 | 28 | @Override 29 | public List validate() { 30 | List errors = super.validate(); 31 | 32 | if (!Encoder.isSupported(encoding) && !VariableString.hasTag(encoding)) { 33 | errors.add("Unsupported encoding"); 34 | } 35 | return errors; 36 | } 37 | 38 | public boolean persist() { 39 | if (validate().size() != 0) { 40 | return false; 41 | } 42 | ruleOperation.setEncoding(VariableString.getAsVariableString(encoding)); 43 | setValidated(true); 44 | return true; 45 | } 46 | 47 | @Override 48 | public boolean record() { 49 | if (validate().size() != 0) { 50 | return false; 51 | } 52 | setValidated(true); 53 | return true; 54 | } 55 | 56 | @Override 57 | public RuleOperationModelType getType() { 58 | return ThenModelType.SetEncoding; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenRunRulesModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.thens.ThenRunRules; 6 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 7 | 8 | import java.util.List; 9 | 10 | public class ThenRunRulesModel extends ThenModel { 11 | 12 | @Getter 13 | private boolean runSingle; 14 | @Getter 15 | private String ruleName; 16 | 17 | public ThenRunRulesModel(ThenRunRules then, Boolean isNew) { 18 | super(then, isNew); 19 | runSingle = then.isRunSingle(); 20 | ruleName = then.getRuleName(); 21 | } 22 | 23 | public void setRunSingle(boolean runSingle) { 24 | this.runSingle = runSingle; 25 | propertyChanged("runSingle", runSingle); 26 | } 27 | 28 | public void setRuleName(String ruleName) { 29 | this.ruleName = ruleName; 30 | propertyChanged("ruleName", ruleName); 31 | } 32 | 33 | public List validate() { 34 | List errors = super.validate(); 35 | if (runSingle && StringUtils.isEmpty(ruleName)) { 36 | errors.add("Rule Name is required"); 37 | } 38 | return errors; 39 | } 40 | 41 | public boolean persist() { 42 | if (validate().size() != 0) { 43 | return false; 44 | } 45 | ruleOperation.setRuleName(ruleName); 46 | ruleOperation.setRunSingle(runSingle); 47 | setValidated(true); 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean record() { 53 | if (validate().size() != 0) { 54 | return false; 55 | } 56 | setValidated(true); 57 | return true; 58 | } 59 | 60 | @Override 61 | public RuleOperationModelType getType() { 62 | return ThenModelType.RunRules; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/events/message/MessageWaiter.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.events.message; 2 | 3 | import synfron.reshaper.burp.core.events.Event; 4 | import synfron.reshaper.burp.core.events.IEventListener; 5 | import synfron.reshaper.burp.core.events.MessageArgs; 6 | import synfron.reshaper.burp.core.events.MessageEvent; 7 | 8 | import java.util.concurrent.*; 9 | import java.util.function.Predicate; 10 | 11 | public class MessageWaiter { 12 | private final Event messageEvent; 13 | private final MessageType messageType; 14 | private final Predicate isMatch; 15 | private T message; 16 | private final IEventListener messageListener = this::onMessage; 17 | private final ExecutorService executor = Executors.newSingleThreadExecutor(); 18 | 19 | public MessageWaiter(MessageEvent messageEvent, MessageType messageType, Predicate isMatch) { 20 | this.messageEvent = messageEvent; 21 | this.messageType = messageType; 22 | this.isMatch = isMatch; 23 | 24 | messageEvent.add(messageListener); 25 | } 26 | 27 | private void onMessage(MessageArgs messageArgs) { 28 | if (messageType == messageArgs.getData().getMessageType() && isMatch.test((T)messageArgs.getData())) { 29 | message = (T)messageArgs.getData(); 30 | executor.shutdown(); 31 | } 32 | } 33 | 34 | public boolean waitForMessage(long timeout, TimeUnit timeUnit) throws InterruptedException { 35 | executor.submit(() -> { 36 | if (message != null) { 37 | executor.shutdown(); 38 | } 39 | }); 40 | if (!executor.awaitTermination(timeout, timeUnit)) { 41 | executor.shutdownNow(); 42 | } 43 | return hasMessage(); 44 | } 45 | 46 | public boolean hasMessage() { 47 | return message != null; 48 | } 49 | 50 | public T getMessage() { 51 | return message; 52 | } 53 | 54 | public void cancel() { 55 | messageEvent.remove(messageListener); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/wizard/vars/FileVariableTagWizardModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.wizard.vars; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 6 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 7 | import synfron.reshaper.burp.core.messages.Encoder; 8 | import synfron.reshaper.burp.core.vars.VariableSource; 9 | import synfron.reshaper.burp.core.vars.VariableSourceEntry; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class FileVariableTagWizardModel implements IVariableTagWizardModel { 15 | 16 | @Getter 17 | private String encoding = Encoder.getDefaultEncoderName(); 18 | 19 | @Getter 20 | private String filePath; 21 | 22 | @Getter 23 | private final PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 24 | 25 | private void propertyChanged(String name, Object value) { 26 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, name, value)); 27 | } 28 | 29 | public void setEncoding(String encoding) { 30 | this.encoding = encoding; 31 | propertyChanged("encoding", encoding); 32 | } 33 | 34 | public void setFilePath(String filePath) { 35 | this.filePath = filePath; 36 | propertyChanged("filePath", filePath); 37 | } 38 | 39 | @Override 40 | public List validate() { 41 | List errors = new ArrayList<>(); 42 | if (StringUtils.isEmpty(encoding)) { 43 | errors.add("Encoding is required"); 44 | } 45 | if (StringUtils.isEmpty(filePath)) { 46 | errors.add("File Path is required"); 47 | } 48 | return errors; 49 | } 50 | 51 | @Override 52 | public VariableSource getVariableSource() { 53 | return VariableSource.File; 54 | } 55 | 56 | @Override 57 | public String getTag() { 58 | return validate().isEmpty() ? 59 | VariableSourceEntry.getShortTag(VariableSource.File, encoding, filePath) : 60 | null; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/rules/Rule.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.rules; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import synfron.reshaper.burp.core.events.IEventListener; 6 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 7 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 8 | import synfron.reshaper.burp.core.rules.thens.Then; 9 | import synfron.reshaper.burp.core.rules.whens.When; 10 | import synfron.reshaper.burp.core.utils.ObjectUtils; 11 | import synfron.reshaper.burp.core.utils.Serializer; 12 | 13 | import java.io.Serializable; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.stream.Collectors; 17 | 18 | public class Rule implements Serializable { 19 | @Getter 20 | private final transient PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 21 | @Getter @Setter 22 | private When[] whens = new When[0]; 23 | @Getter @Setter 24 | private Then[] thens = new Then[0]; 25 | @Getter 26 | private boolean enabled = true; 27 | @Getter 28 | private boolean autoRun = true; 29 | @Getter 30 | private String name; 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, "name", name)); 35 | } 36 | 37 | public void setEnabled(boolean enabled) { 38 | this.enabled = enabled; 39 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, "enabled", enabled)); 40 | } 41 | 42 | public void setAutoRun(boolean autoRun) { 43 | this.autoRun = autoRun; 44 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, "autoRun", autoRun)); 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return name; 50 | } 51 | 52 | public Rule withListener(IEventListener listener) { 53 | propertyChangedEvent.add(listener); 54 | return this; 55 | } 56 | 57 | public Rule copy() { 58 | Rule rule = Serializer.copy(this); 59 | rule.name = null; 60 | rule.enabled = false; 61 | return rule; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpResponseStatusLine.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.utils.CollectionUtils; 6 | 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | public class HttpResponseStatusLine extends HttpEntity { 11 | private final String statusLine; 12 | private boolean parsed; 13 | @Getter 14 | private boolean changed; 15 | private String code; 16 | private String message; 17 | private String version; 18 | 19 | public HttpResponseStatusLine(String statusLine) { 20 | this.statusLine = statusLine; 21 | } 22 | 23 | private void prepare() { 24 | if (!parsed) { 25 | String[] lineParts = statusLine.split(" ", 3); 26 | version = CollectionUtils.elementAtOrDefault(lineParts, 0, ""); 27 | code = CollectionUtils.elementAtOrDefault(lineParts, 1, ""); 28 | message = CollectionUtils.elementAtOrDefault(lineParts, 2, ""); 29 | parsed = true; 30 | } 31 | } 32 | 33 | public String getVersion() { 34 | prepare(); 35 | return version; 36 | } 37 | 38 | public void setVersion(String version) { 39 | prepare(); 40 | this.version = version; 41 | changed = true; 42 | } 43 | 44 | public String getCode() { 45 | prepare(); 46 | return code; 47 | } 48 | 49 | public void setCode(String code) { 50 | prepare(); 51 | this.code = code; 52 | changed = true; 53 | } 54 | 55 | public String getMessage() { 56 | prepare(); 57 | return message; 58 | } 59 | 60 | public void setMessage(String message) { 61 | prepare(); 62 | this.message = message; 63 | changed = true; 64 | } 65 | 66 | public String getValue() { 67 | return !isChanged() ? statusLine : Stream.of(getVersion(), getCode(), getMessage()) 68 | .filter(StringUtils::isNotEmpty) 69 | .collect(Collectors.joining(" ") 70 | ); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/vars/Variables.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.vars; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.events.*; 5 | import synfron.reshaper.burp.core.utils.CaseInsensitiveString; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | 11 | public class Variables { 12 | @Getter 13 | protected final CollectionChangedEvent collectionChangedEvent = new CollectionChangedEvent(); 14 | protected HashMap variables = new HashMap<>(); 15 | 16 | public List getValues() { 17 | return new ArrayList<>(variables.values()); 18 | } 19 | 20 | public Variable add(String name) 21 | { 22 | CaseInsensitiveString key = new CaseInsensitiveString(name); 23 | boolean hasItem = variables.containsKey(key); 24 | Variable variable = variables.computeIfAbsent(new CaseInsensitiveString(name), (k) -> new Variable(name)); 25 | if (!hasItem) { 26 | collectionChangedEvent.invoke(new CollectionChangedArgs(this, CollectionChangedAction.Add, name, variable)); 27 | } 28 | return variable; 29 | } 30 | 31 | public Variable get(String name) 32 | { 33 | CaseInsensitiveString key = new CaseInsensitiveString(name); 34 | if (!variables.containsKey(key)) 35 | { 36 | throw new IndexOutOfBoundsException("Variable does not exist."); 37 | } 38 | return variables.get(key); 39 | } 40 | 41 | public Variable getOrDefault(String name) 42 | { 43 | return variables.get(new CaseInsensitiveString(name)); 44 | } 45 | 46 | public boolean has(String name) 47 | { 48 | return variables.containsKey(new CaseInsensitiveString(name)); 49 | } 50 | 51 | public boolean remove(String name) 52 | { 53 | Variable variable = variables.remove(new CaseInsensitiveString(name)); 54 | boolean result = variable != null; 55 | if (result) { 56 | collectionChangedEvent.invoke(new CollectionChangedArgs(this, CollectionChangedAction.Remove, name, variable)); 57 | } 58 | return result; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/whens/WhenHasEntityComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.messages.MessageValue; 4 | import synfron.reshaper.burp.core.rules.whens.WhenHasEntity; 5 | import synfron.reshaper.burp.ui.models.rules.whens.WhenHasEntityModel; 6 | import synfron.reshaper.burp.ui.utils.ComponentVisibilityManager; 7 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 8 | 9 | import javax.swing.*; 10 | import java.awt.event.ActionEvent; 11 | 12 | public class WhenHasEntityComponent extends WhenComponent { 13 | private JComboBox messageValue; 14 | private JTextField identifier; 15 | 16 | public WhenHasEntityComponent(WhenHasEntityModel when) { 17 | super(when); 18 | initComponent(); 19 | } 20 | 21 | private void initComponent() { 22 | identifier = createTextField(true); 23 | messageValue = createComboBox(MessageValue.values()); 24 | 25 | messageValue.setSelectedItem(model.getMessageValue()); 26 | identifier.setText(model.getIdentifier()); 27 | 28 | messageValue.addActionListener(this::onMessageValueChanged); 29 | identifier.getDocument().addDocumentListener(new DocumentActionListener(this::onIdentifierChanged)); 30 | 31 | mainContainer.add(getLabeledField("Message Value", messageValue), "wrap"); 32 | mainContainer.add(ComponentVisibilityManager.withVisibilityFieldChangeDependency( 33 | getLabeledField("Identifier *", identifier), 34 | messageValue, 35 | () -> ((MessageValue)messageValue.getSelectedItem()).isIdentifierRequired() 36 | ), "wrap"); 37 | getDefaultComponents().forEach(component -> mainContainer.add(component, "wrap")); 38 | mainContainer.add(getPaddedButton(validate)); 39 | } 40 | 41 | private void onMessageValueChanged(ActionEvent actionEvent) { 42 | model.setMessageValue((MessageValue)messageValue.getSelectedItem()); 43 | } 44 | 45 | private void onIdentifierChanged(ActionEvent actionEvent) { 46 | model.setIdentifier(identifier.getText()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpRequestQueryParams.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | import lombok.Getter; 4 | import org.apache.http.NameValuePair; 5 | import org.apache.http.message.BasicNameValuePair; 6 | import synfron.reshaper.burp.core.utils.*; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | public class HttpRequestQueryParams extends HttpEntity { 12 | @Getter 13 | private boolean changed; 14 | private final List parameters; 15 | private ListMap params; 16 | 17 | public HttpRequestQueryParams(List parameters) { 18 | this.parameters = parameters; 19 | } 20 | 21 | public void prepare() { 22 | if (params == null) { 23 | params = new ListMap<>(); 24 | for (NameValuePair parameter : parameters) { 25 | params.add(parameter.getName(), parameter.getValue()); 26 | } 27 | } 28 | } 29 | 30 | public List getParamNames() { 31 | prepare(); 32 | return params.keys().stream().sorted().collect(Collectors.toList()); 33 | } 34 | 35 | public boolean hasQueryParameter(String name) { 36 | prepare(); 37 | return params.containsKey(name); 38 | } 39 | 40 | public String getQueryParameter(String name, GetItemPlacement itemPlacement) { 41 | prepare(); 42 | return params.get(name, itemPlacement); 43 | } 44 | 45 | public void setQueryParameter(String name, String value, SetItemPlacement itemPlacement) { 46 | if (value != null) { 47 | prepare(); 48 | params.set(name, value, itemPlacement); 49 | changed = true; 50 | } else { 51 | deleteParameter(name, IItemPlacement.toDelete(itemPlacement)); 52 | } 53 | } 54 | 55 | public void deleteParameter(String name, DeleteItemPlacement itemPlacement) { 56 | prepare(); 57 | params.remove(name, itemPlacement); 58 | changed = true; 59 | } 60 | 61 | public List getValue() { 62 | return !isChanged() ? parameters : params.entries(BasicNameValuePair::new); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/wizard/vars/MessageVariableTagWizardComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.wizard.vars; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | import synfron.reshaper.burp.core.messages.MessageValue; 5 | import synfron.reshaper.burp.ui.components.IFormComponent; 6 | import synfron.reshaper.burp.ui.models.rules.wizard.vars.MessageVariableTagWizardModel; 7 | import synfron.reshaper.burp.ui.utils.ComponentVisibilityManager; 8 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 9 | 10 | import javax.swing.*; 11 | import java.awt.event.ActionEvent; 12 | 13 | public class MessageVariableTagWizardComponent extends JPanel implements IFormComponent { 14 | private final MessageVariableTagWizardModel model; 15 | private JComboBox messageValue; 16 | private JTextField identifier; 17 | 18 | public MessageVariableTagWizardComponent(MessageVariableTagWizardModel model) { 19 | this.model = model; 20 | initComponent(); 21 | } 22 | 23 | private void initComponent() { 24 | setLayout(new MigLayout()); 25 | 26 | messageValue = createComboBox(MessageValue.values()); 27 | identifier = createTextField(true); 28 | 29 | messageValue.setSelectedItem(model.getMessageValue()); 30 | identifier.setText(model.getIdentifier()); 31 | 32 | messageValue.addActionListener(this::onMessageValueChanged); 33 | identifier.getDocument().addDocumentListener(new DocumentActionListener(this::onIdentifierChanged)); 34 | 35 | add(getLabeledField("Message Value", messageValue), "wrap"); 36 | add(ComponentVisibilityManager.withVisibilityFieldChangeDependency( 37 | getLabeledField("Identifier *", identifier), 38 | messageValue, 39 | () -> ((MessageValue)messageValue.getSelectedItem()).isIdentifierRequired() 40 | ), "wrap"); 41 | } 42 | 43 | private void onMessageValueChanged(ActionEvent actionEvent) { 44 | model.setMessageValue((MessageValue)messageValue.getSelectedItem()); 45 | } 46 | 47 | private void onIdentifierChanged(ActionEvent actionEvent) { 48 | model.setIdentifier(identifier.getText()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/wizard/vars/SpecialVariableTagWizardComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.wizard.vars; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | import synfron.reshaper.burp.ui.components.IFormComponent; 5 | import synfron.reshaper.burp.ui.models.rules.wizard.vars.SpecialVariableTagWizardModel; 6 | import synfron.reshaper.burp.ui.utils.ComponentVisibilityManager; 7 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 8 | 9 | import javax.swing.*; 10 | import java.awt.event.ActionEvent; 11 | 12 | public class SpecialVariableTagWizardComponent extends JPanel implements IFormComponent { 13 | private final SpecialVariableTagWizardModel model; 14 | private JComboBox specialChar; 15 | private JTextField value; 16 | 17 | public SpecialVariableTagWizardComponent(SpecialVariableTagWizardModel model) { 18 | this.model = model; 19 | initComponent(); 20 | } 21 | 22 | private void initComponent() { 23 | setLayout(new MigLayout()); 24 | 25 | specialChar = createComboBox(model.getSpecialChars().toArray(new SpecialVariableTagWizardModel.SpecialChar[0])); 26 | value = createTextField(true); 27 | 28 | specialChar.setSelectedItem(model.getSpecialChar()); 29 | value.setText(model.getValue()); 30 | 31 | specialChar.addActionListener(this::onSpecialCharChanged); 32 | value.getDocument().addDocumentListener(new DocumentActionListener(this::onValueChanged)); 33 | 34 | add(getLabeledField("Type", specialChar), "wrap"); 35 | add(ComponentVisibilityManager.withVisibilityFieldChangeDependency( 36 | getLabeledField("Value *", value), 37 | specialChar, 38 | () -> ((SpecialVariableTagWizardModel.SpecialChar)specialChar.getSelectedItem()).isValueRequired() 39 | )); 40 | } 41 | 42 | private void onSpecialCharChanged(ActionEvent actionEvent) { 43 | model.setSpecialChar((SpecialVariableTagWizardModel.SpecialChar) specialChar.getSelectedItem()); 44 | } 45 | 46 | private void onValueChanged(ActionEvent actionEvent) { 47 | model.setValue(value.getText()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenRunScriptComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | import synfron.reshaper.burp.core.rules.thens.ThenRunScript; 5 | import synfron.reshaper.burp.ui.models.rules.thens.ThenRunScriptModel; 6 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 7 | 8 | import javax.swing.*; 9 | import java.awt.*; 10 | import java.awt.event.ActionEvent; 11 | 12 | public class ThenRunScriptComponent extends ThenComponent { 13 | private JTextPane script; 14 | private JTextField maxExecutionSeconds; 15 | 16 | public ThenRunScriptComponent(ThenRunScriptModel then) { 17 | super(then); 18 | initComponent(); 19 | } 20 | 21 | private void initComponent() { 22 | mainContainer.setLayout(new BorderLayout()); 23 | JScrollPane scrollPane = new JScrollPane(); 24 | script = createTextPane(); 25 | scrollPane.setViewportView(script); 26 | 27 | script.setText(model.getScript()); 28 | 29 | script.getDocument().addDocumentListener(new DocumentActionListener(this::onScriptChanged)); 30 | 31 | mainContainer.add(new JLabel("Script *"), BorderLayout.PAGE_START); 32 | mainContainer.add(scrollPane, BorderLayout.CENTER); 33 | mainContainer.add(getOtherFields(), BorderLayout.PAGE_END); 34 | } 35 | 36 | private Component getOtherFields() { 37 | JPanel container = new JPanel(new MigLayout()); 38 | 39 | maxExecutionSeconds = createTextField(false); 40 | 41 | maxExecutionSeconds.setText(model.getMaxExecutionSeconds()); 42 | 43 | maxExecutionSeconds.getDocument().addDocumentListener(new DocumentActionListener(this::onMaxExecutionSecondsChanged)); 44 | 45 | container.add(getLabeledField("Max Execution (secs) *", maxExecutionSeconds), "wrap"); 46 | container.add(getPaddedButton(validate)); 47 | return container; 48 | } 49 | 50 | private void onScriptChanged(ActionEvent actionEvent) { 51 | model.setScript(script.getText()); 52 | 53 | } 54 | 55 | private void onMaxExecutionSecondsChanged(ActionEvent actionEvent) { 56 | model.setMaxExecutionSeconds(maxExecutionSeconds.getText()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenHasEntityModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.messages.MessageValue; 6 | import synfron.reshaper.burp.core.rules.whens.WhenHasEntity; 7 | import synfron.reshaper.burp.core.vars.VariableString; 8 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 9 | 10 | import java.util.List; 11 | 12 | public class WhenHasEntityModel extends WhenModel { 13 | 14 | @Getter 15 | private MessageValue messageValue; 16 | @Getter 17 | private String identifier = ""; 18 | 19 | public WhenHasEntityModel(WhenHasEntity when, Boolean isNew) { 20 | super(when, isNew); 21 | messageValue = when.getMessageValue(); 22 | identifier = VariableString.toString(when.getIdentifier(), identifier); 23 | } 24 | 25 | public void setMessageValue(MessageValue messageValue) { 26 | this.messageValue = messageValue; 27 | propertyChanged("messageValue", messageValue); 28 | } 29 | 30 | public void setIdentifier(String identifier) { 31 | this.identifier = identifier; 32 | propertyChanged("identifier", identifier); 33 | } 34 | 35 | @Override 36 | public List validate() { 37 | List errors = super.validate(); 38 | if (StringUtils.isEmpty(identifier) && messageValue.isIdentifierRequired()) { 39 | errors.add("Identifier is required"); 40 | } 41 | return errors; 42 | } 43 | 44 | public boolean persist() { 45 | if (validate().size() != 0) { 46 | return false; 47 | } 48 | ruleOperation.setMessageValue(messageValue); 49 | ruleOperation.setIdentifier(VariableString.getAsVariableString(identifier)); 50 | return super.persist(); 51 | } 52 | 53 | @Override 54 | public boolean record() { 55 | if (validate().size() != 0) { 56 | return false; 57 | } 58 | setValidated(true); 59 | return true; 60 | } 61 | 62 | @Override 63 | public RuleOperationModelType getType() { 64 | return WhenModelType.HasEntity; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/RuleOperationComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules; 2 | 3 | import lombok.Getter; 4 | import net.miginfocom.swing.MigLayout; 5 | import synfron.reshaper.burp.core.events.IEventListener; 6 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 7 | import synfron.reshaper.burp.core.rules.IRuleOperation; 8 | import synfron.reshaper.burp.ui.components.IFormComponent; 9 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModel; 10 | 11 | import javax.swing.*; 12 | import java.awt.event.ActionEvent; 13 | 14 | public abstract class RuleOperationComponent

, T extends IRuleOperation> extends JScrollPane implements IFormComponent { 15 | 16 | @Getter 17 | protected final P model; 18 | protected final JPanel mainContainer; 19 | protected final JButton validate; 20 | private final IEventListener modelPropertyChangedListener = this::onModelPropertyChanged; 21 | 22 | protected RuleOperationComponent(P model) { 23 | this.model = model; 24 | mainContainer = new JPanel(new MigLayout()); 25 | setViewportView(mainContainer); 26 | 27 | validate = new JButton("Validate"); 28 | setValidateButtonState(); 29 | validate.addActionListener(this::onValidate); 30 | 31 | model.getPropertyChangedEvent().add(modelPropertyChangedListener); 32 | } 33 | 34 | private void onModelPropertyChanged(PropertyChangedArgs propertyChangedArgs) { 35 | if ("validated".equals(propertyChangedArgs.getName())) { 36 | setValidateButtonState(); 37 | } 38 | } 39 | 40 | private void setValidateButtonState() { 41 | if (model.isValidated()) { 42 | validate.setEnabled(false); 43 | validate.setText("Validated"); 44 | } else { 45 | validate.setEnabled(true); 46 | validate.setText("Validate"); 47 | } 48 | } 49 | 50 | private void onValidate(ActionEvent actionEvent) { 51 | if (!model.persist()) { 52 | JOptionPane.showMessageDialog(this, 53 | String.join("\n", model.validate()), 54 | "Validation Error", 55 | JOptionPane.ERROR_MESSAGE); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/messages/entities/HttpRequestStatusLine.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.messages.entities; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import synfron.reshaper.burp.core.utils.CollectionUtils; 5 | 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | public class HttpRequestStatusLine extends HttpEntity { 10 | private final String statusLine; 11 | private boolean parsed; 12 | private boolean changed; 13 | private HttpRequestUri url; 14 | private String method; 15 | private String version; 16 | 17 | public HttpRequestStatusLine(String statusLine) { 18 | this.statusLine = statusLine; 19 | } 20 | 21 | private void prepare() { 22 | if (!parsed) { 23 | String[] lineParts = statusLine.split(" ", 3); 24 | method = CollectionUtils.elementAtOrDefault(lineParts, 0, ""); 25 | url = new HttpRequestUri(CollectionUtils.elementAtOrDefault(lineParts, 1, "")); 26 | version = CollectionUtils.elementAtOrDefault(lineParts, 2, ""); 27 | parsed = true; 28 | } 29 | } 30 | 31 | public HttpRequestUri getUrl() { 32 | prepare(); 33 | return url; 34 | } 35 | 36 | public void setUrl(String url) { 37 | prepare(); 38 | this.url = new HttpRequestUri(url); 39 | changed = true; 40 | } 41 | 42 | public String getVersion() { 43 | prepare(); 44 | return version; 45 | } 46 | 47 | public void setVersion(String version) { 48 | prepare(); 49 | this.version = version; 50 | changed = true; 51 | } 52 | 53 | public String getMethod() { 54 | prepare(); 55 | return method; 56 | } 57 | 58 | public void setMethod(String method) { 59 | prepare(); 60 | this.method = method; 61 | changed = true; 62 | } 63 | 64 | public boolean isChanged() { 65 | return changed || (url != null && url.isChanged()); 66 | } 67 | 68 | public String getValue() { 69 | return !isChanged() ? statusLine : Stream.of(getMethod(), getUrl().getValue(), getVersion()) 70 | .filter(StringUtils::isNotEmpty) 71 | .collect(Collectors.joining(" ") 72 | ); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/wizard/vars/MessageVariableTagWizardModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.wizard.vars; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 6 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 7 | import synfron.reshaper.burp.core.messages.MessageValue; 8 | import synfron.reshaper.burp.core.vars.VariableSource; 9 | import synfron.reshaper.burp.core.vars.VariableSourceEntry; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class MessageVariableTagWizardModel implements IVariableTagWizardModel { 15 | 16 | @Getter 17 | private MessageValue messageValue = MessageValue.HttpRequestBody; 18 | 19 | @Getter 20 | private String identifier; 21 | 22 | @Getter 23 | private final PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 24 | 25 | private void propertyChanged(String name, Object value) { 26 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, name, value)); 27 | } 28 | 29 | public void setMessageValue(MessageValue messageValue) { 30 | this.messageValue = messageValue; 31 | propertyChanged("messageValue", messageValue); 32 | } 33 | 34 | public void setIdentifier(String identifier) { 35 | this.identifier = identifier; 36 | propertyChanged("identifier", identifier); 37 | } 38 | 39 | @Override 40 | public List validate() { 41 | List errors = new ArrayList<>(); 42 | if (messageValue.isIdentifierRequired() && StringUtils.isEmpty(identifier)) { 43 | errors.add("Identifier is required"); 44 | } 45 | return errors; 46 | } 47 | 48 | @Override 49 | public VariableSource getVariableSource() { 50 | return VariableSource.Message; 51 | } 52 | 53 | @Override 54 | public String getTag() { 55 | return validate().isEmpty() ? 56 | VariableSourceEntry.getShortTag( 57 | VariableSource.Message, 58 | messageValue.name().toLowerCase(), 59 | messageValue.isIdentifierRequired() ? identifier : null 60 | ) : 61 | null; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenRunScriptModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.thens.ThenRunScript; 6 | import synfron.reshaper.burp.core.utils.TextUtils; 7 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 8 | 9 | import java.util.List; 10 | 11 | public class ThenRunScriptModel extends ThenModel { 12 | 13 | @Getter 14 | private String script; 15 | @Getter 16 | private String maxExecutionSeconds; 17 | 18 | public ThenRunScriptModel(ThenRunScript then, Boolean isNew) { 19 | super(then, isNew); 20 | script = then.getScript(); 21 | maxExecutionSeconds = TextUtils.toString(then.getMaxExecutionSeconds()); 22 | } 23 | 24 | public void setScript(String script) { 25 | this.script = script; 26 | propertyChanged("script", script); 27 | } 28 | 29 | public void setMaxExecutionSeconds(String maxExecutionSeconds) { 30 | this.maxExecutionSeconds = maxExecutionSeconds; 31 | propertyChanged("maxExecutionSeconds", maxExecutionSeconds); 32 | } 33 | 34 | public List validate() { 35 | List errors = super.validate(); 36 | if (StringUtils.isEmpty(script)) { 37 | errors.add("Script is required"); 38 | } 39 | if (!TextUtils.isInt(maxExecutionSeconds)) { 40 | errors.add("Max Execution (secs) must be an integer"); 41 | } 42 | return errors; 43 | } 44 | 45 | public boolean persist() { 46 | if (validate().size() != 0) { 47 | return false; 48 | } 49 | ruleOperation.setScript(script); 50 | ruleOperation.setMaxExecutionSeconds(Integer.parseInt(maxExecutionSeconds)); 51 | setValidated(true); 52 | return true; 53 | } 54 | 55 | @Override 56 | public boolean record() { 57 | if (validate().size() != 0) { 58 | return false; 59 | } 60 | setValidated(true); 61 | return true; 62 | } 63 | 64 | @Override 65 | public RuleOperationModelType getType() { 66 | return ThenModelType.RunScript; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenModelType.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import synfron.reshaper.burp.core.rules.RuleOperationType; 4 | import synfron.reshaper.burp.core.rules.whens.*; 5 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 6 | 7 | import java.util.List; 8 | 9 | public class WhenModelType

, T extends When> extends RuleOperationModelType { 10 | public static final WhenModelType EventDirection = new WhenModelType<>("Event Direction", WhenEventDirectionModel.class, WhenType.EventDirection); 11 | public static final WhenModelType HasEntity = new WhenModelType<>("Has Entity", WhenHasEntityModel.class, WhenType.HasEntity); 12 | public static final WhenModelType MatchesText = new WhenModelType<>("Matches Text", WhenMatchesTextModel.class, WhenType.MatchesText); 13 | public static final WhenModelType ContentType = new WhenModelType<>("Content Type", WhenContentTypeModel.class, WhenType.ContentType); 14 | public static final WhenModelType MimeType = new WhenModelType<>("MIME Type", WhenMimeTypeModel.class, WhenType.MimeType); 15 | public static final WhenModelType ProxyName = new WhenModelType<>("Proxy Name", WhenProxyNameModel.class, WhenType.ProxyName); 16 | public static final WhenModelType FromTool = new WhenModelType<>("From Tool", WhenFromToolModel.class, WhenType.FromTool); 17 | public static final WhenModelType InScope = new WhenModelType<>("In Scope", WhenInScopeModel.class, WhenType.InScope); 18 | 19 | private WhenModelType(String name, Class

type, RuleOperationType ruleOperationType) { 20 | super(name, type, ruleOperationType); 21 | } 22 | 23 | public static List> getTypes() { 24 | return List.of( 25 | EventDirection, 26 | HasEntity, 27 | MatchesText, 28 | ContentType, 29 | MimeType, 30 | ProxyName, 31 | FromTool, 32 | InScope 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/components/rules/thens/ThenRunRulesComponent.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.components.rules.thens; 2 | 3 | import burp.BurpExtender; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.RulesRegistry; 6 | import synfron.reshaper.burp.core.rules.thens.ThenRunRules; 7 | import synfron.reshaper.burp.ui.models.rules.thens.ThenRunRulesModel; 8 | import synfron.reshaper.burp.ui.utils.ComponentVisibilityManager; 9 | import synfron.reshaper.burp.ui.utils.DocumentActionListener; 10 | 11 | import javax.swing.*; 12 | import java.awt.event.ActionEvent; 13 | import java.util.Arrays; 14 | import java.util.stream.Collectors; 15 | import java.util.stream.Stream; 16 | 17 | public class ThenRunRulesComponent extends ThenComponent { 18 | private JComboBox ruleName; 19 | private JCheckBox runSingle; 20 | 21 | public ThenRunRulesComponent(ThenRunRulesModel then) { 22 | super(then); 23 | initComponent(); 24 | } 25 | 26 | private void initComponent() { 27 | runSingle = new JCheckBox("Run Single"); 28 | ruleName = createComboBox(Stream.concat( 29 | Arrays.stream(BurpExtender.getConnector().getRulesEngine().getRulesRegistry().getRules()).map(rule -> rule.getName()), 30 | Stream.of(model.getRuleName()) 31 | ).filter(StringUtils::isNotEmpty).sorted().distinct().toArray(String[]::new)); 32 | 33 | runSingle.setSelected(model.isRunSingle()); 34 | ruleName.setSelectedItem(model.getRuleName()); 35 | 36 | runSingle.addActionListener(this::onRunSingleChanged); 37 | ruleName.addActionListener(this::onRuleNameChanged); 38 | 39 | mainContainer.add(runSingle, "wrap"); 40 | mainContainer.add(ComponentVisibilityManager.withVisibilityFieldChangeDependency( 41 | getLabeledField("Rule Name *", ruleName), 42 | runSingle, 43 | () -> runSingle.isSelected() 44 | ), "wrap"); 45 | mainContainer.add(getPaddedButton(validate)); 46 | } 47 | 48 | private void onRunSingleChanged(ActionEvent actionEvent) { 49 | model.setRunSingle(runSingle.isSelected()); 50 | } 51 | 52 | private void onRuleNameChanged(ActionEvent actionEvent) { 53 | model.setRuleName((String) ruleName.getSelectedItem()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/vars/VariableSourceEntry.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.vars; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import java.io.Serializable; 7 | import java.util.Arrays; 8 | import java.util.Objects; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | @Getter 13 | public class VariableSourceEntry implements Serializable { 14 | private final VariableSource variableSource; 15 | private final String name; 16 | private final String tag; 17 | 18 | private VariableSourceEntry() { 19 | this(null, null, null); 20 | } 21 | 22 | public VariableSourceEntry(VariableSource variableSource, String name, String tag) { 23 | this.variableSource = variableSource; 24 | this.name = name; 25 | this.tag = tag; 26 | } 27 | 28 | public VariableSourceEntry(VariableSource variableSource, String name) { 29 | this.variableSource = variableSource; 30 | this.name = name; 31 | this.tag = getTag(); 32 | } 33 | 34 | public String getTag() { 35 | return StringUtils.isNotEmpty(tag) ? tag : getTag(variableSource, name); 36 | } 37 | 38 | public static String getTag(VariableSource variableSource, String name) { 39 | return String.format("{{%s:%s}}", variableSource.toString().toLowerCase(), name); 40 | } 41 | 42 | public static String getTag(VariableSource variableSource, String... names) { 43 | return String.format("{{%s}}", Stream.concat( 44 | Stream.of(StringUtils.defaultString(variableSource.toString().toLowerCase())), 45 | Arrays.stream(names).map(name -> StringUtils.defaultIfEmpty(name, null)) 46 | ).filter(Objects::nonNull).collect(Collectors.joining(":"))); 47 | } 48 | 49 | public static String getShortTag(VariableSource variableSource, String name) { 50 | return String.format("{{%s:%s}}", variableSource.getShortName(), name); 51 | } 52 | 53 | public static String getShortTag(VariableSource variableSource, String... names) { 54 | return String.format("{{%s}}", Stream.concat( 55 | Stream.of(StringUtils.defaultString(variableSource.getShortName())), 56 | Arrays.stream(names).map(name -> StringUtils.defaultIfEmpty(name, null)) 57 | ).filter(Objects::nonNull).collect(Collectors.joining(":"))); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/utils/ComponentVisibilityManager.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.utils; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.util.List; 6 | import java.util.function.BooleanSupplier; 7 | 8 | public class ComponentVisibilityManager { 9 | 10 | public static Component withVisibilityFieldChangeDependency( 11 | Component dependent, 12 | Component dependee, 13 | BooleanSupplier condition 14 | ) { 15 | return withVisibilityFieldChangeDependency(dependent, List.of(dependee), condition); 16 | } 17 | 18 | public static Component withVisibilityFieldChangeDependency( 19 | Component dependent, 20 | List dependees, 21 | BooleanSupplier condition 22 | ) { 23 | JPanel container = new JPanel(); 24 | ((FlowLayout)container.getLayout()).setHgap(0); 25 | ((FlowLayout)container.getLayout()).setVgap(0); 26 | if (dependent.isEnabled()) { 27 | container.add(dependent); 28 | } 29 | dependees.forEach(dependee -> { 30 | if (dependee instanceof JTextField) { 31 | ((JTextField) dependee).getDocument().addDocumentListener(new DocumentActionListener(event -> updateVisibilityFieldChangeDependency(container, dependent, condition))); 32 | } else if (dependee instanceof JCheckBox) { 33 | ((JCheckBox) dependee).addActionListener(event -> updateVisibilityFieldChangeDependency(container, dependent, condition)); 34 | } else if (dependee instanceof JComboBox) { 35 | ((JComboBox) dependee).addActionListener(event -> updateVisibilityFieldChangeDependency(container, dependent, condition)); 36 | } 37 | }); 38 | updateVisibilityFieldChangeDependency(container, dependent, condition); 39 | return container; 40 | } 41 | 42 | private static void updateVisibilityFieldChangeDependency(JPanel container, Component dependent, BooleanSupplier condition) { 43 | boolean isVisible = condition.getAsBoolean(); 44 | if (isVisible != dependent.isEnabled()) { 45 | if (isVisible) { 46 | container.add(dependent); 47 | } else { 48 | container.remove(dependent); 49 | } 50 | container.revalidate(); 51 | container.repaint(); 52 | dependent.setEnabled(isVisible); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/thens/ThenDeleteVariableModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.thens; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.rules.thens.ThenDeleteVariable; 6 | import synfron.reshaper.burp.core.vars.VariableSource; 7 | import synfron.reshaper.burp.core.vars.VariableString; 8 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 9 | 10 | import java.util.List; 11 | 12 | public class ThenDeleteVariableModel extends ThenModel { 13 | 14 | @Getter 15 | private VariableSource targetSource; 16 | @Getter 17 | private String variableName; 18 | 19 | public ThenDeleteVariableModel(ThenDeleteVariable then, Boolean isNew) { 20 | super(then, isNew); 21 | targetSource = then.getTargetSource(); 22 | variableName = VariableString.toString(then.getVariableName(), variableName); 23 | } 24 | 25 | public void setTargetSource(VariableSource targetSource) { 26 | this.targetSource = targetSource; 27 | propertyChanged("targetSource", targetSource); 28 | } 29 | 30 | public void setVariableName(String variableName) { 31 | this.variableName = variableName; 32 | propertyChanged("variableName", variableName); 33 | } 34 | 35 | public List validate() { 36 | List errors = super.validate(); 37 | if (StringUtils.isEmpty(variableName)) { 38 | errors.add("Variable Name is required"); 39 | } else if (!VariableString.isValidVariableName(variableName)) { 40 | errors.add("Variable Name is invalid"); 41 | } 42 | return errors; 43 | } 44 | 45 | public boolean persist() { 46 | if (validate().size() != 0) { 47 | return false; 48 | } 49 | ruleOperation.setTargetSource(targetSource); 50 | ruleOperation.setVariableName(VariableString.getAsVariableString(variableName)); 51 | setValidated(true); 52 | return true; 53 | } 54 | 55 | @Override 56 | public boolean record() { 57 | if (validate().size() != 0) { 58 | return false; 59 | } 60 | setValidated(true); 61 | return true; 62 | } 63 | 64 | @Override 65 | public RuleOperationModelType getType() { 66 | return ThenModelType.DeleteVariable; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/core/settings/GeneralSettings.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.core.settings; 2 | 3 | import lombok.Data; 4 | import synfron.reshaper.burp.core.BurpTool; 5 | import synfron.reshaper.burp.core.messages.Encoder; 6 | 7 | @Data 8 | public class GeneralSettings { 9 | private boolean captureProxy = true; 10 | private boolean captureTarget; 11 | private boolean captureSpider; 12 | private boolean captureScanner; 13 | private boolean captureRepeater; 14 | private boolean captureIntruder; 15 | private boolean captureExtender; 16 | private boolean enableEventDiagnostics; 17 | private int diagnosticValueMaxLength = 200; 18 | private String RemoteImportAddress = "https://github.com/synfron/ReshaperForBurp"; 19 | private boolean enableSanityCheckWarnings = true; 20 | private boolean logInExtenderOutput = true; 21 | private int logTabCharacterLimit = 1000000; 22 | private String defaultEncoding = Encoder.getDefaultEncoderName(); 23 | 24 | public void importSettings(GeneralSettings other) { 25 | if (other != null) { 26 | this.captureProxy = other.captureProxy; 27 | this.captureTarget = other.captureTarget; 28 | this.captureSpider = other.captureSpider; 29 | this.captureScanner = other.captureScanner; 30 | this.captureRepeater = other.captureRepeater; 31 | this.captureIntruder = other.captureIntruder; 32 | this.captureExtender = other.captureExtender; 33 | this.enableEventDiagnostics = other.enableEventDiagnostics; 34 | this.diagnosticValueMaxLength = other.diagnosticValueMaxLength; 35 | this.enableSanityCheckWarnings = other.enableSanityCheckWarnings; 36 | this.logInExtenderOutput = other.logInExtenderOutput; 37 | this.logTabCharacterLimit = other.logTabCharacterLimit; 38 | this.RemoteImportAddress = other.RemoteImportAddress; 39 | } 40 | } 41 | 42 | public boolean isCapture(BurpTool burpTool) { 43 | return switch (burpTool) { 44 | case Proxy -> isCaptureProxy(); 45 | case Repeater -> isCaptureRepeater(); 46 | case Target -> isCaptureTarget(); 47 | case Spider -> isCaptureSpider(); 48 | case Scanner -> isCaptureScanner(); 49 | case Intruder -> isCaptureIntruder(); 50 | case Extender -> isCaptureExtender(); 51 | case Session -> true; 52 | }; 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/wizard/vars/EventVariableTagWizardModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.wizard.vars; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 6 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 7 | import synfron.reshaper.burp.core.vars.VariableSource; 8 | import synfron.reshaper.burp.core.vars.VariableSourceEntry; 9 | import synfron.reshaper.burp.core.vars.VariableString; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | public class EventVariableTagWizardModel implements IVariableTagWizardModel { 16 | 17 | @Getter 18 | private final List variableNames; 19 | 20 | @Getter 21 | private String variableName; 22 | 23 | @Getter 24 | private final PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 25 | 26 | public EventVariableTagWizardModel(List entries) { 27 | variableNames = entries.stream() 28 | .filter(entry -> entry.getVariableSource() == VariableSource.Event) 29 | .map(VariableSourceEntry::getName) 30 | .filter(VariableString::isValidVariableName) 31 | .distinct() 32 | .sorted(String::compareToIgnoreCase) 33 | .collect(Collectors.toList()); 34 | variableName = variableNames.stream().findFirst().orElse(null); 35 | } 36 | 37 | private void propertyChanged(String name, Object value) { 38 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, name, value)); 39 | } 40 | 41 | public void setVariableName(String variableName) { 42 | this.variableName = variableName; 43 | propertyChanged("variableName", variableName); 44 | } 45 | 46 | @Override 47 | public List validate() { 48 | List errors = new ArrayList<>(); 49 | if (StringUtils.isEmpty(variableName)) { 50 | errors.add("Variable Name is required"); 51 | } 52 | return errors; 53 | } 54 | 55 | @Override 56 | public VariableSource getVariableSource() { 57 | return VariableSource.Event; 58 | } 59 | 60 | @Override 61 | public String getTag() { 62 | return validate().isEmpty() ? 63 | VariableSourceEntry.getShortTag(VariableSource.Event, variableName) : 64 | null; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /docs/Variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | ## Custom Variables 4 | 5 | Custom variables allow the sharing of values between Rules and are scoped at the Global or Event level. Global and Event variables can be set by Thens or in the UI (Global variables only). Custom variables are only accessible within Reshaper and are readable by Whens and Thens. 6 | 7 | Event variables are shared among rules running on a single HTTP event (either request or response). 8 | 9 | Global variables are shared among multiple HTTP events for as long at the extension is loaded or until the variables are deleted. Global variables can be set to be Persistent in the Global Variables tab of Reshaper. Persistent variables will be saved and reloaded between Reshaper sessions. 10 | 11 | ## Accessor Variables 12 | 13 | Accessor variables provide access to utility functionality and data that is not strictly created by Reshaper. 14 | 15 | Message variables provide access to event message values (e.g. Request URI). 16 | 17 | File variables provide access to the contents of a text file. 18 | 19 | Special character variables provide access to special characters which typically require escape character sequences to use. (e.g. new lines, tabs, unicode characters) 20 | 21 | ## Variable Tags 22 | 23 | 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. 24 | {% raw %} 25 | 26 | **Event Variable Tag (event, e):** `{{event:MyVariableName}}` 27 | 28 | **Global Variable Tag (global, g):** `{{global:MyVariableName}}` 29 | 30 | For example, if Global variable named `firstName` has the value `John` and variable named `lastName` has the value `Smith`. A field with the value `{{global:firstName}}'s full name is {{global:firstName}} {{global:lastName}}` will be read as `John's full name is John Smith`. 31 | 32 | **Message Variable Tag (message, m):** `{{message:messageValueKey}}` or `{{message:messageValueKey:identifier}}` (e.g. `{{message:httprequesturi}}`, `{{message:httprequestheader:Host}}`). See [Message Values](MessageValues.html#) 33 | 34 | **File Variable Tag (file, f):** `{{file:encoding:filePath}}`. Example: `{{file:utf-8:~/Documents/file.txt}}` 35 | 36 | **Special Character Tag (special, s):** `{{s:specialCharacterSequences}}`. Examples: `{{s:n}}` (new line), `{{s:rn}}` (carriage return + new line), `{{s:u00A9}}` (Copyright symbol) 37 | 38 | **Cookie Jar Tag (cookiejar, cj):** `{{cookiejar:domain:name}}` or `{{cookiejar:domain:name:path}}`. Example: `{{cookiejar:example.com:tracker:/}}` 39 | 40 | 41 | {% endraw %} 42 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/whens/WhenModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.whens; 2 | 3 | import lombok.Getter; 4 | import synfron.reshaper.burp.core.events.IEventListener; 5 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 6 | import synfron.reshaper.burp.core.rules.whens.When; 7 | import synfron.reshaper.burp.core.utils.ObjectUtils; 8 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModel; 9 | import synfron.reshaper.burp.ui.models.rules.RuleOperationModelType; 10 | 11 | public abstract class WhenModel

, T extends When> extends RuleOperationModel { 12 | 13 | @Getter 14 | private boolean negate; 15 | @Getter 16 | private boolean useOrCondition; 17 | 18 | public WhenModel(T ruleOperation, Boolean isNew) { 19 | super(ruleOperation, isNew); 20 | negate = ruleOperation.isNegate(); 21 | useOrCondition = ruleOperation.isUseOrCondition(); 22 | } 23 | 24 | public WhenModel withListener(IEventListener listener) { 25 | getPropertyChangedEvent().add(listener); 26 | return this; 27 | } 28 | 29 | public void setNegate(boolean negate) { 30 | this.negate = negate; 31 | propertyChanged("negate", negate); 32 | } 33 | 34 | public void setUseOrCondition(boolean useOrCondition) { 35 | this.useOrCondition = useOrCondition; 36 | propertyChanged("useOrCondition", useOrCondition); 37 | } 38 | 39 | @Override 40 | public boolean persist() { 41 | ruleOperation.setNegate(negate); 42 | ruleOperation.setUseOrCondition(useOrCondition); 43 | 44 | setValidated(true); 45 | return true; 46 | } 47 | 48 | public static WhenModel getNewModel(RuleOperationModelType ruleOperationModelType) { 49 | return (WhenModel) ObjectUtils.construct( 50 | ruleOperationModelType.getType(), 51 | ObjectUtils.construct( 52 | ruleOperationModelType.getRuleOperationType().getType() 53 | ), 54 | true 55 | ); 56 | } 57 | 58 | public static WhenModel getModel(When when) { 59 | return (WhenModel) ObjectUtils.construct( 60 | WhenModelType.getTypes().stream() 61 | .filter(type -> type.getRuleOperationType() == when.getType()) 62 | .findFirst() 63 | .get().getType(), 64 | when, 65 | false 66 | ); 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/synfron/reshaper/burp/ui/models/rules/wizard/vars/GlobalVariableTagWizardModel.java: -------------------------------------------------------------------------------- 1 | package synfron.reshaper.burp.ui.models.rules.wizard.vars; 2 | 3 | import lombok.Getter; 4 | import org.apache.commons.lang3.StringUtils; 5 | import synfron.reshaper.burp.core.events.PropertyChangedArgs; 6 | import synfron.reshaper.burp.core.events.PropertyChangedEvent; 7 | import synfron.reshaper.burp.core.vars.*; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | import java.util.stream.Stream; 13 | 14 | public class GlobalVariableTagWizardModel implements IVariableTagWizardModel { 15 | 16 | @Getter 17 | private final List variableNames; 18 | 19 | @Getter 20 | private String variableName; 21 | 22 | @Getter 23 | private final PropertyChangedEvent propertyChangedEvent = new PropertyChangedEvent(); 24 | 25 | public GlobalVariableTagWizardModel(List entries) { 26 | variableNames = Stream.concat( 27 | GlobalVariables.get().getValues().stream().map(Variable::getName), 28 | entries.stream() 29 | .filter(entry -> entry.getVariableSource() == VariableSource.Global) 30 | .map(VariableSourceEntry::getName) 31 | ) 32 | .filter(VariableString::isValidVariableName) 33 | .distinct() 34 | .sorted(String::compareToIgnoreCase) 35 | .collect(Collectors.toList()); 36 | variableName = variableNames.stream().findFirst().orElse(null); 37 | } 38 | 39 | private void propertyChanged(String name, Object value) { 40 | propertyChangedEvent.invoke(new PropertyChangedArgs(this, name, value)); 41 | } 42 | 43 | public void setVariableName(String variableName) { 44 | this.variableName = variableName; 45 | propertyChanged("variableName", variableName); 46 | } 47 | 48 | @Override 49 | public List validate() { 50 | List errors = new ArrayList<>(); 51 | if (StringUtils.isEmpty(variableName)) { 52 | errors.add("Variable Name is required"); 53 | } 54 | return errors; 55 | } 56 | 57 | @Override 58 | public VariableSource getVariableSource() { 59 | return VariableSource.Global; 60 | } 61 | 62 | @Override 63 | public String getTag() { 64 | return validate().isEmpty() ? 65 | VariableSourceEntry.getShortTag(VariableSource.Global, variableName) : 66 | null; 67 | } 68 | } 69 | --------------------------------------------------------------------------------