当前位置:首页 > 综合

shiro反序列化漏洞原理

Shiro反序列化漏洞原理

Apache Shiro框架里有个“记住我”功能,序列用户登录后勾选它,化漏服务端会生成一个加密的洞原cookie。这个cookie里存的序列就是序列化后的用户对象。问题出在加密用的化漏密钥——如果密钥是硬编码的或者太弱,攻击者就能自己构造恶意cookie。洞原

2016年那次爆出的序列Shiro-550漏洞,密钥是化漏默认的`kPH+bIxk5D2deZiIxcaaaA==`。这个密钥在官方文档里躺着,洞原谁都能看到。序列你猜怎么着?化漏直到今天,互联网上还有大量系统用着这个默认密钥。洞原我见过一些银行内部系统,序列扫描时直接命中这个漏洞,化漏运维人员一脸茫然。洞原

攻击流程其实不复杂。攻击者先拿到一个合法cookie,反序列化出来看看结构。Shiro用的是Java原生序列化,对象里有`PrincipalCollection`接口的实现类。攻击者替换成恶意构造的`SimplePrincipalCollection`,里面塞进一个`CommonCollections6`这样的 gadget链。然后重新用默认密钥加密,打回去。

服务端收到cookie后,先解密——密钥对了,解密成功。然后反序列化——这一步就炸了。恶意对象在readObject()时触发链式调用,最终执行`Runtime.exec()`。整个过程不需要任何认证,只要目标系统暴露了登录接口。

这里有个关键点:Shiro的RememberMe cookie是独立的,不依赖session。所以即使目标系统开启了严格的会话管理,这个漏洞照样能打。我做过测试,把tomcat的session超时设成30秒,攻击完全不受影响。

修复方式也简单粗暴——升级到1.4.2以上版本,或者自己设置随机密钥。但现实是,很多系统改不了密钥,因为一改,所有已登录用户的rememberMe cookie全部失效。业务方不乐意,运维就拖着。拖到后来,就成了永恒漏洞。

还有个变种是Shiro-721,利用Padding Oracle攻击。这个更麻烦,不需要知道密钥,通过不断提交密文观察响应差异,逐字节还原出明文。虽然慢,但能打穿动态密钥的系统。不过这个利用条件苛刻,需要拿到一个合法cookie,而且目标响应时间要稳定。

说到底,这类漏洞的本质是“信任了不该信任的输入”。Shiro把密钥当成了安全边界,却没意识到密钥泄露后,整个序列化机制就裸奔了。Java反序列化本身就像个潘多拉魔盒,一旦开了口,什么都能往里塞。

现在很多新框架改用JSON序列化,但遗留系统里Shiro还是主力。每次扫内网,都能看到几个命中这个漏洞的IP。修不修,全看安全团队能不能说服业务方接受一次“强制下线”。

分享到: