当前位置:首页 > 娱乐

反序列漏洞

2015年,反序Apache Commons Collections 爆出一个反序列化漏洞,列漏WebLogic、反序JBoss、列漏Jenkins 全中招。反序攻击者构造一段恶意序列化数据,列漏目标服务器反序列化时直接执行任意代码。反序这不是列漏某个框架的疏忽,而是反序 Java 序列化机制本身的设计缺陷。

序列化是列漏什么?把对象转成字节流,方便存储或传输。反序反序列化就是列漏反过来,把字节流还原成对象。反序问题出在还原过程——Java 允许在 readObject() 方法里写自定义逻辑,列漏而很多库的反序类恰好在这个方法里做了危险操作,比如反射调用任意方法、执行系统命令。

攻击链的核心叫“gadget chain”。单看每个类都没问题,但把它们串起来,就能从反序列化入口一路走到 Runtime.exec()。Commons Collections 里的 InvokerTransformer 可以反射调用任意方法,ChainedTransformer 把多个 Transformer 串成链,再配合 AnnotationInvocationHandler 的 readObject 触发——整条链就跑通了。ysoserial 这个工具把这些链都集成好了,选个 payload 直接生成攻击数据。

我见过一个真实案例。某企业内部系统用了存在漏洞的 Commons Collections 3.2.1,攻击者通过一个上传接口把序列化数据塞进 session 文件,服务器重启后加载 session 触发反序列化,直接拿到 shell。日志里只留下一行 java.io.InvalidClassException,运维根本没当回事。

为什么反序列化漏洞这么难防

它不像 SQL 注入那样有明确的输入点。反序列化的入口可能藏在 cookie、session、RMI、JMS、缓存文件、甚至 HTTP 请求头里。你永远不知道下一个触发点在哪。Java 生态里序列化用得又极其广泛,从框架到中间件,几乎无处不在。

黑名单机制基本没用。今天封了 Commons Collections,明天又冒出 Spring、Groovy、BeanShell 的新链。白名单稍微靠谱,但业务复杂时根本列不全。Oracle 在 JDK 里加过序列化过滤器,但默认配置太宽松,效果有限。

怎么处理

最直接的办法:不用 Java 原生序列化。换成 JSON、Protobuf、MessagePack,从根上绕开这个问题。如果必须用,在 ObjectInputStream 上覆盖 resolveClass 方法,做类名白名单校验。WebLogic 后来就是这么修的。

另一个思路是 JEP 290 引入的序列化过滤机制。通过 jdk.serialFilter 系统属性或 ObjectInputFilter 接口,在反序列化时拦截非法类。但配置需要细粒度调优,搞不好会误杀正常业务。

还有个笨办法但有效:把反序列化操作跑在低权限沙箱里。就算被绕过了,攻击者也拿不到高权限。不过沙箱逃逸漏洞也不少,只能算纵深防御的一层。

反序列化漏洞的本质是信任边界模糊。你以为只是还原一个对象,实际上是在执行一段代码。只要 Java 序列化机制不改,这类漏洞就会一直存在。开发者能做的,就是尽量别用它,非用不可时把过滤做严。

分享到: