Skip to content

Java代码审计-反序列化

描述

一般来说,把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。与PHP反序列化漏洞一样,一旦用户输入的不可信数据进行了反序列化操作,那么就有可能触发序列化参数中包含的恶意代码。这个非预期的对象产生过程很有可能会带来任意代码执行,以便攻击者做进一步的攻击。在Java中反序列化漏洞之所以比较严重的原因之一是:Java存在大量的公用库,例如Apache Commons Collections。而这其中实现的一些类可以被反序列化用来实现任意代码执行。WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些应用的反序列化漏洞能够得以利用,便是依靠了Apache Commons Collections。当然反序列漏洞的根源并不在于公共库,而是在于Java程序没有对反序列化生成的对象的类型做限制。Java反序列化漏洞一般有以下几种危害:任意代码执行,获取SHELL,对服务器进行破坏。

审计技巧

  • 查找用于解析的类库(xml、yml、json等),XMLDecoder.readObjectYaml.loadXStream.fromXMLObjectMapper.readValueJSON.parseObject追踪方法调用栈然后考虑参数是否可控,以及应用的Class Path中是否包含Apache Commons Collections等危险库(ysoserial所支持的其他库亦可)。同时满足了这些条件后,我们便可直接通过ysoserial生成所需的命令执行的反序列化语句。

利用链

利用链通常分为三部分,触发点、中继点、执行点。

  • 触发点
  • 触发点比较简单,主要是readObj

  • 中继点

  • 动态代理

    相关知识可参考Java动态代理

    要实现动态代理需要有三个类:

    • 委托类

    ​ 委托类就是处理业务逻辑的类,动态代理的目的就是在委托类中的代码运行时插入其他的操作,如日志打印。此外,委托类必须实现某个接口。

    • 中介类

    中介类是对InvocationHandler接口的实现,它持有一个委托类对象的引用,在代理类调用相关方法时,会劫持到中介类的invoke方法中,在插入操作后,通过反射调用委托类的方法。

    • 代理类

    代理类通过Proxy.newProxyInstance来创建,返回类型是委托类所实现的接口的类型。其他类会调用代理类来获取相应的功能,委托类是透明的。

  • 执行点

反序列化利用链的挖掘比较困难的点是反序列化执行点,有了反序列化执行点,一般情况下都可以挖掘出不止一条的利用连。所以反序列化执行点应该是整个利用链首先关注的。

常见执行命令的方式:

  • 反射利用Runtime.getRuntime().execjava.lang.ProcessBuilder执行
  • JNDI远程调用
  • Templates执行字节码
  • EL表达式
  • 其他可执行命令的接口

防御方式

黑白名单

  • 在readObject反序列化时首先会调用resolveClass读取反序列化的类名,可以通过重写ObjectInputStream对象的resolveClass方法即可实现对反序列化类的校验。

  • 第三方扩展:

https://github.com/ikkisoft/SerialKiller

https://github.com/Contrast-Security-OSS/contrast-rO0

  • Java 9包含了支持序列化数据过滤的新特性,开发人员也可以继承java.io.ObjectInputFilter类重写checkInput方法实现自定义的过滤器,并使用ObjectInputStream对象的setObjectInputFilter设置过滤器来实现反序列化类白/黑名单控制。

将输入内容进行编码

将输入的内容用用户无法猜测的方式进行编码或对称加密然后再发送到后端,但是在哪一步加密是一个问题,如果在前端,就有加密算法被破解的风险。

禁止用户输入反序列化数据

受实际业务需求的影响非常大,不能作为一种通用的修复手段。由此看来,黑白名单仍然是最常用的防御手段。

参考地址

Java 反序列化漏洞始末(1)— Apache Commons

浅析Java序列化和反序列化

https://github.com/Cryin/Paper/blob/master/%E6%B5%85%E8%B0%88Java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E4%BF%AE%E5%A4%8D%E6%96%B9%E6%A1%88.md

Java反序列 Jdk7u21 Payload 学习笔记

FastJson反序列化的前世今生

java反序列化RCE回显研究

山石JavaWeb靶场的反序列化相关页面,具体代码见com.hillstone.controller.deserialize

Comments