diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index 0a9e3cd..823e672 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -4,21 +4,30 @@ on:
push:
branches:
- develop
+ paths:
+ - 'src/**'
+ - 'pom.xml'
+
pull_request:
branches:
- develop
+ paths:
+ - 'src/**'
+ - 'pom.xml'
jobs:
build:
runs-on: ubuntu-latest
-
steps:
+
- uses: actions/checkout@v2
+
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
+
- name: Cache local Maven repository
uses: actions/cache@v2
with:
@@ -26,5 +35,12 @@ jobs:
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
+
- name: Build with Maven
run: mvn -B package --file pom.xml
+
+ - name: Archive generated JAR file
+ uses: actions/upload-artifact@v2
+ with:
+ name: cstc-develop-artifact
+ path: target/CSTC-*
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index 7552e72..9bd26e1 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -4,21 +4,30 @@ on:
push:
branches:
- master
+ paths:
+ - 'src/**'
+ - 'pom.xml'
+
pull_request:
branches:
- master
+ paths:
+ - 'src/**'
+ - 'pom.xml'
jobs:
build:
runs-on: ubuntu-latest
-
steps:
+
- uses: actions/checkout@v2
+
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
+
- name: Cache local Maven repository
uses: actions/cache@v2
with:
@@ -26,5 +35,12 @@ jobs:
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
+
- name: Build with Maven
run: mvn -B package --file pom.xml
+
+ - name: Archive generated JAR file
+ uses: actions/upload-artifact@v2
+ with:
+ name: cstc-master-artifact
+ path: target/CSTC-*
diff --git a/pom.xml b/pom.xml
index 654af5b..89a61fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,88 +1,119 @@
+
- 4.0.0
- de.usd.CSTC
- CSTC
- 1.2.1
- CSTC
- CSTC
-
- UTF-8
-
-
- src
-
-
- src
-
- **/*.java
-
-
-
- res
-
- **/*.java
-
-
-
-
-
- maven-compiler-plugin
- 3.7.0
-
-
- 1.8
-
-
-
- maven-assembly-plugin
-
-
- package
-
- single
-
-
-
-
-
- jar-with-dependencies
-
-
-
-
-
-
-
- com.jayway.jsonpath
- json-path
- 2.4.0
-
-
- net.portswigger.burp.extender
- burp-extender-api
- 1.7.22
-
-
- org.bouncycastle
- bcprov-jdk15on
- 1.59
-
-
-
- com.fasterxml.jackson.core
- jackson-core
- 2.11.1
-
-
-
- com.fasterxml.jackson.core
- jackson-databind
- 2.11.1
-
-
- org.apache.commons
- commons-text
- 1.8
-
-
+
+ 4.0.0
+ de.usd.CSTC
+ CSTC
+ 1.3.0
+ CSTC
+ CSTC
+
+
+ UTF-8
+
+
+
+
+
+ com.jayway.jsonpath
+ json-path
+ 2.7.0
+
+
+
+ net.portswigger.burp.extender
+ burp-extender-api
+ 2.3
+
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.70
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.14.2
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.14.2
+
+
+
+ org.apache.commons
+ commons-text
+ 1.10.0
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+
+
+
+ src/main/java
+
+
+
+ src/main/java
+
+ **/*.java
+
+
+
+
+ res
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.11.0
+
+
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
+ false
+ true
+
+
+
+
+ maven-assembly-plugin
+
+
+ package
+
+ single
+
+
+
+
+
+ jar-with-dependencies
+
+
+
+
+
+
diff --git a/src/burp/BurpExtender.java b/src/burp/BurpExtender.java
deleted file mode 100644
index c5dbbe3..0000000
--- a/src/burp/BurpExtender.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package burp;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JMenuItem;
-
-import de.usd.cstchef.view.FormatTab;
-import de.usd.cstchef.view.RecipePanel;
-import de.usd.cstchef.view.View;
-
-public class BurpExtender implements IBurpExtender, ITab, IMessageEditorTabFactory, IHttpListener, IContextMenuFactory {
-
- private final String extensionName = "CSTC";
- private IBurpExtenderCallbacks callbacks;
- private View view;
-
- @Override
- public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {
- this.callbacks = callbacks;
- Logger.getInstance().init(callbacks.getStdout(), callbacks.getStderr());
- BurpUtils.getInstance().init(callbacks);
-
- callbacks.setExtensionName(this.extensionName);
- callbacks.addSuiteTab(this);
- callbacks.registerHttpListener(this);
- callbacks.registerContextMenuFactory(this);
- callbacks.registerMessageEditorTabFactory(this);
- }
-
-
- @Override
- public String getTabCaption() {
- return this.extensionName;
- }
-
- @Override
- public Component getUiComponent() {
- this.view = new View();
- return this.view;
- }
-
- @Override
- public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
- if (messageIsRequest && view.getOutgoingRecipePanel().shouldProcess(toolFlag)) {
- byte[] request = messageInfo.getRequest();
- byte[] modifiedRequest = view.getOutgoingRecipePanel().bake(request);
- Logger.getInstance().log("modified request: \n" + new String(modifiedRequest));
- messageInfo.setRequest(modifiedRequest);
- } else if (view.getIncomingRecipePanel().shouldProcess(toolFlag)) {
- byte[] response = messageInfo.getResponse();
- byte[] modifiedResponse = view.getIncomingRecipePanel().bake(response);
- messageInfo.setResponse(modifiedResponse);
- Logger.getInstance().log("modified response: \n" + new String(modifiedResponse));
- }
- }
-
- @Override
- public List createMenuItems(IContextMenuInvocation invoc) {
-
- List menuItems = new ArrayList<>();
- JMenuItem incomingMenu = new JMenuItem("Send to CSTC (Incoming)");
- JMenuItem outgoingMenu = new JMenuItem("Send to CSTC (Outgoing)");
- JMenuItem incomingFormatMenu = new JMenuItem("Send to CSTC (Formating)");
-
- menuItems.add(incomingMenu);
- menuItems.add(outgoingMenu);
- menuItems.add(incomingFormatMenu);
-
- incomingMenu.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- IHttpRequestResponse[] msgs = invoc.getSelectedMessages();
- if (msgs != null && msgs.length > 0) {
- view.getIncomingRecipePanel().setInput(msgs[0]);
- }
- }
- });
-
- outgoingMenu.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- IHttpRequestResponse[] msgs = invoc.getSelectedMessages();
- if (msgs != null && msgs.length > 0) {
- view.getOutgoingRecipePanel().setInput(msgs[0]);
- }
-
- }
- });
-
- incomingFormatMenu.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- IHttpRequestResponse[] msgs = invoc.getSelectedMessages();
- if (msgs != null && msgs.length > 0) {
- view.getFormatRecipePanel().setInput(msgs[0]);
- }
- }
- });
-
- return menuItems;
- }
-
- @Override
- public IMessageEditorTab createNewInstance(IMessageEditorController controller, boolean editable) {
- RecipePanel requestFormatPanel = this.view.getOutgoingRecipePanel();
- // TODO do we need the format panel or do we want to use the incoming recipe?
- RecipePanel responseFormatPanel = this.view.getFormatRecipePanel();
- return new FormatTab(requestFormatPanel, responseFormatPanel, editable);
- }
-}
diff --git a/src/burp/BurpUtils.java b/src/burp/BurpUtils.java
deleted file mode 100644
index 20bc559..0000000
--- a/src/burp/BurpUtils.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package burp;
-
-public class BurpUtils {
-
- private static BurpUtils instance;
- private IBurpExtenderCallbacks callbacks;
-
- public static BurpUtils getInstance() {
- if (BurpUtils.instance == null) {
- BurpUtils.instance = new BurpUtils();
- }
- return BurpUtils.instance;
- }
-
- private BurpUtils() {
- }
-
- public void init(IBurpExtenderCallbacks callbacks) {
- this.callbacks = callbacks;
- }
-
- public IBurpExtenderCallbacks getCallbacks() throws IllegalAccessError {
- if (this.callbacks == null) {
- throw new IllegalAccessError("Only works within burpsuite");
- }
- return callbacks;
- }
-
- public static boolean inBurp() {
- try {
- BurpUtils.getInstance().getCallbacks();
- return true;
- } catch (IllegalAccessError e) {
- return false;
- }
- }
-
-}
diff --git a/src/burp/CstcMessageEditorController.java b/src/burp/CstcMessageEditorController.java
deleted file mode 100644
index b25c775..0000000
--- a/src/burp/CstcMessageEditorController.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package burp;
-
-public class CstcMessageEditorController implements IMessageEditorController {
-
- private IHttpService httpService = null;
- private byte[] request = null;
- private byte[] response = null;
-
- public void setHttpRequestResponse(IHttpRequestResponse requestResponse) {
- this.httpService = requestResponse.getHttpService();
- this.request = requestResponse.getRequest();
- this.response = requestResponse.getResponse();
- }
-
- public void setRequest(byte[] request) {
- this.request = request;
- }
-
- public void setResponse(byte[] response) {
- this.request = response;
- }
-
- @Override
- public IHttpService getHttpService() {
- return httpService;
- }
-
- @Override
- public byte[] getRequest() {
- return request;
- }
-
- @Override
- public byte[] getResponse() {
- return response;
- }
-}
diff --git a/src/burp/Logger.java b/src/burp/Logger.java
deleted file mode 100644
index 465d70d..0000000
--- a/src/burp/Logger.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package burp;
-
-import java.io.OutputStream;
-import java.io.PrintWriter;
-
-public class Logger {
-
- private static Logger instance;
-
- private PrintWriter stdout;
- private PrintWriter stderr;
-
- public static Logger getInstance() {
- if (Logger.instance == null) {
- Logger.instance = new Logger();
- }
- return Logger.instance;
- }
-
- private Logger() {
-
- }
-
- public void init(OutputStream stdOut, OutputStream stdErr) {
- this.stdout = new PrintWriter(stdOut, true);
- this.stderr = new PrintWriter(stdErr, true);
- }
-
- public void log(String msg) {
- if (this.stdout == null) {
- System.out.println(msg);
- } else {
- this.stdout.println(msg);
- }
- }
-
- public void err(String msg) {
- if (this.stderr == null) {
- System.err.println(msg);
- } else {
- this.stderr.println(msg);
- }
- }
-}
diff --git a/src/de/usd/cstchef/VariableStore.java b/src/de/usd/cstchef/VariableStore.java
deleted file mode 100644
index 5c6521c..0000000
--- a/src/de/usd/cstchef/VariableStore.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.usd.cstchef;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-public class VariableStore {
-
- private static VariableStore instance;
-
- private HashMap variables = new HashMap<>();
- private ReentrantLock lock = new ReentrantLock();
-
- public static VariableStore getInstance() {
- if (VariableStore.instance == null) {
- VariableStore.instance = new VariableStore();
- }
- return VariableStore.instance;
- }
-
- private VariableStore() {
- }
-
- public void lock() {
- this.lock.lock();
- }
-
- public void unlock() {
- this.lock.unlock();
- }
-
- public synchronized byte[] getVariable(String name) {
- return this.variables.get(name);
- }
-
- public synchronized void setVariable(String key, byte[] value) {
- this.variables.put(key, value);
- }
-
- public synchronized void removeVariable(String key) {
- this.variables.remove(key);
- }
-
- public synchronized HashMap getVariables() {
- HashMap variablesCopy = new HashMap<>();
-
- for (Map.Entry entry : this.variables.entrySet()) {
- byte[] orig = entry.getValue();
- byte[] newContent = new byte[orig.length];
- System.arraycopy(orig, 0, newContent, 0, orig.length);
- variablesCopy.put(entry.getKey(), newContent);
- }
- return variablesCopy;
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/Operation.java b/src/de/usd/cstchef/operations/Operation.java
deleted file mode 100644
index 31d43d6..0000000
--- a/src/de/usd/cstchef/operations/Operation.java
+++ /dev/null
@@ -1,492 +0,0 @@
-package de.usd.cstchef.operations;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.EOFException;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JFileChooser;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JPasswordField;
-import javax.swing.JSpinner;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.border.Border;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.MatteBorder;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import burp.Logger;
-import de.usd.cstchef.view.ui.FormatTextField;
-import de.usd.cstchef.view.ui.VariableTextArea;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-public abstract class Operation extends JPanel {
-
- private static Color defaultBgColor = new Color(223, 240, 216);
- private static Color defaultFontColor = new Color(70, 136, 71);
- private static Color disabledBgColor = new Color(223, 223, 223);
- private static Color disabledFontColor = new Color(153, 153, 153);
- private static Color breakBgColor = new Color(242, 222, 222);
- private static Color breakFontColor = new Color(185, 74, 72);
- private static Color errorBgColor = new Color(255, 121, 128);
- private static Color errorFontColor = new Color(185, 74, 72);
-
- private static ImageIcon breakIcon = new ImageIcon(Operation.class.getResource("/stop.png"));
- private static ImageIcon breakIconActive = new ImageIcon(Operation.class.getResource("/stop_active.png"));
- private static ImageIcon disableIcon = new ImageIcon(Operation.class.getResource("/disable.png"));
- private static ImageIcon removeIcon = new ImageIcon(Operation.class.getResource("/remove.png"));
- private static ImageIcon helpIcon = new ImageIcon(Operation.class.getResource("/help.png"));
-
- private NotifyChangeListener notifyChangeListener;
-
- private boolean breakpoint = false;
- private boolean disabled = false;
- private boolean error = false;
-
- private ChangeListener changeListener;
- private JTextArea errorArea;
- private Box contentBox;
- private Map uiElements;
-
- private int operationSkip = 0;
- private int laneSkip = 0;
-
- public Operation() {
- super();
- this.uiElements = new HashMap<>();
-
- this.setLayout(new BorderLayout());
- this.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
- // set border
- Border margin = BorderFactory.createEmptyBorder(10, 10, 10, 10);
- MatteBorder lineBorder = new MatteBorder(0, 0, 1, 0, Color.BLACK);
- CompoundBorder border = new CompoundBorder(lineBorder, margin);
- this.setBorder(border);
-
- // add header
- JPanel header = new JPanel();
- header.setBackground(new Color(0, 0, 0, 0)); // transparent
-
- BoxLayout layout = new BoxLayout(header, BoxLayout.X_AXIS);
- header.setLayout(layout);
- header.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
- OperationInfos opInfos = this.getClass().getAnnotation(OperationInfos.class);
-
- JLabel titleLbl = new JLabel(opInfos.name());
- Font f = titleLbl.getFont();
- titleLbl.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
-
- JButton disableBtn = createIconButton(Operation.disableIcon);
- disableBtn.setToolTipText("Disable");
- JButton breakpointBtn = createIconButton(Operation.breakIcon);
- breakpointBtn.setToolTipText("Breakpoint");
- JButton removeBtn = createIconButton(Operation.removeIcon);
- removeBtn.setToolTipText("Remove");
- JButton helpBtn = createIconButton(Operation.helpIcon);
- helpBtn.setToolTipText(opInfos.description());
-
- disableBtn.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- disabled = !isDisabled();
- refreshColors();
- validate();
- repaint();
- notifyChange();
- }
- });
-
- breakpointBtn.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- breakpoint = !isBreakpoint();
- ImageIcon newIcon = isBreakpoint() ? Operation.breakIconActive : Operation.breakIcon;
- breakpointBtn.setIcon(newIcon);
- refreshColors();
- validate();
- repaint();
- notifyChange();
- }
- });
- JPanel me = this;
- removeBtn.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- Container parent = getParent();
- onRemove();
- parent.remove(me);
- parent.validate();
- parent.repaint();
- notifyChange();
- }
- });
-
- header.add(titleLbl);
- header.add(Box.createHorizontalStrut(6));
- header.add(helpBtn);
- header.add(Box.createHorizontalGlue());
- header.add(disableBtn);
- header.add(Box.createHorizontalStrut(3));
- header.add(breakpointBtn);
- header.add(Box.createHorizontalStrut(3));
- header.add(removeBtn);
-
- this.add(header, BorderLayout.NORTH);
-
- errorArea = new JTextArea();
- errorArea.setEditable(false);
- errorArea.setLineWrap(true);
- errorArea.setWrapStyleWord(true);
- errorArea.setBackground(new Color(0, 0, 0, 0));
- errorArea.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
- errorArea.setFocusable(false);
- errorArea.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
-
- this.add(errorArea, BorderLayout.SOUTH);
-
- contentBox = Box.createVerticalBox();
- this.add(contentBox, BorderLayout.CENTER);
-
- this.createUI();
- this.refreshColors();
- }
-
- public Map getState() {
- Map properties = new HashMap<>();
- for (String key : this.uiElements.keySet()) {
- if( key.startsWith("noupdate") )
- properties.put(key, null);
- else
- properties.put(key, getUiValues(this.uiElements.get(key)));
- }
-
- return properties;
- }
-
- private Object getUiValues(Component comp) {
- Object result = null;
- if (comp instanceof JPasswordField) {
- result = "";
- } else if (comp instanceof VariableTextArea) {
- result = ((VariableTextArea) comp).getRawText();
- } else if (comp instanceof VariableTextField) {
- result = ((VariableTextField) comp).getRawText();
- } else if (comp instanceof JTextField) {
- result = ((JTextField) comp).getText();
- } else if (comp instanceof JSpinner) {
- result = ((JSpinner) comp).getValue();
- } else if (comp instanceof JComboBox) {
- result = ((JComboBox>) comp).getSelectedItem();
- if( result != null )
- result = result.toString();
- } else if (comp instanceof JCheckBox) {
- result = ((JCheckBox) comp).isSelected();
- } else if (comp instanceof FormatTextField) {
- result = ((FormatTextField) comp).getValues();
- } else if (comp instanceof JFileChooser) {
- result = ((JFileChooser) comp).getName();
- }
-
- return result;
- }
-
- public void load(Map parameters) {
- for (String key : this.uiElements.keySet()) {
- Object value = parameters.get(key);
- this.setUiValue(this.uiElements.get(key), value);
- }
- }
-
- private void setUiValue(Component comp, Object value) {
- if (comp == null || value == null) {
- return;
- }
-
- if (comp instanceof JTextField) {
- ((JTextField) comp).setText((String) value);
- } else if (comp instanceof JSpinner) {
- ((JSpinner) comp).setValue(value);
- } else if (comp instanceof JComboBox) {
- ((JComboBox>) comp).setSelectedItem(value);
- } else if (comp instanceof VariableTextArea) {
- ((VariableTextArea) comp).setText((String) value);
- } else if (comp instanceof JCheckBox) {
- ((JCheckBox) comp).setSelected((boolean) value);
- } else if (comp instanceof FormatTextField) {
- ((FormatTextField) comp).setValues((Map) value);
- } else if (comp instanceof JFileChooser) {
- ((JFileChooser) comp).setName((String)value);
- }
- }
-
- private JButton createIconButton(ImageIcon icon) {
- JButton btn = new JButton();
- btn.setBorder(BorderFactory.createEmptyBorder());
- btn.setIcon(icon);
- btn.setContentAreaFilled(false);
- btn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- btn.setAlignmentX(Component.RIGHT_ALIGNMENT);
-
- return btn;
- }
-
- private void refreshColors() {
- Color bgColor;
- Color fontColor;
- if (this.isDisabled()) {
- bgColor = Operation.disabledBgColor;
- fontColor = Operation.disabledFontColor;
- } else if (this.isError()) {
- bgColor = Operation.errorBgColor;
- fontColor = Operation.errorFontColor;
- } else if (this.isBreakpoint()) {
- bgColor = Operation.breakBgColor;
- fontColor = Operation.breakFontColor;
- } else {
- bgColor = Operation.defaultBgColor;
- fontColor = Operation.defaultFontColor;
- }
-
- this.setBackground(bgColor);
- this.changeFontColor(this, fontColor);
- }
-
- private void changeFontColor(Container container, Color color) {
- for (Component comp : container.getComponents()) {
- if (comp instanceof JLabel || comp.equals(errorArea)) {
- comp.setForeground(color);
- } else if (comp instanceof Container) {
- changeFontColor((Container) comp, color);
- }
- }
- }
-
- protected void addUIElement(String caption, Component comp) {
- this.addUIElement(caption, comp, true, null);
- }
-
- protected void addUIElement(String caption, Component comp, boolean notifyChange) {
- this.addUIElement(caption, comp, notifyChange, null);
- }
-
- protected void addUIElement(String caption, Component comp, String identifier) {
- this.addUIElement(caption, comp, true, identifier);
- }
-
- protected void addUIElement(String caption, Component comp, boolean notifyChange, String identifier) {
- comp.setCursor(Cursor.getDefaultCursor());
-
- Box box = Box.createHorizontalBox();
- box.setAlignmentX(Component.LEFT_ALIGNMENT);
- if (comp instanceof JCheckBox) {
- comp.setBackground(new Color(0, 0, 0, 0));
- }
- JLabel lbl = new JLabel(caption);
- box.add(lbl);
- box.add(Box.createHorizontalStrut(10));
- box.add(comp);
- this.contentBox.add(box);
- this.contentBox.add(Box.createVerticalStrut(10));
- if( identifier == null )
- identifier = caption;
- this.uiElements.put(identifier, comp);
-
- if (notifyChange) {
- if (notifyChangeListener == null) {
- notifyChangeListener = new NotifyChangeListener();
- }
-
- if (comp instanceof JTextField) {
- ((JTextField) comp).getDocument().addDocumentListener(notifyChangeListener);
- } else if (comp instanceof JSpinner) {
- ((JSpinner) comp).addChangeListener(notifyChangeListener);
- } else if (comp instanceof JComboBox) {
- ((JComboBox>) comp).addActionListener(notifyChangeListener);
- } else if (comp instanceof VariableTextArea) {
- ((VariableTextArea) comp).addDocumentListener(notifyChangeListener);
- } else if (comp instanceof JCheckBox) {
- ((JCheckBox) comp).addActionListener(notifyChangeListener);
- } else if (comp instanceof FormatTextField) {
- ((FormatTextField) comp).addDocumentListener(notifyChangeListener);
- } else {
- Logger.getInstance().err("could not add a default change listener for " + comp.getClass());
- }
- }
- }
-
- @Override
- public Dimension getPreferredSize() {
- Dimension dim = super.getPreferredSize();
- int width = this.getParent().getWidth();
- dim.setSize(width, dim.height);
- return dim;
- }
-
- public byte[] performOperation(byte[] input) {
- try {
- byte[] result = this.perform(input);
- this.setErrorMessage(null);
- return result;
- } catch (EOFException e) {
- this.setErrorMessage(new EOFException("End of file"));
- return new byte[0];
- } catch (Throwable e) {
- this.setErrorMessage(e);
- return new byte[0];
- }
- }
-
- public void setErrorMessage(Throwable e) {
- boolean error = e != null;
-
- String msg = error ? e.getMessage() : "";
- String text;
- if (msg == null) {
- text = e.getClass().getName();
- } else {
- text = error ? (msg.isEmpty() ? e.toString() : msg) : "";
- }
-
- this.errorArea.setText(text);
-
- this.setError(error);
- this.refreshColors();
- this.validate();
- this.repaint();
- }
-
- public void removeChangeListener() {
- this.changeListener = null;
- }
-
- public void setChangeListener(ChangeListener listener) {
- this.changeListener = listener;
- }
-
- protected void notifyChange() {
- if (this.changeListener != null) {
- this.changeListener.stateChanged(new ChangeEvent(this));
- }
- }
-
- public boolean isBreakpoint() {
- return breakpoint;
- }
-
- public void setBreakpoint(boolean breakpoint) {
- this.breakpoint = breakpoint;
- }
-
- public boolean isDisabled() {
- return disabled;
- }
-
- public void setDisabled(boolean disabled) {
- this.disabled = disabled;
- }
-
- public boolean isError() {
- return error;
- }
-
- public void setError(boolean error) {
- this.error = error;
- }
-
- public void setOperationSkip(int count) {
- if( count < 0 )
- count = 0;
- this.operationSkip = count;
- }
-
- public int getOperationSkip() {
- return this.operationSkip;
- }
-
- public void setLaneSkip(int count) {
- if( count < 0 )
- count = 0;
- this.laneSkip = count;
- }
-
- public int getLaneSkip() {
- return this.laneSkip;
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface OperationInfos {
-
- public String name()
-
- default "Unnamed plugin!";
-
- public String description()
-
- default "Change this description!";
-
- public OperationCategory category() default OperationCategory.MISC;
- }
-
- protected abstract byte[] perform(byte[] input) throws Exception;
-
- public void createUI() {
-
- }
-
- public void onRemove() {
-
- }
-
- private class NotifyChangeListener implements DocumentListener, ActionListener, ChangeListener {
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- notifyChange();
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- notifyChange();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- notifyChange();
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- notifyChange();
- }
-
- @Override
- public void stateChanged(ChangeEvent e) {
- notifyChange();
- }
- }
-}
diff --git a/src/de/usd/cstchef/operations/OperationCategory.java b/src/de/usd/cstchef/operations/OperationCategory.java
deleted file mode 100644
index 10abe79..0000000
--- a/src/de/usd/cstchef/operations/OperationCategory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package de.usd.cstchef.operations;
-
-public enum OperationCategory {
- ARITHMETIC("Arithmetic"),
- BYTEOPERATION("Byte Operations"),
- COMPRESSION("Compression"),
- CONDITIONALS("Conditionals"),
- DATAFORMAT("Data format"),
- DATES("Date / Time"),
- ENCRYPTION("Encryption / Encoding"),
- EXTRACTORS("Extractors"),
- HASHING("Hashing"),
- MISC("Misc"),
- NETWORKING("Networking"),
- SETTER("Setter"),
- SIGNATURE("Signature"),
- STRING("String"),
- UTILS("Utils");
-// LANGUAGE("Language"),
-// FLOWCONTROL("Flow control");
-
- private final String text;
-
- OperationCategory(final String text) {
- this.text = text;
- }
-
- @Override
- public String toString() {
- return text;
- }
-}
diff --git a/src/de/usd/cstchef/operations/arithmetic/ArithmeticDelimiterOperation.java b/src/de/usd/cstchef/operations/arithmetic/ArithmeticDelimiterOperation.java
deleted file mode 100644
index 830ad73..0000000
--- a/src/de/usd/cstchef/operations/arithmetic/ArithmeticDelimiterOperation.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package de.usd.cstchef.operations.arithmetic;
-
-import java.util.Set;
-
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.operations.Operation;
-
-public abstract class ArithmeticDelimiterOperation extends Operation {
-
- private JComboBox delimiterBox;
- private JCheckBox floatCheckBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String delimiterKey = (String) this.delimiterBox.getSelectedItem();
- String delimiter = Utils.delimiters.get(delimiterKey);
- String[] lines = new String(input).split(delimiter);
- if (lines.length < 2) {
- return input;
- }
-
- double[] numbers = new double[lines.length];
-
- double result = Utils.parseNumber(lines[0].trim());
- numbers[0] = result;
- double val;
- for (int i = 1; i < lines.length; i++) {
- val = Utils.parseNumber(lines[i].trim());
- numbers[i] = val;
- result = this.calculate(result, val);
- }
-
- result = onFinish(result, numbers);
- String str = "";
- if (floatCheckBox.isSelected()) {
- str = String.valueOf(result);
- }
- else {
- str = String.valueOf(Math.round(result));
- }
- return str.getBytes();
- }
-
- protected double onFinish(double result, double[] lines) {
- return result;
- }
-
- protected abstract double calculate(double a, double b);
-
- @Override
- public void createUI() {
- Set delimSet = Utils.delimiters.keySet();
- String[] delimiters = delimSet.toArray(new String[delimSet.size()]);
-
- this.delimiterBox = new JComboBox(delimiters);
- this.addUIElement("Delimiter", this.delimiterBox);
-
- this.floatCheckBox = new JCheckBox();
- this.addUIElement("Point Number", this.floatCheckBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/arithmetic/ArithmeticOperation.java b/src/de/usd/cstchef/operations/arithmetic/ArithmeticOperation.java
deleted file mode 100644
index 02b11ff..0000000
--- a/src/de/usd/cstchef/operations/arithmetic/ArithmeticOperation.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package de.usd.cstchef.operations.arithmetic;
-
-import javax.swing.JCheckBox;
-import javax.swing.JTextField;
-
-import de.usd.cstchef.operations.Operation;
-
-public abstract class ArithmeticOperation extends Operation {
-
- private JTextField numberInput;
- private JCheckBox floatCheckBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String result = "";
- try {
-
- String i = new String(input);
-
- //A little trick
- if (i.isEmpty()) {
- i = "0";
- }
-
- Double input_number = Double.valueOf(i);
- Double static_number = Double.valueOf(numberInput.getText());
- Double result_number = calculate(input_number, static_number);
-
-
- if (this.floatCheckBox.isSelected()) {
- result = String.valueOf(result_number);
- } else {
- result = String.valueOf(Math.round(result_number));
- }
-
- } catch( Exception e ) {
- throw new IllegalArgumentException("Input is not a number.");
- }
-
- return result.getBytes();
- }
-
- protected abstract double calculate(double input_number, double static_number);
-
- @Override
- public void createUI() {
- this.numberInput = new JTextField("1");
- this.addUIElement("Number", this.numberInput);
-
- this.floatCheckBox = new JCheckBox();
- this.addUIElement("Point Number", this.floatCheckBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/arithmetic/Divide.java b/src/de/usd/cstchef/operations/arithmetic/Divide.java
deleted file mode 100644
index 5c2a9d3..0000000
--- a/src/de/usd/cstchef/operations/arithmetic/Divide.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package de.usd.cstchef.operations.arithmetic;
-
-import javax.swing.JCheckBox;
-
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "Single - Divide", category = OperationCategory.ARITHMETIC, description = "Divide input by the given number")
-public class Divide extends ArithmeticOperation {
-
- private JCheckBox reverse;
-
- @Override
- protected double calculate(double input_number, double static_number) {
-
- if( reverse.isSelected() ) {
-
- if( input_number == 0 )
- input_number = 1;
-
- return static_number / input_number;
-
- } else {
-
- if( static_number == 0 )
- static_number = 1;
-
- return input_number / static_number;
-
- }
- }
-
- @Override
- public void createUI() {
- super.createUI();
-
- this.reverse = new JCheckBox();
- this.addUIElement("Reverse", this.reverse);
- }
-}
diff --git a/src/de/usd/cstchef/operations/arithmetic/Median.java b/src/de/usd/cstchef/operations/arithmetic/Median.java
deleted file mode 100644
index dad3f38..0000000
--- a/src/de/usd/cstchef/operations/arithmetic/Median.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.usd.cstchef.operations.arithmetic;
-
-import java.util.Arrays;
-
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "List - Median", category = OperationCategory.ARITHMETIC, description = "Computes the median of a list of numbers.")
-public class Median extends ArithmeticDelimiterOperation {
-
- @Override
- protected double calculate(double a, double b) {
- // we dont need this here
- return a;
- }
-
- @Override
- protected double onFinish(double intermediateResult, double[] lines) {
- Arrays.sort(lines);
- double result;
-
- if (lines.length % 2 == 0) {
- int mid = lines.length / 2;
- result = (lines[mid] + lines[mid - 1]) / 2;
- } else {
- result = lines[(int) (Math.floor(lines.length / 2))];
- }
- return result;
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/byteoperation/ByteKeyOperation.java b/src/de/usd/cstchef/operations/byteoperation/ByteKeyOperation.java
deleted file mode 100644
index c75063a..0000000
--- a/src/de/usd/cstchef/operations/byteoperation/ByteKeyOperation.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package de.usd.cstchef.operations.byteoperation;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.view.ui.FormatTextField;
-
-public abstract class ByteKeyOperation extends Operation {
-
- private FormatTextField inputTxt;
-
- public void createUI() {
- this.inputTxt = new FormatTextField();
- this.addUIElement("Key", inputTxt);
- }
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] result = new byte[input.length];
- byte[] key = this.inputTxt.getText();
-
- if (key.length == 0) {
- return input;
- }
-
- int keyCounter = 0;
- for (int i = 0; i < input.length; i++) {
- byte var = key[keyCounter];
- keyCounter = (keyCounter + 1) % key.length;
- result[i] = calculate(input[i], var);
- }
-
- return result;
- }
-
- protected abstract byte calculate(byte input, byte var);
-
-}
diff --git a/src/de/usd/cstchef/operations/conditional/ConditionalOperation.java b/src/de/usd/cstchef/operations/conditional/ConditionalOperation.java
deleted file mode 100644
index a928361..0000000
--- a/src/de/usd/cstchef/operations/conditional/ConditionalOperation.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package de.usd.cstchef.operations.conditional;
-
-import javax.swing.JTextField;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-public abstract class ConditionalOperation extends Operation {
-
- protected VariableTextField expr;
- private JTextField operationSkipField;
- private JTextField laneSkipField;
-
- public void setOperationSkip() {
-
- try {
- int operationSkip = Integer.valueOf(operationSkipField.getText());
- this.setOperationSkip(operationSkip);
- } catch( Exception e ) {
- throw new IllegalArgumentException("Input is not a number.");
- }
- }
-
- public void setLaneSkip() {
-
- try {
- int laneSkip = Integer.valueOf(laneSkipField.getText());
- this.setLaneSkip(laneSkip);
- } catch( Exception e ) {
- throw new IllegalArgumentException("Input is not a number.");
- }
- }
-
- public void resetSkips() {
- this.setOperationSkip(0);
- this.setLaneSkip(0);
- }
-
- @Override
- public void createUI() {
- this.expr = new VariableTextField();
- this.addUIElement("Expr", this.expr);
-
- this.operationSkipField = new JTextField("0");
- this.addUIElement("Skip Operations", this.operationSkipField);
-
- this.laneSkipField = new JTextField("0");
- this.addUIElement("Skip Lanes", this.laneSkipField);
-
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/conditional/NumberCompare.java b/src/de/usd/cstchef/operations/conditional/NumberCompare.java
deleted file mode 100644
index f336d85..0000000
--- a/src/de/usd/cstchef/operations/conditional/NumberCompare.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package de.usd.cstchef.operations.conditional;
-
-import javax.swing.JComboBox;
-
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "Number Compare", category = OperationCategory.CONDITIONALS, description = "Skip if evaluates to true")
-public class NumberCompare extends ConditionalOperation {
-
- private JComboBox operationBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- Double inputNumber;
- Double userNumber;
-
- try {
- String tmp = new String(input);
- inputNumber = Double.valueOf(tmp);
- userNumber = Double.valueOf(this.expr.getText());
- } catch( Exception e ) {
- throw new IllegalArgumentException("Input is not a number.");
- }
-
- boolean condition = false;
- switch ((String)this.operationBox.getSelectedItem()) {
- case "equal":
- if( inputNumber.compareTo(userNumber) == 0 )
- condition = true;
- break;
- case "not equal":
- if( inputNumber.compareTo(userNumber) != 0 )
- condition = true;
- break;
- case "greater":
- if( inputNumber < userNumber )
- condition = true;
- break;
- case "lower":
- if( inputNumber > userNumber )
- condition = true;
- break;
- case "greater equal":
- if( inputNumber <= userNumber )
- condition = true;
- break;
- case "lower equal":
- if( inputNumber >= userNumber )
- condition = true;
- break;
- }
-
- if( condition ) {
- this.setOperationSkip();
- this.setLaneSkip();
- } else {
- this.resetSkips();
- }
-
- return input;
- }
-
- @Override
- public void createUI() {
- super.createUI();
- this.operationBox = new JComboBox<>(new String[] {"equal", "not equal", "lower", "greater", "lower equal", "greater equal"});
- this.operationBox.setSelectedItem("equal");
- this.addUIElement("Lineseperator", this.operationBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/conditional/RegexMatch.java b/src/de/usd/cstchef/operations/conditional/RegexMatch.java
deleted file mode 100644
index 2f156af..0000000
--- a/src/de/usd/cstchef/operations/conditional/RegexMatch.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package de.usd.cstchef.operations.conditional;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.swing.JCheckBox;
-
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "Regex Match", category = OperationCategory.CONDITIONALS, description = "Skip if regex matches")
-public class RegexMatch extends ConditionalOperation {
-
- private JCheckBox invert;
- private JCheckBox find;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- Pattern p = Pattern.compile(this.expr.getText());
- Matcher m = p.matcher(new String(input));
-
- boolean condition = false;
- if( find.isSelected() ) {
- condition = m.find();
- } else {
- condition = m.matches();
- }
-
- if( condition ^ invert.isSelected() ) {
- this.setOperationSkip();
- this.setLaneSkip();
- } else {
- this.resetSkips();
- }
-
- return input;
- }
-
- @Override
- public void createUI() {
- super.createUI();
-
- this.invert = new JCheckBox();
- this.addUIElement("Invert Match", this.invert);
-
- this.find = new JCheckBox();
- this.addUIElement("Find anywhere", this.find);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/conditional/StringContains.java b/src/de/usd/cstchef/operations/conditional/StringContains.java
deleted file mode 100644
index d29ee8a..0000000
--- a/src/de/usd/cstchef/operations/conditional/StringContains.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package de.usd.cstchef.operations.conditional;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "String Contains", category = OperationCategory.CONDITIONALS, description = "Skip if input contains")
-public class StringContains extends ConditionalOperation {
-
- private JCheckBox invert;
- private JCheckBox caseSensitive;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = cbs.getHelpers();
- int start = helpers.indexOf(input, this.expr.getBytes(), caseSensitive.isSelected(), 0, input.length);
-
- if( (start >= 0) ^ invert.isSelected() ) {
- this.setOperationSkip();
- this.setLaneSkip();
- } else {
- this.resetSkips();
- }
-
- return input;
- }
-
- @Override
- public void createUI() {
- super.createUI();
-
- this.invert = new JCheckBox();
- this.addUIElement("Invert Match", this.invert);
-
- this.caseSensitive = new JCheckBox();
- this.addUIElement("Case Sensitive", this.caseSensitive);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/conditional/StringMatch.java b/src/de/usd/cstchef/operations/conditional/StringMatch.java
deleted file mode 100644
index 56cfbf0..0000000
--- a/src/de/usd/cstchef/operations/conditional/StringMatch.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.usd.cstchef.operations.conditional;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "String Match", category = OperationCategory.CONDITIONALS, description = "Skip if input matches")
-public class StringMatch extends ConditionalOperation {
-
- private JCheckBox invert;
- private JCheckBox caseSensitive;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] search = this.expr.getBytes();
- if( search.length != input.length ) {
- if( invert.isSelected() ) {
- this.setOperationSkip();
- this.setLaneSkip();
- } else {
- this.resetSkips();
- }
- return input;
- }
-
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = cbs.getHelpers();
- int start = helpers.indexOf(input, search, caseSensitive.isSelected(), 0, input.length);
-
- if( (start >= 0) ^ invert.isSelected() ) {
- this.setOperationSkip();
- this.setLaneSkip();
- } else {
- this.resetSkips();
- }
-
- return input;
- }
-
- @Override
- public void createUI() {
- super.createUI();
-
- this.invert = new JCheckBox();
- this.addUIElement("Invert Match", this.invert);
-
- this.caseSensitive = new JCheckBox();
- this.addUIElement("Case Sensitive", this.caseSensitive);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/dataformat/FromHex.java b/src/de/usd/cstchef/operations/dataformat/FromHex.java
deleted file mode 100644
index 3ba4659..0000000
--- a/src/de/usd/cstchef/operations/dataformat/FromHex.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.usd.cstchef.operations.dataformat;
-
-import java.util.Set;
-
-import javax.swing.JComboBox;
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.dataformat.ToHex.Delimiter;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "From Hex", category = OperationCategory.DATAFORMAT, description = "From hex")
-public class FromHex extends Operation {
-
- private JComboBox delimiterBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String selectedKey = (String) this.delimiterBox.getSelectedItem();
- Delimiter delimiter = ToHex.delimiters.get(selectedKey);
-
- if (delimiter.value.length == 0) { // No delimiter
- return Hex.decode(input);
- }
-
- String delimiterStr = new String(delimiter.value);
- String inputStr = new String(input);
- inputStr = inputStr.replace(delimiterStr, "");
-
- return Hex.decode(inputStr);
- }
-
- @Override
- public void createUI() {
- Set choices = ToHex.delimiters.keySet();
- delimiterBox = new JComboBox(choices.toArray(new String[choices.size()]));
- delimiterBox.setSelectedIndex(0);
-
- this.addUIElement("Delimiter", delimiterBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/dataformat/HtmlEncode.java b/src/de/usd/cstchef/operations/dataformat/HtmlEncode.java
deleted file mode 100644
index 051a9a2..0000000
--- a/src/de/usd/cstchef/operations/dataformat/HtmlEncode.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package de.usd.cstchef.operations.dataformat;
-
-import java.io.ByteArrayOutputStream;
-
-import javax.swing.JCheckBox;
-
-import org.apache.commons.text.StringEscapeUtils;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTML Encode", category = OperationCategory.DATAFORMAT, description = "HTML Encode")
-public class HtmlEncode extends Operation {
-
- private JCheckBox checkbox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] result = null;
- if( checkbox.isSelected() ) {
-
- byte[] delimiter = "".getBytes();
- byte[] closer = ";".getBytes();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(delimiter);
- for (int i = 0; i < input.length - 1; i++) {
- out.write(String.valueOf(Byte.toUnsignedInt(input[i])).getBytes());
- out.write(closer);
- out.write(delimiter);
- }
-
- out.write(String.valueOf(Byte.toUnsignedInt(input[input.length - 1])).getBytes());
- out.write(closer);
- result = out.toByteArray();
-
- } else {
- String tmp = new String(input);
- tmp = StringEscapeUtils.escapeHtml4(tmp);
- result = tmp.getBytes();
- }
-
- return result;
- }
-
- @Override
- public void createUI() {
- this.checkbox = new JCheckBox("Encode all");
- this.checkbox.setSelected(false);
- this.addUIElement(null, this.checkbox, "checkbox1");
- }
-}
diff --git a/src/de/usd/cstchef/operations/dataformat/ToHex.java b/src/de/usd/cstchef/operations/dataformat/ToHex.java
deleted file mode 100644
index 4a3737f..0000000
--- a/src/de/usd/cstchef/operations/dataformat/ToHex.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package de.usd.cstchef.operations.dataformat;
-
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Set;
-
-import javax.swing.JComboBox;
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "To Hex", category = OperationCategory.DATAFORMAT, description = "To hex")
-public class ToHex extends Operation {
-
- static HashMap delimiters = new HashMap() {
- {
- put("None", new Delimiter(""));
- put("Space", new Delimiter(" "));
- put("Comma", new Delimiter(","));
- put("Colon", new Delimiter(":"));
- put("Semi-colon", new Delimiter(";"));
- put("Colon", new Delimiter(":"));
- put("Line feed", new Delimiter("\n"));
- put("CRLF", new Delimiter("\r\n"));
- put("0x", new Delimiter("0x", true));
- put("\\x", new Delimiter("\\x", true));
- }
- };
-
- private JComboBox delimiterBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String selectedKey = (String) this.delimiterBox.getSelectedItem();
- Delimiter delimiter = ToHex.delimiters.get(selectedKey);
-
- if (delimiter.value.length == 0) { // No delimiter
- return Hex.encode(input);
- }
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- if (input.length > 0 && delimiter.writeAtStart) {
- out.write(delimiter.value);
- }
-
- for (int i = 0; i < input.length - 1; i++) {
- out.write(Hex.encode(new byte[] { input[i] }));
- out.write(delimiter.value);
- }
-
- if (input.length > 0) {
- out.write(Hex.encode(new byte[] { input[input.length - 1] })); // wow
- if (delimiter.writeAtEnd) {
- out.write(delimiter.value);
- }
- }
-
- return out.toByteArray();
- }
-
- @Override
- public void createUI() {
- Set choices = ToHex.delimiters.keySet();
- delimiterBox = new JComboBox(choices.toArray(new String[choices.size()]));
- delimiterBox.setSelectedIndex(0);
-
- this.addUIElement("Delimiter", delimiterBox);
- }
-
- public static class Delimiter {
- public byte[] value;
- public boolean writeAtStart;
- public boolean writeAtEnd;
-
- public Delimiter(String value) {
- this(value, false, false);
- }
-
- public Delimiter(String value, boolean writeAtStart) {
- this(value, writeAtStart, false);
- }
-
- public Delimiter(String value, boolean writeAtStart, boolean writeAtEnd) {
- this.value = value.getBytes();
- this.writeAtStart = writeAtStart;
- this.writeAtEnd = writeAtEnd;
- }
- }
-}
diff --git a/src/de/usd/cstchef/operations/dataformat/UrlEncode.java b/src/de/usd/cstchef/operations/dataformat/UrlEncode.java
deleted file mode 100644
index 813f670..0000000
--- a/src/de/usd/cstchef/operations/dataformat/UrlEncode.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package de.usd.cstchef.operations.dataformat;
-
-import java.io.ByteArrayOutputStream;
-
-import javax.swing.JCheckBox;
-
-import org.bouncycastle.util.encoders.Hex;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "Url Encode", category = OperationCategory.DATAFORMAT, description = "Url encode")
-public class UrlEncode extends Operation {
-
- private JCheckBox checkbox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = cbs.getHelpers();
-
- byte[] result = null;
- if( checkbox.isSelected() ) {
-
- byte[] delimiter = "%".getBytes();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(delimiter);
-
- for (int i = 0; i < input.length - 1; i++) {
- out.write(Hex.encode(new byte[] { input[i] }));
- out.write(delimiter);
- }
-
- out.write(Hex.encode(new byte[] { input[input.length - 1] }));
- result = out.toByteArray();
-
- } else {
- result = helpers.urlEncode(input);
- }
-
- return result;
- }
-
- @Override
- public void createUI() {
- this.checkbox = new JCheckBox("Encode all");
- this.checkbox.setSelected(false);
- this.addUIElement(null, this.checkbox, "checkbox1");
- }
-}
diff --git a/src/de/usd/cstchef/operations/datetime/UnixTimestamp.java b/src/de/usd/cstchef/operations/datetime/UnixTimestamp.java
deleted file mode 100644
index a1a6085..0000000
--- a/src/de/usd/cstchef/operations/datetime/UnixTimestamp.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.usd.cstchef.operations.datetime;
-
-import javax.swing.JCheckBox;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "Unix Timestamp", category = OperationCategory.DATES, description = "Returnes the current unix timestamp.")
-public class UnixTimestamp extends Operation {
-
- private JCheckBox milliBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- long timestamp = 0;
- if (milliBox.isSelected()) {
- timestamp = System.currentTimeMillis();
- }
- else {
- timestamp = System.currentTimeMillis() / 1000L;
- }
- return String.valueOf(timestamp).getBytes();
- }
-
- public void createUI() {
- this.milliBox = new JCheckBox();
- this.addUIElement("Milliseconds", this.milliBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/encryption/CipherUtils.java b/src/de/usd/cstchef/operations/encryption/CipherUtils.java
deleted file mode 100644
index 117c138..0000000
--- a/src/de/usd/cstchef/operations/encryption/CipherUtils.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package de.usd.cstchef.operations.encryption;
-
-import java.security.Provider;
-import java.security.Security;
-import java.util.HashMap;
-
-public class CipherUtils {
-
- private static CipherUtils instance;
-
- private HashMap algos;
-
- private CipherUtils() {
- algos = new HashMap<>();
-
- getCipherInfos();
- }
-
- private void getCipherInfos() {
- for (Provider provider : Security.getProviders()) {
- for (String key : provider.stringPropertyNames()) {
- if (key.startsWith("Cipher")) {
- String[] parts = key.split(" ");
- if (parts.length < 2) {
- continue;
- }
- String cipherName = parts[0].substring(7);
- String type = parts[1];
-
- CipherInfo info = algos.getOrDefault(cipherName, new CipherInfo());
- String property = provider.getProperty(key);
-
- if (type.equals("SupportedModes")) {
- String[] modes = property.split("\\|");
- info.setModes(modes);
- } else if (type.equals("SupportedPaddings")) {
- String[] paddings = property.split("\\|");
- info.setPaddings(paddings);
- }
- this.algos.put(cipherName, info);
- }
- }
- }
- }
-
- public static CipherUtils getInstance() {
- if (instance == null) {
- instance = new CipherUtils();
- }
- return instance;
- }
-
- public CipherInfo getCipherInfo(String algorithm) {
- return this.algos.getOrDefault(algorithm, new CipherInfo());
- }
-
- public class CipherInfo {
-
- private String[] modes;
- private String[] paddings;
-
-
- public CipherInfo() {
- this.modes = new String[0];
- this.paddings = new String[0];
- }
-
- public CipherInfo(String[] modes, String[] paddings) {
- this.modes = modes;
- this.paddings = paddings;
- }
-
- public String[] getModes() {
- return modes;
- }
-
- public void setModes(String[] modes) {
- this.modes = modes;
- }
-
- public String[] getPaddings() {
- return paddings;
- }
-
- public void setPaddings(String[] paddings) {
- this.paddings = paddings;
- }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("Modes: ");
- for (String mode : this.modes) {
- buf.append(mode);
- buf.append("|");
- }
- buf.append(", Paddings: ");
- for (String padding : this.paddings) {
- buf.append(padding);
- buf.append("|");
- }
-
- return buf.toString();
- }
-
- }
-}
diff --git a/src/de/usd/cstchef/operations/encryption/CryptOperation.java b/src/de/usd/cstchef/operations/encryption/CryptOperation.java
deleted file mode 100644
index a0ca5f2..0000000
--- a/src/de/usd/cstchef/operations/encryption/CryptOperation.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package de.usd.cstchef.operations.encryption;
-
-import javax.crypto.Cipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.swing.JComboBox;
-
-import org.bouncycastle.util.encoders.Hex;
-import org.bouncycastle.util.encoders.Base64;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.encryption.CipherUtils.CipherInfo;
-import de.usd.cstchef.view.ui.FormatTextField;
-
-public abstract class CryptOperation extends Operation {
-
- private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
-
- protected String algorithm;
- protected FormatTextField ivTxt;
- protected FormatTextField keyTxt;
-
- protected JComboBox cipherMode;
- protected JComboBox inputMode;
- protected JComboBox outputMode;
- protected JComboBox paddings;
-
- public CryptOperation(String alogrithm) {
- super();
- this.algorithm = alogrithm;
- this.createMyUI();
- }
-
- protected byte[] crypt(byte[] input, int cipherMode, String algorithm, String mode, String padding)
- throws Exception {
- byte[] key = keyTxt.getText();
- byte[] iv = ivTxt.getText();
-
- SecretKeySpec secretKeySpec = new SecretKeySpec(key, algorithm);
- IvParameterSpec ivSpec = new IvParameterSpec(iv);
- Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, mode, padding));
-
- if( mode.equals("ECB") ) {
- cipher.init(cipherMode, secretKeySpec);
- } else {
- cipher.init(cipherMode, secretKeySpec, ivSpec);
- }
-
- String selectedInputMode = (String)inputMode.getSelectedItem();
- String selectedOutputMode = (String)outputMode.getSelectedItem();
-
- if( selectedInputMode.equals("Hex") )
- input = Hex.decode(input);
- if( selectedInputMode.equals("Base64") )
- input = Base64.decode(input);
-
- byte[] encrypted = cipher.doFinal(input);
-
- if( selectedOutputMode.equals("Hex") )
- encrypted = Hex.encode(encrypted);
- if( selectedOutputMode.equals("Base64") )
- encrypted = Base64.encode(encrypted);
-
- return encrypted;
- }
-
- public void createMyUI() {
- this.ivTxt = new FormatTextField();
- this.addUIElement("IV", this.ivTxt);
-
- this.keyTxt = new FormatTextField();
- this.addUIElement("Key", this.keyTxt);
- CipherUtils utils = CipherUtils.getInstance();
-
- CipherInfo info = utils.getCipherInfo(this.algorithm);
- this.cipherMode = new JComboBox<>(info.getModes());
- this.addUIElement("Mode", this.cipherMode);
-
- this.paddings = new JComboBox<>(info.getPaddings());
- this.addUIElement("Padding", this.paddings);
-
- this.inputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Input", this.inputMode);
-
- this.outputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Output", this.outputMode);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/encryption/DecryptionOperation.java b/src/de/usd/cstchef/operations/encryption/DecryptionOperation.java
deleted file mode 100644
index 9d7b7b6..0000000
--- a/src/de/usd/cstchef/operations/encryption/DecryptionOperation.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.usd.cstchef.operations.encryption;
-
-import javax.crypto.Cipher;
-
-public abstract class DecryptionOperation extends CryptOperation {
-
- public DecryptionOperation(String alogrithm) {
- super(alogrithm);
- }
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- return this.crypt(input, Cipher.DECRYPT_MODE, this.algorithm, (String) this.cipherMode.getSelectedItem(),
- (String) this.paddings.getSelectedItem());
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/encryption/EncryptionOperation.java b/src/de/usd/cstchef/operations/encryption/EncryptionOperation.java
deleted file mode 100644
index 65e90ed..0000000
--- a/src/de/usd/cstchef/operations/encryption/EncryptionOperation.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.usd.cstchef.operations.encryption;
-
-import javax.crypto.Cipher;
-
-public abstract class EncryptionOperation extends CryptOperation {
-
- public EncryptionOperation(String alogrithm) {
- super(alogrithm);
- }
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- return this.crypt(input, Cipher.ENCRYPT_MODE, this.algorithm, (String) this.cipherMode.getSelectedItem(),
- (String) this.paddings.getSelectedItem());
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/encryption/RsaDecryption.java b/src/de/usd/cstchef/operations/encryption/RsaDecryption.java
deleted file mode 100644
index 908a3e0..0000000
--- a/src/de/usd/cstchef/operations/encryption/RsaDecryption.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package de.usd.cstchef.operations.encryption;
-
-import javax.crypto.Cipher;
-import javax.swing.JComboBox;
-
-import org.bouncycastle.util.encoders.Base64;
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.encryption.CipherUtils.CipherInfo;
-import de.usd.cstchef.operations.signature.KeystoreOperation;
-
-@OperationInfos(name = "RSA Decryption", category = OperationCategory.ENCRYPTION, description = "Decrypt input using a private key")
-public class RsaDecryption extends KeystoreOperation {
-
- private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
-
- protected String algorithm = "RSA";
- protected String cipherMode = "ECB";
-
- protected JComboBox inputMode;
- protected JComboBox outputMode;
- protected JComboBox paddings;
-
- public RsaDecryption() {
- super();
- this.createMyUI();
- }
-
- protected byte[] perform(byte[] input) throws Exception {
-
- if( ! this.keyAvailable.isSelected() )
- throw new IllegalArgumentException("No private key available.");
-
- String padding = (String)paddings.getSelectedItem();
- Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, cipherMode, padding));
- cipher.init(Cipher.DECRYPT_MODE, this.selectedEntry.getPrivateKey());
-
- String selectedInputMode = (String)inputMode.getSelectedItem();
- String selectedOutputMode = (String)outputMode.getSelectedItem();
-
- if( selectedInputMode.equals("Hex") )
- input = Hex.decode(input);
- if( selectedInputMode.equals("Base64") )
- input = Base64.decode(input);
-
- byte[] encrypted = cipher.doFinal(input);
-
- if( selectedOutputMode.equals("Hex") )
- encrypted = Hex.encode(encrypted);
- if( selectedOutputMode.equals("Base64") )
- encrypted = Base64.encode(encrypted);
-
- return encrypted;
- }
-
- public void createMyUI() {
-
- super.createMyUI();
-
- CipherUtils utils = CipherUtils.getInstance();
- CipherInfo info = utils.getCipherInfo(this.algorithm);
-
- this.paddings = new JComboBox<>(info.getPaddings());
- this.addUIElement("Padding", this.paddings);
-
- this.inputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Input", this.inputMode);
-
- this.outputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Output", this.outputMode);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/encryption/RsaEncryption.java b/src/de/usd/cstchef/operations/encryption/RsaEncryption.java
deleted file mode 100644
index edcde37..0000000
--- a/src/de/usd/cstchef/operations/encryption/RsaEncryption.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package de.usd.cstchef.operations.encryption;
-
-import javax.crypto.Cipher;
-import javax.swing.JComboBox;
-
-import org.bouncycastle.util.encoders.Base64;
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.encryption.CipherUtils.CipherInfo;
-import de.usd.cstchef.operations.signature.KeystoreOperation;
-
-@OperationInfos(name = "RSA Encryption", category = OperationCategory.ENCRYPTION, description = "Encrypt input using a certificate")
-public class RsaEncryption extends KeystoreOperation {
-
- private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
-
- protected String algorithm = "RSA";
- protected String cipherMode = "ECB";
-
- protected JComboBox inputMode;
- protected JComboBox outputMode;
- protected JComboBox paddings;
-
- public RsaEncryption() {
- super();
- this.createMyUI();
- }
-
- protected byte[] perform(byte[] input) throws Exception {
-
- if( ! this.certAvailable.isSelected() )
- throw new IllegalArgumentException("No certificate available.");
-
- String padding = (String)paddings.getSelectedItem();
- Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, cipherMode, padding));
- cipher.init(Cipher.ENCRYPT_MODE, this.cert.getPublicKey());
-
- String selectedInputMode = (String)inputMode.getSelectedItem();
- String selectedOutputMode = (String)outputMode.getSelectedItem();
-
- if( selectedInputMode.equals("Hex") )
- input = Hex.decode(input);
- if( selectedInputMode.equals("Base64") )
- input = Base64.decode(input);
-
- byte[] encrypted = cipher.doFinal(input);
-
- if( selectedOutputMode.equals("Hex") )
- encrypted = Hex.encode(encrypted);
- if( selectedOutputMode.equals("Base64") )
- encrypted = Base64.encode(encrypted);
-
- return encrypted;
- }
-
- public void createMyUI() {
-
- super.createMyUI();
-
- CipherUtils utils = CipherUtils.getInstance();
- CipherInfo info = utils.getCipherInfo(this.algorithm);
-
- this.paddings = new JComboBox<>(info.getPaddings());
- this.addUIElement("Padding", this.paddings);
-
- this.inputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Input", this.inputMode);
-
- this.outputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Output", this.outputMode);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpBodyExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpBodyExtractor.java
deleted file mode 100644
index 3f8c907..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpBodyExtractor.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IRequestInfo;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "HTTP Body", category = OperationCategory.EXTRACTORS, description = "Extracts the body of a HTTP request.")
-public class HttpBodyExtractor extends Operation {
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- try {
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IRequestInfo requestInfo = cbs.getHelpers().analyzeRequest(input);
- int bodyOffset = requestInfo.getBodyOffset();
-
- byte[] body = Arrays.copyOfRange(input, bodyOffset, input.length);
- return body;
- } catch (Exception e) {
- throw new IllegalArgumentException("Provided input is not a valid http request.");
- }
- }
-}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java
deleted file mode 100644
index a1616d8..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import org.bouncycastle.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IResponseInfo;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HTTP Cookie", category = OperationCategory.EXTRACTORS, description = "Extracts a cookie from a HTTP request.")
-public class HttpCookieExtractor extends Operation {
-
- private VariableTextField cookieNameField;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] cookieName = cookieNameField.getBytes();
- if( cookieName.length == 0 )
- return input;
-
- byte[] cookieSearch = new byte[cookieName.length + 1];
- System.arraycopy(cookieName, 0, cookieSearch, 0, cookieName.length);
- System.arraycopy("=".getBytes(), 0, cookieSearch, cookieName.length, 1);
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- IResponseInfo resp = helpers.analyzeResponse(input);
- boolean isRequest = (resp.getStatusCode() == 0);
-
- String cookieHeader = "\r\nSet-Cookie: ";
- if(isRequest)
- cookieHeader = "\r\nCookie: ";
-
- try {
-
- int offset = helpers.indexOf(input, cookieHeader.getBytes(), false, 0, length);
- int line_end = helpers.indexOf(input, "\r\n".getBytes(), false, offset + 2, length);
- int start = helpers.indexOf(input, cookieSearch, true, offset, line_end);
- int end = helpers.indexOf(input, ";".getBytes(), true, start, line_end);
-
- if( end < 0 )
- end = line_end;
-
- return Arrays.copyOfRange(input, start + cookieName.length + 1, end);
-
- } catch( IllegalArgumentException e ) {
- throw new IllegalArgumentException("Cookie not found.");
- }
- }
-
- @Override
- public void createUI() {
- this.cookieNameField = new VariableTextField();
- this.addUIElement("Name", this.cookieNameField);
- }
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpGetExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpGetExtractor.java
deleted file mode 100644
index 5a4762b..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpGetExtractor.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HTTP GET Param", category = OperationCategory.EXTRACTORS, description = "Extracts a GET Parameter of a HTTP request.")
-public class HttpGetExtractor extends Operation {
-
- protected VariableTextField parameter;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String parameterName = parameter.getText();
- if( parameterName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- IParameter param = helpers.getRequestParameter(input, parameterName);
- if( param == null)
- throw new IllegalArgumentException("Parameter name not found.");
- if( param.getType() != IParameter.PARAM_URL )
- throw new IllegalArgumentException("Parameter type is not GET.");
-
- int start = param.getValueStart();
- int end = param.getValueEnd();
-
- byte[] result = Arrays.copyOfRange(input, start, end);
- return result;
-
- }
-
- @Override
- public void createUI() {
- this.parameter = new VariableTextField();
- this.addUIElement("Parameter", this.parameter);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpHeaderExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpHeaderExtractor.java
deleted file mode 100644
index 1783046..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpHeaderExtractor.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import org.bouncycastle.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HTTP Header", category = OperationCategory.EXTRACTORS, description = "Extracts a header of a HTTP request.")
-public class HttpHeaderExtractor extends Operation {
-
- private VariableTextField headerNameField;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] headerName = headerNameField.getBytes();
- if( headerName.length == 0 )
- return input;
-
- byte[] headerSearch = new byte[headerName.length + 4];
- System.arraycopy("\r\n".getBytes(), 0, headerSearch, 0, 2);
- System.arraycopy(headerName, 0, headerSearch, 2, headerName.length);
- System.arraycopy(": ".getBytes(), 0, headerSearch, headerName.length + 2, 2);
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- int offset = helpers.indexOf(input, headerSearch, true, 0, length);
-
- if( offset < 0 )
- throw new IllegalArgumentException("Header not found.");
-
- int valueStart = helpers.indexOf(input, " ".getBytes(), false, offset, length);
- if( valueStart < 0 )
- throw new IllegalArgumentException("Invalid Header format.");
- int valueEnd = helpers.indexOf(input, "\r\n".getBytes(), false, valueStart, length);
- if( valueEnd < 0 )
- throw new IllegalArgumentException("Invalid Header format.");
-
- byte[] result = Arrays.copyOfRange(input, valueStart + 1, valueEnd);
- return result;
- }
-
- @Override
- public void createUI() {
- this.headerNameField = new VariableTextField();
- this.addUIElement("Name", this.headerNameField);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpJsonExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpJsonExtractor.java
deleted file mode 100644
index ac3acaf..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpJsonExtractor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.Arrays;
-
-import javax.swing.JTextField;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP JSON", category = OperationCategory.EXTRACTORS, description = "Get a JSON value from HTTP message.")
-public class HttpJsonExtractor extends Operation {
-
- private JTextField fieldTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String keyName = fieldTxt.getText();
- if( keyName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- IParameter param = helpers.getRequestParameter(input, keyName);
- if( param == null)
- throw new IllegalArgumentException("Key not found.");
- if( param.getType() != IParameter.PARAM_JSON )
- throw new IllegalArgumentException("Parameter type is not JSON");
-
- int start = param.getValueStart();
- int end = param.getValueEnd();
-
- byte[] result = Arrays.copyOfRange(input, start, end);
- return result;
- }
-
- @Override
- public void createUI() {
- this.fieldTxt = new JTextField();
- this.addUIElement("Field", this.fieldTxt);
- }
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpMethodExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpMethodExtractor.java
deleted file mode 100644
index 6b21d4b..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpMethodExtractor.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import org.bouncycastle.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP Method", category = OperationCategory.EXTRACTORS, description = "Extracts the method of a HTTP request.")
-public class HttpMethodExtractor extends Operation {
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- try {
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- int methodEnd = helpers.indexOf(input, " ".getBytes(), false, 0, length);
- byte[] result = Arrays.copyOfRange(input, 0, methodEnd);
-
- return result;
-
- } catch (Exception e) {
- throw new IllegalArgumentException("Provided input is not a valid http request.");
- }
- }
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpPostExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpPostExtractor.java
deleted file mode 100644
index 7a0f171..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpPostExtractor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HTTP POST Param", category = OperationCategory.EXTRACTORS, description = "Extracts a POST parameter of a HTTP request.")
-public class HttpPostExtractor extends Operation {
-
- protected VariableTextField parameter;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String parameterName = parameter.getText();
- if( parameterName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- IParameter param = helpers.getRequestParameter(input, parameterName);
- if( param == null)
- throw new IllegalArgumentException("Parameter name not found.");
- if( param.getType() != IParameter.PARAM_BODY )
- throw new IllegalArgumentException("Parameter type is not POST");
-
- int start = param.getValueStart();
- int end = param.getValueEnd();
-
- byte[] result = Arrays.copyOfRange(input, start, end);
- return result;
- }
-
- @Override
- public void createUI() {
- this.parameter = new VariableTextField();
- this.addUIElement("Parameter", this.parameter);
- }
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpUriExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpUriExtractor.java
deleted file mode 100644
index e07a6f0..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpUriExtractor.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.Arrays;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP URI", category = OperationCategory.EXTRACTORS, description = "Extracts the URI of a HTTP request.")
-public class HttpUriExtractor extends Operation {
-
- private JCheckBox checkbox;
-
- @Override
- public void createUI() {
- this.checkbox = new JCheckBox("With parameters");
- this.checkbox.setSelected(true);
- this.addUIElement(null, this.checkbox, "checkbox1");
- }
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- try {
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- int firstMark = helpers.indexOf(input, " ".getBytes(), false, 0, length);
- int lineMark = helpers.indexOf(input, " ".getBytes(), false, firstMark + 1, length);
-
- int secondMark = helpers.indexOf(input, "?".getBytes(), false, firstMark + 1, length);
-
- if( this.checkbox.isSelected() || secondMark < 0 || secondMark >= lineMark) {
- secondMark = lineMark;
- }
-
- byte[] result = Arrays.copyOfRange(input, firstMark + 1, secondMark);
- return result;
-
- } catch (Exception e) {
- throw new IllegalArgumentException("Provided input is not a valid http request.");
- }
- }
-}
diff --git a/src/de/usd/cstchef/operations/extractors/HttpXmlExtractor.java b/src/de/usd/cstchef/operations/extractors/HttpXmlExtractor.java
deleted file mode 100644
index f14ef5e..0000000
--- a/src/de/usd/cstchef/operations/extractors/HttpXmlExtractor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.Arrays;
-
-import javax.swing.JTextField;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP XML", category = OperationCategory.EXTRACTORS, description = "Extract XML value from HTTP message.")
-public class HttpXmlExtractor extends Operation {
-
- private JTextField fieldTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String keyName = fieldTxt.getText();
- if( keyName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- IParameter param = helpers.getRequestParameter(input, keyName);
- if( param == null)
- throw new IllegalArgumentException("Key not found.");
- if( param.getType() != IParameter.PARAM_XML )
- throw new IllegalArgumentException("Parameter type is not XML");
-
- int start = param.getValueStart();
- int end = param.getValueEnd();
-
- byte[] result = Arrays.copyOfRange(input, start, end);
- return result;
- }
-
- @Override
- public void createUI() {
- this.fieldTxt = new JTextField();
- this.addUIElement("Field", this.fieldTxt);
- }
-}
diff --git a/src/de/usd/cstchef/operations/extractors/JsonExtractor.java b/src/de/usd/cstchef/operations/extractors/JsonExtractor.java
deleted file mode 100644
index 86b6534..0000000
--- a/src/de/usd/cstchef/operations/extractors/JsonExtractor.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import javax.swing.JTextField;
-
-import com.jayway.jsonpath.Configuration;
-import com.jayway.jsonpath.JsonPath;
-import com.jayway.jsonpath.spi.json.JsonProvider;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "JSON", category = OperationCategory.EXTRACTORS, description = "Extracts values of json objects.")
-public class JsonExtractor extends Operation {
-
- private static JsonProvider provider;
-
- //TODO should this be a VariableTextField?
- private JTextField fieldTxt;
-
- public JsonExtractor() {
- super();
- if (JsonExtractor.provider == null) {
- JsonExtractor.provider = Configuration.defaultConfiguration().jsonProvider();
- }
- }
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- if( fieldTxt.getText().equals("") )
- return input;
-
- Object document = provider.parse(new String(input));
- Object result = JsonPath.read(document, fieldTxt.getText());
-
- if( result == null )
- result = "null";
-
- Class extends Object> resultClass = result.getClass();
-
- if( resultClass == String.class ) {
- return ((String)result).getBytes();
- } else if( resultClass == Integer.class || resultClass == Float.class || resultClass == Double.class ) {
- return String.valueOf(result).getBytes();
- } else if( resultClass == Boolean.class ) {
- return String.valueOf(result).getBytes();
- }
-
- throw new IllegalArgumentException("JSON data of unknown type.");
- }
-
- @Override
- public void createUI() {
- this.fieldTxt = new JTextField();
- this.addUIElement("Field", this.fieldTxt);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/extractors/LineExtractor.java b/src/de/usd/cstchef/operations/extractors/LineExtractor.java
deleted file mode 100644
index badd030..0000000
--- a/src/de/usd/cstchef/operations/extractors/LineExtractor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import javax.swing.JComboBox;
-
-import org.bouncycastle.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "Line Extractor", category = OperationCategory.EXTRACTORS, description = "Extracts the specified line number.")
-public class LineExtractor extends Operation {
-
- private VariableTextField lineNumberField;
- private JComboBox formatBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- int lineNumber = 0;
- try {
- String number = lineNumberField.getText();
- lineNumber = Integer.valueOf(number);
- } catch(Exception e) {
- return input;
- }
-
- if( lineNumber <= 0 )
- return input;
-
- byte[] lineEndings = "\r\n".getBytes();
- switch ((String) this.formatBox.getSelectedItem()) {
- case "\\r\\n":
- lineEndings = "\r\n".getBytes();
- break;
- case "\\r":
- lineEndings = "\r".getBytes();
- break;
- case "\\n":
- lineEndings = "\n".getBytes();
- break;
- }
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- int start = 0;
- int offset = 0;
- int counter = 0;
- while( counter < lineNumber - 1 ) {
- offset = helpers.indexOf(input, lineEndings, false, start, length);
- if( offset >= 0 ) {
- start = offset + lineEndings.length;
- counter++;
- } else {
- break;
- }
- }
-
- int end = helpers.indexOf(input, lineEndings, false, start, length);
- if( end < 0 )
- end = length;
-
- byte[] result = Arrays.copyOfRange(input, start, end);
- return result;
- }
-
- @Override
- public void createUI() {
- this.lineNumberField = new VariableTextField();
- this.addUIElement("Name", this.lineNumberField);
- this.formatBox = new JComboBox<>(new String[] {"\\r\\n", "\\r", "\\n"});
- this.formatBox.setSelectedItem("\\r\\n");
- this.addUIElement("Lineseperator", this.formatBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/extractors/RegexExtractor.java b/src/de/usd/cstchef/operations/extractors/RegexExtractor.java
deleted file mode 100644
index 1f16cbd..0000000
--- a/src/de/usd/cstchef/operations/extractors/RegexExtractor.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package de.usd.cstchef.operations.extractors;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.swing.JComboBox;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "Regex", category = OperationCategory.EXTRACTORS, description = "Extracts using a regex.")
-public class RegexExtractor extends Operation {
-
- private static String LIST_MATCHES = "List matches";
- private static String LIST_GROUPS = "List capture groups";
-
- private VariableTextField regexTxt;
- private JComboBox outputBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- Pattern p = Pattern.compile(this.regexTxt.getText());
- Matcher m = p.matcher(new String(input));
- String outputType = (String) this.outputBox.getSelectedItem();
-
- StringBuffer buf = new StringBuffer();
-
- while (m.find()) {
- if (outputType.equals(LIST_MATCHES)) {
- buf.append(m.group()).append("\n");
- } else {
- for (int i = 1; i <= m.groupCount(); i++) {
- buf.append(m.group(i)).append("\n");
- }
- }
- }
-
- if( buf.length() > 0 )
- buf.setLength(buf.length() - 1);
-
- return buf.toString().getBytes();
- }
-
- @Override
- public void createUI() {
- this.regexTxt = new VariableTextField();
- this.addUIElement("Regex", this.regexTxt);
-
- this.outputBox = new JComboBox<>(new String[] { LIST_MATCHES, LIST_GROUPS });
- this.addUIElement("Output format", this.outputBox);
- }
-}
diff --git a/src/de/usd/cstchef/operations/hashing/HashOperation.java b/src/de/usd/cstchef/operations/hashing/HashOperation.java
deleted file mode 100644
index 718e4ad..0000000
--- a/src/de/usd/cstchef/operations/hashing/HashOperation.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package de.usd.cstchef.operations.hashing;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import javax.swing.JComboBox;
-
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.Operation;
-
-public abstract class HashOperation extends Operation {
-
- private JComboBox sizeBox;
- private String algorithm;
-
- public HashOperation(String alogrithm) {
- super();
- this.algorithm = alogrithm;
- }
-
- public HashOperation(String alogrithm, String... sizes) {
- super();
- this.algorithm = alogrithm;
- createMyUI(sizes);
- }
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- return this.hash(input);
- }
-
- protected byte[] hash(byte[] input) throws NoSuchAlgorithmException {
- String algo = this.algorithm + (this.sizeBox != null ? (String) sizeBox.getSelectedItem() : "");
-
- MessageDigest digest = MessageDigest.getInstance(algo);
- byte[] hash = digest.digest(input);
- return Hex.encode(hash);
- }
-
- public void createMyUI(String[] sizes) {
- sizeBox = new JComboBox(sizes);
- sizeBox.setSelectedIndex(0);
- this.addUIElement("Size", sizeBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/hashing/Hmac.java b/src/de/usd/cstchef/operations/hashing/Hmac.java
deleted file mode 100644
index 764c4d0..0000000
--- a/src/de/usd/cstchef/operations/hashing/Hmac.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package de.usd.cstchef.operations.hashing;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.swing.JComboBox;
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HMAC", category = OperationCategory.HASHING, description = "Creates an HMAC with the chosen hashing function.")
-public class Hmac extends Operation {
-
- private VariableTextField keyTxt;
- private JComboBox hashAlgoBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- byte[] key = this.keyTxt.getText().getBytes();
- String algo = "Hmac" + (String) hashAlgoBox.getSelectedItem();
- SecretKeySpec signingKey = new SecretKeySpec(key, algo);
- Mac mac = Mac.getInstance(algo);
- mac.init(signingKey);
- return Hex.encode(mac.doFinal(input));
- }
-
- @Override
- public void createUI() {
- String[] algorithms = { "MD5", "SHA1", "SHA256", "SHA224", "SHA384", "SHA512", "GOST3411" };
- this.hashAlgoBox = new JComboBox<>(algorithms);
- this.addUIElement("Hashing function", this.hashAlgoBox);
-
- this.keyTxt = new VariableTextField();
- this.addUIElement("Key", this.keyTxt);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/misc/ReadFile.java b/src/de/usd/cstchef/operations/misc/ReadFile.java
deleted file mode 100644
index 302b9c6..0000000
--- a/src/de/usd/cstchef/operations/misc/ReadFile.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package de.usd.cstchef.operations.misc;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.FileInputStream;
-import javax.swing.JButton;
-import javax.swing.JFileChooser;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "Read File", category = OperationCategory.MISC, description = "Reads data from a file.")
-public class ReadFile extends Operation implements ActionListener {
-
- private final JFileChooser fileChooser = new JFileChooser();
- private VariableTextField fileNameTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String path = fileNameTxt.getText();
-
- File file = new File(path);
- FileInputStream fis = new FileInputStream(file);
- byte[] data = new byte[(int) file.length()];
- fis.read(data);
- fis.close();
-
- return data;
- }
-
- public void createUI() {
- this.fileNameTxt = new VariableTextField();
- this.addUIElement("Filename", this.fileNameTxt);
-
- JButton chooseFileButton = new JButton("Select file");
- chooseFileButton.addActionListener(this);
- this.addUIElement(null, chooseFileButton, false, "button1");
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int returnVal = fileChooser.showOpenDialog(this);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- File file = fileChooser.getSelectedFile();
- this.fileNameTxt.setText(file.getAbsolutePath());
- }
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/misc/WriteFile.java b/src/de/usd/cstchef/operations/misc/WriteFile.java
deleted file mode 100644
index 8ca2990..0000000
--- a/src/de/usd/cstchef/operations/misc/WriteFile.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package de.usd.cstchef.operations.misc;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import javax.swing.JButton;
-import javax.swing.JFileChooser;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "Write File", category = OperationCategory.MISC, description = "Appends data to the end of a file.")
-public class WriteFile extends Operation implements ActionListener {
-
- private final JFileChooser fileChooser = new JFileChooser();
- private VariableTextField fileNameTxt;
- private String lastPath = "";
- private FileOutputStream out;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String path = fileNameTxt.getText();
-
- if (!lastPath.equals(path)) {
- if (out != null) {
- out.close();
- out = null;
- }
- if (!path.isEmpty()) {
- out = new FileOutputStream(path);
- }
- lastPath = path;
- }
-
- if (out != null) {
- out.write(input);
- out.write('\n');
- }
-
- return input;
- }
-
- public void createUI() {
- this.fileNameTxt = new VariableTextField();
- this.fileNameTxt.setEditable(false);
- this.addUIElement("Filename", this.fileNameTxt);
-
- JButton chooseFileButton = new JButton("Select file");
- chooseFileButton.addActionListener(this);
- this.addUIElement(null, chooseFileButton, false, "button1");
- }
-
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int returnVal = fileChooser.showOpenDialog(this);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- File file = fileChooser.getSelectedFile();
- this.fileNameTxt.setText(file.getAbsolutePath());
- }
- }
-
- @Override
- public void onRemove() {
- if (out != null) {
- try {
- out.close();
- } catch (IOException e) {
- }
- }
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/networking/HTTPRequest.java b/src/de/usd/cstchef/operations/networking/HTTPRequest.java
deleted file mode 100644
index 030a8b4..0000000
--- a/src/de/usd/cstchef/operations/networking/HTTPRequest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.usd.cstchef.operations.networking;
-
-import javax.swing.JCheckBox;
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IHttpRequestResponse;
-import burp.IHttpService;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HTTP Request", category = OperationCategory.NETWORKING, description = "Makes an http reqeust and returns the response.")
-public class HTTPRequest extends Operation {
-
- private VariableTextField hostTxt;
- private VariableTextField portTxt;
- private JCheckBox sslEnabledBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helper = callbacks.getHelpers();
- String protocol = sslEnabledBox.isSelected() ? "https" : "http";
- IHttpService service = helper.buildHttpService(hostTxt.getText(), Integer.valueOf(portTxt.getText()), protocol);
- IHttpRequestResponse response = callbacks.makeHttpRequest(service, input);
- return response.getResponse();
- }
-
- @Override
- public void createUI() {
- this.hostTxt = new VariableTextField();
- this.addUIElement("Host", this.hostTxt);
-
- this.portTxt = new VariableTextField();
- this.addUIElement("Port", this.portTxt);
-
- this.sslEnabledBox = new JCheckBox();
- this.addUIElement("SSL", this.sslEnabledBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpGetSetter.java b/src/de/usd/cstchef/operations/setter/HttpGetSetter.java
deleted file mode 100644
index 14cfb9b..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpGetSetter.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP GET Param", category = OperationCategory.SETTER, description = "Sets a GET parameter to the specified value.")
-public class HttpGetSetter extends SetterOperation {
-
- private JCheckBox addIfNotPresent;
- private JCheckBox urlEncode;
- private JCheckBox urlEncodeAll;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String parameterName = getWhere();
- if( parameterName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- byte[] newValue = getWhatBytes();
-
- if( urlEncodeAll.isSelected() || urlEncode.isSelected() )
- newValue = urlEncode(newValue, urlEncodeAll.isSelected(), helpers);
-
- IParameter param = getParameter(input, parameterName, IParameter.PARAM_URL, helpers);
-
- if( param == null ) {
-
- if( !addIfNotPresent.isSelected() )
- return input;
-
- param = helpers.buildParameter(parameterName, "dummy", IParameter.PARAM_URL);
- input = helpers.addParameter(input, param);
- param = getParameter(input, parameterName, IParameter.PARAM_URL, helpers);
- }
-
- byte[] newRequest = replaceParam(input, param, newValue);
- return newRequest;
- }
-
- @Override
- public void createUI() {
- super.createUI();
-
- this.urlEncode = new JCheckBox("URL encode");
- this.urlEncode.setSelected(false);
- this.addUIElement(null, this.urlEncode, "checkbox1");
-
- this.urlEncodeAll = new JCheckBox("URL encode all");
- this.urlEncodeAll.setSelected(false);
- this.addUIElement(null, this.urlEncodeAll, "checkbox2");
-
- this.addIfNotPresent = new JCheckBox("Add if not present");
- this.addIfNotPresent.setSelected(true);
- this.addUIElement(null, this.addIfNotPresent, "checkbox3");
- }
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpHeaderSetter.java b/src/de/usd/cstchef/operations/setter/HttpHeaderSetter.java
deleted file mode 100644
index 3653471..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpHeaderSetter.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IRequestInfo;
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP Header", category = OperationCategory.SETTER, description = "Set a HTTP header to the specified value.")
-public class HttpHeaderSetter extends SetterOperation {
-
- private JCheckBox addIfNotPresent;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] newValue = getWhatBytes();
- byte[] headerName = getWhereBytes();
- if( headerName.length == 0 )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- byte[] headerSearch = new byte[headerName.length + 2];
- System.arraycopy(headerName, 0, headerSearch, 0, headerName.length);
- System.arraycopy(": ".getBytes(), 0, headerSearch, headerName.length, 2);
-
- try {
-
- int offset = helpers.indexOf(input, headerSearch, false, 0, length);
- int start = helpers.indexOf(input, ": ".getBytes(), false, offset, length) + 2;
- int end = helpers.indexOf(input, "\r\n".getBytes(), false, start, length);
- return Utils.insertAtOffset(input, start, end, newValue);
-
- } catch( IllegalArgumentException e ) {
-
- if( !addIfNotPresent.isSelected() )
- return input;
-
- IRequestInfo info = helpers.analyzeRequest(input);
- int bodyOffset = info.getBodyOffset() - 2;
-
- byte[] value = new byte[headerSearch.length + newValue.length + 2];
- System.arraycopy(headerSearch, 0, value, 0, headerSearch.length);
- System.arraycopy(newValue, 0, value, headerName.length + 2, newValue.length);
- System.arraycopy("\r\n".getBytes(), 0, value, headerName.length + 2 + newValue.length, 2);
- return Utils.insertAtOffset(input, bodyOffset, bodyOffset, value);
-
- }
- }
-
- @Override
- public void createUI() {
- super.createUI();
- this.addIfNotPresent = new JCheckBox("Add if not present");
- this.addIfNotPresent.setSelected(true);
- this.addUIElement(null, this.addIfNotPresent, "checkbox1");
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpJsonSetter.java b/src/de/usd/cstchef/operations/setter/HttpJsonSetter.java
deleted file mode 100644
index 2ff016b..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpJsonSetter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP JSON", category = OperationCategory.SETTER, description = "Set a JSON parameter to the specified value.")
-public class HttpJsonSetter extends SetterOperation {
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String parameterName = getWhere();
- if( parameterName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- byte[] newValue = getWhatBytes();
- IParameter param = getParameter(input, parameterName, IParameter.PARAM_JSON, helpers);
-
- if( param == null )
- return input;
-
- byte[] newRequest = replaceParam(input, param, newValue);
- return newRequest;
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpPostSetter.java b/src/de/usd/cstchef/operations/setter/HttpPostSetter.java
deleted file mode 100644
index c2b38af..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpPostSetter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP POST Param", category = OperationCategory.SETTER, description = "Set a POST parameter to the specified value.")
-public class HttpPostSetter extends SetterOperation {
-
- private JCheckBox addIfNotPresent;
- private JCheckBox urlEncode;
- private JCheckBox urlEncodeAll;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String parameterName = getWhere();
- if( parameterName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- byte[] newValue = getWhatBytes();
-
- if( urlEncodeAll.isSelected() || urlEncode.isSelected() )
- newValue = urlEncode(newValue, urlEncodeAll.isSelected(), helpers);
-
- IParameter param = getParameter(input, parameterName, IParameter.PARAM_BODY, helpers);
-
- if( param == null ) {
-
- if( !addIfNotPresent.isSelected() )
- return input;
-
- param = helpers.buildParameter(parameterName, "dummy", IParameter.PARAM_BODY);
- input = helpers.addParameter(input, param);
- param = getParameter(input, parameterName, IParameter.PARAM_BODY, helpers);
- if( param == null )
- // This case occurs when the HTTP request is a JSON or XML request. Burp does not
- // support adding parameters to these and therefore the request should stay unmodified.
- throw new IllegalArgumentException("Failure while adding the parameter. Operation cannot be used on XML or JSON.");
- }
-
- byte[] newRequest = replaceParam(input, param, newValue);
- return newRequest;
- }
-
- @Override
- public void createUI() {
- super.createUI();
-
- this.urlEncode = new JCheckBox("URL encode");
- this.urlEncode.setSelected(false);
- this.addUIElement(null, this.urlEncode, "checkbox1");
-
- this.urlEncodeAll = new JCheckBox("URL encode all");
- this.urlEncodeAll.setSelected(false);
- this.addUIElement(null, this.urlEncodeAll, "checkbox2");
-
- this.addIfNotPresent = new JCheckBox("Add if not present");
- this.addIfNotPresent.setSelected(true);
- this.addUIElement(null, this.addIfNotPresent, "checkbox3");
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpSetBody.java b/src/de/usd/cstchef/operations/setter/HttpSetBody.java
deleted file mode 100644
index c4ba5ce..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpSetBody.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import java.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IRequestInfo;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.FormatTextField;
-
-@OperationInfos(name = "HTTP Body", category = OperationCategory.SETTER, description = "Set the HTTP body to the specified value.")
-public class HttpSetBody extends Operation {
-
- private FormatTextField replacementTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IRequestInfo requestInfo = cbs.getHelpers().analyzeRequest(input);
- int bodyOffset = requestInfo.getBodyOffset();
-
- byte[] noBody = Arrays.copyOfRange(input, 0, bodyOffset);
- byte[] newBody = replacementTxt.getText();
- byte[] newRequest = new byte[noBody.length + newBody.length];
- System.arraycopy(noBody, 0, newRequest, 0, noBody.length);
- System.arraycopy(newBody, 0, newRequest, noBody.length, newBody.length);
-
- return newRequest;
- }
-
- @Override
- public void createUI() {
- this.replacementTxt = new FormatTextField();
- this.addUIElement("Body", this.replacementTxt);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpSetCookie.java b/src/de/usd/cstchef/operations/setter/HttpSetCookie.java
deleted file mode 100644
index d11d80d..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpSetCookie.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IResponseInfo;
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP Cookie", category = OperationCategory.SETTER, description = "Set a HTTP cookie to the specified value.")
-public class HttpSetCookie extends SetterOperation {
-
- private JCheckBox addIfNotPresent;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] newValue = getWhatBytes();
- byte[] cookieName = getWhereBytes();
- if( cookieName.length == 0 )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- byte[] cookieSearch = new byte[cookieName.length + 1];
- System.arraycopy(cookieName, 0, cookieSearch, 0, cookieName.length);
- System.arraycopy("=".getBytes(), 0, cookieSearch, cookieName.length, 1);
-
- IResponseInfo resp = helpers.analyzeResponse(input);
- boolean isRequest = (resp.getStatusCode() == 0);
-
- String cookieHeader = "\r\nSet-Cookie: ";
- if(isRequest)
- cookieHeader = "\r\nCookie: ";
-
- int offset = -1;
- int cookieHeaderLength = cookieHeader.length();
-
- try {
-
- offset = helpers.indexOf(input, cookieHeader.getBytes(), false, 0, length);
- int line_end = helpers.indexOf(input, "\r\n".getBytes(), false, offset + 2, length);
- int start = helpers.indexOf(input, cookieSearch, true, offset, line_end);
- int end = helpers.indexOf(input, ";".getBytes(), true, start, line_end);
-
- if( end < 0 )
- end = line_end;
-
- return Utils.insertAtOffset(input, start + cookieSearch.length, end, newValue);
-
- } catch( IllegalArgumentException e ) {
-
- if( !addIfNotPresent.isSelected() )
- return input;
-
- if( (offset > 0) && isRequest ) {
-
- byte[] value = new byte[cookieName.length + newValue.length + 3];
- System.arraycopy(cookieName, 0, value, 0, cookieName.length);
- System.arraycopy("=".getBytes(), 0, value, cookieName.length, 1);
- System.arraycopy(newValue, 0, value, cookieName.length + 1, newValue.length);
- System.arraycopy("; ".getBytes(), 0, value, cookieName.length + 1 + newValue.length, 2);
- return Utils.insertAtOffset(input, offset + cookieHeaderLength, offset + cookieHeaderLength, value);
-
- } else {
-
- int bodyOffset = resp.getBodyOffset() - 4;
- byte[] value = new byte[cookieName.length + newValue.length + cookieHeaderLength + 2];
- System.arraycopy(cookieHeader.getBytes(), 0, value, 0, cookieHeaderLength);
- System.arraycopy(cookieName, 0, value, cookieHeaderLength, cookieName.length);
- System.arraycopy("=".getBytes(), 0, value, cookieHeaderLength + cookieName.length, 1);
- System.arraycopy(newValue, 0, value, cookieHeaderLength + cookieName.length + 1, newValue.length);
- System.arraycopy(";".getBytes(), 0, value, cookieHeaderLength + cookieName.length + 1 + newValue.length, 1);
- return Utils.insertAtOffset(input, bodyOffset, bodyOffset, value);
- }
- }
- }
-
- @Override
- public void createUI() {
- super.createUI();
- this.addIfNotPresent = new JCheckBox("Add if not present");
- this.addIfNotPresent.setSelected(true);
- this.addUIElement(null, this.addIfNotPresent, "checkbox1");
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpSetUri.java b/src/de/usd/cstchef/operations/setter/HttpSetUri.java
deleted file mode 100644
index ad55dc1..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpSetUri.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import java.util.Arrays;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "HTTP URI", category = OperationCategory.SETTER, description = "Sets the specified variable as the uri.")
-public class HttpSetUri extends Operation {
-
- private VariableTextField uriTxt;
- private JCheckBox checkbox;
-
- @Override
- public void createUI() {
- this.uriTxt = new VariableTextField();
- this.addUIElement("Uri", this.uriTxt);
-
- this.checkbox = new JCheckBox("Keep parameters");
- this.checkbox.setSelected(false);
- this.addUIElement(null, this.checkbox, "checkbox1");
- }
-
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- try {
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- int firstMark = helpers.indexOf(input, " ".getBytes(), false, 0, length);
- int lineMark = helpers.indexOf(input, " ".getBytes(), false, firstMark + 1, length);
-
- int secondMark = helpers.indexOf(input, "?".getBytes(), false, firstMark + 1, length);
-
- if( !this.checkbox.isSelected() || secondMark < 0 || secondMark >= lineMark ) {
- secondMark = lineMark;
- }
-
- byte[] method = Arrays.copyOfRange(input, 0, firstMark + 1);
- byte[] newUri = this.uriTxt.getBytes();
- byte[] rest = Arrays.copyOfRange(input, secondMark, length);
-
- byte[] newRequest = new byte[method.length + newUri.length + rest.length];
- System.arraycopy(method, 0, newRequest, 0, method.length);
- System.arraycopy(newUri, 0, newRequest, method.length, newUri.length);
- System.arraycopy(rest, 0, newRequest, method.length + newUri.length, rest.length);
-
- return newRequest;
-
- } catch (Exception e) {
- throw new IllegalArgumentException("Provided input is not a valid http request.");
- }
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/HttpXmlSetter.java b/src/de/usd/cstchef/operations/setter/HttpXmlSetter.java
deleted file mode 100644
index b783db9..0000000
--- a/src/de/usd/cstchef/operations/setter/HttpXmlSetter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "HTTP XML", category = OperationCategory.SETTER, description = "Set a XML parameter to the specified value.")
-public class HttpXmlSetter extends SetterOperation {
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String parameterName = getWhere();
- if( parameterName.equals("") )
- return input;
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- byte[] newValue = getWhatBytes();
- IParameter param = getParameter(input, parameterName, IParameter.PARAM_XML, helpers);
-
- if( param == null )
- return input;
-
- byte[] newRequest = replaceParam(input, param, newValue);
- return newRequest;
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/JsonSetter.java b/src/de/usd/cstchef/operations/setter/JsonSetter.java
deleted file mode 100644
index 99447f1..0000000
--- a/src/de/usd/cstchef/operations/setter/JsonSetter.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-
-import javax.swing.JCheckBox;
-
-import com.jayway.jsonpath.DocumentContext;
-import com.jayway.jsonpath.JsonPath;
-
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "JSON", category = OperationCategory.SETTER, description = "Set value of json object.")
-public class JsonSetter extends SetterOperation implements ActionListener {
-
- private JCheckBox addIfNotPresent;
- private VariableTextField path;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- if( getWhere().equals("") )
- return input;
-
- DocumentContext document = JsonPath.parse(new String(input));
-
- try {
- document.read(getWhere());
- } catch( Exception e ) {
-
- if( !addIfNotPresent.isSelected() )
- throw new IllegalArgumentException("Key not found.");
-
- String insertPath = this.path.getText();
- if( insertPath.equals("Insert-Path") || insertPath.equals("") )
- insertPath = "$";
-
- document = document.put(insertPath, getWhere(), getWhat());
- return document.jsonString().getBytes();
- }
-
- document.set(getWhere(), getWhat());
- return document.jsonString().getBytes();
- }
-
- @Override
- public void createUI() {
- super.createUI();
- this.addIfNotPresent = new JCheckBox("Add if not present");
- this.addIfNotPresent.setSelected(true);
- this.addIfNotPresent.addActionListener(this);
- this.addUIElement(null, this.addIfNotPresent, "checkbox1");
-
- this.path = new VariableTextField();
- this.path.setText("Insert-Path");
- this.path.setForeground(Color.GRAY);
- this.path.addFocusListener(new FocusListener() {
- @Override
- public void focusGained(FocusEvent e) {
- if (path.getText().equals("Insertion Path")) {
- path.setText("");
- path.setForeground(null);
- }
- }
- @Override
- public void focusLost(FocusEvent e) {
- if (path.getText().isEmpty()) {
- path.setForeground(Color.GRAY);
- path.setText("Insertion Path");
- }
- }
- });
- this.addUIElement(null, this.path, "textbox1");
- }
-
- @Override
- public void actionPerformed(ActionEvent arg0) {
- if( arg0.getSource() == this.addIfNotPresent ) {
- if( this.addIfNotPresent.isSelected() ) {
- this.path.setEditable(true);
- } else {
- this.path.setEditable(false);
- }
- }
- }
-}
diff --git a/src/de/usd/cstchef/operations/setter/LineSetter.java b/src/de/usd/cstchef/operations/setter/LineSetter.java
deleted file mode 100644
index ebff621..0000000
--- a/src/de/usd/cstchef/operations/setter/LineSetter.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import java.util.Arrays;
-
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "Line Setter", category = OperationCategory.SETTER, description = "Sets a line to the specified value.")
-public class LineSetter extends SetterOperation {
-
- private JCheckBox append;
- private JComboBox formatBox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- int lineNumber;
- try {
- String number = getWhere();
- lineNumber = Integer.valueOf(number);
- } catch( Exception e ) {
- return input;
- }
-
- if( lineNumber <= 0 )
- return input;
-
- byte[] newValue = getWhatBytes();
- byte[] lineEndings = "\r\n".getBytes();
- switch ((String) this.formatBox.getSelectedItem()) {
- case "\\r\\n":
- lineEndings = "\r\n".getBytes();
- break;
- case "\\r":
- lineEndings = "\r".getBytes();
- break;
- case "\\n":
- lineEndings = "\n".getBytes();
- break;
- }
-
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
- int length = input.length;
-
- int start = 0;
- int offset = 0;
- int counter = 0;
- while( counter < lineNumber - 1 ) {
- offset = helpers.indexOf(input, lineEndings, false, start, length);
- if( offset >= 0 ) {
- start = offset + lineEndings.length;
- counter++;
- } else {
- break;
- }
- }
-
- int end = helpers.indexOf(input, lineEndings, false, start, length);
- if( end < 0 )
- end = length;
-
- if( append.isSelected() ) {
- byte[] value = new byte[newValue.length + lineEndings.length];
- System.arraycopy(lineEndings, 0, value, 0, lineEndings.length);
- System.arraycopy(newValue, 0, value, lineEndings.length, newValue.length);
- return Utils.insertAtOffset(input, end, end, value);
- } else {
- return Utils.insertAtOffset(input, start, end, newValue);
- }
- }
-
- @Override
- public void createUI() {
- super.createUI();
- this.append = new JCheckBox("Insert below");
- this.append.setSelected(false);
- this.addUIElement(null, this.append, "checkbox1");
-
- this.formatBox = new JComboBox<>(new String[] {"\\r\\n", "\\r", "\\n"});
- this.formatBox.setSelectedItem("\\r\\n");
- this.addUIElement("Lineseperator", this.formatBox);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/setter/SetterOperation.java b/src/de/usd/cstchef/operations/setter/SetterOperation.java
deleted file mode 100644
index b3be909..0000000
--- a/src/de/usd/cstchef/operations/setter/SetterOperation.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package de.usd.cstchef.operations.setter;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-import org.bouncycastle.util.encoders.Hex;
-
-import burp.IExtensionHelpers;
-import burp.IParameter;
-import burp.IRequestInfo;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-public abstract class SetterOperation extends Operation {
-
- private VariableTextField whereToSet;
- private VariableTextField whatToSet;
-
- @Override
- public void createUI() {
- this.whereToSet = new VariableTextField();
- this.whatToSet = new VariableTextField();
- this.addUIElement("Key", this.whereToSet);
- this.addUIElement("Value", this.whatToSet);
- }
-
- protected String getWhere() {
- return whereToSet.getText();
- }
-
- protected byte[] getWhereBytes() {
- return whereToSet.getBytes();
- }
-
- protected String getWhat() {
- return whatToSet.getText();
- }
-
- protected byte[] getWhatBytes() {
- return whatToSet.getBytes();
- }
-
- // This is required because Burps getRequestParameter returns always the first occurrence of the parameter name.
- // If you have e.g. a cookie with the same name as the POST parameter, you have no chance of getting the POST
- // parameter using getRequestParameter (at least I do not know how).
- protected IParameter getParameter(byte[] request, String paramName, byte type, IExtensionHelpers helpers) {
-
- IRequestInfo info = helpers.analyzeRequest(request);
- List parameters = info.getParameters();
- IParameter param = null;
-
- for(IParameter p:parameters) {
- if( p.getName().equals(paramName) )
- if( p.getType() == type ) {
- param = p;
- break;
- }
- }
- return param;
- }
-
- protected byte[] urlEncode(byte[] input, boolean all, IExtensionHelpers helpers) throws IOException {
-
- byte[] newValue = input;
-
- if( all ) {
- byte[] delimiter = "%".getBytes();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(delimiter);
-
- for (int i = 0; i < newValue.length - 1; i++) {
- out.write(Hex.encode(new byte[] { newValue[i] }));
- out.write(delimiter);
- }
-
- out.write(Hex.encode(new byte[] { newValue[newValue.length - 1] }));
- newValue = out.toByteArray();
-
- } else {
- newValue = helpers.urlEncode(input);
- }
-
- return newValue;
- }
-
- protected byte[] replaceParam(byte[] request, IParameter param, byte[] newValue) {
-
- int length = request.length;
- int start = param.getValueStart();
- int end = param.getValueEnd();
-
- byte[] prefix = Arrays.copyOfRange(request, 0, start);
- byte[] rest = Arrays.copyOfRange(request, end, length);
-
- byte[] newRequest = new byte[prefix.length + newValue.length + rest.length];
- System.arraycopy(prefix, 0, newRequest, 0, prefix.length);
- System.arraycopy(newValue, 0, newRequest, prefix.length, newValue.length);
- System.arraycopy(rest, 0, newRequest, prefix.length + newValue.length, rest.length);
-
- return newRequest;
- }
-}
diff --git a/src/de/usd/cstchef/operations/signature/RsaSignature.java b/src/de/usd/cstchef/operations/signature/RsaSignature.java
deleted file mode 100644
index b02b463..0000000
--- a/src/de/usd/cstchef/operations/signature/RsaSignature.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package de.usd.cstchef.operations.signature;
-
-import java.security.Signature;
-
-import javax.swing.JComboBox;
-
-import org.bouncycastle.util.encoders.Base64;
-import org.bouncycastle.util.encoders.Hex;
-
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "RSA Signature", category = OperationCategory.SIGNATURE, description = "Create an RSA signature")
-public class RsaSignature extends KeystoreOperation {
-
- private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
-
- protected JComboBox algos;
- protected JComboBox inputMode;
- protected JComboBox outputMode;
-
- public RsaSignature() {
- super();
- this.createMyUI();
- }
-
- protected byte[] perform(byte[] input) throws Exception {
-
- if( !this.keyAvailable.isSelected() )
- throw new IllegalArgumentException("No private key available.");
-
- String algo = (String)algos.getSelectedItem();
- Signature signature = Signature.getInstance(algo);
-
- String selectedInputMode = (String)inputMode.getSelectedItem();
- String selectedOutputMode = (String)outputMode.getSelectedItem();
-
- if( selectedInputMode.equals("Hex") )
- input = Hex.decode(input);
- if( selectedInputMode.equals("Base64") )
- input = Base64.decode(input);
-
- signature.initSign(this.selectedEntry.getPrivateKey());
- signature.update(input);
- byte[] result = signature.sign();
-
- if( selectedOutputMode.equals("Hex") )
- result = Hex.encode(result);
- if( selectedOutputMode.equals("Base64") )
- result = Base64.encode(result);
-
- return result;
- }
-
- public void createMyUI() {
-
- super.createMyUI();
- SignatureUtils utils = SignatureUtils.getInstance();
-
- this.algos = new JComboBox<>(utils.getRsaAlgos());
- this.addUIElement("Padding", this.algos);
-
- this.inputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Input", this.inputMode);
-
- this.outputMode = new JComboBox<>(inOutModes);
- this.addUIElement("Output", this.outputMode);
- }
-}
diff --git a/src/de/usd/cstchef/operations/signature/SignatureUtils.java b/src/de/usd/cstchef/operations/signature/SignatureUtils.java
deleted file mode 100644
index 04be967..0000000
--- a/src/de/usd/cstchef/operations/signature/SignatureUtils.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package de.usd.cstchef.operations.signature;
-
-import java.security.Provider;
-import java.security.Provider.Service;
-import java.security.Security;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class SignatureUtils {
-
- private static SignatureUtils instance;
-
- private List algos;
-
- private SignatureUtils() {
- algos = new ArrayList();;
- getSignatureInfos();
- }
-
- private void getSignatureInfos() {
- for (Provider provider : Security.getProviders())
- for (Service service : provider.getServices())
- if (service.getType().equals("Signature"))
- algos.add(service.getAlgorithm());
- }
-
- public static SignatureUtils getInstance() {
- if (instance == null) {
- instance = new SignatureUtils();
- }
- return instance;
- }
-
- public String[] getAlgos() {
- return algos.toArray(new String[0]);
- }
- public String[] getRsaAlgos() {
- List rsaAlgos = algos.stream().filter(p -> p.contains("RSA")).collect(Collectors.toList());
- return rsaAlgos.toArray(new String[0]);
- }
-}
diff --git a/src/de/usd/cstchef/operations/string/Prefix.java b/src/de/usd/cstchef/operations/string/Prefix.java
deleted file mode 100644
index 374a8a8..0000000
--- a/src/de/usd/cstchef/operations/string/Prefix.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.usd.cstchef.operations.string;
-
-import java.io.ByteArrayOutputStream;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.FormatTextField;
-
-@OperationInfos(name = "Prefix", category = OperationCategory.STRING, description = "Adds a prefix.")
-public class Prefix extends Operation {
-
- private FormatTextField prefixTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(prefixTxt.getText());
- out.write(input);
-
- return out.toByteArray();
- }
-
- @Override
- public void createUI() {
- this.prefixTxt = new FormatTextField();
- this.addUIElement("Prefix", this.prefixTxt);
- }
-
-}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/string/Replace.java b/src/de/usd/cstchef/operations/string/Replace.java
deleted file mode 100644
index 1dc86b6..0000000
--- a/src/de/usd/cstchef/operations/string/Replace.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.usd.cstchef.operations.string;
-
-import javax.swing.JCheckBox;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.VariableTextArea;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "Replace", category = OperationCategory.STRING, description = "Uses a regular expression to replace all occurences. Has side effect on binary content due to String Encoding.")
-public class Replace extends Operation {
-
- private JCheckBox checkbox;
- private VariableTextField exptTxt;
- private VariableTextArea replacementTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] result = null;
- if( checkbox.isSelected() ) {
- String inputStr = new String(input);
- result = inputStr.replaceAll(exptTxt.getText(), replacementTxt.getText()).getBytes();
- } else {
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = cbs.getHelpers();
-
- int start = helpers.indexOf(input, exptTxt.getBytes(), true, 0, input.length);
-
- if(start < 0)
- return input;
-
- byte[] replaced = exptTxt.getBytes();
- byte[] replacement = replacementTxt.getBytes();
-
- byte[] newRequest = new byte[input.length + replacement.length - replaced.length];
- System.arraycopy(input, 0, newRequest, 0, start);
- System.arraycopy(replacement, 0, newRequest, start, replacement.length);
- System.arraycopy(input, start + replaced.length, newRequest, start + replacement.length, input.length - replaced.length - start);
-
- result = newRequest;
- }
-
- return result;
- }
-
- @Override
- public void createUI() {
- this.exptTxt = new VariableTextField();
- this.addUIElement("Expr", this.exptTxt);
-
- this.checkbox = new JCheckBox("Regex");
- this.checkbox.setSelected(false);
- this.addUIElement(null, this.checkbox, "checkbox1");
-
- this.replacementTxt = new VariableTextArea();
- this.addUIElement("Value", this.replacementTxt);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/string/SplitAndSelect.java b/src/de/usd/cstchef/operations/string/SplitAndSelect.java
deleted file mode 100644
index 5d8e19b..0000000
--- a/src/de/usd/cstchef/operations/string/SplitAndSelect.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package de.usd.cstchef.operations.string;
-
-import org.bouncycastle.util.Arrays;
-
-import burp.BurpUtils;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.VariableTextField;
-
-@OperationInfos(name = "Split and Select", category = OperationCategory.STRING, description = "Split input and select one item.")
-public class SplitAndSelect extends Operation {
-
- private VariableTextField item;
- private VariableTextField delim;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] delimmiter = delim.getBytes();
-
- int itemNumber = 0;
- try {
- String itemValue = item.getText();
- itemNumber = Integer.valueOf(itemValue);
- } catch(Exception e) {
- return input;
- }
-
- if( itemNumber < 0 )
- return input;
-
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = cbs.getHelpers();
- int length = input.length;
-
- int start = 0;
- int offset = 0;
- int counter = 0;
- while( counter < itemNumber ) {
- offset = helpers.indexOf(input, delimmiter, false, start, length);
- if( offset >= 0 ) {
- start = offset + delimmiter.length;
- counter++;
- } else {
- break;
- }
- }
-
- int end = helpers.indexOf(input, delimmiter, false, start, length);
- if( end < 0 )
- end = length;
-
- byte[] result = Arrays.copyOfRange(input, start, end);
- return result;
- }
-
- @Override
- public void createUI() {
- this.delim = new VariableTextField();
- this.addUIElement("Delimmiter", this.delim);
- this.item = new VariableTextField();
- this.addUIElement("Item number", this.item);
- }
-}
diff --git a/src/de/usd/cstchef/operations/string/Substring.java b/src/de/usd/cstchef/operations/string/Substring.java
deleted file mode 100644
index 3a984d0..0000000
--- a/src/de/usd/cstchef/operations/string/Substring.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.usd.cstchef.operations.string;
-
-import javax.swing.JSpinner;
-
-import org.bouncycastle.util.Arrays;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "Substring", category = OperationCategory.STRING, description = "Extracts a substring.")
-public class Substring extends Operation {
-
- private JSpinner startSpinner;
- private JSpinner endSpinner;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- int start = (int) startSpinner.getValue();
- int end = (int) endSpinner.getValue();
-
- if( start < 0 )
- start = input.length + start;
- if( end < 0 )
- end = input.length + end;
- if( end > input.length )
- end = input.length + 1;
-
- byte[] slice = Arrays.copyOfRange(input, start, end);
- return slice;
- }
-
- @Override
- public void createUI() {
- this.startSpinner = new JSpinner();
- this.addUIElement("Start", this.startSpinner);
-
- this.endSpinner = new JSpinner();
- this.addUIElement("End", this.endSpinner);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/string/Suffix.java b/src/de/usd/cstchef/operations/string/Suffix.java
deleted file mode 100644
index cf85b74..0000000
--- a/src/de/usd/cstchef/operations/string/Suffix.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.usd.cstchef.operations.string;
-
-import java.io.ByteArrayOutputStream;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.view.ui.FormatTextField;
-
-@OperationInfos(name = "Suffix", category = OperationCategory.STRING, description = "Adds a suffix.")
-public class Suffix extends Operation {
-
- private FormatTextField suffixTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(input);
- out.write(suffixTxt.getText());
-
- return out.toByteArray();
- }
-
- @Override
- public void createUI() {
- this.suffixTxt = new FormatTextField ();
- this.addUIElement("Suffix", this.suffixTxt);
- }
-
-}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/utils/GetVariable.java b/src/de/usd/cstchef/operations/utils/GetVariable.java
deleted file mode 100644
index e6041c7..0000000
--- a/src/de/usd/cstchef/operations/utils/GetVariable.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.usd.cstchef.operations.utils;
-
-import javax.swing.JTextField;
-
-import de.usd.cstchef.VariableStore;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "Get Variable", category = OperationCategory.UTILS, description = "Retrives a stored variable.")
-public class GetVariable extends Operation {
-
- private JTextField varNameTxt;
- private JTextField defaultTxt;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String varName = this.varNameTxt.getText().trim();
- byte[] var = VariableStore.getInstance().getVariable(varName);
- return var == null ? this.defaultTxt.getText().getBytes() : var;
- }
-
- public void createUI() {
- this.varNameTxt = new JTextField();
- this.addUIElement("Variable name", this.varNameTxt);
-
- this.defaultTxt = new JTextField();
- this.addUIElement("Default value", this.defaultTxt);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/utils/RandomNumber.java b/src/de/usd/cstchef/operations/utils/RandomNumber.java
deleted file mode 100644
index 57cca74..0000000
--- a/src/de/usd/cstchef/operations/utils/RandomNumber.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.usd.cstchef.operations.utils;
-
-import java.security.SecureRandom;
-
-import javax.swing.JTextField;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-
-@OperationInfos(name = "Random Number", category = OperationCategory.UTILS, description = "Generate a random number.")
-public class RandomNumber extends Operation {
-
- private JTextField maximum;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- SecureRandom secRand = new SecureRandom();
- try {
- int bound = Integer.valueOf(this.maximum.getText()) + 1;
- int random = Math.abs(secRand.nextInt(bound));
- return String.valueOf(random).getBytes();
- } catch( Exception e ) {
- int random = Math.abs(secRand.nextInt());
- return String.valueOf(random).getBytes();
- }
- }
-
- public void createUI() {
- this.maximum = new JTextField();
- this.addUIElement("Maximum Number", this.maximum);
- }
-
-}
diff --git a/src/de/usd/cstchef/operations/utils/SetIfEmpty.java b/src/de/usd/cstchef/operations/utils/SetIfEmpty.java
deleted file mode 100644
index d1e0581..0000000
--- a/src/de/usd/cstchef/operations/utils/SetIfEmpty.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package de.usd.cstchef.operations.utils;
-
-import javax.swing.JCheckBox;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.view.ui.FormatTextField;
-
-@OperationInfos(name = "Set if Empty", category = OperationCategory.UTILS, description = "Sets a value if the input is empty.")
-public class SetIfEmpty extends Operation {
-
- private FormatTextField value;
- private JCheckBox checkbox;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- byte[] valueToSet = value.getText();
- if( input.length == 0 ) {
- return valueToSet;
- }
-
- if( !checkbox.isSelected() )
- return input;
-
- int i = 0;
- while( i < input.length ) {
- if( input[i] != 32 ) {
- return input;
- }
- i++;
- }
-
- return valueToSet;
- }
-
- public void createUI() {
- this.value = new FormatTextField();
- this.addUIElement("Value to set", this.value);
-
- this.checkbox = new JCheckBox("Space is empty");
- this.checkbox.setSelected(false);
- this.addUIElement(null, this.checkbox, "checkbox1");
- }
-}
diff --git a/src/de/usd/cstchef/operations/utils/StoreVariable.java b/src/de/usd/cstchef/operations/utils/StoreVariable.java
deleted file mode 100644
index a23fc83..0000000
--- a/src/de/usd/cstchef/operations/utils/StoreVariable.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.usd.cstchef.operations.utils;
-
-import javax.swing.JTextField;
-
-import de.usd.cstchef.VariableStore;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-@OperationInfos(name = "Store Variable", category = OperationCategory.UTILS, description = "Stores variables to be retrieved later.")
-public class StoreVariable extends Operation {
-
- private JTextField varNameTxt;
- private String oldVarName;
-
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String newVarName = this.varNameTxt.getText().trim();
- VariableStore store = VariableStore.getInstance();
- // remove old variable from hashmap
- if (!newVarName.equals(oldVarName)) {
- store.removeVariable(this.oldVarName);
- this.oldVarName = newVarName;
- }
-
- if (!newVarName.isEmpty()) {
- store.setVariable(newVarName, input);
- }
-
- return input;
- }
-
- public void createUI() {
- this.varNameTxt = new JTextField();
- this.addUIElement("Variable name", this.varNameTxt);
- }
-
- @Override
- public void onRemove() {
- VariableStore.getInstance().removeVariable(this.oldVarName);
- }
-
-}
diff --git a/src/de/usd/cstchef/view/AddOperationMouseAdapter.java b/src/de/usd/cstchef/view/AddOperationMouseAdapter.java
deleted file mode 100644
index 38efaf8..0000000
--- a/src/de/usd/cstchef/view/AddOperationMouseAdapter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.Container;
-import javax.swing.JTree;
-import javax.swing.tree.TreePath;
-
-import de.usd.cstchef.operations.Operation;
-
-public class AddOperationMouseAdapter extends OperationMouseAdapter {
-
-
- public AddOperationMouseAdapter(JTree source, Container target) {
- super(source, target);
- }
-
- @Override
- protected Operation getDraggedOperation(int x, int y) {
- TreePath draggedPath = ((JTree) this.source).getClosestPathForLocation(x, y);
- if (draggedPath != null) {
- Object node = draggedPath.getLastPathComponent();
- if (node.getClass().equals(OperationTreeNode.class)) {
- Class extends Operation> cls = ((OperationTreeNode) node).getOperationClass();
- try {
- return cls.newInstance();
- } catch (InstantiationException | IllegalAccessException e) {
- }
- }
- }
- return null;
- }
-
-}
diff --git a/src/de/usd/cstchef/view/BurpEditorWrapper.java b/src/de/usd/cstchef/view/BurpEditorWrapper.java
deleted file mode 100644
index 4d6af6c..0000000
--- a/src/de/usd/cstchef/view/BurpEditorWrapper.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.Component;
-import java.util.Arrays;
-
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import burp.BurpUtils;
-import burp.IMessageEditor;
-import burp.IMessageEditorController;
-
-public class BurpEditorWrapper implements IMessageEditor, DocumentListener {
-
- private JTextArea fallbackArea;
- private IMessageEditor burpEditor;
- public boolean fallbackMode;
- boolean isModified;
- byte[] lastContent;
-
- public BurpEditorWrapper(IMessageEditorController controller, boolean editable) {
- if (BurpUtils.inBurp()) {
- this.burpEditor = BurpUtils.getInstance().getCallbacks().createMessageEditor(controller, editable);
- fallbackMode = false;
- } else {
- this.fallbackArea = new JTextArea();
- this.fallbackArea.getDocument().addDocumentListener(this);
- fallbackMode = true;
- }
- }
-
- @Override
- public Component getComponent() {
- if (fallbackMode) {
- JScrollPane inputScrollPane = new JScrollPane(fallbackArea);
- return inputScrollPane;
- }
- return burpEditor.getComponent();
- }
-
- @Override
- public byte[] getMessage() {
- byte[] result;
- result = fallbackMode ? fallbackArea.getText().getBytes() : burpEditor.getMessage();
- return result == null ? new byte[0] : result;
- }
-
- @Override
- public byte[] getSelectedData() {
- return null;
- }
-
- @Override
- public int[] getSelectionBounds() {
- return null;
- }
-
- @Override
- public boolean isMessageModified() {
- if (fallbackMode) {
- boolean state = this.isModified;
- this.isModified = false;
- return state;
- }
- // TODO: a little hack here
- if (!Arrays.equals(lastContent, getMessage())) {
- lastContent = getMessage();
- return true;
- }
- return false;
- }
-
- @Override
- public void setMessage(byte[] arg0, boolean arg1) {
- if (fallbackMode) {
- fallbackArea.setText(new String(arg0));
- } else {
- this.lastContent = arg0;
- burpEditor.setMessage(arg0, arg1); //TODO fix second parameter
- }
- }
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- this.isModified = true;
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- this.isModified = true;
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- this.isModified = true;
- }
-
-}
diff --git a/src/de/usd/cstchef/view/FormatTab.java b/src/de/usd/cstchef/view/FormatTab.java
deleted file mode 100644
index 8fe2978..0000000
--- a/src/de/usd/cstchef/view/FormatTab.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.Component;
-
-import burp.BurpUtils;
-import burp.IMessageEditorTab;
-import burp.ITextEditor;
-import burp.Logger;
-
-public class FormatTab implements IMessageEditorTab {
- private ITextEditor txtInput;
- private boolean editable;
- private RecipePanel responseFormatRecipePanel;
- private RecipePanel requestFormatRecipePanel;
- private byte[] currentMessage;
-
- public FormatTab(RecipePanel requestFormatRecipePanel, RecipePanel responseFormatRecipePanel, boolean editable) {
- this.editable = editable;
- this.responseFormatRecipePanel = responseFormatRecipePanel;
- this.requestFormatRecipePanel = requestFormatRecipePanel;
- txtInput = BurpUtils.getInstance().getCallbacks().createTextEditor();
- txtInput.setEditable(editable);
- }
-
- @Override
- public String getTabCaption() {
- return "CSTC";
- }
-
- @Override
- public Component getUiComponent() {
- return txtInput.getComponent();
- }
-
- @Override
- public boolean isEnabled(byte[] content, boolean isRequest) {
- return true;
- }
-
- @Override
- public void setMessage(byte[] content, boolean isRequest) {
- currentMessage = content;
-
- if (content == null) {
- txtInput.setText("Nothing here".getBytes());
- txtInput.setEditable(false);
- return;
- }
- RecipePanel recipe = isRequest ? this.requestFormatRecipePanel : this.responseFormatRecipePanel;
- Logger.getInstance().log("baking new stuff");
- byte[] result = recipe.bake(content);
- this.txtInput.setText(result);
- }
-
- @Override
- public byte[] getMessage() {
- return currentMessage;
- }
-
- @Override
- public boolean isModified() {
- return txtInput.isTextModified();
- }
-
- @Override
- public byte[] getSelectedData() {
- return txtInput.getSelectedText();
- }
-
-}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/view/LayoutPanel.java b/src/de/usd/cstchef/view/LayoutPanel.java
deleted file mode 100644
index ad5892c..0000000
--- a/src/de/usd/cstchef/view/LayoutPanel.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Font;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.UIManager;
-
-public class LayoutPanel extends JPanel {
-
- private Box headerBox;
-
- public LayoutPanel() {
- this("No tile");
- }
-
- public LayoutPanel(String title) {
- super();
- this.setLayout(new BorderLayout(0, 0));
-
- this.headerBox = Box.createHorizontalBox();
- this.headerBox.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- this.headerBox.setOpaque(true);
- this.headerBox.setBackground(UIManager.getColor("Panel.background"));
-
- JLabel titleLbl = new JLabel(title);
- titleLbl.setAlignmentX(Component.LEFT_ALIGNMENT);
-
- Font f = titleLbl.getFont();
- titleLbl.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
-
- this.headerBox.add(titleLbl);
- this.headerBox.add(Box.createHorizontalGlue());
-
- this.add(headerBox, BorderLayout.PAGE_START);
- }
-
- public void addActionComponent(JComponent comp) {
- comp.setAlignmentX(Component.RIGHT_ALIGNMENT);
- this.headerBox.add(comp);
- this.headerBox.add(Box.createHorizontalStrut(10));
- }
-}
diff --git a/src/de/usd/cstchef/view/MoveOperationMouseAdapter.java b/src/de/usd/cstchef/view/MoveOperationMouseAdapter.java
deleted file mode 100644
index 25587f6..0000000
--- a/src/de/usd/cstchef/view/MoveOperationMouseAdapter.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.Component;
-import java.awt.Container;
-
-import de.usd.cstchef.operations.Operation;
-
-public class MoveOperationMouseAdapter extends OperationMouseAdapter {
-
- public MoveOperationMouseAdapter(RecipeStepPanel source, Container target) {
- super(source.getOperationsPanel(), target);
- }
-
- @Override
- protected Operation getDraggedOperation(int x, int y) {
- Component comp = this.source.getComponentAt(x, y);
- comp.getParent().remove(comp);
-
- return comp instanceof Operation ? (Operation) comp : null;
- }
-
-}
diff --git a/src/de/usd/cstchef/view/OperationMouseAdapter.java b/src/de/usd/cstchef/view/OperationMouseAdapter.java
deleted file mode 100644
index fef166f..0000000
--- a/src/de/usd/cstchef/view/OperationMouseAdapter.java
+++ /dev/null
@@ -1,241 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.dnd.DragSource;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.Objects;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JWindow;
-import javax.swing.SwingUtilities;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-/*
- * Based on:
- * https://stackoverflow.com/questions/27245283/java-drag-and-drop-to-change-the-order-of-panels
- */
-public abstract class OperationMouseAdapter extends MouseAdapter {
-
- private static final Rectangle R1 = new Rectangle();
- private static final Rectangle R2 = new Rectangle();
-
- private static Rectangle prevRect;
-
- private final JWindow window = new JWindow();
- private Container panelPreview;
- private JLabel windowPreviewLbl;
- private JLabel panelPreviewLbl;
-
- private Point startPt;
- private Point dragOffset;
- private final int gestureMotionThreshold = DragSource.getDragThreshold();
-
- protected Container source;
- protected Container target;
- private RecipeStepPanel currentTargetPanel;
-
- private Operation draggedOperation;
-
- public OperationMouseAdapter(Container source, Container target) {
- super();
- this.source = source;
- this.target = target;
- window.setSize(300, 35);
- window.setLocationRelativeTo(null);
- window.setBackground(new Color(0, true));
- window.setVisible(false);
-
- Container windowPreview = createPreview("My Preview");
- windowPreviewLbl = (JLabel) windowPreview.getComponent(0);
- window.add(windowPreview);
- panelPreview = createPreview("My Preview");
- panelPreviewLbl = (JLabel) panelPreview.getComponent(0);
-
- dragOffset = new Point(window.getWidth() / 3, window.getHeight() / 2);
- }
-
- private Container createPreview(String title) {
- Box previewBox = Box.createHorizontalBox();
- previewBox.setOpaque(true);
- previewBox.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- previewBox.setBackground(new Color(127, 237, 247, 255));
-
- JLabel previewLbl = new JLabel(title);
- previewLbl.setForeground(new Color(58, 135, 173));
-
- previewBox.add(previewLbl);
- return previewBox;
- }
-
- private void startDragging(Point pt) {
- OperationInfos opInfos = this.draggedOperation.getClass().getAnnotation(OperationInfos.class);
- if (opInfos == null) {
- return;
- }
-
- String name = opInfos.name();
- windowPreviewLbl.setText(name);
- panelPreviewLbl.setText(name);
-
- updateWindowLocation(pt, this.source);
- window.setVisible(true);
- }
-
- private void updateWindowLocation(Point pt, Container parent) {
- Point p = new Point(pt.x - dragOffset.x, pt.y - dragOffset.y);
- SwingUtilities.convertPointToScreen(p, parent);
- window.setLocation(p);
- }
-
- private int getTargetIndex(Rectangle r, Point pt, int i, boolean previewIndexSmaller) {
- int ht2 = (int) (0.5 + r.height * 0.5);
- R1.setBounds(r.x, r.y, r.width, ht2);
- R2.setBounds(r.x, r.y + ht2, r.width, ht2);
- if (R1.contains(pt)) {
- prevRect = R1;
- return previewIndexSmaller ? i - 1 : i - 1 > 0 ? i : 0;
- } else if (R2.contains(pt)) {
- prevRect = R2;
- return i;
- }
- return -1;
- }
-
- private void addComponent(RecipeStepPanel line, Component comp, int idx) {
- line.removeComponent(comp);
- line.addComponent(comp, idx);
- }
-
- @Override
- public void mousePressed(MouseEvent e) {
- this.startPt = e.getPoint();
- }
-
- protected abstract Operation getDraggedOperation(int x, int y);
-
- @Override
- public void mouseDragged(MouseEvent e) {
- Point pt = e.getPoint();
- JComponent parent = (JComponent) e.getComponent();
-
- // not yet dragging and motion > threshold
- if (this.draggedOperation == null && startPt != null) {
- double a = Math.pow(pt.x - startPt.x, 2);
- double b = Math.pow(pt.y - startPt.y, 2);
- if (Math.sqrt(a + b) > gestureMotionThreshold) {
- this.draggedOperation = this.getDraggedOperation(startPt.x, startPt.y);
- if (this.draggedOperation != null) {
- startDragging(pt);
- }
- }
- return;
- }
-
- // dragging, but no component was created
- if (!window.isVisible() || draggedOperation == null) {
- return;
- }
-
- pt = SwingUtilities.convertPoint(parent, e.getPoint(), this.target);
- updateWindowLocation(pt, this.target);
-
- Component targetLine = this.target.getComponentAt(pt);
-
- // changed the target, remove the old preview
- if (currentTargetPanel != null) {
- if (targetLine == null || !targetLine.equals(currentTargetPanel)) {
- this.currentTargetPanel.removeComponent(panelPreview);
- this.currentTargetPanel = null;
- }
- }
-
- // we have no valid target
- if (targetLine == null || !(targetLine instanceof RecipeStepPanel)) {
- return;
- }
-
- RecipeStepPanel targetPanel = (RecipeStepPanel) this.target.getComponentAt(pt);
- this.currentTargetPanel = targetPanel;
-
- JPanel operationsPanel = currentTargetPanel.getOperationsPanel();
- pt = SwingUtilities.convertPoint(this.target, pt, operationsPanel);
-
- if (prevRect != null && prevRect.contains(pt)) {
- return;
- }
-
- boolean gotPreview = false;
- for (int i = 0; i < operationsPanel.getComponentCount(); i++) {
- Component comp = operationsPanel.getComponent(i);
- Rectangle r = comp.getBounds();
- // inside our gap, do nothing
- if (Objects.equals(comp, panelPreview)) {
- if (r.contains(pt)) {
- return;
- } else {
- gotPreview = true;
- continue;
- }
- }
-
- int tgt;
- if (!(comp instanceof Operation)) { //this is the dummy panel
- int count = operationsPanel.getComponentCount();
- tgt = count > 1 ? operationsPanel.getComponentCount() - 2 : 0;
- } else {
- tgt = getTargetIndex(r, pt, i, gotPreview);
- }
-
- if (tgt >= 0) {
- addComponent(currentTargetPanel, panelPreview, tgt);
- return;
- }
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- startPt = null;
-
- // no dragging
- if (!window.isVisible() || draggedOperation == null) {
- return;
- }
- int addIndex = -1;
-
- // get the index of the preview element
- if (currentTargetPanel != null) {
- JPanel operationsPanel = this.currentTargetPanel.getOperationsPanel();
- for (int i = 0; i < operationsPanel.getComponentCount(); i++) {
- Component comp = operationsPanel.getComponent(i);
- if (comp.equals(this.panelPreview)) {
- addIndex = i;
- break;
- }
- }
- // remove preview from panel
- currentTargetPanel.removeComponent(this.panelPreview);
- }
-
- if (addIndex != -1) {
- currentTargetPanel.addComponent(this.draggedOperation, addIndex);
- }
-
- this.draggedOperation = null;
- prevRect = null;
- this.startPt = null;
- this.window.setVisible(false);
- this.currentTargetPanel = null;
- }
-}
diff --git a/src/de/usd/cstchef/view/OperationTreeNode.java b/src/de/usd/cstchef/view/OperationTreeNode.java
deleted file mode 100644
index 2c9ae47..0000000
--- a/src/de/usd/cstchef/view/OperationTreeNode.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.usd.cstchef.view;
-
-import javax.swing.tree.DefaultMutableTreeNode;
-
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-public class OperationTreeNode extends DefaultMutableTreeNode {
-
- private String name;
- private String toolTipText;
- private Class extends Operation> operationClass;
-
- public OperationTreeNode(Class extends Operation> operationClass) {
- super();
- OperationInfos infos = operationClass.getAnnotation(OperationInfos.class);
- this.name = infos.name();
- this.toolTipText = infos.description();
-
- this.operationClass = operationClass;
- }
-
- public String getToolTipText() {
- return this.toolTipText;
- }
-
- public Class extends Operation> getOperationClass() {
- return operationClass;
- }
-
- @Override
- public String toString() {
- return this.name;
- }
-}
diff --git a/src/de/usd/cstchef/view/OperationsTree.java b/src/de/usd/cstchef/view/OperationsTree.java
deleted file mode 100644
index 05ef9e6..0000000
--- a/src/de/usd/cstchef/view/OperationsTree.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.event.MouseEvent;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-
-import javax.swing.ImageIcon;
-import javax.swing.JTree;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.MutableTreeNode;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-
-import burp.Logger;
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.operations.Operation;
-import de.usd.cstchef.operations.OperationCategory;
-import de.usd.cstchef.operations.Operation.OperationInfos;
-
-public class OperationsTree extends JTree {
-
- private DefaultTreeModel model;
- private static ImageIcon nodeIcon = new ImageIcon(Operation.class.getResource("/operation.png"));
- private static ImageIcon openIcon = new ImageIcon(Operation.class.getResource("/folder_open.png"));
- private static ImageIcon closedIcon = new ImageIcon(Operation.class.getResource("/folder_closed.png"));
-
- public OperationsTree() {
- super();
-
- this.model = (DefaultTreeModel) this.getModel();
- this.model.setRoot(this.createTree());
- this.setToolTipText("");
- DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) this.getCellRenderer();
- renderer.setLeafIcon(nodeIcon);
- renderer.setClosedIcon(closedIcon);
- renderer.setOpenIcon(openIcon);
- }
-
- @Override
- public String getToolTipText(MouseEvent evt) {
- if (getRowForLocation(evt.getX(), evt.getY()) == -1) {
- return null;
- }
-
- TreePath curPath = getPathForLocation(evt.getX(), evt.getY());
- Object node = curPath.getLastPathComponent();
-
- if (node.getClass().equals(OperationTreeNode.class)) {
- return ((OperationTreeNode) node).getToolTipText();
- } else if (node.getClass().equals(DefaultMutableTreeNode.class)) {
- return null;
- }
-
- return "";
- }
-
- public void search(String text) {
- DefaultMutableTreeNode root = this.createTree();
- this.model.setRoot(root);
-
- if (text.trim().equals("")) {
- return;
- }
-
- ArrayList nodesToRemove = new ArrayList<>();
- Enumeration e = root.breadthFirstEnumeration();
- while (e.hasMoreElements()) {
- DefaultMutableTreeNode nextNode = (DefaultMutableTreeNode) e.nextElement();
- if (!nextNode.toString().toLowerCase().contains(text.toLowerCase())) {
- if (nextNode.getChildCount() == 0) {
- nodesToRemove.add(nextNode);
- }
- }
- }
-
- for (DefaultMutableTreeNode node : nodesToRemove) {
- this.removeNode(node);
- }
-
- nodesToRemove.clear();
- for (int i = 0; i < root.getChildCount(); i++) {
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
- if (node.getChildCount() == 0) {
- nodesToRemove.add(node);
- }
- }
-
- for (DefaultMutableTreeNode node : nodesToRemove) {
- this.removeNode(node);
- }
-
- this.expandAll(new TreePath(root));
- }
-
- private void removeNode(TreeNode selNode) {
- if (selNode == null) {
- return;
- }
-
- MutableTreeNode parent = (MutableTreeNode) (selNode.getParent());
- if (parent == null) {
- return;
- }
-
- if (selNode.getChildCount() == 0) {
- this.model.removeNodeFromParent((MutableTreeNode) selNode);
- }
- }
-
- private DefaultMutableTreeNode createTree() {
- DefaultMutableTreeNode root = new DefaultMutableTreeNode();
-
- // add all categories
- HashMap categoryNodes = new HashMap<>();
- for (OperationCategory category : OperationCategory.values()) {
- DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(category.toString());
- root.add(categoryNode);
- categoryNodes.put(category, categoryNode);
- }
-
- // TODO add operations to categories - reflections do not work in burp :(
- Class extends Operation>[] operations = Utils.getOperations();
- for (Class extends Operation> operation : operations) {
- OperationInfos operationInfos = operation.getAnnotation(OperationInfos.class);
- if (operationInfos == null) {
- if (!Modifier.isAbstract(operation.getModifiers())) {
- Logger.getInstance().err("Found a operation without annotaion: " + operation);
- }
- continue;
- }
-
- OperationCategory category = operationInfos.category();
- DefaultMutableTreeNode parent = categoryNodes.get(category);
-
- OperationTreeNode newOperationNode = new OperationTreeNode(operation);
- parent.add(newOperationNode);
- }
-
- return root;
- }
-
- private void expandAll(TreePath path) {
- TreeNode node = (TreeNode) path.getLastPathComponent();
-
- if (node.getChildCount() >= 0) {
- Enumeration enumeration = node.children();
- while (enumeration.hasMoreElements()) {
- TreeNode n = (TreeNode) enumeration.nextElement();
- TreePath p = path.pathByAddingChild(n);
-
- expandAll(p);
- }
- }
- this.expandPath(path);
- }
-}
diff --git a/src/de/usd/cstchef/view/PopupVariableMenu.java b/src/de/usd/cstchef/view/PopupVariableMenu.java
deleted file mode 100644
index 697cb33..0000000
--- a/src/de/usd/cstchef/view/PopupVariableMenu.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.HashMap;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import javax.swing.text.JTextComponent;
-
-public class PopupVariableMenu extends JPopupMenu implements ActionListener, PopupMenuListener {
-
- private JTextComponent parent;
- private static SortedMap variableMap;
-
- public PopupVariableMenu(JTextComponent parent) {
- super();
- this.parent = parent;
- this.addPopupMenuListener(this);
-
- }
-
- public void refreshMenu() {
- this.removeAll();
-
- for (String key : variableMap.keySet()) {
- JMenuItem item = new JMenuItem(key);
- item.addActionListener(this);
- this.add(item);
- }
- }
-
- public static void refresh(HashMap variables) {
- if (variables == null) {
- variableMap = new TreeMap();
- } else {
- variableMap = new TreeMap(variables);
- }
- }
-
- @Override
- public void actionPerformed(ActionEvent arg0) {
- parent.setText(parent.getText() + "$" + arg0.getActionCommand());
- }
-
- @Override
- public void popupMenuCanceled(PopupMenuEvent arg0) {
- // not needed
- }
-
- @Override
- public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
- // not needed
- }
-
- @Override
- public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
- this.refreshMenu();
- }
-
-}
diff --git a/src/de/usd/cstchef/view/RecipePanel.java b/src/de/usd/cstchef/view/RecipePanel.java
deleted file mode 100644
index 3350676..0000000
--- a/src/de/usd/cstchef/view/RecipePanel.java
+++ /dev/null
@@ -1,544 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JFileChooser;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-import javax.swing.ToolTipManager;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import burp.BurpUtils;
-import burp.CstcMessageEditorController;
-import burp.IBurpExtenderCallbacks;
-import burp.IExtensionHelpers;
-import burp.IHttpRequestResponse;
-import burp.IParameter;
-import burp.IRequestInfo;
-import burp.Logger;
-import de.usd.cstchef.VariableStore;
-import de.usd.cstchef.operations.Operation;
-
-public class RecipePanel extends JPanel implements ChangeListener {
-
- private static Logger logger = Logger.getInstance();
-
- private int operationSteps = 10;
- private boolean autoBake = true;
- private boolean isRequest = true;
- private int bakeThreshold = 400;
- private String recipeName;
- private int filterMask;
-
- private BurpEditorWrapper inputText;
- private BurpEditorWrapper outputText;
-
- private JPanel operationLines;
- private RequestFilterDialog requestFilterDialog;
-
- private CstcMessageEditorController controllerOrig;
- private CstcMessageEditorController controllerMod;
-
- private Timer bakeTimer;
-
- public RecipePanel(String recipeName, boolean isRequest) {
-
- this.recipeName = recipeName;
- this.isRequest = isRequest;
-
- ToolTipManager tooltipManager = ToolTipManager.sharedInstance();
- tooltipManager.setInitialDelay(0);
- this.setLayout(new GridLayout(0, 1));
-
- JSplitPane inOut = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-
- controllerOrig = new CstcMessageEditorController();
- controllerMod = new CstcMessageEditorController();
-
- // create input panel
- JPanel inputPanel = new LayoutPanel("Input");
- inputText = new BurpEditorWrapper(controllerOrig, true);
- inputPanel.add(inputText.getComponent());
-
- // create output panel
- JPanel outputPanel = new LayoutPanel("Output");
- outputText = new BurpEditorWrapper(controllerMod, false);
- outputPanel.add(outputText.getComponent());
-
- JPanel searchTreePanel = new JPanel();
- searchTreePanel.setLayout(new BorderLayout());
- JTextField searchText = new JTextField();
- searchTreePanel.add(searchText, BorderLayout.PAGE_START);
-
- OperationsTree operationsTree = new OperationsTree();
- operationsTree.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- operationsTree.setRootVisible(false);
- searchTreePanel.add(new JScrollPane(operationsTree));
- searchText.getDocument().addDocumentListener(new DocumentListener() {
- @Override
- public void removeUpdate(DocumentEvent e) {
- operationsTree.search(searchText.getText());
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- operationsTree.search(searchText.getText());
- }
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- operationsTree.search(searchText.getText());
- }
- });
-
- // create operations panel
- JPanel operationsPanel = new LayoutPanel("Operations");
- operationsPanel.add(searchTreePanel);
- operationsPanel.setBackground(Color.WHITE);
- inOut.setTopComponent(inputPanel);
- inOut.setBottomComponent(outputPanel);
- inOut.setResizeWeight(0.5);
-
- // create active operations (middle) panel
- LayoutPanel activeOperationsPanel = new LayoutPanel("Recipe");
-
- // add action items
- JButton filters = new JButton("Filter");
- this.requestFilterDialog = new RequestFilterDialog();
- activeOperationsPanel.addActionComponent(filters);
- filters.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- int result = JOptionPane.showConfirmDialog(null, requestFilterDialog, "Request Filter", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
- if (result == JOptionPane.OK_OPTION) {
- filterMask = requestFilterDialog.getFilterMask();
- }
- }
- });
-
- JButton bakeButton = new JButton("Bake");
- activeOperationsPanel.addActionComponent(bakeButton);
- bakeButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- bake(false);
- }
- });
-
- JButton saveButton = new JButton("Save");
- activeOperationsPanel.addActionComponent(saveButton);
- saveButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- try {
- JFileChooser fc = new JFileChooser();
- int returnVal = fc.showSaveDialog(RecipePanel.this);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- File file = fc.getSelectedFile();
- save(file);
- }
- } catch (IOException e) {
- JOptionPane.showMessageDialog(null, "The file could not be saved.");
- }
- }
- });
-
- JButton loadButton = new JButton("Load");
- activeOperationsPanel.addActionComponent(loadButton);
- loadButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- try {
- JFileChooser fc = new JFileChooser();
- int returnVal = fc.showOpenDialog(RecipePanel.this);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- File file = fc.getSelectedFile();
- String jsonState = new String(Files.readAllBytes(Paths.get(file.getPath())));
- restoreState(jsonState);
- }
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException e) {
- JOptionPane.showMessageDialog(null, "The provided file could not be loaded.");
- }
- }
- });
-
- JCheckBox bakeCheckBox = new JCheckBox("Auto bake");
- bakeCheckBox.setSelected(this.autoBake);
- activeOperationsPanel.addActionComponent(bakeCheckBox);
- bakeCheckBox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent ae) {
- autoBake = bakeCheckBox.isSelected();
- bake(false);
- }
- });
-
- JButton variablesButton = new JButton("Variables");
- activeOperationsPanel.addActionComponent(variablesButton);
- variablesButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- VariablesWindow vw = VariablesWindow.getInstance();
- vw.refresh(VariableStore.getInstance().getVariables());
- vw.setVisible(true);
- }
- });
-
- operationLines = new JPanel();
- operationLines.setLayout(new GridBagLayout());
-
- // add dummy panel
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.gridheight = GridBagConstraints.REMAINDER;
- gbc.weightx = 1;
- gbc.weighty = 1;
- JPanel dummyPanel = new JPanel();
- dummyPanel.setBackground(Color.YELLOW);
-
- GridBagConstraints co = new GridBagConstraints();
- co.gridheight = GridBagConstraints.REMAINDER;
- co.weighty = 1;
- co.fill = GridBagConstraints.VERTICAL;
-
- operationLines.add(dummyPanel, gbc); // this is the magic!11!!
-
- for (int i = operationSteps; i > 0; i--) {
- RecipeStepPanel opPanel = new RecipeStepPanel(String.valueOf(i), this);
- operationLines.add(opPanel, co, 0);
-
- JPanel panel = opPanel.getOperationsPanel();
- MoveOperationMouseAdapter moma = new MoveOperationMouseAdapter(opPanel, operationLines);
- panel.addMouseListener(moma );
- panel.addMouseMotionListener(moma );
- }
-
- JScrollPane activeOperationsScrollPane = new JScrollPane(operationLines, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
- JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- activeOperationsPanel.add(activeOperationsScrollPane);
-
- JSplitPane opsInOut = new JSplitPane();
- opsInOut.setResizeWeight(0.5);
-
- opsInOut.setLeftComponent(activeOperationsPanel);
- opsInOut.setRightComponent(inOut);
-
- JSplitPane opSplit = new JSplitPane();
- opSplit.setRightComponent(opsInOut);
- opSplit.setLeftComponent(operationsPanel);
- opSplit.setResizeWeight(0.1);
-
- this.add(opSplit);
-
- AddOperationMouseAdapter dma = new AddOperationMouseAdapter(operationsTree, operationLines);
- operationsTree.addMouseListener(dma);
- operationsTree.addMouseMotionListener(dma);
-
- loadRecipeFromBurp();
- startAutoBakeTimer();
- }
-
- private void loadRecipeFromBurp() {
- logger.log("[" + this.recipeName + "] Autoloading...");
- boolean inBurp = BurpUtils.inBurp();
- //Check if we run inside a burp
- if (inBurp) {
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- String jsonState = callbacks.loadExtensionSetting("cstc_" + this.recipeName);
- if (jsonState != null && jsonState != "") {
- try {
- logger.log("[" + this.recipeName + "] Restoring state.");
- //We remove the setting and set it again to be safe in an error case
- callbacks.saveExtensionSetting("cstc_" + this.recipeName, "");
- restoreState(jsonState);
- callbacks.saveExtensionSetting("cstc_" + this.recipeName, jsonState);
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException e) {
- Logger.getInstance().err("There was an error restoring the state of RecipePanel " + this.recipeName);
- }
- }
- }
- else {
- logger.log("[" + this.recipeName + "] Autoloading aborted. Not running inside Burp.");
- }
- }
-
- private void autoSaveToBurp() {
- boolean inBurp = BurpUtils.inBurp();
- //Check if we run inside a burp
- if (inBurp) {
- try {
- String jsonState = getStateAsJSON();
- BurpUtils.getInstance().getCallbacks().saveExtensionSetting("cstc_" + this.recipeName, jsonState);
- } catch (IOException e) {
- Logger.getInstance().err("There was an error persisting the current state of the recipe panel.");
- }
- }
- }
-
- public void setInput(IHttpRequestResponse requestResponse) {
- if( isRequest )
- this.inputText.setMessage(requestResponse.getRequest(), true);
- else {
- byte[] responseBytes = requestResponse.getResponse();
- if( responseBytes == null )
- responseBytes = "Your request has no server response yet :(".getBytes();
- this.inputText.setMessage(responseBytes, false);
- }
-
- this.controllerOrig.setHttpRequestResponse(requestResponse);
- this.controllerMod.setHttpRequestResponse(requestResponse);
-
- this.bake(false);
- }
-
- private void restoreState(String jsonState) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
- // TODO do we want to remove all existing operations before loading here?
- ObjectMapper mapper = new ObjectMapper();
- JsonNode stepNodes = mapper.readTree(jsonState);
- if (!stepNodes.isArray()) {
- throw new IOException("wrong data format");
- }
-
- for (int step = 0; step < stepNodes.size(); step++) {
- JsonNode operationNodes = stepNodes.get(step);
- if (!operationNodes.isArray()) {
- throw new IOException("wrong data format");
- }
-
- for (int i = 0; i < operationNodes.size(); i++) {
- JsonNode operationNode = operationNodes.get(i);
- String operation = operationNode.get("operation").asText();
- Map parameters = mapper.convertValue(operationNode.get("parameters"), Map.class);
- Class cls = (Class) Class.forName(operation);
- // check if it is an operation
- Operation op = cls.newInstance();
- op.load(parameters);
- RecipeStepPanel panel = (RecipeStepPanel) this.operationLines.getComponent(step);
- panel.addComponent(op, i);
- }
- }
- }
-
- private String getStateAsJSON() throws IOException {
- ObjectMapper mapper = new ObjectMapper();
- ArrayNode stepsNode = mapper.createArrayNode();
-
- for (int step = 0; step < this.operationSteps; step++) {
- ArrayNode operationsNode = mapper.createArrayNode();
-
- RecipeStepPanel stepPanel = (RecipeStepPanel) this.operationLines.getComponent(step);
- List operations = stepPanel.getOperations();
- for (Operation op : operations) {
- ObjectNode operationNode = mapper.createObjectNode();
- operationNode.put("operation", op.getClass().getName());
- operationsNode.add(operationNode);
- operationNode.putPOJO("parameters", op.getState());
- }
- stepsNode.add(operationsNode);
- }
- return mapper.writeValueAsString(stepsNode);
- }
-
- private void save(File file) throws IOException {
- FileWriter fw = new FileWriter(file);
- fw.write(getStateAsJSON());
- fw.close();
- }
-
- private byte[] doBake(byte[] input) {
- if (input == null || input.length == 0) {
- return new byte[0];
- }
- byte[] result = input.clone();
- byte[] intermediateResult = input;
- boolean outputChanged;
- VariableStore store = VariableStore.getInstance();
- out: for (int j = 0; j < this.operationLines.getComponentCount(); j++) {
-
- Component operationLine = this.operationLines.getComponent(j);
- if (!(operationLine instanceof RecipeStepPanel)) {
- continue;
- }
-
- String stepVariableName = String.format("%s_step%d", this.recipeName, (j + 1));
- store.removeVariable(stepVariableName);
-
- intermediateResult = input;
- outputChanged = false;
-
- List operationList = ((RecipeStepPanel)operationLine).getOperations();
- for(int i = 0; i < operationList.size(); i++) {
-
- Operation op = operationList.get(i);
- if (op.isDisabled()) {
- continue;
- }
-
- intermediateResult = op.performOperation(intermediateResult);
- outputChanged = true;
-
- if (op.isBreakpoint()) {
- result = intermediateResult;
- store.setVariable(stepVariableName, intermediateResult);
- break out;
- }
-
- i += op.getOperationSkip();
- j += op.getLaneSkip();
- }
-
- if (outputChanged) {
- result = intermediateResult;
- store.setVariable(stepVariableName, intermediateResult);
- }
- }
-
- if (BurpUtils.inBurp()) {
- IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
-
- IRequestInfo info;
- try {
- info = helpers.analyzeRequest(result);
- } catch( IllegalArgumentException e ) {
- // In this case there is no valid HTTP request and no Content-Length update is requried.
- return result;
- }
-
- List headers = info.getHeaders();
- int offset = info.getBodyOffset();
-
- if( result.length == offset ) {
- // In this case there is no body and we do not need to update the content length header.
- return result;
- }
-
- for(String header : headers) {
- if(header.startsWith("Content-Length:")) {
- // To update the content-length header, we just add a dummy parameter and remove it right away.
- // Burps extension helpers will care about updating the length without any string transformations.
- IParameter dummy = helpers.buildParameter("dummy", "dummy", IParameter.PARAM_BODY);
- result = helpers.addParameter(result, dummy);
- result = helpers.removeParameter(result, dummy);
- break;
- }
- }
- return result;
-
- } else {
- return result;
- }
- }
-
- private void bake(boolean spamProtection) {
- if (this.bakeTimer != null) {
- this.bakeTimer.cancel();
- }
- this.bakeTimer = new Timer(this.recipeName);
- TimerTask tt = new TimerTask() {
- @Override
- public void run() {
- byte[] result = doBake(inputText.getMessage());
- HashMap variables = VariableStore.getInstance().getVariables();
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- if( isRequest) {
- outputText.setMessage(result, true);
- controllerMod.setRequest(result);
- } else {
- outputText.setMessage(result, false);
- controllerMod.setResponse(result);
- }
- VariablesWindow vw = VariablesWindow.getInstance();
- if (vw.isVisible()) {
- vw.refresh(variables);
- }
- PopupVariableMenu.refresh(variables);
- }
- });
- autoSaveToBurp();
- }
- };
- int threshold = spamProtection ? this.bakeThreshold : 0;
- this.bakeTimer.schedule(tt, threshold);
- }
-
- public byte[] bake(byte[] input) {
- VariableStore store = VariableStore.getInstance();
- try {
- store.lock();
- return this.doBake(input);
- } finally {
- store.unlock();
- }
- }
-
- private void startAutoBakeTimer() {
- TimerTask repeatedTask = new TimerTask() {
- public void run() {
- if (inputText.isMessageModified()) {
- logger.log("autobaking");
- autoBake();
- }
- }
- };
- Timer timer = new Timer("Timer");
- long delay = 1000L;
- long period = 1000L;
- timer.scheduleAtFixedRate(repeatedTask, delay, period);
- }
-
- private void autoBake() {
- if (!this.autoBake) {
- return;
- }
- VariableStore store = VariableStore.getInstance();
- try {
- store.lock();
- this.bake(true);
- } finally {
- store.unlock();
- }
- }
-
- @Override
- public void stateChanged(ChangeEvent e) {
- this.autoBake();
- }
-
- public boolean shouldProcess(int tool) {
- return (this.filterMask & tool) != 0;
- }
-}
diff --git a/src/de/usd/cstchef/view/RecipeStepPanel.java b/src/de/usd/cstchef/view/RecipeStepPanel.java
deleted file mode 100644
index 1b714f5..0000000
--- a/src/de/usd/cstchef/view/RecipeStepPanel.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextField;
-import javax.swing.border.Border;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.MatteBorder;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import de.usd.cstchef.operations.*;
-
-public class RecipeStepPanel extends JPanel {
-
- private JPanel operationsLine;
- private GridBagConstraints addContraints;
- private ChangeListener changeListener;
-
- public RecipeStepPanel(String title, ChangeListener changelistener) {
- this.changeListener = changelistener;
- this.setLayout(new BorderLayout());
- this.setPreferredSize(new Dimension(300, 0));
-
- // header
- Box headerBox = Box.createHorizontalBox();
- // add borders
- Border margin = BorderFactory.createEmptyBorder(10, 10, 10, 10);
- MatteBorder lineBorder = new MatteBorder(0, 0, 2, 0, Color.DARK_GRAY);
- CompoundBorder border = new CompoundBorder(lineBorder, margin);
- headerBox.setBorder(border);
-
- JTextField contentTextField = new JTextField();
- contentTextField.setBorder(null);
- contentTextField.setBackground(new Color(0, 0, 0, 0));
- contentTextField.setText(title);
- headerBox.add(contentTextField);
-
- this.add(headerBox, BorderLayout.NORTH);
-
- // body
- operationsLine = new JPanel(new GridBagLayout());
-
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.gridwidth = GridBagConstraints.REMAINDER;
- gbc.gridheight = GridBagConstraints.REMAINDER;
- gbc.weightx = 1;
- gbc.weighty = 1;
- gbc.fill = GridBagConstraints.BOTH;
-
- JPanel dummyPanel = new JPanel();
- operationsLine.add(dummyPanel, gbc);
-
- this.addContraints = new GridBagConstraints();
- this.addContraints.gridwidth = GridBagConstraints.REMAINDER;
- this.addContraints.weightx = 1;
- this.addContraints.fill = GridBagConstraints.HORIZONTAL;
-
- JScrollPane scrollPane = new JScrollPane(operationsLine);
- scrollPane.setBorder(new MatteBorder(0, 2, 0, 0, Color.DARK_GRAY));
- scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
- scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
- scrollPane.getVerticalScrollBar().setUnitIncrement(16);
-
- this.add(scrollPane, BorderLayout.CENTER);
- }
-
- public void addComponent(Component comp, int index) {
- operationsLine.add(comp, addContraints, index);
- operationsLine.revalidate();
- operationsLine.repaint();
- if (comp instanceof Operation) {
- ((Operation) comp).setChangeListener(this.changeListener);
- this.changeListener.stateChanged(new ChangeEvent(this));
- }
- }
-
- public void removeComponent(Component comp) {
- operationsLine.remove(comp);
- operationsLine.revalidate();
- operationsLine.repaint();
- this.changeListener.stateChanged(new ChangeEvent(this));
- }
-
- public JPanel getOperationsPanel() {
- return this.operationsLine;
- }
-
- public List getOperations() {
- List result = new ArrayList<>();
-
- for (int i = 0; i < this.operationsLine.getComponentCount(); i++) {
- Component op = this.operationsLine.getComponent(i);
- if (!(op instanceof Operation)) {
- continue;
- }
-
- result.add((Operation) op);
- }
- return result;
- }
-
-}
diff --git a/src/de/usd/cstchef/view/RequestFilterDialog.java b/src/de/usd/cstchef/view/RequestFilterDialog.java
deleted file mode 100644
index 176791a..0000000
--- a/src/de/usd/cstchef/view/RequestFilterDialog.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import burp.IBurpExtenderCallbacks;
-
-public class RequestFilterDialog extends JPanel {
- private LinkedHashMap filterSettings;
-
- public RequestFilterDialog() {
- this.filterSettings = new LinkedHashMap<>();
- this.filterSettings.put(new Filter("Proxy", IBurpExtenderCallbacks.TOOL_PROXY), false);
- this.filterSettings.put(new Filter("Repeater", IBurpExtenderCallbacks.TOOL_REPEATER), false);
- this.filterSettings.put(new Filter("Spider", IBurpExtenderCallbacks.TOOL_SPIDER), false);
- this.filterSettings.put(new Filter("Scanner", IBurpExtenderCallbacks.TOOL_SCANNER), false);
- this.filterSettings.put(new Filter("Intruder", IBurpExtenderCallbacks.TOOL_INTRUDER), false);
-
- this.setLayout(new GridLayout(0, 2));
-
- for (Map.Entry entry : this.filterSettings.entrySet()) {
- Filter filter = entry.getKey();
- boolean selected = entry.getValue();
- this.add(new JLabel(filter.getName() + ": "));
-
- JCheckBox box = new JCheckBox();
- box.setSelected(selected);
- box.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- filterSettings.put(filter, box.isSelected());
- }
- });
- this.add(box);
- }
- }
-
- public int getFilterMask() {
- int filterMask = 0;
- for (Map.Entry entry : this.filterSettings.entrySet()) {
- Filter filter = entry.getKey();
- boolean selected = entry.getValue();
- if (selected) {
- filterMask |= filter.getValue();
- }
- }
- return filterMask;
- }
-
- class Filter {
- private String name;
- private int value;
-
- public Filter(String name, int value) {
- this.name = name;
- this.value = value;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getValue() {
- return value;
- }
-
- public void setValue(int value) {
- this.value = value;
- }
- }
-}
diff --git a/src/de/usd/cstchef/view/VariablesWindow.java b/src/de/usd/cstchef/view/VariablesWindow.java
deleted file mode 100644
index 01a5756..0000000
--- a/src/de/usd/cstchef/view/VariablesWindow.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GridBagLayout;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.util.HashMap;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.JTextArea;
-import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.DefaultTableModel;
-import javax.swing.table.TableCellRenderer;
-import javax.swing.table.TableColumn;
-
-public class VariablesWindow extends JFrame {
-
- private static VariablesWindow instance;
-
- public static VariablesWindow getInstance() {
- if (VariablesWindow.instance == null) {
- VariablesWindow.instance = new VariablesWindow();
- }
- return VariablesWindow.instance;
- }
-
- private JLabel emptyLbl;
- private JTable table;
-
- private VariablesWindow() {
- super("Variables");
- this.setSize(new Dimension(600, 480));
-
- DefaultTableModel model = new DefaultTableModel(new String[] { "Variable Name", "Content" }, 0);
- this.table = new JTable(model) {
- public boolean isCellEditable(int row, int column) {
- return false;
- };
- };
-
- this.addComponentListener(new ComponentAdapter() {
- public void componentResized(ComponentEvent e) {
- if (table.getModel().getRowCount() == 0) {
- setColumnWidth(new Dimension());
- }
- }
- });
-
- this.table.setLayout(new GridBagLayout());
- this.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
- this.table.getColumnModel().getColumn(0).setPreferredWidth(200);
- this.table.getColumnModel().getColumn(1).setCellRenderer(new WordWrapCellRenderer());
- this.table.getTableHeader().setReorderingAllowed(false);
- this.table.getTableHeader().setResizingAllowed(false);
- this.table.setFillsViewportHeight(true);
- ((DefaultTableCellRenderer)table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment(JLabel.LEFT);
-
- this.emptyLbl = new JLabel("no variables defined");
- this.table.add(this.emptyLbl);
-
- JScrollPane scrollPane = new JScrollPane(this.table);
- this.add(scrollPane);
- }
-
- public void refresh(HashMap variables) {
- DefaultTableModel model = (DefaultTableModel) this.table.getModel();
- model.setRowCount(0);
- this.emptyLbl.setVisible(variables.isEmpty());
- SortedMap sortedMap = new TreeMap(variables);
-
- for (String key : sortedMap.keySet()) {
- model.addRow(new String[] { key, new String(sortedMap.get(key)) });
- }
- }
-
- private void setColumnWidth(Dimension preferredSize) {
- TableColumn contentColumn = this.table.getColumnModel().getColumn(1);
- int parentWidth = this.table.getParent().getWidth();
- int width = Integer.max(preferredSize.width + WordWrapCellRenderer.MARGIN, parentWidth - this.table.getColumnModel().getColumn(0).getWidth());
- contentColumn.setPreferredWidth(width);
- }
-
- class WordWrapCellRenderer extends JTextArea implements TableCellRenderer {
- private static final int MARGIN = 20;
-
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
- Dimension preferredSize = getPreferredSize();
- setText(value.toString());
- setSize(preferredSize.width, getPreferredSize().height);
- if (table.getRowHeight(row) != getPreferredSize().height) {
- table.setRowHeight(row, getPreferredSize().height);
- }
- setColumnWidth(preferredSize);
- return this;
- }
- }
-}
diff --git a/src/de/usd/cstchef/view/View.java b/src/de/usd/cstchef/view/View.java
deleted file mode 100644
index 22faa09..0000000
--- a/src/de/usd/cstchef/view/View.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package de.usd.cstchef.view;
-
-import java.awt.BorderLayout;
-import java.security.Security;
-
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JTabbedPane;
-import javax.swing.WindowConstants;
-
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-
-public class View extends JPanel {
-
- private RecipePanel incomingRecipePanel;
- private RecipePanel outgoingRecipePanel;
- private RecipePanel formatRecipePanel;
-
- public View() {
- Security.addProvider(new BouncyCastleProvider());
-
- this.setLayout(new BorderLayout());
- JTabbedPane tabbedPane = new JTabbedPane();
-
- incomingRecipePanel = new RecipePanel("Incomming", false);
- outgoingRecipePanel = new RecipePanel("Outgoing", true);
- formatRecipePanel = new RecipePanel("Formatting", true);
-
- tabbedPane.addTab("Outgoing Requests", null, outgoingRecipePanel, "Outgoing requests from the browser, the repeater or another tool.");
- tabbedPane.addTab("Incoming Responses", null, incomingRecipePanel, "Responses from the server.");
- tabbedPane.addTab("Formating", null, formatRecipePanel, "Formating for messages.");
- this.add(tabbedPane);
- }
-
- public RecipePanel getIncomingRecipePanel() {
- return this.incomingRecipePanel;
- }
-
- public RecipePanel getOutgoingRecipePanel() {
- return this.outgoingRecipePanel;
- }
-
- public RecipePanel getFormatRecipePanel() {
- return this.formatRecipePanel;
- }
-
- public static void main(String[] args) {
- JFrame frame = new JFrame("CSTC");
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- View view = new View();
-
- frame.setContentPane(view);
- frame.setSize(800, 600);
- frame.setVisible(true);
-// frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
- }
-}
diff --git a/src/de/usd/cstchef/view/ui/FormatTextField.java b/src/de/usd/cstchef/view/ui/FormatTextField.java
deleted file mode 100644
index 53e0b39..0000000
--- a/src/de/usd/cstchef/view/ui/FormatTextField.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package de.usd.cstchef.view.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.UnsupportedEncodingException;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.Box;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.event.DocumentListener;
-import org.bouncycastle.util.encoders.Hex;
-
-public class FormatTextField extends JPanel implements ActionListener {
-
- public VariableTextField txtField;
- private JComboBox formatBox;
- private DocumentListener docListener;
-
- public FormatTextField() {
- this.setLayout(new BorderLayout());
- this.setBackground(new Color(0, 0, 0, 0));
- this.txtField = new VariableTextField();
- this.formatBox = new JComboBox<>(new String[] {"Raw", "UTF-8", "Hex", "Latin1", "Base64"});
- this.formatBox.addActionListener(this);
-
- Box box = Box.createHorizontalBox();
- box.add(formatBox);
- box.add(Box.createHorizontalStrut(10));
- box.add(txtField);
-
- this.add(box);
- }
-
- public Map getValues() {
- Map values = new HashMap<>();
- values.put("text", this.txtField.getText());
- values.put("encoding", this.formatBox.getSelectedItem().toString());
- return values;
- }
-
- public void setValues(Map values) {
- String text = values.get("text");
- this.txtField.setText(text);
- Object encoding = values.get("encoding");
- this.formatBox.setSelectedItem(encoding);
- }
-
- public byte[] getText() throws UnsupportedEncodingException {
-
- byte[] raw = this.txtField.getBytes();
- byte[] result = null;
-
- switch ((String) this.formatBox.getSelectedItem()) {
- case "Raw":
- result = raw;
- break;
- case "Hex":
- result = Hex.decode(raw);
- break;
- case "Base64":
- result = Base64.getDecoder().decode(raw);
- break;
- case "Latin1":
- result = this.txtField.getText().getBytes("ISO-8859-1");
- break;
- case "UTF-8":
- result = this.txtField.getText().getBytes("UTF-8");
- break;
- }
- return result;
- }
-
- public void addDocumentListener(DocumentListener listener) {
- this.docListener = listener;
- this.txtField.getDocument().addDocumentListener(listener);
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if (this.docListener != null) {
- this.docListener.changedUpdate(null);
- }
- }
-
-}
diff --git a/src/de/usd/cstchef/view/ui/VariableTextArea.java b/src/de/usd/cstchef/view/ui/VariableTextArea.java
deleted file mode 100644
index 0b8b1c3..0000000
--- a/src/de/usd/cstchef/view/ui/VariableTextArea.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package de.usd.cstchef.view.ui;
-
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.event.DocumentListener;
-
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.view.PopupVariableMenu;
-
-
-public class VariableTextArea extends JScrollPane {
-
- private JTextArea txtArea;
-
- public VariableTextArea() {
- this.txtArea = new JTextArea();
- this.setViewportView(this.txtArea);
- this.txtArea.setRows(5);
- this.txtArea.setComponentPopupMenu(new PopupVariableMenu(this.txtArea));
- }
-
- public String getText() {
- String text = this.txtArea.getText();
- return Utils.replaceVariables(text);
- }
-
- public byte[] getBytes() {
- byte[] bytes = this.txtArea.getText().getBytes();
- return Utils.replaceVariablesByte(bytes);
- }
-
- public void setText(String text) {
- this.txtArea.setText(text);
- }
-
- public String getRawText() {
- return this.txtArea.getText();
- }
-
- public void addDocumentListener(DocumentListener notifyChangeListener) {
- this.txtArea.getDocument().addDocumentListener(notifyChangeListener);
- }
-
-}
diff --git a/src/de/usd/cstchef/view/ui/VariableTextField.java b/src/de/usd/cstchef/view/ui/VariableTextField.java
deleted file mode 100644
index c9f2caf..0000000
--- a/src/de/usd/cstchef/view/ui/VariableTextField.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.usd.cstchef.view.ui;
-
-import javax.swing.JTextField;
-
-import de.usd.cstchef.Utils;
-import de.usd.cstchef.view.PopupVariableMenu;
-
-public class VariableTextField extends JTextField {
-
- public VariableTextField() {
- super();
- this.setComponentPopupMenu(new PopupVariableMenu(this));
- }
-
- @Override
- public String getText() {
- String text = super.getText();
- return Utils.replaceVariables(text);
- }
-
- public byte[] getBytes() {
- byte[] bytes = super.getText().getBytes();
- return Utils.replaceVariablesByte(bytes);
- }
-
- public String getRawText() {
- return super.getText();
- }
-
-}
diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java
new file mode 100644
index 0000000..8262661
--- /dev/null
+++ b/src/main/java/burp/BurpExtender.java
@@ -0,0 +1,114 @@
+package burp;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JMenuItem;
+
+import de.usd.cstchef.view.FormatTab;
+import de.usd.cstchef.view.RecipePanel;
+import de.usd.cstchef.view.View;
+
+public class BurpExtender implements IBurpExtender, ITab, IMessageEditorTabFactory, IHttpListener, IContextMenuFactory {
+
+ private final String extensionName = "CSTC";
+ private IBurpExtenderCallbacks callbacks;
+ private View view;
+
+ @Override
+ public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {
+ this.callbacks = callbacks;
+ Logger.getInstance().init(callbacks.getStdout(), callbacks.getStderr());
+ BurpUtils.getInstance().init(callbacks);
+
+ callbacks.setExtensionName(this.extensionName);
+ callbacks.addSuiteTab(this);
+ callbacks.registerHttpListener(this);
+ callbacks.registerContextMenuFactory(this);
+ callbacks.registerMessageEditorTabFactory(this);
+ }
+
+
+ @Override
+ public String getTabCaption() {
+ return this.extensionName;
+ }
+
+ @Override
+ public Component getUiComponent() {
+ this.view = new View();
+ return this.view;
+ }
+
+ @Override
+ public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
+ if (messageIsRequest && view.getOutgoingRecipePanel().shouldProcess(toolFlag)) {
+ byte[] request = messageInfo.getRequest();
+ byte[] modifiedRequest = view.getOutgoingRecipePanel().bake(request);
+ Logger.getInstance().log("modified request: \n" + new String(modifiedRequest));
+ messageInfo.setRequest(modifiedRequest);
+ } else if (view.getIncomingRecipePanel().shouldProcess(toolFlag)) {
+ byte[] response = messageInfo.getResponse();
+ byte[] modifiedResponse = view.getIncomingRecipePanel().bake(response);
+ messageInfo.setResponse(modifiedResponse);
+ Logger.getInstance().log("modified response: \n" + new String(modifiedResponse));
+ }
+ }
+
+ @Override
+ public List createMenuItems(IContextMenuInvocation invoc) {
+
+ List menuItems = new ArrayList<>();
+ JMenuItem incomingMenu = new JMenuItem("Send to CSTC (Incoming)");
+ JMenuItem outgoingMenu = new JMenuItem("Send to CSTC (Outgoing)");
+ JMenuItem incomingFormatMenu = new JMenuItem("Send to CSTC (Formating)");
+
+ menuItems.add(incomingMenu);
+ menuItems.add(outgoingMenu);
+ menuItems.add(incomingFormatMenu);
+
+ incomingMenu.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ IHttpRequestResponse[] msgs = invoc.getSelectedMessages();
+ if (msgs != null && msgs.length > 0) {
+ view.getIncomingRecipePanel().setInput(msgs[0]);
+ }
+ }
+ });
+
+ outgoingMenu.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ IHttpRequestResponse[] msgs = invoc.getSelectedMessages();
+ if (msgs != null && msgs.length > 0) {
+ view.getOutgoingRecipePanel().setInput(msgs[0]);
+ }
+
+ }
+ });
+
+ incomingFormatMenu.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ IHttpRequestResponse[] msgs = invoc.getSelectedMessages();
+ if (msgs != null && msgs.length > 0) {
+ view.getFormatRecipePanel().setInput(msgs[0]);
+ }
+ }
+ });
+
+ return menuItems;
+ }
+
+ @Override
+ public IMessageEditorTab createNewInstance(IMessageEditorController controller, boolean editable) {
+ RecipePanel requestFormatPanel = this.view.getOutgoingRecipePanel();
+ // TODO do we need the format panel or do we want to use the incoming recipe?
+ RecipePanel responseFormatPanel = this.view.getFormatRecipePanel();
+ return new FormatTab(requestFormatPanel, responseFormatPanel, editable);
+ }
+}
diff --git a/src/main/java/burp/BurpUtils.java b/src/main/java/burp/BurpUtils.java
new file mode 100644
index 0000000..251d052
--- /dev/null
+++ b/src/main/java/burp/BurpUtils.java
@@ -0,0 +1,38 @@
+package burp;
+
+public class BurpUtils {
+
+ private static BurpUtils instance;
+ private IBurpExtenderCallbacks callbacks;
+
+ public static BurpUtils getInstance() {
+ if (BurpUtils.instance == null) {
+ BurpUtils.instance = new BurpUtils();
+ }
+ return BurpUtils.instance;
+ }
+
+ private BurpUtils() {
+ }
+
+ public void init(IBurpExtenderCallbacks callbacks) {
+ this.callbacks = callbacks;
+ }
+
+ public IBurpExtenderCallbacks getCallbacks() throws IllegalAccessError {
+ if (this.callbacks == null) {
+ throw new IllegalAccessError("Only works within burpsuite");
+ }
+ return callbacks;
+ }
+
+ public static boolean inBurp() {
+ try {
+ BurpUtils.getInstance().getCallbacks();
+ return true;
+ } catch (IllegalAccessError e) {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/burp/CstcMessageEditorController.java b/src/main/java/burp/CstcMessageEditorController.java
new file mode 100644
index 0000000..79aecd0
--- /dev/null
+++ b/src/main/java/burp/CstcMessageEditorController.java
@@ -0,0 +1,37 @@
+package burp;
+
+public class CstcMessageEditorController implements IMessageEditorController {
+
+ private IHttpService httpService = null;
+ private byte[] request = null;
+ private byte[] response = null;
+
+ public void setHttpRequestResponse(IHttpRequestResponse requestResponse) {
+ this.httpService = requestResponse.getHttpService();
+ this.request = requestResponse.getRequest();
+ this.response = requestResponse.getResponse();
+ }
+
+ public void setRequest(byte[] request) {
+ this.request = request;
+ }
+
+ public void setResponse(byte[] response) {
+ this.request = response;
+ }
+
+ @Override
+ public IHttpService getHttpService() {
+ return httpService;
+ }
+
+ @Override
+ public byte[] getRequest() {
+ return request;
+ }
+
+ @Override
+ public byte[] getResponse() {
+ return response;
+ }
+}
diff --git a/src/main/java/burp/Logger.java b/src/main/java/burp/Logger.java
new file mode 100644
index 0000000..c3a73dd
--- /dev/null
+++ b/src/main/java/burp/Logger.java
@@ -0,0 +1,44 @@
+package burp;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+public class Logger {
+
+ private static Logger instance;
+
+ private PrintWriter stdout;
+ private PrintWriter stderr;
+
+ public static Logger getInstance() {
+ if (Logger.instance == null) {
+ Logger.instance = new Logger();
+ }
+ return Logger.instance;
+ }
+
+ private Logger() {
+
+ }
+
+ public void init(OutputStream stdOut, OutputStream stdErr) {
+ this.stdout = new PrintWriter(stdOut, true);
+ this.stderr = new PrintWriter(stdErr, true);
+ }
+
+ public void log(String msg) {
+ if (this.stdout == null) {
+ System.out.println(msg);
+ } else {
+ this.stdout.println(msg);
+ }
+ }
+
+ public void err(String msg) {
+ if (this.stderr == null) {
+ System.err.println(msg);
+ } else {
+ this.stderr.println(msg);
+ }
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/Delimiter.java b/src/main/java/de/usd/cstchef/Delimiter.java
new file mode 100644
index 0000000..f08ff52
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/Delimiter.java
@@ -0,0 +1,46 @@
+package de.usd.cstchef;
+
+public enum Delimiter
+{
+ COMMA("Comma", ","),
+ SPACE("Space", " "),
+ LINE_FEED("Line feed", "\n"),
+ COLON("Colon", ":"),
+ CLRF("CLRF", "\r\n"),
+ SEMICOLON("Semicolon", ";");
+
+ private String name;
+ private String value;
+
+ Delimiter(String name, String value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getValue()
+ {
+ return this.value;
+ }
+
+ public static Delimiter getByName(String name)
+ {
+ for(Delimiter delim : Delimiter.values() )
+
+ if( delim.name.equals(name) )
+ return delim;
+
+ return null;
+ }
+
+ public static String[] getNames()
+ {
+ Delimiter[] delims = Delimiter.values();
+ String[] names = new String[delims.length];
+
+ for(int ctr = 0; ctr < delims.length; ctr++ )
+ names[ctr] = delims[ctr].name;
+
+ return names;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/Utils.java b/src/main/java/de/usd/cstchef/Utils.java
similarity index 67%
rename from src/de/usd/cstchef/Utils.java
rename to src/main/java/de/usd/cstchef/Utils.java
index 506585f..0e7b4f8 100644
--- a/src/de/usd/cstchef/Utils.java
+++ b/src/main/java/de/usd/cstchef/Utils.java
@@ -101,123 +101,113 @@
import de.usd.cstchef.operations.string.Length;
import de.usd.cstchef.operations.string.Prefix;
import de.usd.cstchef.operations.string.Replace;
+import de.usd.cstchef.operations.string.Reverse;
import de.usd.cstchef.operations.string.SplitAndSelect;
import de.usd.cstchef.operations.string.StaticString;
import de.usd.cstchef.operations.string.Substring;
import de.usd.cstchef.operations.string.Suffix;
+import de.usd.cstchef.operations.string.Uppercase;
+import de.usd.cstchef.operations.string.Lowercase;
import de.usd.cstchef.operations.utils.GetVariable;
import de.usd.cstchef.operations.utils.NoOperation;
import de.usd.cstchef.operations.utils.RandomNumber;
+import de.usd.cstchef.operations.utils.RandomUUID;
import de.usd.cstchef.operations.utils.SetIfEmpty;
import de.usd.cstchef.operations.utils.StoreVariable;
import de.usd.cstchef.view.View;
public class Utils {
- // TODO find a better way to do this
-
-
- public static HashMap delimiters = new HashMap() {
- {
- put("Comma", ",");
- put("Space", " ");
- put("Line feed", "\n");
- put("Colon", ":");
- put("CLRF", "\r\n");
- put("Semi-colon", ";");
- }
- };
-
- public static double parseNumber(String in) {
- // TODO hex values??
- return Double.valueOf(in);
- }
-
- public static String replaceVariables(String text) {
- HashMap variables = VariableStore.getInstance().getVariables();
- for (Entry entry : variables.entrySet()) {
- // TODO this is easy, but very bad, how to do this right?
- text = text.replace("$" + entry.getKey(), new String(entry.getValue()));
- }
-
- return text;
- }
-
- public static byte[] replaceVariablesByte(byte[] bytes) {
- HashMap variables = VariableStore.getInstance().getVariables();
+ public static double parseNumber(String in) {
+ // TODO hex values??
+ return Double.valueOf(in);
+ }
+
+ public static String replaceVariables(String text) {
+ HashMap variables = VariableStore.getInstance().getVariables();
+ for (Entry entry : variables.entrySet()) {
+ // TODO this is easy, but very bad, how to do this right?
+ text = text.replace("$" + entry.getKey(), new String(entry.getValue()));
+ }
+
+ return text;
+ }
+
+ public static byte[] replaceVariablesByte(byte[] bytes) {
+ HashMap variables = VariableStore.getInstance().getVariables();
IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = callbacks.getHelpers();
+ IExtensionHelpers helpers = callbacks.getHelpers();
- byte[] currentKey;
- for (Entry entry : variables.entrySet()) {
+ byte[] currentKey;
+ for (Entry entry : variables.entrySet()) {
int offset = 0;
- currentKey = ("$" + entry.getKey()).getBytes();
+ currentKey = ("$" + entry.getKey()).getBytes();
while( offset >= 0 ) {
offset = helpers.indexOf(bytes, currentKey, true, offset, bytes.length);
if( offset >= 0 )
bytes = insertAtOffset(bytes, offset, offset + currentKey.length, entry.getValue());
}
- }
- return bytes;
- }
+ }
+ return bytes;
+ }
public static byte[] insertAtOffset(byte[] input, int start, int end, byte[] newValue) {
- byte[] prefix = Arrays.copyOfRange(input, 0, start);
- byte[] rest = Arrays.copyOfRange(input, end, input.length);
-
- byte[] output = new byte[prefix.length + newValue.length + rest.length];
- System.arraycopy(prefix, 0, output, 0, prefix.length);
- System.arraycopy(newValue, 0, output, prefix.length, newValue.length);
- System.arraycopy(rest, 0, output, prefix.length + newValue.length, rest.length);
-
- return output;
- }
-
- public static Class extends Operation>[] getOperationsBurp() {
- ZipInputStream zip = null;
- List> operations = new ArrayList>();
-
- try {
- File f = new File(View.class.getProtectionDomain().getCodeSource().getLocation().toURI());
- zip = new ZipInputStream(new FileInputStream(f.getAbsolutePath()));
- for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
- if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
- continue;
- }
-
- String className = entry.getName().replace('/', '.');
- className = className.substring(0, className.length() - ".class".length());
- if (!className.contains("de.usd.operations")) {
- continue;
- }
-
- Class cls = Class.forName(className);
- if (Operation.class.isAssignableFrom(cls)) {
- Logger.getInstance().log(cls.toString());
- operations.add(cls);
- }
- }
- } catch (URISyntaxException e) {
- } catch (ClassNotFoundException e) {
- } catch (FileNotFoundException e) {
- } catch (IOException e) {
- } finally {
- try {
- zip.close();
- } catch (IOException e) {
- }
- }
-
- return operations.toArray(new Class[operations.size()]);
- }
-
- // TODO reflection does not work in Burp Suite
- @SuppressWarnings("unchecked")
- public static Class extends Operation>[] getOperationsDev() {
- return new Class[] {
+ byte[] prefix = Arrays.copyOfRange(input, 0, start);
+ byte[] rest = Arrays.copyOfRange(input, end, input.length);
+
+ byte[] output = new byte[prefix.length + newValue.length + rest.length];
+ System.arraycopy(prefix, 0, output, 0, prefix.length);
+ System.arraycopy(newValue, 0, output, prefix.length, newValue.length);
+ System.arraycopy(rest, 0, output, prefix.length + newValue.length, rest.length);
+
+ return output;
+ }
+
+ public static Class extends Operation>[] getOperationsBurp() {
+ ZipInputStream zip = null;
+ List> operations = new ArrayList>();
+
+ try {
+ File f = new File(View.class.getProtectionDomain().getCodeSource().getLocation().toURI());
+ zip = new ZipInputStream(new FileInputStream(f.getAbsolutePath()));
+ for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
+ if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
+ continue;
+ }
+
+ String className = entry.getName().replace('/', '.');
+ className = className.substring(0, className.length() - ".class".length());
+ if (!className.contains("de.usd.operations")) {
+ continue;
+ }
+
+ Class cls = Class.forName(className);
+ if (Operation.class.isAssignableFrom(cls)) {
+ Logger.getInstance().log(cls.toString());
+ operations.add(cls);
+ }
+ }
+ } catch (URISyntaxException e) {
+ } catch (ClassNotFoundException e) {
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ } finally {
+ try {
+ zip.close();
+ } catch (IOException e) {
+ }
+ }
+
+ return operations.toArray(new Class[operations.size()]);
+ }
+
+ // TODO reflection does not work in Burp Suite
+ @SuppressWarnings("unchecked")
+ public static Class extends Operation>[] getOperationsDev() {
+ return new Class[] {
Addition.class, AddKey.class, AesDecryption.class, AesEncryption.class, And.class,
Blake.class, DateTime.class, Deflate.class, DesDecryption.class, DesEncryption.class,
Divide.class, DivideList.class, DSTU7564.class, FromBase64.class, FromHex.class,
@@ -231,19 +221,19 @@ public static Class extends Operation>[] getOperationsDev() {
JsonExtractor.class, JsonSetter.class, Length.class, LineExtractor.class,
LineSetter.class, MD2.class, MD4.class, MD5.class, Mean.class, Median.class,
Multiply.class, MultiplyList.class, NoOperation.class, NumberCompare.class, Prefix.class,
- RandomNumber.class, ReadFile.class, RegexExtractor.class, Replace.class, RIPEMD.class,
- RsaDecryption.class, RsaEncryption.class, RsaSignature.class, RegexMatch.class,
+ RandomNumber.class, RandomUUID.class ,ReadFile.class, RegexExtractor.class, Reverse.class, Replace.class,
+ RIPEMD.class, RsaDecryption.class, RsaEncryption.class, RsaSignature.class, RegexMatch.class,
SetIfEmpty.class, SHA1.class, SHA2.class, SHA3.class, Skein.class, SplitAndSelect.class,
- StaticString.class, StoreVariable.class, Sub.class, Substring.class, Subtraction.class,
+ StaticString.class, StoreVariable.class, Sub.class, Substring.class, Uppercase.class, Lowercase.class, Subtraction.class,
Suffix.class, Sum.class, StringContains.class, StringMatch.class, Tiger.class,
ToBase64.class, ToHex.class, UnixTimestamp.class, UrlDecode.class, UrlEncode.class,
Whirlpool.class, WriteFile.class, XmlFullSignature.class, XmlMultiSignature.class,
Xor.class, SoapMultiSignature.class
- };
- }
+ };
+ }
- public static Class extends Operation>[] getOperations() {
- return BurpUtils.inBurp() ? Utils.getOperationsDev() : Utils.getOperationsDev();
- }
+ public static Class extends Operation>[] getOperations() {
+ return BurpUtils.inBurp() ? Utils.getOperationsDev() : Utils.getOperationsDev();
+ }
}
diff --git a/src/main/java/de/usd/cstchef/VariableStore.java b/src/main/java/de/usd/cstchef/VariableStore.java
new file mode 100644
index 0000000..a182599
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/VariableStore.java
@@ -0,0 +1,56 @@
+package de.usd.cstchef;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class VariableStore {
+
+ private static VariableStore instance;
+
+ private HashMap variables = new HashMap<>();
+ private ReentrantLock lock = new ReentrantLock();
+
+ public static VariableStore getInstance() {
+ if (VariableStore.instance == null) {
+ VariableStore.instance = new VariableStore();
+ }
+ return VariableStore.instance;
+ }
+
+ private VariableStore() {
+ }
+
+ public void lock() {
+ this.lock.lock();
+ }
+
+ public void unlock() {
+ this.lock.unlock();
+ }
+
+ public synchronized byte[] getVariable(String name) {
+ return this.variables.get(name);
+ }
+
+ public synchronized void setVariable(String key, byte[] value) {
+ this.variables.put(key, value);
+ }
+
+ public synchronized void removeVariable(String key) {
+ this.variables.remove(key);
+ }
+
+ public synchronized HashMap getVariables() {
+ HashMap variablesCopy = new HashMap<>();
+
+ for (Map.Entry entry : this.variables.entrySet()) {
+ byte[] orig = entry.getValue();
+ byte[] newContent = new byte[orig.length];
+ System.arraycopy(orig, 0, newContent, 0, orig.length);
+ variablesCopy.put(entry.getKey(), newContent);
+ }
+ return variablesCopy;
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/Operation.java b/src/main/java/de/usd/cstchef/operations/Operation.java
new file mode 100644
index 0000000..3e38acd
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/Operation.java
@@ -0,0 +1,496 @@
+package de.usd.cstchef.operations;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.EOFException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JSpinner;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.MatteBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import burp.Logger;
+import de.usd.cstchef.view.ui.FormatTextField;
+import de.usd.cstchef.view.ui.VariableTextArea;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+public abstract class Operation extends JPanel {
+
+ private static Color defaultBgColor = new Color(223, 240, 216);
+ private static Color defaultFontColor = new Color(70, 136, 71);
+ private static Color disabledBgColor = new Color(223, 223, 223);
+ private static Color disabledFontColor = new Color(153, 153, 153);
+ private static Color breakBgColor = new Color(242, 222, 222);
+ private static Color breakFontColor = new Color(185, 74, 72);
+ private static Color errorBgColor = new Color(255, 121, 128);
+ private static Color errorFontColor = new Color(185, 74, 72);
+
+ private static ImageIcon breakIcon = new ImageIcon(Operation.class.getResource("/stop.png"));
+ private static ImageIcon breakIconActive = new ImageIcon(Operation.class.getResource("/stop_active.png"));
+ private static ImageIcon disableIcon = new ImageIcon(Operation.class.getResource("/disable.png"));
+ private static ImageIcon removeIcon = new ImageIcon(Operation.class.getResource("/remove.png"));
+ private static ImageIcon helpIcon = new ImageIcon(Operation.class.getResource("/help.png"));
+
+ private NotifyChangeListener notifyChangeListener;
+
+ private boolean breakpoint = false;
+ private boolean disabled = false;
+ private boolean error = false;
+
+ private ChangeListener changeListener;
+ private JTextArea errorArea;
+ private Box contentBox;
+ private Map uiElements;
+
+ private int operationSkip = 0;
+ private int laneSkip = 0;
+
+ public Operation() {
+ super();
+ this.uiElements = new HashMap<>();
+
+ this.setLayout(new BorderLayout());
+ this.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+ // set border
+ Border margin = BorderFactory.createEmptyBorder(10, 10, 10, 10);
+ MatteBorder lineBorder = new MatteBorder(0, 0, 1, 0, Color.BLACK);
+ CompoundBorder border = new CompoundBorder(lineBorder, margin);
+ this.setBorder(border);
+
+ // add header
+ JPanel header = new JPanel();
+ header.setBackground(new Color(0, 0, 0, 0)); // transparent
+
+ BoxLayout layout = new BoxLayout(header, BoxLayout.X_AXIS);
+ header.setLayout(layout);
+ header.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
+ OperationInfos opInfos = this.getClass().getAnnotation(OperationInfos.class);
+
+ JLabel titleLbl = new JLabel(opInfos.name());
+ Font f = titleLbl.getFont();
+ titleLbl.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
+
+ JButton disableBtn = createIconButton(Operation.disableIcon);
+ disableBtn.setToolTipText("Disable");
+ JButton breakpointBtn = createIconButton(Operation.breakIcon);
+ breakpointBtn.setToolTipText("Breakpoint");
+ JButton removeBtn = createIconButton(Operation.removeIcon);
+ removeBtn.setToolTipText("Remove");
+ JButton helpBtn = createIconButton(Operation.helpIcon);
+ helpBtn.setToolTipText(opInfos.description());
+
+ disableBtn.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ disabled = !isDisabled();
+ refreshColors();
+ validate();
+ repaint();
+ notifyChange();
+ }
+ });
+
+ breakpointBtn.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ breakpoint = !isBreakpoint();
+ ImageIcon newIcon = isBreakpoint() ? Operation.breakIconActive : Operation.breakIcon;
+ breakpointBtn.setIcon(newIcon);
+ refreshColors();
+ validate();
+ repaint();
+ notifyChange();
+ }
+ });
+ JPanel me = this;
+ removeBtn.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Container parent = getParent();
+ onRemove();
+ parent.remove(me);
+ parent.validate();
+ parent.repaint();
+ notifyChange();
+ }
+ });
+
+ header.add(titleLbl);
+ header.add(Box.createHorizontalStrut(6));
+ header.add(helpBtn);
+ header.add(Box.createHorizontalGlue());
+ header.add(disableBtn);
+ header.add(Box.createHorizontalStrut(3));
+ header.add(breakpointBtn);
+ header.add(Box.createHorizontalStrut(3));
+ header.add(removeBtn);
+
+ this.add(header, BorderLayout.NORTH);
+
+ errorArea = new JTextArea();
+ errorArea.setEditable(false);
+ errorArea.setLineWrap(true);
+ errorArea.setWrapStyleWord(true);
+ errorArea.setBackground(new Color(0, 0, 0, 0));
+ errorArea.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
+ errorArea.setFocusable(false);
+ errorArea.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
+
+ this.add(errorArea, BorderLayout.SOUTH);
+
+ contentBox = Box.createVerticalBox();
+ this.add(contentBox, BorderLayout.CENTER);
+
+ this.createUI();
+ this.refreshColors();
+ }
+
+ public Map getState() {
+ Map properties = new HashMap<>();
+ for (String key : this.uiElements.keySet()) {
+ if( key.startsWith("noupdate") )
+ properties.put(key, null);
+ else
+ properties.put(key, getUiValues(this.uiElements.get(key)));
+ }
+
+ return properties;
+ }
+
+ private Object getUiValues(Component comp) {
+ Object result = null;
+ if (comp instanceof JPasswordField) {
+ result = "";
+ } else if (comp instanceof VariableTextArea) {
+ result = ((VariableTextArea) comp).getRawText();
+ } else if (comp instanceof VariableTextField) {
+ result = ((VariableTextField) comp).getRawText();
+ } else if (comp instanceof JTextField) {
+ result = ((JTextField) comp).getText();
+ } else if (comp instanceof JSpinner) {
+ result = ((JSpinner) comp).getValue();
+ } else if (comp instanceof JComboBox) {
+ result = ((JComboBox>) comp).getSelectedItem();
+ if( result != null )
+ result = result.toString();
+ } else if (comp instanceof JCheckBox) {
+ result = ((JCheckBox) comp).isSelected();
+ } else if (comp instanceof FormatTextField) {
+ result = ((FormatTextField) comp).getValues();
+ } else if (comp instanceof JFileChooser) {
+ result = ((JFileChooser) comp).getName();
+ }
+
+ return result;
+ }
+
+ public void load(Map parameters) {
+ for (String key : this.uiElements.keySet()) {
+ Object value = parameters.get(key);
+ this.setUiValue(this.uiElements.get(key), value);
+ }
+ }
+
+ private void setUiValue(Component comp, Object value) {
+ if (comp == null || value == null) {
+ return;
+ }
+
+ if (comp instanceof JTextField) {
+ ((JTextField) comp).setText((String) value);
+ } else if (comp instanceof JSpinner) {
+ ((JSpinner) comp).setValue(value);
+ } else if (comp instanceof JComboBox) {
+ ((JComboBox>) comp).setSelectedItem(value);
+ } else if (comp instanceof VariableTextArea) {
+ ((VariableTextArea) comp).setText((String) value);
+ } else if (comp instanceof JCheckBox) {
+ ((JCheckBox) comp).setSelected((boolean) value);
+ } else if (comp instanceof FormatTextField) {
+ ((FormatTextField) comp).setValues((Map) value);
+ } else if (comp instanceof JFileChooser) {
+ ((JFileChooser) comp).setName((String)value);
+ }
+ }
+
+ private JButton createIconButton(ImageIcon icon) {
+ JButton btn = new JButton();
+ btn.setBorder(BorderFactory.createEmptyBorder());
+ btn.setIcon(icon);
+ btn.setContentAreaFilled(false);
+ btn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ btn.setAlignmentX(Component.RIGHT_ALIGNMENT);
+
+ return btn;
+ }
+
+ private void refreshColors() {
+ Color bgColor;
+ Color fontColor;
+ if (this.isDisabled()) {
+ bgColor = Operation.disabledBgColor;
+ fontColor = Operation.disabledFontColor;
+ } else if (this.isError()) {
+ bgColor = Operation.errorBgColor;
+ fontColor = Operation.errorFontColor;
+ } else if (this.isBreakpoint()) {
+ bgColor = Operation.breakBgColor;
+ fontColor = Operation.breakFontColor;
+ } else {
+ bgColor = Operation.defaultBgColor;
+ fontColor = Operation.defaultFontColor;
+ }
+
+ this.setBackground(bgColor);
+ this.changeFontColor(this, fontColor);
+ }
+
+ private void changeFontColor(Container container, Color color) {
+ for (Component comp : container.getComponents()) {
+ if (comp instanceof JLabel || comp.equals(errorArea)) {
+ comp.setForeground(color);
+ } else if (comp instanceof Container) {
+ changeFontColor((Container) comp, color);
+ }
+ }
+ }
+
+ protected void addUIElement(String caption, Component comp) {
+ this.addUIElement(caption, comp, true, null);
+ }
+
+ protected void addUIElement(String caption, Component comp, boolean notifyChange) {
+ this.addUIElement(caption, comp, notifyChange, null);
+ }
+
+ protected void addUIElement(String caption, Component comp, String identifier) {
+ this.addUIElement(caption, comp, true, identifier);
+ }
+
+ protected void addUIElement(String caption, Component comp, boolean notifyChange, String identifier) {
+ comp.setCursor(Cursor.getDefaultCursor());
+
+ Box box = Box.createHorizontalBox();
+ box.setAlignmentX(Component.LEFT_ALIGNMENT);
+ if (comp instanceof JCheckBox) {
+ comp.setBackground(new Color(0, 0, 0, 0));
+ }
+ JLabel lbl = new JLabel(caption);
+ box.add(lbl);
+ box.add(Box.createHorizontalStrut(10));
+ box.add(comp);
+ this.contentBox.add(box);
+ this.contentBox.add(Box.createVerticalStrut(10));
+ if( identifier == null )
+ identifier = caption;
+ this.uiElements.put(identifier, comp);
+
+ if (notifyChange) {
+ if (notifyChangeListener == null) {
+ notifyChangeListener = new NotifyChangeListener();
+ }
+
+ if (comp instanceof JTextField) {
+ ((JTextField) comp).getDocument().addDocumentListener(notifyChangeListener);
+ } else if (comp instanceof JSpinner) {
+ ((JSpinner) comp).addChangeListener(notifyChangeListener);
+ } else if (comp instanceof JComboBox) {
+ ((JComboBox>) comp).addActionListener(notifyChangeListener);
+ } else if (comp instanceof VariableTextArea) {
+ ((VariableTextArea) comp).addDocumentListener(notifyChangeListener);
+ } else if (comp instanceof JCheckBox) {
+ ((JCheckBox) comp).addActionListener(notifyChangeListener);
+ } else if (comp instanceof FormatTextField) {
+ ((FormatTextField) comp).addDocumentListener(notifyChangeListener);
+ } else {
+ Logger.getInstance().err("could not add a default change listener for " + comp.getClass());
+ }
+ }
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension dim = super.getPreferredSize();
+ int width = this.getParent().getWidth();
+ dim.setSize(width, dim.height);
+ return dim;
+ }
+
+ public byte[] performOperation(byte[] input) {
+ try {
+ byte[] result = this.perform(input);
+ this.setErrorMessage(null);
+ return result;
+ } catch (EOFException e) {
+ this.setErrorMessage(new EOFException("End of file"));
+ return new byte[0];
+ } catch (Throwable e) {
+ this.setErrorMessage(e);
+ return new byte[0];
+ }
+ }
+
+ public void setErrorMessage(Throwable e) {
+ boolean error = e != null;
+
+ String msg = error ? e.getMessage() : "";
+ String text;
+ if (msg == null) {
+ text = e.getClass().getName();
+ } else {
+ text = error ? (msg.isEmpty() ? e.toString() : msg) : "";
+ }
+
+ this.errorArea.setText(text);
+
+ this.setError(error);
+ this.refreshColors();
+ this.validate();
+ this.repaint();
+ }
+
+ public void removeChangeListener() {
+ this.changeListener = null;
+ }
+
+ public void setChangeListener(ChangeListener listener) {
+ this.changeListener = listener;
+ }
+
+ protected void notifyChange() {
+ if (this.changeListener != null) {
+ this.changeListener.stateChanged(new ChangeEvent(this));
+ }
+ }
+
+ public boolean isBreakpoint() {
+ return breakpoint;
+ }
+
+ public void setBreakpoint(boolean breakpoint) {
+ this.breakpoint = breakpoint;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ refreshColors();
+ validate();
+ repaint();
+ notifyChange();
+ }
+
+ public boolean isError() {
+ return error;
+ }
+
+ public void setError(boolean error) {
+ this.error = error;
+ }
+
+ public void setOperationSkip(int count) {
+ if( count < 0 )
+ count = 0;
+ this.operationSkip = count;
+ }
+
+ public int getOperationSkip() {
+ return this.operationSkip;
+ }
+
+ public void setLaneSkip(int count) {
+ if( count < 0 )
+ count = 0;
+ this.laneSkip = count;
+ }
+
+ public int getLaneSkip() {
+ return this.laneSkip;
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ public @interface OperationInfos {
+
+ public String name()
+
+ default "Unnamed plugin!";
+
+ public String description()
+
+ default "Change this description!";
+
+ public OperationCategory category() default OperationCategory.MISC;
+ }
+
+ protected abstract byte[] perform(byte[] input) throws Exception;
+
+ public void createUI() {
+
+ }
+
+ public void onRemove() {
+
+ }
+
+ private class NotifyChangeListener implements DocumentListener, ActionListener, ChangeListener {
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ notifyChange();
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ notifyChange();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ notifyChange();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ notifyChange();
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ notifyChange();
+ }
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/OperationCategory.java b/src/main/java/de/usd/cstchef/operations/OperationCategory.java
new file mode 100644
index 0000000..01e8a3d
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/OperationCategory.java
@@ -0,0 +1,32 @@
+package de.usd.cstchef.operations;
+
+public enum OperationCategory {
+ ARITHMETIC("Arithmetic"),
+ BYTEOPERATION("Byte Operations"),
+ COMPRESSION("Compression"),
+ CONDITIONALS("Conditionals"),
+ DATAFORMAT("Data format"),
+ DATES("Date / Time"),
+ ENCRYPTION("Encryption / Encoding"),
+ EXTRACTORS("Extractors"),
+ HASHING("Hashing"),
+ MISC("Misc"),
+ NETWORKING("Networking"),
+ SETTER("Setter"),
+ SIGNATURE("Signature"),
+ STRING("String"),
+ UTILS("Utils");
+// LANGUAGE("Language"),
+// FLOWCONTROL("Flow control");
+
+ private final String text;
+
+ OperationCategory(final String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+}
diff --git a/src/de/usd/cstchef/operations/arithmetic/Addition.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Addition.java
similarity index 59%
rename from src/de/usd/cstchef/operations/arithmetic/Addition.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/Addition.java
index 4daacd0..61c3f2c 100644
--- a/src/de/usd/cstchef/operations/arithmetic/Addition.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Addition.java
@@ -4,10 +4,11 @@
import de.usd.cstchef.operations.OperationCategory;
@OperationInfos(name = "Single - Add", category = OperationCategory.ARITHMETIC, description = "Add to the input the given number.")
-public class Addition extends ArithmeticOperation {
-
- @Override
- protected double calculate(double input_number, double static_number) {
- return input_number + static_number;
- }
+public class Addition extends ArithmeticOperation
+{
+ @Override
+ protected double calculate(double input_number, double static_number)
+ {
+ return input_number + static_number;
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/arithmetic/ArithmeticDelimiterOperation.java b/src/main/java/de/usd/cstchef/operations/arithmetic/ArithmeticDelimiterOperation.java
new file mode 100644
index 0000000..9050058
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/ArithmeticDelimiterOperation.java
@@ -0,0 +1,74 @@
+package de.usd.cstchef.operations.arithmetic;
+
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+
+import de.usd.cstchef.Delimiter;
+import de.usd.cstchef.Utils;
+import de.usd.cstchef.operations.Operation;
+
+public abstract class ArithmeticDelimiterOperation extends Operation
+{
+ private JComboBox delimiterBox;
+ private JCheckBox floatCheckBox;
+
+ protected Delimiter getDelimiter() throws IllegalArgumentException
+ {
+ String delimString = (String)this.delimiterBox.getSelectedItem();
+ Delimiter delim = Delimiter.getByName(delimString);
+
+ if( delim == null )
+ throw new IllegalArgumentException("Invalid delimiter.");
+
+ return delim;
+ }
+
+ protected boolean isFloat()
+ {
+ return floatCheckBox.isSelected();
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception
+ {
+ String delimiter = getDelimiter().getValue();
+ String[] lines = new String(input).split(delimiter);
+
+ if (lines.length < 2)
+ return input;
+
+ double[] numbers = new double[lines.length];
+ double result = Utils.parseNumber(lines[0].trim());
+
+ for(int i = 1; i < lines.length; i++)
+ {
+ numbers[i] = Utils.parseNumber(lines[i].trim());
+ result = this.calculate(result, numbers[i]);
+ }
+
+ result = onFinish(result, numbers);
+
+ if( !isFloat() )
+ return String.valueOf(Math.round(result)).getBytes();
+
+ return String.valueOf(result).getBytes();
+ }
+
+ protected double onFinish(double result, double[] lines)
+ {
+ return result;
+ }
+
+ protected abstract double calculate(double a, double b);
+
+ @Override
+ public void createUI()
+ {
+ this.delimiterBox = new JComboBox(Delimiter.getNames());
+ this.addUIElement("Delimiter", this.delimiterBox);
+
+ this.floatCheckBox = new JCheckBox();
+ this.addUIElement("Point Number", this.floatCheckBox);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/arithmetic/ArithmeticOperation.java b/src/main/java/de/usd/cstchef/operations/arithmetic/ArithmeticOperation.java
new file mode 100644
index 0000000..c17bf06
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/ArithmeticOperation.java
@@ -0,0 +1,61 @@
+package de.usd.cstchef.operations.arithmetic;
+
+import javax.swing.JCheckBox;
+import javax.swing.JTextField;
+
+import de.usd.cstchef.operations.Operation;
+
+public abstract class ArithmeticOperation extends Operation
+{
+ private JTextField numberInput;
+ private JCheckBox floatCheckBox;
+
+ protected double getNumber()
+ {
+ return Double.valueOf(numberInput.getText());
+ }
+
+ protected boolean isFloat()
+ {
+ return floatCheckBox.isSelected();
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception
+ {
+ try
+ {
+ String i = new String(input);
+
+ if (i.isEmpty())
+ i = "0";
+
+ Double input_number = Double.valueOf(i);
+ Double static_number = getNumber();
+ Double result_number = calculate(input_number, static_number);
+
+ if ( isFloat() )
+ return String.valueOf(result_number).getBytes();
+
+ return String.valueOf(Math.round(result_number)).getBytes();
+
+ }
+
+ catch( Exception e )
+ {
+ throw new IllegalArgumentException("Input is not a number.");
+ }
+ }
+
+ protected abstract double calculate(double input_number, double static_number);
+
+ @Override
+ public void createUI()
+ {
+ this.numberInput = new JTextField("1");
+ this.addUIElement("Number", this.numberInput);
+
+ this.floatCheckBox = new JCheckBox();
+ this.addUIElement("Point Number", this.floatCheckBox);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/usd/cstchef/operations/arithmetic/Divide.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Divide.java
new file mode 100644
index 0000000..46a7e31
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Divide.java
@@ -0,0 +1,46 @@
+package de.usd.cstchef.operations.arithmetic;
+
+import javax.swing.JCheckBox;
+
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "Single - Divide", category = OperationCategory.ARITHMETIC, description = "Divide input by the given number")
+public class Divide extends ArithmeticOperation
+{
+ private JCheckBox reverse;
+
+ protected boolean isReverse()
+ {
+ return reverse.isSelected();
+ }
+
+ @Override
+ protected double calculate(double input_number, double static_number)
+ {
+ if( isReverse() )
+ {
+ if( input_number == 0 )
+ input_number = 1;
+
+ return static_number / input_number;
+ }
+
+ else
+ {
+ if( static_number == 0 )
+ static_number = 1;
+
+ return input_number / static_number;
+ }
+ }
+
+ @Override
+ public void createUI()
+ {
+ super.createUI();
+
+ this.reverse = new JCheckBox();
+ this.addUIElement("Reverse", this.reverse);
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/arithmetic/DivideList.java b/src/main/java/de/usd/cstchef/operations/arithmetic/DivideList.java
similarity index 63%
rename from src/de/usd/cstchef/operations/arithmetic/DivideList.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/DivideList.java
index bc4992c..c3bee77 100644
--- a/src/de/usd/cstchef/operations/arithmetic/DivideList.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/DivideList.java
@@ -4,11 +4,11 @@
import de.usd.cstchef.operations.Operation.OperationInfos;
@OperationInfos(name = "List - Divide", category = OperationCategory.ARITHMETIC, description = "Divides a list of numbers.")
-public class DivideList extends ArithmeticDelimiterOperation {
-
- @Override
- protected double calculate(double a, double b) {
- return a / b;
- }
-
-}
+public class DivideList extends ArithmeticDelimiterOperation
+{
+ @Override
+ protected double calculate(double a, double b)
+ {
+ return a / b;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/arithmetic/Mean.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Mean.java
similarity index 51%
rename from src/de/usd/cstchef/operations/arithmetic/Mean.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/Mean.java
index c0b96f1..a1b3798 100644
--- a/src/de/usd/cstchef/operations/arithmetic/Mean.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Mean.java
@@ -4,16 +4,17 @@
import de.usd.cstchef.operations.Operation.OperationInfos;
@OperationInfos(name = "List - Mean", category = OperationCategory.ARITHMETIC, description = "Computes the mean of a list of numbers.")
-public class Mean extends ArithmeticDelimiterOperation {
+public class Mean extends ArithmeticDelimiterOperation
+{
+ @Override
+ protected double calculate(double a, double b)
+ {
+ return a + b;
+ }
- @Override
- protected double calculate(double a, double b) {
- return a + b;
- }
-
- @Override
- protected double onFinish(double result, double[] lines) {
- return result / lines.length;
- }
-
-}
+ @Override
+ protected double onFinish(double result, double[] lines)
+ {
+ return result / lines.length;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/usd/cstchef/operations/arithmetic/Median.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Median.java
new file mode 100644
index 0000000..ab29e6e
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Median.java
@@ -0,0 +1,36 @@
+package de.usd.cstchef.operations.arithmetic;
+
+import java.util.Arrays;
+
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+
+@OperationInfos(name = "List - Median", category = OperationCategory.ARITHMETIC, description = "Computes the median of a list of numbers.")
+public class Median extends ArithmeticDelimiterOperation
+{
+ @Override
+ protected double calculate(double a, double b)
+ {
+ return a;
+ }
+
+ @Override
+ protected double onFinish(double intermediateResult, double[] lines)
+ {
+ Arrays.sort(lines);
+ double result;
+
+ if (lines.length % 2 == 0)
+ {
+ int mid = lines.length / 2;
+ result = (lines[mid] + lines[mid - 1]) / 2;
+ }
+
+ else
+ {
+ result = lines[(int) (Math.floor(lines.length / 2))];
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/arithmetic/Multiply.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Multiply.java
similarity index 60%
rename from src/de/usd/cstchef/operations/arithmetic/Multiply.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/Multiply.java
index 0b9b5a9..1fd4934 100644
--- a/src/de/usd/cstchef/operations/arithmetic/Multiply.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Multiply.java
@@ -4,11 +4,11 @@
import de.usd.cstchef.operations.OperationCategory;
@OperationInfos(name = "Single - Multiply", category = OperationCategory.ARITHMETIC, description = "Multiply input with the given number")
-public class Multiply extends ArithmeticOperation {
-
- @Override
- protected double calculate(double input_number, double static_number) {
- return input_number * static_number;
- }
-
-}
+public class Multiply extends ArithmeticOperation
+{
+ @Override
+ protected double calculate(double input_number, double static_number)
+ {
+ return input_number * static_number;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/arithmetic/MultiplyList.java b/src/main/java/de/usd/cstchef/operations/arithmetic/MultiplyList.java
similarity index 63%
rename from src/de/usd/cstchef/operations/arithmetic/MultiplyList.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/MultiplyList.java
index 2ba1e6e..5672221 100644
--- a/src/de/usd/cstchef/operations/arithmetic/MultiplyList.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/MultiplyList.java
@@ -4,11 +4,11 @@
import de.usd.cstchef.operations.Operation.OperationInfos;
@OperationInfos(name = "List - Multiply", category = OperationCategory.ARITHMETIC, description = "Multiplies a list of numbers.")
-public class MultiplyList extends ArithmeticDelimiterOperation {
-
- @Override
- protected double calculate(double a, double b) {
- return a * b;
- }
-
-}
+public class MultiplyList extends ArithmeticDelimiterOperation
+{
+ @Override
+ protected double calculate(double a, double b)
+ {
+ return a * b;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/arithmetic/Subtraction.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Subtraction.java
similarity index 60%
rename from src/de/usd/cstchef/operations/arithmetic/Subtraction.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/Subtraction.java
index 63e6c34..f8e2721 100644
--- a/src/de/usd/cstchef/operations/arithmetic/Subtraction.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Subtraction.java
@@ -4,10 +4,11 @@
import de.usd.cstchef.operations.Operation.OperationInfos;
@OperationInfos(name = "Single - Subtract", category = OperationCategory.ARITHMETIC, description = "Subtract from the input the given number.")
-public class Subtraction extends ArithmeticOperation {
-
- @Override
- protected double calculate(double input_number, double static_number) {
- return input_number - static_number;
- }
-}
+public class Subtraction extends ArithmeticOperation
+{
+ @Override
+ protected double calculate(double input_number, double static_number)
+ {
+ return input_number - static_number;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/arithmetic/Sum.java b/src/main/java/de/usd/cstchef/operations/arithmetic/Sum.java
similarity index 64%
rename from src/de/usd/cstchef/operations/arithmetic/Sum.java
rename to src/main/java/de/usd/cstchef/operations/arithmetic/Sum.java
index 9f6256d..65880ca 100644
--- a/src/de/usd/cstchef/operations/arithmetic/Sum.java
+++ b/src/main/java/de/usd/cstchef/operations/arithmetic/Sum.java
@@ -4,11 +4,12 @@
import de.usd.cstchef.operations.Operation.OperationInfos;
@OperationInfos(name = "List - Sum", category = OperationCategory.ARITHMETIC, description = "Sums a list of numbers.")
-public class Sum extends ArithmeticDelimiterOperation {
-
- @Override
- protected double calculate(double a, double b) {
- return a + b;
- }
-
-}
+public class Sum extends ArithmeticDelimiterOperation
+{
+
+ @Override
+ protected double calculate(double a, double b)
+ {
+ return a + b;
+ }
+}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/byteoperation/AddKey.java b/src/main/java/de/usd/cstchef/operations/byteoperation/AddKey.java
similarity index 74%
rename from src/de/usd/cstchef/operations/byteoperation/AddKey.java
rename to src/main/java/de/usd/cstchef/operations/byteoperation/AddKey.java
index 955c598..57c5fba 100644
--- a/src/de/usd/cstchef/operations/byteoperation/AddKey.java
+++ b/src/main/java/de/usd/cstchef/operations/byteoperation/AddKey.java
@@ -6,9 +6,9 @@
@OperationInfos(name = "Add", category = OperationCategory.BYTEOPERATION, description = "Adds the input with the given key.")
public class AddKey extends ByteKeyOperation {
- @Override
- protected byte calculate(byte input, byte var) {
- return (byte) ((input + var) % 255);
- }
+ @Override
+ protected byte calculate(byte input, byte var) {
+ return (byte) ((input + var) % 255);
+ }
}
diff --git a/src/de/usd/cstchef/operations/byteoperation/And.java b/src/main/java/de/usd/cstchef/operations/byteoperation/And.java
similarity index 74%
rename from src/de/usd/cstchef/operations/byteoperation/And.java
rename to src/main/java/de/usd/cstchef/operations/byteoperation/And.java
index 571e8c7..ad11cc4 100644
--- a/src/de/usd/cstchef/operations/byteoperation/And.java
+++ b/src/main/java/de/usd/cstchef/operations/byteoperation/And.java
@@ -6,9 +6,9 @@
@OperationInfos(name = "And", category = OperationCategory.BYTEOPERATION, description = "Ands the input with the given key.")
public class And extends ByteKeyOperation {
- @Override
- protected byte calculate(byte input, byte var) {
- return (byte) ((input & var) % 255);
- }
+ @Override
+ protected byte calculate(byte input, byte var) {
+ return (byte) ((input & var) % 255);
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/byteoperation/ByteKeyOperation.java b/src/main/java/de/usd/cstchef/operations/byteoperation/ByteKeyOperation.java
new file mode 100644
index 0000000..54026fc
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/byteoperation/ByteKeyOperation.java
@@ -0,0 +1,37 @@
+package de.usd.cstchef.operations.byteoperation;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.view.ui.FormatTextField;
+
+public abstract class ByteKeyOperation extends Operation {
+
+ private FormatTextField inputTxt;
+
+ public void createUI() {
+ this.inputTxt = new FormatTextField();
+ this.addUIElement("Key", inputTxt);
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] result = new byte[input.length];
+ byte[] key = this.inputTxt.getText();
+
+ if (key.length == 0) {
+ return input;
+ }
+
+ int keyCounter = 0;
+ for (int i = 0; i < input.length; i++) {
+ byte var = key[keyCounter];
+ keyCounter = (keyCounter + 1) % key.length;
+ result[i] = calculate(input[i], var);
+ }
+
+ return result;
+ }
+
+ protected abstract byte calculate(byte input, byte var);
+
+}
diff --git a/src/de/usd/cstchef/operations/byteoperation/Sub.java b/src/main/java/de/usd/cstchef/operations/byteoperation/Sub.java
similarity index 74%
rename from src/de/usd/cstchef/operations/byteoperation/Sub.java
rename to src/main/java/de/usd/cstchef/operations/byteoperation/Sub.java
index 68e4cf8..0f7892b 100644
--- a/src/de/usd/cstchef/operations/byteoperation/Sub.java
+++ b/src/main/java/de/usd/cstchef/operations/byteoperation/Sub.java
@@ -6,9 +6,9 @@
@OperationInfos(name = "Sub", category = OperationCategory.BYTEOPERATION, description = "Substracts the input with the given key.")
public class Sub extends ByteKeyOperation {
- @Override
- protected byte calculate(byte input, byte var) {
- return (byte) ((input - var) % 255);
- }
+ @Override
+ protected byte calculate(byte input, byte var) {
+ return (byte) ((input - var) % 255);
+ }
}
diff --git a/src/de/usd/cstchef/operations/byteoperation/Xor.java b/src/main/java/de/usd/cstchef/operations/byteoperation/Xor.java
similarity index 74%
rename from src/de/usd/cstchef/operations/byteoperation/Xor.java
rename to src/main/java/de/usd/cstchef/operations/byteoperation/Xor.java
index cda432e..bc91ad6 100644
--- a/src/de/usd/cstchef/operations/byteoperation/Xor.java
+++ b/src/main/java/de/usd/cstchef/operations/byteoperation/Xor.java
@@ -6,9 +6,9 @@
@OperationInfos(name = "Xor", category = OperationCategory.BYTEOPERATION, description = "Xors the input with the given key.")
public class Xor extends ByteKeyOperation {
- @Override
- protected byte calculate(byte input, byte var) {
- return (byte) ((input ^ var) % 255);
- }
+ @Override
+ protected byte calculate(byte input, byte var) {
+ return (byte) ((input ^ var) % 255);
+ }
}
diff --git a/src/de/usd/cstchef/operations/compression/Deflate.java b/src/main/java/de/usd/cstchef/operations/compression/Deflate.java
similarity index 82%
rename from src/de/usd/cstchef/operations/compression/Deflate.java
rename to src/main/java/de/usd/cstchef/operations/compression/Deflate.java
index e8d3c01..a98b7a9 100644
--- a/src/de/usd/cstchef/operations/compression/Deflate.java
+++ b/src/main/java/de/usd/cstchef/operations/compression/Deflate.java
@@ -16,16 +16,16 @@ protected byte[] perform(byte[] input) throws Exception {
Deflater deflater = new Deflater();
deflater.setInput(input);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(input.length);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(input.length);
deflater.finish();
- byte[] buffer = new byte[1024];
- while( !deflater.finished() ) {
+ byte[] buffer = new byte[1024];
+ while( !deflater.finished() ) {
int count = deflater.deflate(buffer);
- outputStream.write(buffer, 0, count);
+ outputStream.write(buffer, 0, count);
}
outputStream.close();
return outputStream.toByteArray();
- }
+ }
}
diff --git a/src/de/usd/cstchef/operations/compression/GUnzip.java b/src/main/java/de/usd/cstchef/operations/compression/GUnzip.java
similarity index 71%
rename from src/de/usd/cstchef/operations/compression/GUnzip.java
rename to src/main/java/de/usd/cstchef/operations/compression/GUnzip.java
index 7cf6efa..8216951 100644
--- a/src/de/usd/cstchef/operations/compression/GUnzip.java
+++ b/src/main/java/de/usd/cstchef/operations/compression/GUnzip.java
@@ -13,20 +13,20 @@ public class GUnzip extends Operation {
@Override
protected byte[] perform(byte[] input) throws Exception {
- ByteArrayInputStream in = new ByteArrayInputStream(input);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(input);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPInputStream gis = new GZIPInputStream(in);
-
- byte[] buffer = new byte[1024];
+
+ byte[] buffer = new byte[1024];
int len;
- while((len = gis.read(buffer)) != -1){
- out.write(buffer, 0, len);
+ while((len = gis.read(buffer)) != -1){
+ out.write(buffer, 0, len);
}
- gis.close();
+ gis.close();
out.close();
in.close();
return out.toByteArray();
- }
+ }
}
diff --git a/src/de/usd/cstchef/operations/compression/Gzip.java b/src/main/java/de/usd/cstchef/operations/compression/Gzip.java
similarity index 66%
rename from src/de/usd/cstchef/operations/compression/Gzip.java
rename to src/main/java/de/usd/cstchef/operations/compression/Gzip.java
index 8c8e1ec..656ef6d 100644
--- a/src/de/usd/cstchef/operations/compression/Gzip.java
+++ b/src/main/java/de/usd/cstchef/operations/compression/Gzip.java
@@ -13,20 +13,20 @@ public class Gzip extends Operation {
@Override
protected byte[] perform(byte[] input) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- GZIPOutputStream gzos = new GZIPOutputStream(out);
- ByteArrayInputStream in = new ByteArrayInputStream(input);
-
- byte[] buffer = new byte[1024];
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ GZIPOutputStream gzos = new GZIPOutputStream(out);
+ ByteArrayInputStream in = new ByteArrayInputStream(input);
+
+ byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
- gzos.write(buffer, 0, len);
+ gzos.write(buffer, 0, len);
}
-
- in.close();
- gzos.close();
- out.close();
+
+ in.close();
+ gzos.close();
+ out.close();
return out.toByteArray();
- }
+ }
}
diff --git a/src/de/usd/cstchef/operations/compression/Inflate.java b/src/main/java/de/usd/cstchef/operations/compression/Inflate.java
similarity index 82%
rename from src/de/usd/cstchef/operations/compression/Inflate.java
rename to src/main/java/de/usd/cstchef/operations/compression/Inflate.java
index 76c083b..93668cb 100644
--- a/src/de/usd/cstchef/operations/compression/Inflate.java
+++ b/src/main/java/de/usd/cstchef/operations/compression/Inflate.java
@@ -16,15 +16,15 @@ protected byte[] perform(byte[] input) throws Exception {
Inflater inflater = new Inflater();
inflater.setInput(input);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(input.length);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(input.length);
- byte[] buffer = new byte[1024];
- while( !inflater.finished() ) {
+ byte[] buffer = new byte[1024];
+ while( !inflater.finished() ) {
int count = inflater.inflate(buffer);
- outputStream.write(buffer, 0, count);
+ outputStream.write(buffer, 0, count);
}
outputStream.close();
return outputStream.toByteArray();
- }
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/conditional/ConditionalOperation.java b/src/main/java/de/usd/cstchef/operations/conditional/ConditionalOperation.java
new file mode 100644
index 0000000..3a9acd7
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/conditional/ConditionalOperation.java
@@ -0,0 +1,52 @@
+package de.usd.cstchef.operations.conditional;
+
+import javax.swing.JTextField;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+public abstract class ConditionalOperation extends Operation {
+
+ protected VariableTextField expr;
+ private JTextField operationSkipField;
+ private JTextField laneSkipField;
+
+ public void setOperationSkip() {
+
+ try {
+ int operationSkip = Integer.valueOf(operationSkipField.getText());
+ this.setOperationSkip(operationSkip);
+ } catch( Exception e ) {
+ throw new IllegalArgumentException("Input is not a number.");
+ }
+ }
+
+ public void setLaneSkip() {
+
+ try {
+ int laneSkip = Integer.valueOf(laneSkipField.getText());
+ this.setLaneSkip(laneSkip);
+ } catch( Exception e ) {
+ throw new IllegalArgumentException("Input is not a number.");
+ }
+ }
+
+ public void resetSkips() {
+ this.setOperationSkip(0);
+ this.setLaneSkip(0);
+ }
+
+ @Override
+ public void createUI() {
+ this.expr = new VariableTextField();
+ this.addUIElement("Expr", this.expr);
+
+ this.operationSkipField = new JTextField("0");
+ this.addUIElement("Skip Operations", this.operationSkipField);
+
+ this.laneSkipField = new JTextField("0");
+ this.addUIElement("Skip Lanes", this.laneSkipField);
+
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/conditional/NumberCompare.java b/src/main/java/de/usd/cstchef/operations/conditional/NumberCompare.java
new file mode 100644
index 0000000..6358b9e
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/conditional/NumberCompare.java
@@ -0,0 +1,73 @@
+package de.usd.cstchef.operations.conditional;
+
+import javax.swing.JComboBox;
+
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "Number Compare", category = OperationCategory.CONDITIONALS, description = "Skip if evaluates to true")
+public class NumberCompare extends ConditionalOperation {
+
+ private JComboBox operationBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ Double inputNumber;
+ Double userNumber;
+
+ try {
+ String tmp = new String(input);
+ inputNumber = Double.valueOf(tmp);
+ userNumber = Double.valueOf(this.expr.getText());
+ } catch( Exception e ) {
+ throw new IllegalArgumentException("Input is not a number.");
+ }
+
+ boolean condition = false;
+ switch ((String)this.operationBox.getSelectedItem()) {
+ case "equal":
+ if( inputNumber.compareTo(userNumber) == 0 )
+ condition = true;
+ break;
+ case "not equal":
+ if( inputNumber.compareTo(userNumber) != 0 )
+ condition = true;
+ break;
+ case "greater":
+ if( inputNumber < userNumber )
+ condition = true;
+ break;
+ case "lower":
+ if( inputNumber > userNumber )
+ condition = true;
+ break;
+ case "greater equal":
+ if( inputNumber <= userNumber )
+ condition = true;
+ break;
+ case "lower equal":
+ if( inputNumber >= userNumber )
+ condition = true;
+ break;
+ }
+
+ if( condition ) {
+ this.setOperationSkip();
+ this.setLaneSkip();
+ } else {
+ this.resetSkips();
+ }
+
+ return input;
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+ this.operationBox = new JComboBox<>(new String[] {"equal", "not equal", "lower", "greater", "lower equal", "greater equal"});
+ this.operationBox.setSelectedItem("equal");
+ this.addUIElement("Lineseperator", this.operationBox);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/conditional/RegexMatch.java b/src/main/java/de/usd/cstchef/operations/conditional/RegexMatch.java
new file mode 100644
index 0000000..fb9b9a8
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/conditional/RegexMatch.java
@@ -0,0 +1,51 @@
+package de.usd.cstchef.operations.conditional;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.JCheckBox;
+
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "Regex Match", category = OperationCategory.CONDITIONALS, description = "Skip if regex matches")
+public class RegexMatch extends ConditionalOperation {
+
+ private JCheckBox invert;
+ private JCheckBox find;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ Pattern p = Pattern.compile(this.expr.getText());
+ Matcher m = p.matcher(new String(input));
+
+ boolean condition = false;
+ if( find.isSelected() ) {
+ condition = m.find();
+ } else {
+ condition = m.matches();
+ }
+
+ if( condition ^ invert.isSelected() ) {
+ this.setOperationSkip();
+ this.setLaneSkip();
+ } else {
+ this.resetSkips();
+ }
+
+ return input;
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+
+ this.invert = new JCheckBox();
+ this.addUIElement("Invert Match", this.invert);
+
+ this.find = new JCheckBox();
+ this.addUIElement("Find anywhere", this.find);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/conditional/StringContains.java b/src/main/java/de/usd/cstchef/operations/conditional/StringContains.java
new file mode 100644
index 0000000..ec118d4
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/conditional/StringContains.java
@@ -0,0 +1,45 @@
+package de.usd.cstchef.operations.conditional;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "String Contains", category = OperationCategory.CONDITIONALS, description = "Skip if input contains")
+public class StringContains extends ConditionalOperation {
+
+ private JCheckBox invert;
+ private JCheckBox caseSensitive;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = cbs.getHelpers();
+ int start = helpers.indexOf(input, this.expr.getBytes(), caseSensitive.isSelected(), 0, input.length);
+
+ if( (start >= 0) ^ invert.isSelected() ) {
+ this.setOperationSkip();
+ this.setLaneSkip();
+ } else {
+ this.resetSkips();
+ }
+
+ return input;
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+
+ this.invert = new JCheckBox();
+ this.addUIElement("Invert Match", this.invert);
+
+ this.caseSensitive = new JCheckBox();
+ this.addUIElement("Case Sensitive", this.caseSensitive);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/conditional/StringMatch.java b/src/main/java/de/usd/cstchef/operations/conditional/StringMatch.java
new file mode 100644
index 0000000..cd749a5
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/conditional/StringMatch.java
@@ -0,0 +1,56 @@
+package de.usd.cstchef.operations.conditional;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "String Match", category = OperationCategory.CONDITIONALS, description = "Skip if input matches")
+public class StringMatch extends ConditionalOperation {
+
+ private JCheckBox invert;
+ private JCheckBox caseSensitive;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] search = this.expr.getBytes();
+ if( search.length != input.length ) {
+ if( invert.isSelected() ) {
+ this.setOperationSkip();
+ this.setLaneSkip();
+ } else {
+ this.resetSkips();
+ }
+ return input;
+ }
+
+ IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = cbs.getHelpers();
+ int start = helpers.indexOf(input, search, caseSensitive.isSelected(), 0, input.length);
+
+ if( (start >= 0) ^ invert.isSelected() ) {
+ this.setOperationSkip();
+ this.setLaneSkip();
+ } else {
+ this.resetSkips();
+ }
+
+ return input;
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+
+ this.invert = new JCheckBox();
+ this.addUIElement("Invert Match", this.invert);
+
+ this.caseSensitive = new JCheckBox();
+ this.addUIElement("Case Sensitive", this.caseSensitive);
+ }
+
+}
diff --git a/src/de/usd/cstchef/operations/dataformat/FromBase64.java b/src/main/java/de/usd/cstchef/operations/dataformat/FromBase64.java
similarity index 77%
rename from src/de/usd/cstchef/operations/dataformat/FromBase64.java
rename to src/main/java/de/usd/cstchef/operations/dataformat/FromBase64.java
index 39fb351..7caa4b0 100644
--- a/src/de/usd/cstchef/operations/dataformat/FromBase64.java
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/FromBase64.java
@@ -9,8 +9,8 @@
@OperationInfos(name = "From Base64", category = OperationCategory.DATAFORMAT, description = "Decode a base64 string.")
public class FromBase64 extends Operation {
- @Override
- protected byte[] perform(byte[] input) {
- return Base64.getDecoder().decode(input);
- }
+ @Override
+ protected byte[] perform(byte[] input) {
+ return Base64.getDecoder().decode(input);
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/dataformat/FromHex.java b/src/main/java/de/usd/cstchef/operations/dataformat/FromHex.java
new file mode 100644
index 0000000..7122eb9
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/FromHex.java
@@ -0,0 +1,43 @@
+package de.usd.cstchef.operations.dataformat;
+
+import java.util.Set;
+
+import javax.swing.JComboBox;
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.dataformat.ToHex.Delimiter;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+
+@OperationInfos(name = "From Hex", category = OperationCategory.DATAFORMAT, description = "From hex")
+public class FromHex extends Operation {
+
+ private JComboBox delimiterBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ String selectedKey = (String) this.delimiterBox.getSelectedItem();
+ Delimiter delimiter = ToHex.delimiters.get(selectedKey);
+
+ if (delimiter.value.length == 0) { // No delimiter
+ return Hex.decode(input);
+ }
+
+ String delimiterStr = new String(delimiter.value);
+ String inputStr = new String(input);
+ inputStr = inputStr.replace(delimiterStr, "");
+
+ return Hex.decode(inputStr);
+ }
+
+ @Override
+ public void createUI() {
+ Set choices = ToHex.delimiters.keySet();
+ delimiterBox = new JComboBox(choices.toArray(new String[choices.size()]));
+ delimiterBox.setSelectedIndex(0);
+
+ this.addUIElement("Delimiter", delimiterBox);
+ }
+
+}
diff --git a/src/de/usd/cstchef/operations/dataformat/HtmlDecode.java b/src/main/java/de/usd/cstchef/operations/dataformat/HtmlDecode.java
similarity index 63%
rename from src/de/usd/cstchef/operations/dataformat/HtmlDecode.java
rename to src/main/java/de/usd/cstchef/operations/dataformat/HtmlDecode.java
index 918d0d1..6d6c445 100644
--- a/src/de/usd/cstchef/operations/dataformat/HtmlDecode.java
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/HtmlDecode.java
@@ -11,12 +11,12 @@
@OperationInfos(name = "HTML Decode", category = OperationCategory.DATAFORMAT, description = "HTML Decode")
public class HtmlDecode extends Operation {
- @Override
- protected byte[] perform(byte[] input) throws Exception {
-
- String tmp = new String(input, StandardCharsets.ISO_8859_1);
- tmp = StringEscapeUtils.unescapeHtml4(tmp);
- return tmp.getBytes(StandardCharsets.ISO_8859_1);
- }
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String tmp = new String(input, StandardCharsets.ISO_8859_1);
+ tmp = StringEscapeUtils.unescapeHtml4(tmp);
+ return tmp.getBytes(StandardCharsets.ISO_8859_1);
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/dataformat/HtmlEncode.java b/src/main/java/de/usd/cstchef/operations/dataformat/HtmlEncode.java
new file mode 100644
index 0000000..b73e076
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/HtmlEncode.java
@@ -0,0 +1,54 @@
+package de.usd.cstchef.operations.dataformat;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.swing.JCheckBox;
+
+import org.apache.commons.text.StringEscapeUtils;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTML Encode", category = OperationCategory.DATAFORMAT, description = "HTML Encode")
+public class HtmlEncode extends Operation {
+
+ private JCheckBox checkbox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] result = null;
+ if( checkbox.isSelected() ) {
+
+ byte[] delimiter = "".getBytes();
+ byte[] closer = ";".getBytes();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(delimiter);
+ for (int i = 0; i < input.length - 1; i++) {
+ out.write(String.valueOf(Byte.toUnsignedInt(input[i])).getBytes());
+ out.write(closer);
+ out.write(delimiter);
+ }
+
+ out.write(String.valueOf(Byte.toUnsignedInt(input[input.length - 1])).getBytes());
+ out.write(closer);
+ result = out.toByteArray();
+
+ } else {
+ String tmp = new String(input);
+ tmp = StringEscapeUtils.escapeHtml4(tmp);
+ result = tmp.getBytes();
+ }
+
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.checkbox = new JCheckBox("Encode all");
+ this.checkbox.setSelected(false);
+ this.addUIElement(null, this.checkbox, "checkbox1");
+ }
+}
diff --git a/src/de/usd/cstchef/operations/dataformat/ToBase64.java b/src/main/java/de/usd/cstchef/operations/dataformat/ToBase64.java
similarity index 77%
rename from src/de/usd/cstchef/operations/dataformat/ToBase64.java
rename to src/main/java/de/usd/cstchef/operations/dataformat/ToBase64.java
index 4070650..2606483 100644
--- a/src/de/usd/cstchef/operations/dataformat/ToBase64.java
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/ToBase64.java
@@ -9,9 +9,9 @@
@OperationInfos(name = "To Base64", category = OperationCategory.DATAFORMAT, description = "Encodes a string to base64.")
public class ToBase64 extends Operation {
- @Override
- protected byte[] perform(byte[] input) {
- return Base64.getEncoder().encode(input);
- }
-
+ @Override
+ protected byte[] perform(byte[] input) {
+ return Base64.getEncoder().encode(input);
+ }
+
}
diff --git a/src/main/java/de/usd/cstchef/operations/dataformat/ToHex.java b/src/main/java/de/usd/cstchef/operations/dataformat/ToHex.java
new file mode 100644
index 0000000..3885cb4
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/ToHex.java
@@ -0,0 +1,92 @@
+package de.usd.cstchef.operations.dataformat;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Set;
+
+import javax.swing.JComboBox;
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+
+@OperationInfos(name = "To Hex", category = OperationCategory.DATAFORMAT, description = "To hex")
+public class ToHex extends Operation {
+
+ static HashMap delimiters = new HashMap() {
+ {
+ put("None", new Delimiter(""));
+ put("Space", new Delimiter(" "));
+ put("Comma", new Delimiter(","));
+ put("Colon", new Delimiter(":"));
+ put("Semi-colon", new Delimiter(";"));
+ put("Colon", new Delimiter(":"));
+ put("Line feed", new Delimiter("\n"));
+ put("CRLF", new Delimiter("\r\n"));
+ put("0x", new Delimiter("0x", true));
+ put("\\x", new Delimiter("\\x", true));
+ }
+ };
+
+ private JComboBox delimiterBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ String selectedKey = (String) this.delimiterBox.getSelectedItem();
+ Delimiter delimiter = ToHex.delimiters.get(selectedKey);
+
+ if (delimiter.value.length == 0) { // No delimiter
+ return Hex.encode(input);
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ if (input.length > 0 && delimiter.writeAtStart) {
+ out.write(delimiter.value);
+ }
+
+ for (int i = 0; i < input.length - 1; i++) {
+ out.write(Hex.encode(new byte[] { input[i] }));
+ out.write(delimiter.value);
+ }
+
+ if (input.length > 0) {
+ out.write(Hex.encode(new byte[] { input[input.length - 1] })); // wow
+ if (delimiter.writeAtEnd) {
+ out.write(delimiter.value);
+ }
+ }
+
+ return out.toByteArray();
+ }
+
+ @Override
+ public void createUI() {
+ Set choices = ToHex.delimiters.keySet();
+ delimiterBox = new JComboBox(choices.toArray(new String[choices.size()]));
+ delimiterBox.setSelectedIndex(0);
+
+ this.addUIElement("Delimiter", delimiterBox);
+ }
+
+ public static class Delimiter {
+ public byte[] value;
+ public boolean writeAtStart;
+ public boolean writeAtEnd;
+
+ public Delimiter(String value) {
+ this(value, false, false);
+ }
+
+ public Delimiter(String value, boolean writeAtStart) {
+ this(value, writeAtStart, false);
+ }
+
+ public Delimiter(String value, boolean writeAtStart, boolean writeAtEnd) {
+ this.value = value.getBytes();
+ this.writeAtStart = writeAtStart;
+ this.writeAtEnd = writeAtEnd;
+ }
+ }
+}
diff --git a/src/de/usd/cstchef/operations/dataformat/UrlDecode.java b/src/main/java/de/usd/cstchef/operations/dataformat/UrlDecode.java
similarity index 60%
rename from src/de/usd/cstchef/operations/dataformat/UrlDecode.java
rename to src/main/java/de/usd/cstchef/operations/dataformat/UrlDecode.java
index 0a04ff1..dd9dd46 100644
--- a/src/de/usd/cstchef/operations/dataformat/UrlDecode.java
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/UrlDecode.java
@@ -10,13 +10,13 @@
@OperationInfos(name = "Url Decode", category = OperationCategory.DATAFORMAT, description = "Url decoding")
public class UrlDecode extends Operation {
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
- IExtensionHelpers helpers = cbs.getHelpers();
-
- byte[] result = helpers.urlDecode(input);
- return result;
- }
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = cbs.getHelpers();
+
+ byte[] result = helpers.urlDecode(input);
+ return result;
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/dataformat/UrlEncode.java b/src/main/java/de/usd/cstchef/operations/dataformat/UrlEncode.java
new file mode 100644
index 0000000..e481530
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/dataformat/UrlEncode.java
@@ -0,0 +1,54 @@
+package de.usd.cstchef.operations.dataformat;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.swing.JCheckBox;
+
+import org.bouncycastle.util.encoders.Hex;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+
+@OperationInfos(name = "Url Encode", category = OperationCategory.DATAFORMAT, description = "Url encode")
+public class UrlEncode extends Operation {
+
+ private JCheckBox checkbox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = cbs.getHelpers();
+
+ byte[] result = null;
+ if( checkbox.isSelected() ) {
+
+ byte[] delimiter = "%".getBytes();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(delimiter);
+
+ for (int i = 0; i < input.length - 1; i++) {
+ out.write(Hex.encode(new byte[] { input[i] }));
+ out.write(delimiter);
+ }
+
+ out.write(Hex.encode(new byte[] { input[input.length - 1] }));
+ result = out.toByteArray();
+
+ } else {
+ result = helpers.urlEncode(input);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.checkbox = new JCheckBox("Encode all");
+ this.checkbox.setSelected(false);
+ this.addUIElement(null, this.checkbox, "checkbox1");
+ }
+}
diff --git a/src/de/usd/cstchef/operations/datetime/DateTime.java b/src/main/java/de/usd/cstchef/operations/datetime/DateTime.java
similarity index 54%
rename from src/de/usd/cstchef/operations/datetime/DateTime.java
rename to src/main/java/de/usd/cstchef/operations/datetime/DateTime.java
index 85d7577..24a6b8e 100644
--- a/src/de/usd/cstchef/operations/datetime/DateTime.java
+++ b/src/main/java/de/usd/cstchef/operations/datetime/DateTime.java
@@ -11,18 +11,18 @@
@OperationInfos(name = "Date Time", category = OperationCategory.DATES, description = "Returnes the current date time formatted with the provided date time pattern.")
public class DateTime extends Operation {
- private VariableTextField patternTxt;
+ private VariableTextField patternTxt;
- @Override
- protected byte[] perform(byte[] input) throws Exception {
- String pattern = this.patternTxt.getText().trim();
- SimpleDateFormat format = new SimpleDateFormat(pattern);
- return format.format(new Date()).getBytes();
- }
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ String pattern = this.patternTxt.getText().trim();
+ SimpleDateFormat format = new SimpleDateFormat(pattern);
+ return format.format(new Date()).getBytes();
+ }
- public void createUI() {
- this.patternTxt = new VariableTextField();
- this.addUIElement("Pattern", this.patternTxt);
- }
+ public void createUI() {
+ this.patternTxt = new VariableTextField();
+ this.addUIElement("Pattern", this.patternTxt);
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/datetime/UnixTimestamp.java b/src/main/java/de/usd/cstchef/operations/datetime/UnixTimestamp.java
new file mode 100644
index 0000000..f8004fd
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/datetime/UnixTimestamp.java
@@ -0,0 +1,31 @@
+package de.usd.cstchef.operations.datetime;
+
+import javax.swing.JCheckBox;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "Unix Timestamp", category = OperationCategory.DATES, description = "Returnes the current unix timestamp.")
+public class UnixTimestamp extends Operation {
+
+ private JCheckBox milliBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ long timestamp = 0;
+ if (milliBox.isSelected()) {
+ timestamp = System.currentTimeMillis();
+ }
+ else {
+ timestamp = System.currentTimeMillis() / 1000L;
+ }
+ return String.valueOf(timestamp).getBytes();
+ }
+
+ public void createUI() {
+ this.milliBox = new JCheckBox();
+ this.addUIElement("Milliseconds", this.milliBox);
+ }
+
+}
diff --git a/src/de/usd/cstchef/operations/encryption/AesDecryption.java b/src/main/java/de/usd/cstchef/operations/encryption/AesDecryption.java
similarity index 86%
rename from src/de/usd/cstchef/operations/encryption/AesDecryption.java
rename to src/main/java/de/usd/cstchef/operations/encryption/AesDecryption.java
index 0e5abc6..d6267a3 100644
--- a/src/de/usd/cstchef/operations/encryption/AesDecryption.java
+++ b/src/main/java/de/usd/cstchef/operations/encryption/AesDecryption.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "AES Decryption", category = OperationCategory.ENCRYPTION, description = "Decrypts via the aes algorithm.")
public class AesDecryption extends DecryptionOperation {
- public AesDecryption() {
- super("AES");
- }
+ public AesDecryption() {
+ super("AES");
+ }
}
diff --git a/src/de/usd/cstchef/operations/encryption/AesEncryption.java b/src/main/java/de/usd/cstchef/operations/encryption/AesEncryption.java
similarity index 86%
rename from src/de/usd/cstchef/operations/encryption/AesEncryption.java
rename to src/main/java/de/usd/cstchef/operations/encryption/AesEncryption.java
index 8d3a02f..c9ea238 100644
--- a/src/de/usd/cstchef/operations/encryption/AesEncryption.java
+++ b/src/main/java/de/usd/cstchef/operations/encryption/AesEncryption.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "AES Encryption", category = OperationCategory.ENCRYPTION, description = "Encrypts via the aes algorithm.")
public class AesEncryption extends EncryptionOperation {
- public AesEncryption() {
- super("AES");
- }
+ public AesEncryption() {
+ super("AES");
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java b/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java
new file mode 100644
index 0000000..5a38482
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java
@@ -0,0 +1,106 @@
+package de.usd.cstchef.operations.encryption;
+
+import java.security.Provider;
+import java.security.Security;
+import java.util.HashMap;
+
+public class CipherUtils {
+
+ private static CipherUtils instance;
+
+ private HashMap algos;
+
+ private CipherUtils() {
+ algos = new HashMap<>();
+
+ getCipherInfos();
+ }
+
+ private void getCipherInfos() {
+ for (Provider provider : Security.getProviders()) {
+ for (String key : provider.stringPropertyNames()) {
+ if (key.startsWith("Cipher")) {
+ String[] parts = key.split(" ");
+ if (parts.length < 2) {
+ continue;
+ }
+ String cipherName = parts[0].substring(7);
+ String type = parts[1];
+
+ CipherInfo info = algos.getOrDefault(cipherName, new CipherInfo());
+ String property = provider.getProperty(key);
+
+ if (type.equals("SupportedModes")) {
+ String[] modes = property.split("\\|");
+ info.setModes(modes);
+ } else if (type.equals("SupportedPaddings")) {
+ String[] paddings = property.split("\\|");
+ info.setPaddings(paddings);
+ }
+ this.algos.put(cipherName, info);
+ }
+ }
+ }
+ }
+
+ public static CipherUtils getInstance() {
+ if (instance == null) {
+ instance = new CipherUtils();
+ }
+ return instance;
+ }
+
+ public CipherInfo getCipherInfo(String algorithm) {
+ return this.algos.getOrDefault(algorithm, new CipherInfo());
+ }
+
+ public class CipherInfo {
+
+ private String[] modes;
+ private String[] paddings;
+
+
+ public CipherInfo() {
+ this.modes = new String[0];
+ this.paddings = new String[0];
+ }
+
+ public CipherInfo(String[] modes, String[] paddings) {
+ this.modes = modes;
+ this.paddings = paddings;
+ }
+
+ public String[] getModes() {
+ return modes;
+ }
+
+ public void setModes(String[] modes) {
+ this.modes = modes;
+ }
+
+ public String[] getPaddings() {
+ return paddings;
+ }
+
+ public void setPaddings(String[] paddings) {
+ this.paddings = paddings;
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("Modes: ");
+ for (String mode : this.modes) {
+ buf.append(mode);
+ buf.append("|");
+ }
+ buf.append(", Paddings: ");
+ for (String padding : this.paddings) {
+ buf.append(padding);
+ buf.append("|");
+ }
+
+ return buf.toString();
+ }
+
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java b/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java
new file mode 100644
index 0000000..552989f
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java
@@ -0,0 +1,89 @@
+package de.usd.cstchef.operations.encryption;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.swing.JComboBox;
+
+import org.bouncycastle.util.encoders.Hex;
+import org.bouncycastle.util.encoders.Base64;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.encryption.CipherUtils.CipherInfo;
+import de.usd.cstchef.view.ui.FormatTextField;
+
+public abstract class CryptOperation extends Operation {
+
+ private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
+
+ protected String algorithm;
+ protected FormatTextField ivTxt;
+ protected FormatTextField keyTxt;
+
+ protected JComboBox cipherMode;
+ protected JComboBox inputMode;
+ protected JComboBox outputMode;
+ protected JComboBox paddings;
+
+ public CryptOperation(String alogrithm) {
+ super();
+ this.algorithm = alogrithm;
+ this.createMyUI();
+ }
+
+ protected byte[] crypt(byte[] input, int cipherMode, String algorithm, String mode, String padding)
+ throws Exception {
+ byte[] key = keyTxt.getText();
+ byte[] iv = ivTxt.getText();
+
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key, algorithm);
+ IvParameterSpec ivSpec = new IvParameterSpec(iv);
+ Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, mode, padding));
+
+ if( mode.equals("ECB") ) {
+ cipher.init(cipherMode, secretKeySpec);
+ } else {
+ cipher.init(cipherMode, secretKeySpec, ivSpec);
+ }
+
+ String selectedInputMode = (String)inputMode.getSelectedItem();
+ String selectedOutputMode = (String)outputMode.getSelectedItem();
+
+ if( selectedInputMode.equals("Hex") )
+ input = Hex.decode(input);
+ if( selectedInputMode.equals("Base64") )
+ input = Base64.decode(input);
+
+ byte[] encrypted = cipher.doFinal(input);
+
+ if( selectedOutputMode.equals("Hex") )
+ encrypted = Hex.encode(encrypted);
+ if( selectedOutputMode.equals("Base64") )
+ encrypted = Base64.encode(encrypted);
+
+ return encrypted;
+ }
+
+ public void createMyUI() {
+ this.ivTxt = new FormatTextField();
+ this.addUIElement("IV", this.ivTxt);
+
+ this.keyTxt = new FormatTextField();
+ this.addUIElement("Key", this.keyTxt);
+ CipherUtils utils = CipherUtils.getInstance();
+
+ CipherInfo info = utils.getCipherInfo(this.algorithm);
+ this.cipherMode = new JComboBox<>(info.getModes());
+ this.addUIElement("Mode", this.cipherMode);
+
+ this.paddings = new JComboBox<>(info.getPaddings());
+ this.addUIElement("Padding", this.paddings);
+
+ this.inputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Input", this.inputMode);
+
+ this.outputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Output", this.outputMode);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/encryption/DecryptionOperation.java b/src/main/java/de/usd/cstchef/operations/encryption/DecryptionOperation.java
new file mode 100644
index 0000000..a232ad7
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/encryption/DecryptionOperation.java
@@ -0,0 +1,17 @@
+package de.usd.cstchef.operations.encryption;
+
+import javax.crypto.Cipher;
+
+public abstract class DecryptionOperation extends CryptOperation {
+
+ public DecryptionOperation(String alogrithm) {
+ super(alogrithm);
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ return this.crypt(input, Cipher.DECRYPT_MODE, this.algorithm, (String) this.cipherMode.getSelectedItem(),
+ (String) this.paddings.getSelectedItem());
+ }
+
+}
diff --git a/src/de/usd/cstchef/operations/encryption/DesDecryption.java b/src/main/java/de/usd/cstchef/operations/encryption/DesDecryption.java
similarity index 86%
rename from src/de/usd/cstchef/operations/encryption/DesDecryption.java
rename to src/main/java/de/usd/cstchef/operations/encryption/DesDecryption.java
index 6a4253e..9b35a1e 100644
--- a/src/de/usd/cstchef/operations/encryption/DesDecryption.java
+++ b/src/main/java/de/usd/cstchef/operations/encryption/DesDecryption.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "DES Decryption", category = OperationCategory.ENCRYPTION, description = "Decrypts via the des algorithm.")
public class DesDecryption extends DecryptionOperation {
- public DesDecryption() {
- super("DES");
- }
+ public DesDecryption() {
+ super("DES");
+ }
}
diff --git a/src/de/usd/cstchef/operations/encryption/DesEncryption.java b/src/main/java/de/usd/cstchef/operations/encryption/DesEncryption.java
similarity index 86%
rename from src/de/usd/cstchef/operations/encryption/DesEncryption.java
rename to src/main/java/de/usd/cstchef/operations/encryption/DesEncryption.java
index 032298e..9e8bcf8 100644
--- a/src/de/usd/cstchef/operations/encryption/DesEncryption.java
+++ b/src/main/java/de/usd/cstchef/operations/encryption/DesEncryption.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "DES Encryption", category = OperationCategory.ENCRYPTION, description = "Encrypts via the des algorithm.")
public class DesEncryption extends EncryptionOperation {
- public DesEncryption() {
- super("DES");
- }
+ public DesEncryption() {
+ super("DES");
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/encryption/EncryptionOperation.java b/src/main/java/de/usd/cstchef/operations/encryption/EncryptionOperation.java
new file mode 100644
index 0000000..0026cc8
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/encryption/EncryptionOperation.java
@@ -0,0 +1,17 @@
+package de.usd.cstchef.operations.encryption;
+
+import javax.crypto.Cipher;
+
+public abstract class EncryptionOperation extends CryptOperation {
+
+ public EncryptionOperation(String alogrithm) {
+ super(alogrithm);
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ return this.crypt(input, Cipher.ENCRYPT_MODE, this.algorithm, (String) this.cipherMode.getSelectedItem(),
+ (String) this.paddings.getSelectedItem());
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/encryption/RsaDecryption.java b/src/main/java/de/usd/cstchef/operations/encryption/RsaDecryption.java
new file mode 100644
index 0000000..16b363e
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/encryption/RsaDecryption.java
@@ -0,0 +1,75 @@
+package de.usd.cstchef.operations.encryption;
+
+import javax.crypto.Cipher;
+import javax.swing.JComboBox;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.encryption.CipherUtils.CipherInfo;
+import de.usd.cstchef.operations.signature.KeystoreOperation;
+
+@OperationInfos(name = "RSA Decryption", category = OperationCategory.ENCRYPTION, description = "Decrypt input using a private key")
+public class RsaDecryption extends KeystoreOperation {
+
+ private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
+
+ protected String algorithm = "RSA";
+ protected String cipherMode = "ECB";
+
+ protected JComboBox inputMode;
+ protected JComboBox outputMode;
+ protected JComboBox paddings;
+
+ public RsaDecryption() {
+ super();
+ this.createMyUI();
+ }
+
+ protected byte[] perform(byte[] input) throws Exception {
+
+ if( ! this.keyAvailable.isSelected() )
+ throw new IllegalArgumentException("No private key available.");
+
+ String padding = (String)paddings.getSelectedItem();
+ Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, cipherMode, padding));
+ cipher.init(Cipher.DECRYPT_MODE, this.selectedEntry.getPrivateKey());
+
+ String selectedInputMode = (String)inputMode.getSelectedItem();
+ String selectedOutputMode = (String)outputMode.getSelectedItem();
+
+ if( selectedInputMode.equals("Hex") )
+ input = Hex.decode(input);
+ if( selectedInputMode.equals("Base64") )
+ input = Base64.decode(input);
+
+ byte[] encrypted = cipher.doFinal(input);
+
+ if( selectedOutputMode.equals("Hex") )
+ encrypted = Hex.encode(encrypted);
+ if( selectedOutputMode.equals("Base64") )
+ encrypted = Base64.encode(encrypted);
+
+ return encrypted;
+ }
+
+ public void createMyUI() {
+
+ super.createMyUI();
+
+ CipherUtils utils = CipherUtils.getInstance();
+ CipherInfo info = utils.getCipherInfo(this.algorithm);
+
+ this.paddings = new JComboBox<>(info.getPaddings());
+ this.addUIElement("Padding", this.paddings);
+
+ this.inputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Input", this.inputMode);
+
+ this.outputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Output", this.outputMode);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/encryption/RsaEncryption.java b/src/main/java/de/usd/cstchef/operations/encryption/RsaEncryption.java
new file mode 100644
index 0000000..49db61a
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/encryption/RsaEncryption.java
@@ -0,0 +1,75 @@
+package de.usd.cstchef.operations.encryption;
+
+import javax.crypto.Cipher;
+import javax.swing.JComboBox;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.encryption.CipherUtils.CipherInfo;
+import de.usd.cstchef.operations.signature.KeystoreOperation;
+
+@OperationInfos(name = "RSA Encryption", category = OperationCategory.ENCRYPTION, description = "Encrypt input using a certificate")
+public class RsaEncryption extends KeystoreOperation {
+
+ private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
+
+ protected String algorithm = "RSA";
+ protected String cipherMode = "ECB";
+
+ protected JComboBox inputMode;
+ protected JComboBox outputMode;
+ protected JComboBox paddings;
+
+ public RsaEncryption() {
+ super();
+ this.createMyUI();
+ }
+
+ protected byte[] perform(byte[] input) throws Exception {
+
+ if( ! this.certAvailable.isSelected() )
+ throw new IllegalArgumentException("No certificate available.");
+
+ String padding = (String)paddings.getSelectedItem();
+ Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, cipherMode, padding));
+ cipher.init(Cipher.ENCRYPT_MODE, this.cert.getPublicKey());
+
+ String selectedInputMode = (String)inputMode.getSelectedItem();
+ String selectedOutputMode = (String)outputMode.getSelectedItem();
+
+ if( selectedInputMode.equals("Hex") )
+ input = Hex.decode(input);
+ if( selectedInputMode.equals("Base64") )
+ input = Base64.decode(input);
+
+ byte[] encrypted = cipher.doFinal(input);
+
+ if( selectedOutputMode.equals("Hex") )
+ encrypted = Hex.encode(encrypted);
+ if( selectedOutputMode.equals("Base64") )
+ encrypted = Base64.encode(encrypted);
+
+ return encrypted;
+ }
+
+ public void createMyUI() {
+
+ super.createMyUI();
+
+ CipherUtils utils = CipherUtils.getInstance();
+ CipherInfo info = utils.getCipherInfo(this.algorithm);
+
+ this.paddings = new JComboBox<>(info.getPaddings());
+ this.addUIElement("Padding", this.paddings);
+
+ this.inputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Input", this.inputMode);
+
+ this.outputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Output", this.outputMode);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpBodyExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpBodyExtractor.java
new file mode 100644
index 0000000..ac682e6
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpBodyExtractor.java
@@ -0,0 +1,28 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IRequestInfo;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+
+@OperationInfos(name = "HTTP Body", category = OperationCategory.EXTRACTORS, description = "Extracts the body of a HTTP request.")
+public class HttpBodyExtractor extends Operation {
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ try {
+ IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
+ IRequestInfo requestInfo = cbs.getHelpers().analyzeRequest(input);
+ int bodyOffset = requestInfo.getBodyOffset();
+
+ byte[] body = Arrays.copyOfRange(input, bodyOffset, input.length);
+ return body;
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Provided input is not a valid http request.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java
new file mode 100644
index 0000000..ae1d10f
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java
@@ -0,0 +1,63 @@
+package de.usd.cstchef.operations.extractors;
+
+import org.bouncycastle.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IResponseInfo;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HTTP Cookie", category = OperationCategory.EXTRACTORS, description = "Extracts a cookie from a HTTP request.")
+public class HttpCookieExtractor extends Operation {
+
+ private VariableTextField cookieNameField;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] cookieName = cookieNameField.getBytes();
+ if( cookieName.length == 0 )
+ return input;
+
+ byte[] cookieSearch = new byte[cookieName.length + 1];
+ System.arraycopy(cookieName, 0, cookieSearch, 0, cookieName.length);
+ System.arraycopy("=".getBytes(), 0, cookieSearch, cookieName.length, 1);
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ IResponseInfo resp = helpers.analyzeResponse(input);
+ boolean isRequest = (resp.getStatusCode() == 0);
+
+ String cookieHeader = "\r\nSet-Cookie: ";
+ if(isRequest)
+ cookieHeader = "\r\nCookie: ";
+
+ try {
+
+ int offset = helpers.indexOf(input, cookieHeader.getBytes(), false, 0, length);
+ int line_end = helpers.indexOf(input, "\r\n".getBytes(), false, offset + 2, length);
+ int start = helpers.indexOf(input, cookieSearch, true, offset, line_end);
+ int end = helpers.indexOf(input, ";".getBytes(), true, start, line_end);
+
+ if( end < 0 )
+ end = line_end;
+
+ return Arrays.copyOfRange(input, start + cookieName.length + 1, end);
+
+ } catch( IllegalArgumentException e ) {
+ throw new IllegalArgumentException("Cookie not found.");
+ }
+ }
+
+ @Override
+ public void createUI() {
+ this.cookieNameField = new VariableTextField();
+ this.addUIElement("Name", this.cookieNameField);
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpGetExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpGetExtractor.java
new file mode 100644
index 0000000..21e06a7
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpGetExtractor.java
@@ -0,0 +1,49 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HTTP GET Param", category = OperationCategory.EXTRACTORS, description = "Extracts a GET Parameter of a HTTP request.")
+public class HttpGetExtractor extends Operation {
+
+ protected VariableTextField parameter;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String parameterName = parameter.getText();
+ if( parameterName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ IParameter param = helpers.getRequestParameter(input, parameterName);
+ if( param == null)
+ throw new IllegalArgumentException("Parameter name not found.");
+ if( param.getType() != IParameter.PARAM_URL )
+ throw new IllegalArgumentException("Parameter type is not GET.");
+
+ int start = param.getValueStart();
+ int end = param.getValueEnd();
+
+ byte[] result = Arrays.copyOfRange(input, start, end);
+ return result;
+
+ }
+
+ @Override
+ public void createUI() {
+ this.parameter = new VariableTextField();
+ this.addUIElement("Parameter", this.parameter);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpHeaderExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpHeaderExtractor.java
new file mode 100644
index 0000000..91870cb
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpHeaderExtractor.java
@@ -0,0 +1,56 @@
+package de.usd.cstchef.operations.extractors;
+
+import org.bouncycastle.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HTTP Header", category = OperationCategory.EXTRACTORS, description = "Extracts a header of a HTTP request.")
+public class HttpHeaderExtractor extends Operation {
+
+ private VariableTextField headerNameField;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] headerName = headerNameField.getBytes();
+ if( headerName.length == 0 )
+ return input;
+
+ byte[] headerSearch = new byte[headerName.length + 4];
+ System.arraycopy("\r\n".getBytes(), 0, headerSearch, 0, 2);
+ System.arraycopy(headerName, 0, headerSearch, 2, headerName.length);
+ System.arraycopy(": ".getBytes(), 0, headerSearch, headerName.length + 2, 2);
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ int offset = helpers.indexOf(input, headerSearch, true, 0, length);
+
+ if( offset < 0 )
+ throw new IllegalArgumentException("Header not found.");
+
+ int valueStart = helpers.indexOf(input, " ".getBytes(), false, offset, length);
+ if( valueStart < 0 )
+ throw new IllegalArgumentException("Invalid Header format.");
+ int valueEnd = helpers.indexOf(input, "\r\n".getBytes(), false, valueStart, length);
+ if( valueEnd < 0 )
+ throw new IllegalArgumentException("Invalid Header format.");
+
+ byte[] result = Arrays.copyOfRange(input, valueStart + 1, valueEnd);
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.headerNameField = new VariableTextField();
+ this.addUIElement("Name", this.headerNameField);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpJsonExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpJsonExtractor.java
new file mode 100644
index 0000000..3f639e2
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpJsonExtractor.java
@@ -0,0 +1,48 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.Arrays;
+
+import javax.swing.JTextField;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP JSON", category = OperationCategory.EXTRACTORS, description = "Get a JSON value from HTTP message.")
+public class HttpJsonExtractor extends Operation {
+
+ private JTextField fieldTxt;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String keyName = fieldTxt.getText();
+ if( keyName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ IParameter param = helpers.getRequestParameter(input, keyName);
+ if( param == null)
+ throw new IllegalArgumentException("Key not found.");
+ if( param.getType() != IParameter.PARAM_JSON )
+ throw new IllegalArgumentException("Parameter type is not JSON");
+
+ int start = param.getValueStart();
+ int end = param.getValueEnd();
+
+ byte[] result = Arrays.copyOfRange(input, start, end);
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.fieldTxt = new JTextField();
+ this.addUIElement("Field", this.fieldTxt);
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpMethodExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpMethodExtractor.java
new file mode 100644
index 0000000..3789a05
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpMethodExtractor.java
@@ -0,0 +1,31 @@
+package de.usd.cstchef.operations.extractors;
+
+import org.bouncycastle.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP Method", category = OperationCategory.EXTRACTORS, description = "Extracts the method of a HTTP request.")
+public class HttpMethodExtractor extends Operation {
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ try {
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ int methodEnd = helpers.indexOf(input, " ".getBytes(), false, 0, length);
+ byte[] result = Arrays.copyOfRange(input, 0, methodEnd);
+
+ return result;
+
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Provided input is not a valid http request.");
+ }
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpPostExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpPostExtractor.java
new file mode 100644
index 0000000..a253ea0
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpPostExtractor.java
@@ -0,0 +1,47 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HTTP POST Param", category = OperationCategory.EXTRACTORS, description = "Extracts a POST parameter of a HTTP request.")
+public class HttpPostExtractor extends Operation {
+
+ protected VariableTextField parameter;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String parameterName = parameter.getText();
+ if( parameterName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ IParameter param = helpers.getRequestParameter(input, parameterName);
+ if( param == null)
+ throw new IllegalArgumentException("Parameter name not found.");
+ if( param.getType() != IParameter.PARAM_BODY )
+ throw new IllegalArgumentException("Parameter type is not POST");
+
+ int start = param.getValueStart();
+ int end = param.getValueEnd();
+
+ byte[] result = Arrays.copyOfRange(input, start, end);
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.parameter = new VariableTextField();
+ this.addUIElement("Parameter", this.parameter);
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpUriExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpUriExtractor.java
new file mode 100644
index 0000000..cc67c5e
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpUriExtractor.java
@@ -0,0 +1,50 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.Arrays;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP URI", category = OperationCategory.EXTRACTORS, description = "Extracts the URI of a HTTP request.")
+public class HttpUriExtractor extends Operation {
+
+ private JCheckBox checkbox;
+
+ @Override
+ public void createUI() {
+ this.checkbox = new JCheckBox("With parameters");
+ this.checkbox.setSelected(true);
+ this.addUIElement(null, this.checkbox, "checkbox1");
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ try {
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ int firstMark = helpers.indexOf(input, " ".getBytes(), false, 0, length);
+ int lineMark = helpers.indexOf(input, " ".getBytes(), false, firstMark + 1, length);
+
+ int secondMark = helpers.indexOf(input, "?".getBytes(), false, firstMark + 1, length);
+
+ if( this.checkbox.isSelected() || secondMark < 0 || secondMark >= lineMark) {
+ secondMark = lineMark;
+ }
+
+ byte[] result = Arrays.copyOfRange(input, firstMark + 1, secondMark);
+ return result;
+
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Provided input is not a valid http request.");
+ }
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpXmlExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpXmlExtractor.java
new file mode 100644
index 0000000..37f845c
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpXmlExtractor.java
@@ -0,0 +1,48 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.Arrays;
+
+import javax.swing.JTextField;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP XML", category = OperationCategory.EXTRACTORS, description = "Extract XML value from HTTP message.")
+public class HttpXmlExtractor extends Operation {
+
+ private JTextField fieldTxt;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String keyName = fieldTxt.getText();
+ if( keyName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ IParameter param = helpers.getRequestParameter(input, keyName);
+ if( param == null)
+ throw new IllegalArgumentException("Key not found.");
+ if( param.getType() != IParameter.PARAM_XML )
+ throw new IllegalArgumentException("Parameter type is not XML");
+
+ int start = param.getValueStart();
+ int end = param.getValueEnd();
+
+ byte[] result = Arrays.copyOfRange(input, start, end);
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.fieldTxt = new JTextField();
+ this.addUIElement("Field", this.fieldTxt);
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/JsonExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/JsonExtractor.java
new file mode 100644
index 0000000..0975fa3
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/JsonExtractor.java
@@ -0,0 +1,59 @@
+package de.usd.cstchef.operations.extractors;
+
+import javax.swing.JTextField;
+
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.spi.json.JsonProvider;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "JSON", category = OperationCategory.EXTRACTORS, description = "Extracts values of json objects.")
+public class JsonExtractor extends Operation {
+
+ private static JsonProvider provider;
+
+ //TODO should this be a VariableTextField?
+ private JTextField fieldTxt;
+
+ public JsonExtractor() {
+ super();
+ if (JsonExtractor.provider == null) {
+ JsonExtractor.provider = Configuration.defaultConfiguration().jsonProvider();
+ }
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ if( fieldTxt.getText().equals("") )
+ return input;
+
+ Object document = provider.parse(new String(input));
+ Object result = JsonPath.read(document, fieldTxt.getText());
+
+ if( result == null )
+ result = "null";
+
+ Class extends Object> resultClass = result.getClass();
+
+ if( resultClass == String.class ) {
+ return ((String)result).getBytes();
+ } else if( resultClass == Integer.class || resultClass == Float.class || resultClass == Double.class ) {
+ return String.valueOf(result).getBytes();
+ } else if( resultClass == Boolean.class ) {
+ return String.valueOf(result).getBytes();
+ }
+
+ throw new IllegalArgumentException("JSON data of unknown type.");
+ }
+
+ @Override
+ public void createUI() {
+ this.fieldTxt = new JTextField();
+ this.addUIElement("Field", this.fieldTxt);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/LineExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/LineExtractor.java
new file mode 100644
index 0000000..59de978
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/LineExtractor.java
@@ -0,0 +1,82 @@
+package de.usd.cstchef.operations.extractors;
+
+import javax.swing.JComboBox;
+
+import org.bouncycastle.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "Line Extractor", category = OperationCategory.EXTRACTORS, description = "Extracts the specified line number.")
+public class LineExtractor extends Operation {
+
+ private VariableTextField lineNumberField;
+ private JComboBox formatBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ int lineNumber = 0;
+ try {
+ String number = lineNumberField.getText();
+ lineNumber = Integer.valueOf(number);
+ } catch(Exception e) {
+ return input;
+ }
+
+ if( lineNumber <= 0 )
+ return input;
+
+ byte[] lineEndings = "\r\n".getBytes();
+ switch ((String) this.formatBox.getSelectedItem()) {
+ case "\\r\\n":
+ lineEndings = "\r\n".getBytes();
+ break;
+ case "\\r":
+ lineEndings = "\r".getBytes();
+ break;
+ case "\\n":
+ lineEndings = "\n".getBytes();
+ break;
+ }
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ int start = 0;
+ int offset = 0;
+ int counter = 0;
+ while( counter < lineNumber - 1 ) {
+ offset = helpers.indexOf(input, lineEndings, false, start, length);
+ if( offset >= 0 ) {
+ start = offset + lineEndings.length;
+ counter++;
+ } else {
+ break;
+ }
+ }
+
+ int end = helpers.indexOf(input, lineEndings, false, start, length);
+ if( end < 0 )
+ end = length;
+
+ byte[] result = Arrays.copyOfRange(input, start, end);
+ return result;
+ }
+
+ @Override
+ public void createUI() {
+ this.lineNumberField = new VariableTextField();
+ this.addUIElement("Name", this.lineNumberField);
+ this.formatBox = new JComboBox<>(new String[] {"\\r\\n", "\\r", "\\n"});
+ this.formatBox.setSelectedItem("\\r\\n");
+ this.addUIElement("Lineseperator", this.formatBox);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/extractors/RegexExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/RegexExtractor.java
new file mode 100644
index 0000000..d3a7c9d
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/extractors/RegexExtractor.java
@@ -0,0 +1,54 @@
+package de.usd.cstchef.operations.extractors;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.JComboBox;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "Regex", category = OperationCategory.EXTRACTORS, description = "Extracts using a regex.")
+public class RegexExtractor extends Operation {
+
+ private static String LIST_MATCHES = "List matches";
+ private static String LIST_GROUPS = "List capture groups";
+
+ private VariableTextField regexTxt;
+ private JComboBox outputBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ Pattern p = Pattern.compile(this.regexTxt.getText());
+ Matcher m = p.matcher(new String(input));
+ String outputType = (String) this.outputBox.getSelectedItem();
+
+ StringBuffer buf = new StringBuffer();
+
+ while (m.find()) {
+ if (outputType.equals(LIST_MATCHES)) {
+ buf.append(m.group()).append("\n");
+ } else {
+ for (int i = 1; i <= m.groupCount(); i++) {
+ buf.append(m.group(i)).append("\n");
+ }
+ }
+ }
+
+ if( buf.length() > 0 )
+ buf.setLength(buf.length() - 1);
+
+ return buf.toString().getBytes();
+ }
+
+ @Override
+ public void createUI() {
+ this.regexTxt = new VariableTextField();
+ this.addUIElement("Regex", this.regexTxt);
+
+ this.outputBox = new JComboBox<>(new String[] { LIST_MATCHES, LIST_GROUPS });
+ this.addUIElement("Output format", this.outputBox);
+ }
+}
diff --git a/src/de/usd/cstchef/operations/hashing/Blake.java b/src/main/java/de/usd/cstchef/operations/hashing/Blake.java
similarity index 70%
rename from src/de/usd/cstchef/operations/hashing/Blake.java
rename to src/main/java/de/usd/cstchef/operations/hashing/Blake.java
index f66702e..ff58992 100644
--- a/src/de/usd/cstchef/operations/hashing/Blake.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/Blake.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "Blake", category = OperationCategory.HASHING, description = "The Blake algorithm")
public class Blake extends HashOperation {
- public Blake() {
- super("BLAKE", "2B-512", "2B-384", "2B-256", "2B-160", "2S-256", "2S-224", "2S-160", "2S-128");
- }
+ public Blake() {
+ super("BLAKE", "2B-512", "2B-384", "2B-256", "2B-160", "2S-256", "2S-224", "2S-160", "2S-128");
+ }
}
diff --git a/src/de/usd/cstchef/operations/hashing/DSTU7564.java b/src/main/java/de/usd/cstchef/operations/hashing/DSTU7564.java
similarity index 80%
rename from src/de/usd/cstchef/operations/hashing/DSTU7564.java
rename to src/main/java/de/usd/cstchef/operations/hashing/DSTU7564.java
index 51c6e16..b253593 100644
--- a/src/de/usd/cstchef/operations/hashing/DSTU7564.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/DSTU7564.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "DSTU7564", category = OperationCategory.HASHING, description = "The Whirlpool algorithm")
public class DSTU7564 extends HashOperation {
- public DSTU7564() {
- super("DSTU7564-", "256", "384", "512");
- }
+ public DSTU7564() {
+ super("DSTU7564-", "256", "384", "512");
+ }
}
diff --git a/src/de/usd/cstchef/operations/hashing/Gost.java b/src/main/java/de/usd/cstchef/operations/hashing/Gost.java
similarity index 80%
rename from src/de/usd/cstchef/operations/hashing/Gost.java
rename to src/main/java/de/usd/cstchef/operations/hashing/Gost.java
index 9756c4b..5215f78 100644
--- a/src/de/usd/cstchef/operations/hashing/Gost.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/Gost.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "Gost", category = OperationCategory.HASHING, description = "The Gost algorithm")
public class Gost extends HashOperation {
- public Gost() {
- super("GOST-3411-2012-", "256", "512");
- }
+ public Gost() {
+ super("GOST-3411-2012-", "256", "512");
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/hashing/HashOperation.java b/src/main/java/de/usd/cstchef/operations/hashing/HashOperation.java
new file mode 100644
index 0000000..8b134ff
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/hashing/HashOperation.java
@@ -0,0 +1,47 @@
+package de.usd.cstchef.operations.hashing;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.swing.JComboBox;
+
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.Operation;
+
+public abstract class HashOperation extends Operation {
+
+ private JComboBox sizeBox;
+ private String algorithm;
+
+ public HashOperation(String alogrithm) {
+ super();
+ this.algorithm = alogrithm;
+ }
+
+ public HashOperation(String alogrithm, String... sizes) {
+ super();
+ this.algorithm = alogrithm;
+ createMyUI(sizes);
+ }
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ return this.hash(input);
+ }
+
+ protected byte[] hash(byte[] input) throws NoSuchAlgorithmException {
+ String algo = this.algorithm + (this.sizeBox != null ? (String) sizeBox.getSelectedItem() : "");
+
+ MessageDigest digest = MessageDigest.getInstance(algo);
+ byte[] hash = digest.digest(input);
+ return Hex.encode(hash);
+ }
+
+ public void createMyUI(String[] sizes) {
+ sizeBox = new JComboBox(sizes);
+ sizeBox.setSelectedIndex(0);
+ this.addUIElement("Size", sizeBox);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/hashing/Hmac.java b/src/main/java/de/usd/cstchef/operations/hashing/Hmac.java
new file mode 100644
index 0000000..88ed871
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/hashing/Hmac.java
@@ -0,0 +1,39 @@
+package de.usd.cstchef.operations.hashing;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.swing.JComboBox;
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HMAC", category = OperationCategory.HASHING, description = "Creates an HMAC with the chosen hashing function.")
+public class Hmac extends Operation {
+
+ private VariableTextField keyTxt;
+ private JComboBox hashAlgoBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ byte[] key = this.keyTxt.getText().getBytes();
+ String algo = "Hmac" + (String) hashAlgoBox.getSelectedItem();
+ SecretKeySpec signingKey = new SecretKeySpec(key, algo);
+ Mac mac = Mac.getInstance(algo);
+ mac.init(signingKey);
+ return Hex.encode(mac.doFinal(input));
+ }
+
+ @Override
+ public void createUI() {
+ String[] algorithms = { "MD5", "SHA1", "SHA256", "SHA224", "SHA384", "SHA512", "GOST3411" };
+ this.hashAlgoBox = new JComboBox<>(algorithms);
+ this.addUIElement("Hashing function", this.hashAlgoBox);
+
+ this.keyTxt = new VariableTextField();
+ this.addUIElement("Key", this.keyTxt);
+ }
+
+}
diff --git a/src/de/usd/cstchef/operations/hashing/MD2.java b/src/main/java/de/usd/cstchef/operations/hashing/MD2.java
similarity index 86%
rename from src/de/usd/cstchef/operations/hashing/MD2.java
rename to src/main/java/de/usd/cstchef/operations/hashing/MD2.java
index b00c7ad..d178e9e 100644
--- a/src/de/usd/cstchef/operations/hashing/MD2.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/MD2.java
@@ -5,9 +5,9 @@
@OperationInfos(name = "MD2", category = OperationCategory.HASHING, description = "The MD2 (Message-Digest 2) algorithm")
public class MD2 extends HashOperation {
-
- public MD2() {
- super("MD2");
- }
-
+
+ public MD2() {
+ super("MD2");
+ }
+
}
diff --git a/src/de/usd/cstchef/operations/hashing/MD4.java b/src/main/java/de/usd/cstchef/operations/hashing/MD4.java
similarity index 87%
rename from src/de/usd/cstchef/operations/hashing/MD4.java
rename to src/main/java/de/usd/cstchef/operations/hashing/MD4.java
index e1e8103..3719dbe 100644
--- a/src/de/usd/cstchef/operations/hashing/MD4.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/MD4.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "MD4", category = OperationCategory.HASHING, description = "The MD4 (Message-Digest 4) algorithm")
public class MD4 extends HashOperation {
- public MD4() {
- super("MD4");
- }
+ public MD4() {
+ super("MD4");
+ }
}
diff --git a/src/de/usd/cstchef/operations/hashing/MD5.java b/src/main/java/de/usd/cstchef/operations/hashing/MD5.java
similarity index 86%
rename from src/de/usd/cstchef/operations/hashing/MD5.java
rename to src/main/java/de/usd/cstchef/operations/hashing/MD5.java
index 40d5fd3..2771957 100644
--- a/src/de/usd/cstchef/operations/hashing/MD5.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/MD5.java
@@ -5,10 +5,10 @@
@OperationInfos(name = "MD5", category = OperationCategory.HASHING, description = "The MD5 (Message-Digest 5) algorithm")
public class MD5 extends HashOperation {
-
- public MD5() {
- super("MD5");
- }
-
+
+ public MD5() {
+ super("MD5");
+ }
+
}
diff --git a/src/de/usd/cstchef/operations/hashing/RIPEMD.java b/src/main/java/de/usd/cstchef/operations/hashing/RIPEMD.java
similarity index 80%
rename from src/de/usd/cstchef/operations/hashing/RIPEMD.java
rename to src/main/java/de/usd/cstchef/operations/hashing/RIPEMD.java
index bee5ed7..4f77e32 100644
--- a/src/de/usd/cstchef/operations/hashing/RIPEMD.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/RIPEMD.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "RIPEMD", category = OperationCategory.HASHING, description = "The RIPEMD algorithm")
public class RIPEMD extends HashOperation {
- public RIPEMD() {
- super("RIPEMD", "256", "128", "160");
- }
+ public RIPEMD() {
+ super("RIPEMD", "256", "128", "160");
+ }
}
\ No newline at end of file
diff --git a/src/de/usd/cstchef/operations/hashing/SHA1.java b/src/main/java/de/usd/cstchef/operations/hashing/SHA1.java
similarity index 85%
rename from src/de/usd/cstchef/operations/hashing/SHA1.java
rename to src/main/java/de/usd/cstchef/operations/hashing/SHA1.java
index beb6d48..a6e650b 100644
--- a/src/de/usd/cstchef/operations/hashing/SHA1.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/SHA1.java
@@ -5,9 +5,9 @@
@OperationInfos(name = "SHA1", category = OperationCategory.HASHING, description = "The SHA1 algorithm")
public class SHA1 extends HashOperation {
-
- public SHA1() {
- super("SHA1");
- }
+
+ public SHA1() {
+ super("SHA1");
+ }
}
diff --git a/src/de/usd/cstchef/operations/hashing/SHA2.java b/src/main/java/de/usd/cstchef/operations/hashing/SHA2.java
similarity index 75%
rename from src/de/usd/cstchef/operations/hashing/SHA2.java
rename to src/main/java/de/usd/cstchef/operations/hashing/SHA2.java
index 1377935..568e6c9 100644
--- a/src/de/usd/cstchef/operations/hashing/SHA2.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/SHA2.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "SHA2", category = OperationCategory.HASHING, description = "The SHA2 algorithm")
public class SHA2 extends HashOperation {
- public SHA2() {
- super("SHA-", "224", "256", "384", "512", "512/224", "512/256");
- }
+ public SHA2() {
+ super("SHA-", "224", "256", "384", "512", "512/224", "512/256");
+ }
}
diff --git a/src/de/usd/cstchef/operations/hashing/SHA3.java b/src/main/java/de/usd/cstchef/operations/hashing/SHA3.java
similarity index 79%
rename from src/de/usd/cstchef/operations/hashing/SHA3.java
rename to src/main/java/de/usd/cstchef/operations/hashing/SHA3.java
index 655fc35..1024cff 100644
--- a/src/de/usd/cstchef/operations/hashing/SHA3.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/SHA3.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "SHA3", category = OperationCategory.HASHING, description = "The SHA3 algorithm")
public class SHA3 extends HashOperation {
- public SHA3() {
- super("SHA3-", "224", "256", "384", "512");
- }
-
+ public SHA3() {
+ super("SHA3-", "224", "256", "384", "512");
+ }
+
}
diff --git a/src/de/usd/cstchef/operations/hashing/Skein.java b/src/main/java/de/usd/cstchef/operations/hashing/Skein.java
similarity index 60%
rename from src/de/usd/cstchef/operations/hashing/Skein.java
rename to src/main/java/de/usd/cstchef/operations/hashing/Skein.java
index e3ea2b3..c4538d5 100644
--- a/src/de/usd/cstchef/operations/hashing/Skein.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/Skein.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "Skein", category = OperationCategory.HASHING, description = "The Skein algorithm")
public class Skein extends HashOperation {
- public Skein() {
- super("Skein-", "256-128", "256-160", "256-224", "256-256", "512-128", "512-160", "512-224", "512-256", "512-384", "512-512", "1024-384", "1024-512", "1024-1024");
- }
-
+ public Skein() {
+ super("Skein-", "256-128", "256-160", "256-224", "256-256", "512-128", "512-160", "512-224", "512-256", "512-384", "512-512", "1024-384", "1024-512", "1024-1024");
+ }
+
}
diff --git a/src/de/usd/cstchef/operations/hashing/Tiger.java b/src/main/java/de/usd/cstchef/operations/hashing/Tiger.java
similarity index 85%
rename from src/de/usd/cstchef/operations/hashing/Tiger.java
rename to src/main/java/de/usd/cstchef/operations/hashing/Tiger.java
index 162f50c..3b9f4ba 100644
--- a/src/de/usd/cstchef/operations/hashing/Tiger.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/Tiger.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "Tiger", category = OperationCategory.HASHING, description = "The Tiger algorithm")
public class Tiger extends HashOperation {
- public Tiger() {
- super("Tiger");
- }
-
+ public Tiger() {
+ super("Tiger");
+ }
+
}
diff --git a/src/de/usd/cstchef/operations/hashing/Whirlpool.java b/src/main/java/de/usd/cstchef/operations/hashing/Whirlpool.java
similarity index 84%
rename from src/de/usd/cstchef/operations/hashing/Whirlpool.java
rename to src/main/java/de/usd/cstchef/operations/hashing/Whirlpool.java
index 5f32952..2e7ff1f 100644
--- a/src/de/usd/cstchef/operations/hashing/Whirlpool.java
+++ b/src/main/java/de/usd/cstchef/operations/hashing/Whirlpool.java
@@ -6,8 +6,8 @@
@OperationInfos(name = "Whirlpool", category = OperationCategory.HASHING, description = "The Whirlpool algorithm")
public class Whirlpool extends HashOperation {
- public Whirlpool() {
- super("WHIRLPOOL");
- }
+ public Whirlpool() {
+ super("WHIRLPOOL");
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/misc/ReadFile.java b/src/main/java/de/usd/cstchef/operations/misc/ReadFile.java
new file mode 100644
index 0000000..f40acee
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/misc/ReadFile.java
@@ -0,0 +1,52 @@
+package de.usd.cstchef.operations.misc;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileInputStream;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "Read File", category = OperationCategory.MISC, description = "Reads data from a file.")
+public class ReadFile extends Operation implements ActionListener {
+
+ private final JFileChooser fileChooser = new JFileChooser();
+ private VariableTextField fileNameTxt;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ String path = fileNameTxt.getText();
+
+ File file = new File(path);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ fis.read(data);
+ fis.close();
+
+ return data;
+ }
+
+ public void createUI() {
+ this.fileNameTxt = new VariableTextField();
+ this.addUIElement("Filename", this.fileNameTxt);
+
+ JButton chooseFileButton = new JButton("Select file");
+ chooseFileButton.addActionListener(this);
+ this.addUIElement(null, chooseFileButton, false, "button1");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int returnVal = fileChooser.showOpenDialog(this);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ File file = fileChooser.getSelectedFile();
+ this.fileNameTxt.setText(file.getAbsolutePath());
+ }
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/misc/WriteFile.java b/src/main/java/de/usd/cstchef/operations/misc/WriteFile.java
new file mode 100644
index 0000000..f2cf7bb
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/misc/WriteFile.java
@@ -0,0 +1,78 @@
+package de.usd.cstchef.operations.misc;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "Write File", category = OperationCategory.MISC, description = "Appends data to the end of a file.")
+public class WriteFile extends Operation implements ActionListener {
+
+ private final JFileChooser fileChooser = new JFileChooser();
+ private VariableTextField fileNameTxt;
+ private String lastPath = "";
+ private FileOutputStream out;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ String path = fileNameTxt.getText();
+
+ if (!lastPath.equals(path)) {
+ if (out != null) {
+ out.close();
+ out = null;
+ }
+ if (!path.isEmpty()) {
+ out = new FileOutputStream(path);
+ }
+ lastPath = path;
+ }
+
+ if (out != null) {
+ out.write(input);
+ out.write('\n');
+ }
+
+ return input;
+ }
+
+ public void createUI() {
+ this.fileNameTxt = new VariableTextField();
+ this.fileNameTxt.setEditable(false);
+ this.addUIElement("Filename", this.fileNameTxt);
+
+ JButton chooseFileButton = new JButton("Select file");
+ chooseFileButton.addActionListener(this);
+ this.addUIElement(null, chooseFileButton, false, "button1");
+ }
+
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int returnVal = fileChooser.showOpenDialog(this);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ File file = fileChooser.getSelectedFile();
+ this.fileNameTxt.setText(file.getAbsolutePath());
+ }
+ }
+
+ @Override
+ public void onRemove() {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/networking/HTTPRequest.java b/src/main/java/de/usd/cstchef/operations/networking/HTTPRequest.java
new file mode 100644
index 0000000..d76335c
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/networking/HTTPRequest.java
@@ -0,0 +1,43 @@
+package de.usd.cstchef.operations.networking;
+
+import javax.swing.JCheckBox;
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IHttpRequestResponse;
+import burp.IHttpService;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HTTP Request", category = OperationCategory.NETWORKING, description = "Makes an http reqeust and returns the response.")
+public class HTTPRequest extends Operation {
+
+ private VariableTextField hostTxt;
+ private VariableTextField portTxt;
+ private JCheckBox sslEnabledBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helper = callbacks.getHelpers();
+ String protocol = sslEnabledBox.isSelected() ? "https" : "http";
+ IHttpService service = helper.buildHttpService(hostTxt.getText(), Integer.valueOf(portTxt.getText()), protocol);
+ IHttpRequestResponse response = callbacks.makeHttpRequest(service, input);
+ return response.getResponse();
+ }
+
+ @Override
+ public void createUI() {
+ this.hostTxt = new VariableTextField();
+ this.addUIElement("Host", this.hostTxt);
+
+ this.portTxt = new VariableTextField();
+ this.addUIElement("Port", this.portTxt);
+
+ this.sslEnabledBox = new JCheckBox();
+ this.addUIElement("SSL", this.sslEnabledBox);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpGetSetter.java b/src/main/java/de/usd/cstchef/operations/setter/HttpGetSetter.java
new file mode 100644
index 0000000..c241dcf
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpGetSetter.java
@@ -0,0 +1,66 @@
+package de.usd.cstchef.operations.setter;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP GET Param", category = OperationCategory.SETTER, description = "Sets a GET parameter to the specified value.")
+public class HttpGetSetter extends SetterOperation {
+
+ private JCheckBox addIfNotPresent;
+ private JCheckBox urlEncode;
+ private JCheckBox urlEncodeAll;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String parameterName = getWhere();
+ if( parameterName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ byte[] newValue = getWhatBytes();
+
+ if( urlEncodeAll.isSelected() || urlEncode.isSelected() )
+ newValue = urlEncode(newValue, urlEncodeAll.isSelected(), helpers);
+
+ IParameter param = getParameter(input, parameterName, IParameter.PARAM_URL, helpers);
+
+ if( param == null ) {
+
+ if( !addIfNotPresent.isSelected() )
+ return input;
+
+ param = helpers.buildParameter(parameterName, "dummy", IParameter.PARAM_URL);
+ input = helpers.addParameter(input, param);
+ param = getParameter(input, parameterName, IParameter.PARAM_URL, helpers);
+ }
+
+ byte[] newRequest = replaceParam(input, param, newValue);
+ return newRequest;
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+
+ this.urlEncode = new JCheckBox("URL encode");
+ this.urlEncode.setSelected(false);
+ this.addUIElement(null, this.urlEncode, "checkbox1");
+
+ this.urlEncodeAll = new JCheckBox("URL encode all");
+ this.urlEncodeAll.setSelected(false);
+ this.addUIElement(null, this.urlEncodeAll, "checkbox2");
+
+ this.addIfNotPresent = new JCheckBox("Add if not present");
+ this.addIfNotPresent.setSelected(true);
+ this.addUIElement(null, this.addIfNotPresent, "checkbox3");
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpHeaderSetter.java b/src/main/java/de/usd/cstchef/operations/setter/HttpHeaderSetter.java
new file mode 100644
index 0000000..9feb7e1
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpHeaderSetter.java
@@ -0,0 +1,66 @@
+package de.usd.cstchef.operations.setter;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IRequestInfo;
+import de.usd.cstchef.Utils;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP Header", category = OperationCategory.SETTER, description = "Set a HTTP header to the specified value.")
+public class HttpHeaderSetter extends SetterOperation {
+
+ private JCheckBox addIfNotPresent;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] newValue = getWhatBytes();
+ byte[] headerName = getWhereBytes();
+ if( headerName.length == 0 )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ byte[] headerSearch = new byte[headerName.length + 2];
+ System.arraycopy(headerName, 0, headerSearch, 0, headerName.length);
+ System.arraycopy(": ".getBytes(), 0, headerSearch, headerName.length, 2);
+
+ try {
+
+ int offset = helpers.indexOf(input, headerSearch, false, 0, length);
+ int start = helpers.indexOf(input, ": ".getBytes(), false, offset, length) + 2;
+ int end = helpers.indexOf(input, "\r\n".getBytes(), false, start, length);
+ return Utils.insertAtOffset(input, start, end, newValue);
+
+ } catch( IllegalArgumentException e ) {
+
+ if( !addIfNotPresent.isSelected() )
+ return input;
+
+ IRequestInfo info = helpers.analyzeRequest(input);
+ int bodyOffset = info.getBodyOffset() - 2;
+
+ byte[] value = new byte[headerSearch.length + newValue.length + 2];
+ System.arraycopy(headerSearch, 0, value, 0, headerSearch.length);
+ System.arraycopy(newValue, 0, value, headerName.length + 2, newValue.length);
+ System.arraycopy("\r\n".getBytes(), 0, value, headerName.length + 2 + newValue.length, 2);
+ return Utils.insertAtOffset(input, bodyOffset, bodyOffset, value);
+
+ }
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+ this.addIfNotPresent = new JCheckBox("Add if not present");
+ this.addIfNotPresent.setSelected(true);
+ this.addUIElement(null, this.addIfNotPresent, "checkbox1");
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpJsonSetter.java b/src/main/java/de/usd/cstchef/operations/setter/HttpJsonSetter.java
new file mode 100644
index 0000000..542e92c
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpJsonSetter.java
@@ -0,0 +1,33 @@
+package de.usd.cstchef.operations.setter;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP JSON", category = OperationCategory.SETTER, description = "Set a JSON parameter to the specified value.")
+public class HttpJsonSetter extends SetterOperation {
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String parameterName = getWhere();
+ if( parameterName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ byte[] newValue = getWhatBytes();
+ IParameter param = getParameter(input, parameterName, IParameter.PARAM_JSON, helpers);
+
+ if( param == null )
+ return input;
+
+ byte[] newRequest = replaceParam(input, param, newValue);
+ return newRequest;
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpPostSetter.java b/src/main/java/de/usd/cstchef/operations/setter/HttpPostSetter.java
new file mode 100644
index 0000000..8dc1158
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpPostSetter.java
@@ -0,0 +1,71 @@
+package de.usd.cstchef.operations.setter;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP POST Param", category = OperationCategory.SETTER, description = "Set a POST parameter to the specified value.")
+public class HttpPostSetter extends SetterOperation {
+
+ private JCheckBox addIfNotPresent;
+ private JCheckBox urlEncode;
+ private JCheckBox urlEncodeAll;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String parameterName = getWhere();
+ if( parameterName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ byte[] newValue = getWhatBytes();
+
+ if( urlEncodeAll.isSelected() || urlEncode.isSelected() )
+ newValue = urlEncode(newValue, urlEncodeAll.isSelected(), helpers);
+
+ IParameter param = getParameter(input, parameterName, IParameter.PARAM_BODY, helpers);
+
+ if( param == null ) {
+
+ if( !addIfNotPresent.isSelected() )
+ return input;
+
+ param = helpers.buildParameter(parameterName, "dummy", IParameter.PARAM_BODY);
+ input = helpers.addParameter(input, param);
+ param = getParameter(input, parameterName, IParameter.PARAM_BODY, helpers);
+ if( param == null )
+ // This case occurs when the HTTP request is a JSON or XML request. Burp does not
+ // support adding parameters to these and therefore the request should stay unmodified.
+ throw new IllegalArgumentException("Failure while adding the parameter. Operation cannot be used on XML or JSON.");
+ }
+
+ byte[] newRequest = replaceParam(input, param, newValue);
+ return newRequest;
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+
+ this.urlEncode = new JCheckBox("URL encode");
+ this.urlEncode.setSelected(false);
+ this.addUIElement(null, this.urlEncode, "checkbox1");
+
+ this.urlEncodeAll = new JCheckBox("URL encode all");
+ this.urlEncodeAll.setSelected(false);
+ this.addUIElement(null, this.urlEncodeAll, "checkbox2");
+
+ this.addIfNotPresent = new JCheckBox("Add if not present");
+ this.addIfNotPresent.setSelected(true);
+ this.addUIElement(null, this.addIfNotPresent, "checkbox3");
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpSetBody.java b/src/main/java/de/usd/cstchef/operations/setter/HttpSetBody.java
new file mode 100644
index 0000000..b07ff2e
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpSetBody.java
@@ -0,0 +1,39 @@
+package de.usd.cstchef.operations.setter;
+
+import java.util.Arrays;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IRequestInfo;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.view.ui.FormatTextField;
+
+@OperationInfos(name = "HTTP Body", category = OperationCategory.SETTER, description = "Set the HTTP body to the specified value.")
+public class HttpSetBody extends Operation {
+
+ private FormatTextField replacementTxt;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ IBurpExtenderCallbacks cbs = BurpUtils.getInstance().getCallbacks();
+ IRequestInfo requestInfo = cbs.getHelpers().analyzeRequest(input);
+ int bodyOffset = requestInfo.getBodyOffset();
+
+ byte[] noBody = Arrays.copyOfRange(input, 0, bodyOffset);
+ byte[] newBody = replacementTxt.getText();
+ byte[] newRequest = new byte[noBody.length + newBody.length];
+ System.arraycopy(noBody, 0, newRequest, 0, noBody.length);
+ System.arraycopy(newBody, 0, newRequest, noBody.length, newBody.length);
+
+ return newRequest;
+ }
+
+ @Override
+ public void createUI() {
+ this.replacementTxt = new FormatTextField();
+ this.addUIElement("Body", this.replacementTxt);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpSetCookie.java b/src/main/java/de/usd/cstchef/operations/setter/HttpSetCookie.java
new file mode 100644
index 0000000..2c8a3a5
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpSetCookie.java
@@ -0,0 +1,92 @@
+package de.usd.cstchef.operations.setter;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IResponseInfo;
+import de.usd.cstchef.Utils;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP Cookie", category = OperationCategory.SETTER, description = "Set a HTTP cookie to the specified value.")
+public class HttpSetCookie extends SetterOperation {
+
+ private JCheckBox addIfNotPresent;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ byte[] newValue = getWhatBytes();
+ byte[] cookieName = getWhereBytes();
+ if( cookieName.length == 0 )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ byte[] cookieSearch = new byte[cookieName.length + 1];
+ System.arraycopy(cookieName, 0, cookieSearch, 0, cookieName.length);
+ System.arraycopy("=".getBytes(), 0, cookieSearch, cookieName.length, 1);
+
+ IResponseInfo resp = helpers.analyzeResponse(input);
+ boolean isRequest = (resp.getStatusCode() == 0);
+
+ String cookieHeader = "\r\nSet-Cookie: ";
+ if(isRequest)
+ cookieHeader = "\r\nCookie: ";
+
+ int offset = -1;
+ int cookieHeaderLength = cookieHeader.length();
+
+ try {
+
+ offset = helpers.indexOf(input, cookieHeader.getBytes(), false, 0, length);
+ int line_end = helpers.indexOf(input, "\r\n".getBytes(), false, offset + 2, length);
+ int start = helpers.indexOf(input, cookieSearch, true, offset, line_end);
+ int end = helpers.indexOf(input, ";".getBytes(), true, start, line_end);
+
+ if( end < 0 )
+ end = line_end;
+
+ return Utils.insertAtOffset(input, start + cookieSearch.length, end, newValue);
+
+ } catch( IllegalArgumentException e ) {
+
+ if( !addIfNotPresent.isSelected() )
+ return input;
+
+ if( (offset > 0) && isRequest ) {
+
+ byte[] value = new byte[cookieName.length + newValue.length + 3];
+ System.arraycopy(cookieName, 0, value, 0, cookieName.length);
+ System.arraycopy("=".getBytes(), 0, value, cookieName.length, 1);
+ System.arraycopy(newValue, 0, value, cookieName.length + 1, newValue.length);
+ System.arraycopy("; ".getBytes(), 0, value, cookieName.length + 1 + newValue.length, 2);
+ return Utils.insertAtOffset(input, offset + cookieHeaderLength, offset + cookieHeaderLength, value);
+
+ } else {
+
+ int bodyOffset = resp.getBodyOffset() - 4;
+ byte[] value = new byte[cookieName.length + newValue.length + cookieHeaderLength + 2];
+ System.arraycopy(cookieHeader.getBytes(), 0, value, 0, cookieHeaderLength);
+ System.arraycopy(cookieName, 0, value, cookieHeaderLength, cookieName.length);
+ System.arraycopy("=".getBytes(), 0, value, cookieHeaderLength + cookieName.length, 1);
+ System.arraycopy(newValue, 0, value, cookieHeaderLength + cookieName.length + 1, newValue.length);
+ System.arraycopy(";".getBytes(), 0, value, cookieHeaderLength + cookieName.length + 1 + newValue.length, 1);
+ return Utils.insertAtOffset(input, bodyOffset, bodyOffset, value);
+ }
+ }
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+ this.addIfNotPresent = new JCheckBox("Add if not present");
+ this.addIfNotPresent.setSelected(true);
+ this.addUIElement(null, this.addIfNotPresent, "checkbox1");
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpSetUri.java b/src/main/java/de/usd/cstchef/operations/setter/HttpSetUri.java
new file mode 100644
index 0000000..348d4c0
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpSetUri.java
@@ -0,0 +1,64 @@
+package de.usd.cstchef.operations.setter;
+
+import java.util.Arrays;
+
+import javax.swing.JCheckBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "HTTP URI", category = OperationCategory.SETTER, description = "Sets the specified variable as the uri.")
+public class HttpSetUri extends Operation {
+
+ private VariableTextField uriTxt;
+ private JCheckBox checkbox;
+
+ @Override
+ public void createUI() {
+ this.uriTxt = new VariableTextField();
+ this.addUIElement("Uri", this.uriTxt);
+
+ this.checkbox = new JCheckBox("Keep parameters");
+ this.checkbox.setSelected(false);
+ this.addUIElement(null, this.checkbox, "checkbox1");
+ }
+
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+ try {
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ int firstMark = helpers.indexOf(input, " ".getBytes(), false, 0, length);
+ int lineMark = helpers.indexOf(input, " ".getBytes(), false, firstMark + 1, length);
+
+ int secondMark = helpers.indexOf(input, "?".getBytes(), false, firstMark + 1, length);
+
+ if( !this.checkbox.isSelected() || secondMark < 0 || secondMark >= lineMark ) {
+ secondMark = lineMark;
+ }
+
+ byte[] method = Arrays.copyOfRange(input, 0, firstMark + 1);
+ byte[] newUri = this.uriTxt.getBytes();
+ byte[] rest = Arrays.copyOfRange(input, secondMark, length);
+
+ byte[] newRequest = new byte[method.length + newUri.length + rest.length];
+ System.arraycopy(method, 0, newRequest, 0, method.length);
+ System.arraycopy(newUri, 0, newRequest, method.length, newUri.length);
+ System.arraycopy(rest, 0, newRequest, method.length + newUri.length, rest.length);
+
+ return newRequest;
+
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Provided input is not a valid http request.");
+ }
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/HttpXmlSetter.java b/src/main/java/de/usd/cstchef/operations/setter/HttpXmlSetter.java
new file mode 100644
index 0000000..a291fa4
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/HttpXmlSetter.java
@@ -0,0 +1,33 @@
+package de.usd.cstchef.operations.setter;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "HTTP XML", category = OperationCategory.SETTER, description = "Set a XML parameter to the specified value.")
+public class HttpXmlSetter extends SetterOperation {
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ String parameterName = getWhere();
+ if( parameterName.equals("") )
+ return input;
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+
+ byte[] newValue = getWhatBytes();
+ IParameter param = getParameter(input, parameterName, IParameter.PARAM_XML, helpers);
+
+ if( param == null )
+ return input;
+
+ byte[] newRequest = replaceParam(input, param, newValue);
+ return newRequest;
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/JsonSetter.java b/src/main/java/de/usd/cstchef/operations/setter/JsonSetter.java
new file mode 100644
index 0000000..d22d0e8
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/JsonSetter.java
@@ -0,0 +1,91 @@
+package de.usd.cstchef.operations.setter;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+import javax.swing.JCheckBox;
+
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.JsonPath;
+
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+@OperationInfos(name = "JSON", category = OperationCategory.SETTER, description = "Set value of json object.")
+public class JsonSetter extends SetterOperation implements ActionListener {
+
+ private JCheckBox addIfNotPresent;
+ private VariableTextField path;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ if( getWhere().equals("") )
+ return input;
+
+ DocumentContext document = JsonPath.parse(new String(input));
+
+ try {
+ document.read(getWhere());
+ } catch( Exception e ) {
+
+ if( !addIfNotPresent.isSelected() )
+ throw new IllegalArgumentException("Key not found.");
+
+ String insertPath = this.path.getText();
+ if( insertPath.equals("Insert-Path") || insertPath.equals("") )
+ insertPath = "$";
+
+ document = document.put(insertPath, getWhere(), getWhat());
+ return document.jsonString().getBytes();
+ }
+
+ document.set(getWhere(), getWhat());
+ return document.jsonString().getBytes();
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+ this.addIfNotPresent = new JCheckBox("Add if not present");
+ this.addIfNotPresent.setSelected(true);
+ this.addIfNotPresent.addActionListener(this);
+ this.addUIElement(null, this.addIfNotPresent, "checkbox1");
+
+ this.path = new VariableTextField();
+ this.path.setText("Insert-Path");
+ this.path.setForeground(Color.GRAY);
+ this.path.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (path.getText().equals("Insertion Path")) {
+ path.setText("");
+ path.setForeground(null);
+ }
+ }
+ @Override
+ public void focusLost(FocusEvent e) {
+ if (path.getText().isEmpty()) {
+ path.setForeground(Color.GRAY);
+ path.setText("Insertion Path");
+ }
+ }
+ });
+ this.addUIElement(null, this.path, "textbox1");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ if( arg0.getSource() == this.addIfNotPresent ) {
+ if( this.addIfNotPresent.isSelected() ) {
+ this.path.setEditable(true);
+ } else {
+ this.path.setEditable(false);
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/LineSetter.java b/src/main/java/de/usd/cstchef/operations/setter/LineSetter.java
new file mode 100644
index 0000000..9ef1b1e
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/LineSetter.java
@@ -0,0 +1,92 @@
+package de.usd.cstchef.operations.setter;
+
+import java.util.Arrays;
+
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+
+import burp.BurpUtils;
+import burp.IBurpExtenderCallbacks;
+import burp.IExtensionHelpers;
+import de.usd.cstchef.Utils;
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "Line Setter", category = OperationCategory.SETTER, description = "Sets a line to the specified value.")
+public class LineSetter extends SetterOperation {
+
+ private JCheckBox append;
+ private JComboBox formatBox;
+
+ @Override
+ protected byte[] perform(byte[] input) throws Exception {
+
+ int lineNumber;
+ try {
+ String number = getWhere();
+ lineNumber = Integer.valueOf(number);
+ } catch( Exception e ) {
+ return input;
+ }
+
+ if( lineNumber <= 0 )
+ return input;
+
+ byte[] newValue = getWhatBytes();
+ byte[] lineEndings = "\r\n".getBytes();
+ switch ((String) this.formatBox.getSelectedItem()) {
+ case "\\r\\n":
+ lineEndings = "\r\n".getBytes();
+ break;
+ case "\\r":
+ lineEndings = "\r".getBytes();
+ break;
+ case "\\n":
+ lineEndings = "\n".getBytes();
+ break;
+ }
+
+ IBurpExtenderCallbacks callbacks = BurpUtils.getInstance().getCallbacks();
+ IExtensionHelpers helpers = callbacks.getHelpers();
+ int length = input.length;
+
+ int start = 0;
+ int offset = 0;
+ int counter = 0;
+ while( counter < lineNumber - 1 ) {
+ offset = helpers.indexOf(input, lineEndings, false, start, length);
+ if( offset >= 0 ) {
+ start = offset + lineEndings.length;
+ counter++;
+ } else {
+ break;
+ }
+ }
+
+ int end = helpers.indexOf(input, lineEndings, false, start, length);
+ if( end < 0 )
+ end = length;
+
+ if( append.isSelected() ) {
+ byte[] value = new byte[newValue.length + lineEndings.length];
+ System.arraycopy(lineEndings, 0, value, 0, lineEndings.length);
+ System.arraycopy(newValue, 0, value, lineEndings.length, newValue.length);
+ return Utils.insertAtOffset(input, end, end, value);
+ } else {
+ return Utils.insertAtOffset(input, start, end, newValue);
+ }
+ }
+
+ @Override
+ public void createUI() {
+ super.createUI();
+ this.append = new JCheckBox("Insert below");
+ this.append.setSelected(false);
+ this.addUIElement(null, this.append, "checkbox1");
+
+ this.formatBox = new JComboBox<>(new String[] {"\\r\\n", "\\r", "\\n"});
+ this.formatBox.setSelectedItem("\\r\\n");
+ this.addUIElement("Lineseperator", this.formatBox);
+ }
+
+}
diff --git a/src/main/java/de/usd/cstchef/operations/setter/SetterOperation.java b/src/main/java/de/usd/cstchef/operations/setter/SetterOperation.java
new file mode 100644
index 0000000..2a6aafb
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/setter/SetterOperation.java
@@ -0,0 +1,104 @@
+package de.usd.cstchef.operations.setter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.bouncycastle.util.encoders.Hex;
+
+import burp.IExtensionHelpers;
+import burp.IParameter;
+import burp.IRequestInfo;
+import de.usd.cstchef.operations.Operation;
+import de.usd.cstchef.view.ui.VariableTextField;
+
+public abstract class SetterOperation extends Operation {
+
+ private VariableTextField whereToSet;
+ private VariableTextField whatToSet;
+
+ @Override
+ public void createUI() {
+ this.whereToSet = new VariableTextField();
+ this.whatToSet = new VariableTextField();
+ this.addUIElement("Key", this.whereToSet);
+ this.addUIElement("Value", this.whatToSet);
+ }
+
+ protected String getWhere() {
+ return whereToSet.getText();
+ }
+
+ protected byte[] getWhereBytes() {
+ return whereToSet.getBytes();
+ }
+
+ protected String getWhat() {
+ return whatToSet.getText();
+ }
+
+ protected byte[] getWhatBytes() {
+ return whatToSet.getBytes();
+ }
+
+ // This is required because Burps getRequestParameter returns always the first occurrence of the parameter name.
+ // If you have e.g. a cookie with the same name as the POST parameter, you have no chance of getting the POST
+ // parameter using getRequestParameter (at least I do not know how).
+ protected IParameter getParameter(byte[] request, String paramName, byte type, IExtensionHelpers helpers) {
+
+ IRequestInfo info = helpers.analyzeRequest(request);
+ List parameters = info.getParameters();
+ IParameter param = null;
+
+ for(IParameter p:parameters) {
+ if( p.getName().equals(paramName) )
+ if( p.getType() == type ) {
+ param = p;
+ break;
+ }
+ }
+ return param;
+ }
+
+ protected byte[] urlEncode(byte[] input, boolean all, IExtensionHelpers helpers) throws IOException {
+
+ byte[] newValue = input;
+
+ if( all ) {
+ byte[] delimiter = "%".getBytes();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(delimiter);
+
+ for (int i = 0; i < newValue.length - 1; i++) {
+ out.write(Hex.encode(new byte[] { newValue[i] }));
+ out.write(delimiter);
+ }
+
+ out.write(Hex.encode(new byte[] { newValue[newValue.length - 1] }));
+ newValue = out.toByteArray();
+
+ } else {
+ newValue = helpers.urlEncode(input);
+ }
+
+ return newValue;
+ }
+
+ protected byte[] replaceParam(byte[] request, IParameter param, byte[] newValue) {
+
+ int length = request.length;
+ int start = param.getValueStart();
+ int end = param.getValueEnd();
+
+ byte[] prefix = Arrays.copyOfRange(request, 0, start);
+ byte[] rest = Arrays.copyOfRange(request, end, length);
+
+ byte[] newRequest = new byte[prefix.length + newValue.length + rest.length];
+ System.arraycopy(prefix, 0, newRequest, 0, prefix.length);
+ System.arraycopy(newValue, 0, newRequest, prefix.length, newValue.length);
+ System.arraycopy(rest, 0, newRequest, prefix.length + newValue.length, rest.length);
+
+ return newRequest;
+ }
+}
diff --git a/src/de/usd/cstchef/operations/signature/KeystoreOperation.java b/src/main/java/de/usd/cstchef/operations/signature/KeystoreOperation.java
similarity index 53%
rename from src/de/usd/cstchef/operations/signature/KeystoreOperation.java
rename to src/main/java/de/usd/cstchef/operations/signature/KeystoreOperation.java
index fc4911e..090aa78 100644
--- a/src/de/usd/cstchef/operations/signature/KeystoreOperation.java
+++ b/src/main/java/de/usd/cstchef/operations/signature/KeystoreOperation.java
@@ -24,7 +24,7 @@ public abstract class KeystoreOperation extends Operation implements ActionListe
protected String[] keyStoreTypes = new String[] {"JKS", "PKCS12"};
protected VariableTextField fileNameTxt;
- protected JPasswordField keyStorePass;
+ protected JPasswordField keyStorePass;
protected Certificate cert = null;
protected KeyStore keyStore = null;
@@ -36,35 +36,35 @@ public abstract class KeystoreOperation extends Operation implements ActionListe
protected JButton chooseFileButton;
protected JButton openKeyStoreButton;
- protected JComboBox keyEntry;
- protected JComboBox keyStoreType;
- protected JFileChooser fileChooser = new JFileChooser();
-
- public KeystoreOperation() {
- super();
- }
-
- private void openKeyStore() {
- try {
- String path = fileNameTxt.getText();
- File keyStoreFile = new File(path);
- String storeType = (String)keyStoreType.getSelectedItem();
- char[] password = keyStorePass.getPassword();
- KeyStore ks = KeyStore.getInstance(storeType);
- ks.load(new FileInputStream(keyStoreFile), password);
- this.keyStore = ks;
- this.keyStoreOpen.setSelected(true);
- this.certAvailable.setSelected(false);
- this.keyAvailable.setSelected(false);
- this.updateKeyEntries();
-
- } catch( Exception e ) {
- this.resetKeyStore();
- }
- }
+ protected JComboBox keyEntry;
+ protected JComboBox keyStoreType;
+ protected JFileChooser fileChooser = new JFileChooser();
+
+ public KeystoreOperation() {
+ super();
+ }
+
+ private void openKeyStore() {
+ try {
+ String path = fileNameTxt.getText();
+ File keyStoreFile = new File(path);
+ String storeType = (String)keyStoreType.getSelectedItem();
+ char[] password = keyStorePass.getPassword();
+ KeyStore ks = KeyStore.getInstance(storeType);
+ ks.load(new FileInputStream(keyStoreFile), password);
+ this.keyStore = ks;
+ this.keyStoreOpen.setSelected(true);
+ this.certAvailable.setSelected(false);
+ this.keyAvailable.setSelected(false);
+ this.updateKeyEntries();
+
+ } catch( Exception e ) {
+ this.resetKeyStore();
+ }
+ }
private void updateKeyEntries(){
- try {
+ try {
Enumeration entries = keyStore.aliases();
keyEntry.removeAllItems();
while (entries.hasMoreElements()) {
@@ -91,13 +91,13 @@ private void selectKeyEntry() {
char[] password = keyStorePass.getPassword();
try {
- this.selectedEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(entry, new KeyStore.PasswordProtection(password));
- if ( this.selectedEntry != null )
- this.keyAvailable.setSelected(true);
- else
- this.keyAvailable.setSelected(false);
+ this.selectedEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(entry, new KeyStore.PasswordProtection(password));
+ if ( this.selectedEntry != null )
+ this.keyAvailable.setSelected(true);
+ else
+ this.keyAvailable.setSelected(false);
} catch( Exception e) {
- this.keyAvailable.setSelected(false);
+ this.keyAvailable.setSelected(false);
}
}
@@ -105,70 +105,70 @@ private void selectKeyEntry() {
private void resetKeyStore() {
this.keyStoreOpen.setSelected(false);
- this.certAvailable.setSelected(false);
- this.keyAvailable.setSelected(false);
+ this.certAvailable.setSelected(false);
+ this.keyAvailable.setSelected(false);
keyStore = null;
selectedEntry = null;
}
- public void createMyUI() {
- this.keyStoreType = new JComboBox<>(this.keyStoreTypes);
- this.keyStoreType.addActionListener(this);
- this.addUIElement("KeyStoreType", this.keyStoreType);
+ public void createMyUI() {
+ this.keyStoreType = new JComboBox<>(this.keyStoreTypes);
+ this.keyStoreType.addActionListener(this);
+ this.addUIElement("KeyStoreType", this.keyStoreType);
- this.fileNameTxt = new VariableTextField();
- this.addUIElement("Filename", this.fileNameTxt);
+ this.fileNameTxt = new VariableTextField();
+ this.addUIElement("Filename", this.fileNameTxt);
- chooseFileButton = new JButton("Select file");
- chooseFileButton.addActionListener(this);
- this.addUIElement(null, this.chooseFileButton, false, "button1");
+ chooseFileButton = new JButton("Select file");
+ chooseFileButton.addActionListener(this);
+ this.addUIElement(null, this.chooseFileButton, false, "button1");
- this.keyStorePass = new JPasswordField();
- this.addUIElement("PrivKeyPassword", this.keyStorePass);
+ this.keyStorePass = new JPasswordField();
+ this.addUIElement("PrivKeyPassword", this.keyStorePass);
- openKeyStoreButton = new JButton("Open keystore");
- openKeyStoreButton.addActionListener(this);
- this.addUIElement(null, this.openKeyStoreButton, false, "button2");
+ openKeyStoreButton = new JButton("Open keystore");
+ openKeyStoreButton.addActionListener(this);
+ this.addUIElement(null, this.openKeyStoreButton, false, "button2");
- this.keyEntry = new JComboBox<>(keyEntries);
- this.keyEntry.addActionListener(this);
- this.addUIElement("KeyEntry", this.keyEntry);
+ this.keyEntry = new JComboBox<>(keyEntries);
+ this.keyEntry.addActionListener(this);
+ this.addUIElement("KeyEntry", this.keyEntry);
this.keyStoreOpen = new JCheckBox("KeyStore Opened");
this.keyStoreOpen.setSelected(false);
this.keyStoreOpen.setEnabled(false);
this.keyStoreOpen.addActionListener(this);
- this.addUIElement(null, this.keyStoreOpen, "noupdate-checkbox1");
-
- this.certAvailable = new JCheckBox("Certificate available");
+ this.addUIElement(null, this.keyStoreOpen, "noupdate-checkbox1");
+
+ this.certAvailable = new JCheckBox("Certificate available");
this.certAvailable.setSelected(false);
this.certAvailable.setEnabled(false);
- this.certAvailable.addActionListener(this);
- this.addUIElement(null, this.certAvailable, "noupdate-checkbox2");
-
- this.keyAvailable = new JCheckBox("PrivKey available");
+ this.certAvailable.addActionListener(this);
+ this.addUIElement(null, this.certAvailable, "noupdate-checkbox2");
+
+ this.keyAvailable = new JCheckBox("PrivKey available");
this.keyAvailable.setSelected(false);
this.keyAvailable.setEnabled(false);
- this.keyAvailable.addActionListener(this);
- this.addUIElement(null, this.keyAvailable, "noupdate-checkbox3");
+ this.keyAvailable.addActionListener(this);
+ this.addUIElement(null, this.keyAvailable, "noupdate-checkbox3");
+
+ }
- }
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
- @Override
- public void actionPerformed(ActionEvent arg0) {
-
if( arg0.getSource() == keyStoreType ) {
-
+
this.resetKeyStore();
} else if( arg0.getSource() == openKeyStoreButton ) {
-
+
this.resetKeyStore();
this.openKeyStore();
} else if( arg0.getSource() == chooseFileButton ) {
-
+
this.resetKeyStore();
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
@@ -178,10 +178,10 @@ public void actionPerformed(ActionEvent arg0) {
} else if( arg0.getSource() == keyEntry ) {
this.selectKeyEntry();
- }
+ }
if( keyStore != null && keyEntry != null ) {
this.notifyChange();
}
- }
+ }
}
diff --git a/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java b/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java
new file mode 100644
index 0000000..af9b959
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java
@@ -0,0 +1,69 @@
+package de.usd.cstchef.operations.signature;
+
+import java.security.Signature;
+
+import javax.swing.JComboBox;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.bouncycastle.util.encoders.Hex;
+
+import de.usd.cstchef.operations.Operation.OperationInfos;
+import de.usd.cstchef.operations.OperationCategory;
+
+@OperationInfos(name = "RSA Signature", category = OperationCategory.SIGNATURE, description = "Create an RSA signature")
+public class RsaSignature extends KeystoreOperation {
+
+ private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" };
+
+ protected JComboBox algos;
+ protected JComboBox inputMode;
+ protected JComboBox outputMode;
+
+ public RsaSignature() {
+ super();
+ this.createMyUI();
+ }
+
+ protected byte[] perform(byte[] input) throws Exception {
+
+ if( !this.keyAvailable.isSelected() )
+ throw new IllegalArgumentException("No private key available.");
+
+ String algo = (String)algos.getSelectedItem();
+ Signature signature = Signature.getInstance(algo);
+
+ String selectedInputMode = (String)inputMode.getSelectedItem();
+ String selectedOutputMode = (String)outputMode.getSelectedItem();
+
+ if( selectedInputMode.equals("Hex") )
+ input = Hex.decode(input);
+ if( selectedInputMode.equals("Base64") )
+ input = Base64.decode(input);
+
+ signature.initSign(this.selectedEntry.getPrivateKey());
+ signature.update(input);
+ byte[] result = signature.sign();
+
+ if( selectedOutputMode.equals("Hex") )
+ result = Hex.encode(result);
+ if( selectedOutputMode.equals("Base64") )
+ result = Base64.encode(result);
+
+ return result;
+ }
+
+ public void createMyUI() {
+
+ super.createMyUI();
+ SignatureUtils utils = SignatureUtils.getInstance();
+
+ this.algos = new JComboBox<>(utils.getRsaAlgos());
+ this.addUIElement("Padding", this.algos);
+
+ this.inputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Input", this.inputMode);
+
+ this.outputMode = new JComboBox<>(inOutModes);
+ this.addUIElement("Output", this.outputMode);
+ }
+}
diff --git a/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java b/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java
new file mode 100644
index 0000000..f474b2b
--- /dev/null
+++ b/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java
@@ -0,0 +1,42 @@
+package de.usd.cstchef.operations.signature;
+
+import java.security.Provider;
+import java.security.Provider.Service;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class SignatureUtils {
+
+ private static SignatureUtils instance;
+
+ private List algos;
+
+ private SignatureUtils() {
+ algos = new ArrayList();;
+ getSignatureInfos();
+ }
+
+ private void getSignatureInfos() {
+ for (Provider provider : Security.getProviders())
+ for (Service service : provider.getServices())
+ if (service.getType().equals("Signature"))
+ algos.add(service.getAlgorithm());
+ }
+
+ public static SignatureUtils getInstance() {
+ if (instance == null) {
+ instance = new SignatureUtils();
+ }
+ return instance;
+ }
+
+ public String[] getAlgos() {
+ return algos.toArray(new String[0]);
+ }
+ public String[] getRsaAlgos() {
+ List rsaAlgos = algos.stream().filter(p -> p.contains("RSA")).collect(Collectors.toList());
+ return rsaAlgos.toArray(new String[0]);
+ }
+}
diff --git a/src/de/usd/cstchef/operations/signature/SoapMultiSignature.java b/src/main/java/de/usd/cstchef/operations/signature/SoapMultiSignature.java
similarity index 79%
rename from src/de/usd/cstchef/operations/signature/SoapMultiSignature.java
rename to src/main/java/de/usd/cstchef/operations/signature/SoapMultiSignature.java
index 5fd344d..93c7818 100644
--- a/src/de/usd/cstchef/operations/signature/SoapMultiSignature.java
+++ b/src/main/java/de/usd/cstchef/operations/signature/SoapMultiSignature.java
@@ -53,26 +53,26 @@ public class SoapMultiSignature extends KeystoreOperation {
public SoapMultiSignature() {
super();
this.digestMethods.put("sha1", DigestMethod.SHA1);
- this.digestMethods.put("sha256", DigestMethod.SHA256);
- this.digestMethods.put("sha512", DigestMethod.SHA512);
- this.signatureMethods.put("rsa-sha1", SignatureMethod.RSA_SHA1);
+ this.digestMethods.put("sha256", DigestMethod.SHA256);
+ this.digestMethods.put("sha512", DigestMethod.SHA512);
+ this.signatureMethods.put("rsa-sha1", SignatureMethod.RSA_SHA1);
this.createMyUI();
}
protected HashMap digestMethods = new HashMap();
- protected HashMap signatureMethods = new HashMap();
+ protected HashMap signatureMethods = new HashMap();
//"rsa-sha256", SignatureMethod.RSA_SHA256,
//"rsa-sha512", SignatureMethod.RSA_SHA512
protected String[] availDigestMethods = new String[] {"sha1", "sha256", "sha512"};
protected String[] availSignatureMethods = new String[] {"rsa-sha1"};//, "rsa-sha256", "rsa-sha512"};
- protected String[] includeKeyInfos = new String[] { "true", "false" };
- protected JComboBox includeKeyInfo;
- protected JComboBox signatureMethod;
- protected JComboBox digestMethod;
- protected JButton addReferenceButton;
- protected FormatTextField idIdentifier;
- protected ArrayList referenceFields = new ArrayList();
+ protected String[] includeKeyInfos = new String[] { "true", "false" };
+ protected JComboBox includeKeyInfo;
+ protected JComboBox signatureMethod;
+ protected JComboBox digestMethod;
+ protected JButton addReferenceButton;
+ protected FormatTextField idIdentifier;
+ protected ArrayList referenceFields = new ArrayList();
protected JCheckBox certificate;
protected JCheckBox subject;
protected JCheckBox issuer;
@@ -121,7 +121,7 @@ private KeyInfo getKeyInfo(XMLSignatureFactory fac, PrivateKeyEntry keyEntry) th
List