前一篇文章我们介绍了 Java 中的两个常见的序列化方式,JDK 序列化和 Hessian2 序列化,本文我们接着来讲述一个后起之秀——Kryo 序列化,它号称 Java 中最快的序列化框架。 Kryo 序列化 Kryo 是一个快速序列化/反序列化工具,依赖于字节码生成机制(底层使用了 ASM 库),因此在序列化速度上有一定的优势,但正因如此,其使用也只能限制在基于 JVM 的语言上。 Fluo Recipes)•Apache Hive[2] (query plan serialization)•Apache Spark[3] (shuffled/cached data serialization 其实对于序列化框架来说,API 基本都差不多,毕竟入参和出参通常都是确定的(需要序列化的对象/序列化的结果)。 如果你觉得本文对你有帮助的话,不要吝啬你的关注和点赞,也欢迎读者在评论区留言讨论,一起进步啊~ References [1] Apache Fluo: https://fluo.apache.org/ [2]
序列化机制中的序列化算法 一、序列化算法的描述 1、当程序试图序列化一个对象的时候,程序会先检查该对象是否已经被序列化过,如果已经从未被序列化过,则将此对象序列化成流 2、如果已经被序列化,那么程序直接输出一个序列化编号,而不再重新序列化该对象 二、对序列化算法的理解 上面的第二条当对象被程序检查到已经序列化过,就不在序列化此对象,而只是向输出流中输出序列化编号 ObjectOutputStream对象序列化这个A对象,就是把这个A对象写入ObjectOutputStream输出流中,那么只会输出一个序列化编号 2、假设用一个ObjectOutputStream 以后的序列化只 是输出序列化编号而已。 public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 2、
Product { Name = "Hello" }; formatter.Serialize(stream, product); stream.Position = 0; var product2 2. 某类型一旦实现ISerializable接口,便不能删除它,否则会失去与派生类型的兼容性。所以密封类实现ISerializable接口是最让人放心的。 3. 反序列化对象的字段时,应调用和对象序列化时传给AddValue方法的值的类型匹配的Get方法。 否则对象是不能正确序列化和反序列化的。如果你的派生类中没有任何额外的字段,因而没有特殊的序列化/反序列化需求,就完全不必实现ISerializable。 myDerived = new MyDerived(); formatter.Serialize(stream, myDerived); stream.Position = 0; var myDerived2
昨天早上上班前,我无意间看到其它师傅们挖的yii2利用链,其中有一个是我之前忽略了的,就想着赶紧分享给大家,但是昨天恰了个饭(文末有福利),发不了文章,只有今天发了 这是一条利用__wakeup魔术方法作为入口的利用链 > yii2真是一个练习反序列化连挖掘的好靶场,我们可以通过它来练习各种魔术方法在反序列化链构造中的使用 php所有的魔术方法如下: __construct(),类的构造函数 __destruct()
CommonsCollections2 反序列化链分析 一、前言 CC链复现的第二篇,CC2存在有好几条链子,这里就分别来进行调试分析一下具体流程 二、前置知识 1、PriorityQueue PriorityQueue ; System.out.println(priorityQueue.poll()); } result: 1 2 2、getDeclaredField getDecalaredField是 ("comparator");//获取PriorityQueue的comparator字段 field2.setAccessible(true);//暴力反射 field2.set(queue, 四、利用链调试 在入口readObject方法出打上断点,就可以看见反序列化过程中调用的readObject方法是PriorityQueue类中的。 newInstance() Runtime.exec() 五、总结 经过这次的分析对java反序列化的利用链构建理解更上一层。
RedisTemplate序列化、反序列化扩展支持FastJson: GenericFastJson2JsonRedisSerializer在使用Spring Data Redis进行数据存储时,默认的序列化方式可能无法满足所有业务需求 本文将介绍如何使用FastJson来扩展RedisTemplate的序列化和反序列化功能,通过实现一个通用的GenericFastJson2JsonRedisSerializer FastJson是一个非常流行的高性能JSON库,它提供了快速的序列化和反序列化能力,非常适合用于Redis中的数据存储。2. -- 请根据实际情况选择最新版本 --></dependency>2. 创建FastJson序列化器接下来,我们需要创建一个基于FastJson的序列化器。 这里提供一个示例实现,名为GenericFastJson2JsonRedisSerializer,它可以用于RedisTemplate的键值对序列化和反序列化。
在实际反序列化漏洞中,需要将 上⾯最终⽣成的outerMap对象变成⼀个序列化流。 在前面Demo中,需要向修饰过的Map类的实例中添加新元素才能触发漏洞。 手动添加新元素->触发利用链->触发漏洞 而在实际反序列化中,则需要找到一个类,并且在它进行反序列化时,**readObject**方法中也存在类似的操作 反序列化->触发readObject方法-> 因为Class类实现了Serializable接口,所以可以被序列化。 new Object[] {"/System/Applications/Calculator.app/Contents/MacOS/Calculator"} ), }; 完整代码2 ,但是反序列化时仍然没弹出计算器。
之前的文章介绍了在VFP中对原生JSON对象的序列化和反序列化。但是,在应用时,有时我们需要依据一定的条件来构造JSON。 "序列化:" ? m.loJSONHelper.stringify(loRoot, .T.) ? m.loRoot.姓名 = [李四] m.loRoot.年龄 = 35 m.loRoot.tags. _set(0, "Visual FoxPro") m.loRoot.tags.item(2).姓名 = "xxxxxx" ? "修改后:" ?
所以不太推荐使用 后面两种序列化方式是重点 Jackson2JsonRedisSerializer 从名字可以看出来,这是把一个对象以Json的形式存储,效率高且对调用者友好 优点是速度快,序列化后的字符串短小精悍 :为我们提供了两个构造方法,一个需要传入序列化对象Class,一个需要传入对象的JavaType: public Jackson2JsonRedisSerializer(Class<T> type) 因为GenericJackson2JsonRedisSerializer本来处理序列化的都是与类型无关的,所以都转换为Object进行处理。因此出现此种现象也是在情理之中的。 替换默认序列化(备注,此处我用Object为例,各位看官请换成自己的类型哦~) Jackson2JsonRedisSerializer jackson2JsonRedisSerializer (objectMapper); // 设置value的序列化规则和 key的序列化规则 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer
调用链分析 对于反序列化的gadget而言,source点通常是确定的:如果反序列化的触发点是ObjectInputStrem,则gadget的source点是xxx.readObject; 如果反序列化的触发点是 本链的整体思路可以简单概述为: 1.JDK原生反序列化触发PriorityQueue.readObject方法,并使用动态代理修改PriorityQueue类的校验器 2.使用修改后的校验器触发compare 第二部分 - 通过动态代理修改代码逻辑 由于反序列化进来后是一个队列,我们需要将队列的反序列化逻辑引导到python代码执行中。而动态代理的实现要求是: 1. 代码逻辑中某个对象的类型是接口 2. 反序列化逻辑中使用该对象调用方法 debug下PriorityQueue类的反序列化方法,发现了个非常巧妙的点: 这里调用了comparator.compare方法,comparator对象的类型是Comparator 代码逻辑中某个对象的类型是接口 2.反序列化逻辑中使用该对象调用方法 因此便找到了PriorityQueue类,部分poc如下: _args.put("rs", new PyString("import
同一类框架,后出现的总会吸收之前框架的优点,然后加以改进,avro在序列化方面相对thrift就是一个很好的例子。 借用Apache Avro 与 Thrift 比较 一文中的几张图来说明一下,avro在序列化方面的改进: 1、无需强制生成目标语言代码 ? 类似刚才的List集合这种情况,这部分信息也需要重复存储到2进制数据中,反序列化时,也不需再关注schema的信息,存储空间更小。 byte数组长度:" + byte2.length); //反序列化 DatumReader<GenericRecord> reader2 = new GenericDatumReader Avro Generic二进制序列后的byte数组长度:2 与前一篇thrift中的序列化结果相比,存储占用的空间比thrift的TCompactProtocol还要小,确实在序列化方面avro做得更好
使用 JSON 模块将 Python 对象转换为 JSON 格式的字符串非常简单,只需调用 json.dumps() 函数并传递要序列化的 Python 对象即可。
dubbo提供了好几种序列化方式,一般我们都是用的是默认的hession2,而dubbox为我们增加了kryo和fst许了方式,主要体现在速度快,占用内存小,然后我们将序列化配置改为是用kryo: <dubbo serialization="kryo"/> 但是是用一段时间后遇到了不少问题,其中最困扰人的是不兼容以前的版本,我们的需求变动频繁,并且迭代比较快,经常需要增加字段或者对类进行重构,这就导致dubbo反序列化时经常报如下错误 后来针对该问题,又将配置改为了dubbo默认序列化配置,才解决版本兼容问题。 所以针对频繁变动的输入输出时,一般建议采用dubbo默认配置,虽然kryo速度快,但是还不够成熟,这也是dubbo默认配置是hession2而不是kryo。 还有一个值得注意的问题:输入输出参数最好都实现Serializable接口,因为hession2要求必须实现Serializable接口,而kryo不作要求,所以为了方便切换,最好都按要求实现序列化接口
1.什么是序列化和反序列化? 协议是⼀种"约定".socketapi的接⼝,在读写数据时,都是按"字符串"的⽅式来发送接收的.如果我们要传输⼀些"结构化的数据"怎么办呢? 这个时候就需要用到序列化和反序列化了!!!!!!! 2.json库的使用(序列化) 序列化指的是 将数据结构或对象转换为⼀种格式,以便在⽹络上传输或存储到⽂件中。 2. 3.json库的使用(反序列化) 反序列化指的是将序列化后的数据重新转换为原来的数据结构或对象。 创建套接字 BindOrDie(port); // 2. 绑定端口 ListenOrDie(backlog); // 3.
而这里的FastJson1&FastJson2是利用FasJson当中某些函数的调用关系,结合java原生反序列化来对目标应用进行攻击的一种方式。 这一部分我们也可以从下面的变量界面看到,它为TemplatesImpl类创建了一个反序列化工具类(ASMSerializer_1_TemplatesImpl)。 而readFields里面就发生了绕过的现象,他会从我们的序列化字节流里面去拿到对应的标识tc,在之前出现过TC_Object,TC_Array等等不同的类型。 从前面的几个结构可以看出来,序列化后的数据其实相当繁琐,多层嵌套很容易搞乱,在恢复对象的时候也不太容易。于是就有了引用这个东西,他可以引用在此之前已经出现过的对象。 所以正是前面出现过的template,使得后续ois在处理反序列化字节流的时候,直接形成了绕过,引用了前面已经反序列化好的template对象,避免了由于B类型没法正常识别而造成的异常。
,在把二进制流转成对象这就是是序列化,反序列化。 1 在Java中,实现序列化只要实现 java.io.Serializable 接口,就可以被序列化了。 ? ? 2 对象序列化保存的是对象的"状态",即它的成员变量。 反序列化时,恢复引用关系, std1 和 std2 指向唯一的对象,二者相等,输出 true。 7 单列模式进行序列化,那还是单例吗? ? ? ? 从上面结果能发现,序列化后反序列化之后,不再是同一个对象了。 序列化与反序列 1.static 属性和transient不能序列化。 2.自定义序列化,则必须要实现writeObject和对应的 readObject方法。
一、序列化: 就是将内存中的对象转换为字节序列,方便持久化到磁盘或者网络传输 SerializeToString(): serializes the message and returns it as 二、反序列化: 就是将字节序列转换为内存中的对象 ParseFromString(data): parses a message from the given string.
序列化(pickling) 把变量从内存中变成可存储或传输的过程 反序列化(unpickling) 把变量内容从序列化的对象重新读到内存里的过程 序列化&反序列化的意义 在程序运行过程中 ,对象可在内存中被自由的修改 一旦程序结束,对象所占内存会被系统回收,所做修改会全部丢失,要想在内存中将对象恢复到修改后状态,就只能重新运行程序进行修改 通过序列化和反序列化,就可把对象某一时刻在内存中的内容状态同步到磁盘 ,或通过网络传输到别的机器上最为一个记录 当想在内存中恢复该对象在那一时刻的状态时,就可通过将磁盘或其他机器上记录的对象状态反序列化至内存,而无需重新运行程序 实例 import pickle##引入 d1 = pickle.loads(bytes) ##pickle.loads()方法把bytes反序列化出对象 print(d1) ##################### f1.close() print(d1) 注意: 不同版本的Python彼此都不兼容,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系 反序列化后的对象是一个新的对象
我之前在《聊一聊RPC》中曾提过什么是序列化和反序列化,当时有说过之后要单独抽出一期来详细聊聊序列化,没想到这一拖竟然拖了一年多,现在来把这个坑补上。 由于篇幅较长,本文先主要介绍两种常见的序列化方式——JDK序列化和Hessian序列化。 ? 反序列化时JVM会按版本号找指定版本的class文件进行反序列化,如果class文件有版本号在序列化和反序列化时不一致就会导致反序列化失败,会抛异常提示版本号不一致, 特点 JDK序列化会把对象类的描述和所有属性的元数据都序列化为字节流 Serialization[2] 而且,和JDK自带序列化不同的是,如果一个对象之前出现过,hessian会直接插入一个R index这样的块来表示一个引用位置,从而省去再次序列化和反序列化的时间。 //hessian.caucho.com/doc/hessian-serialization.html [2] Serialization: http://hessian.caucho.com/doc/
1.什么是序列化和反序列化 内存中的字典、列表、集合以及各种对象,如何保存到一个文件中? 如果是自己定义的类的实例,如何保存到一个文件中? ;可以将数据序列化后持久化,或者网络传输; 也可以将从文件中或者从网络接收到的字节序列反序列化; 2.pickle库 python中的序列化、反序列化模块; dumps 对象序列化为bytes对象; dump : pickle.dump(99, f) pickle.dump(“aa”, f) pickle.dump([“a”, “b”, “c”], f) pickle.dump({“a”: 1, “b”: 2, <class ‘int’> 99 # <class ‘str’> aa # <class ‘list’> [‘a’, ‘b’, ‘c’] # <class ‘dict’> {‘a’: 1, ‘b’: 2, 一般来说,本地序列化的情况,应用较少,大多数场景都应用在网络传输中;将数据序列化后通过网络传输到远程节点,远程服务器上的服务将接收到的数据反序列化后,就可以使用了;但是要注意一点,远程接收端,反序列化时必须有对应的数据类型