CodeQL与Shiro550碰撞

💡 原文中文,约15600字,阅读约需38分钟。
📝

内容提要

本文探讨了Shiro550反序列化漏洞利用中,如何绕过CommonsBeanutils依赖限制。作者通过CodeQL分析,发现JDK内置的AttrCompare和String.CASE_INSENSITIVE_ORDER类可替代原Comparator,并测试了第三方组件如log4j的PropertySource.Comparator和Commons-lang的ObjectToStringComparator。文章提供了具体利用代码,并指出在存在CommonsBeanutils组件时,Shiro550漏洞几乎必然可利用,最后讨论了serialVersionUID版本兼容问题。

🔎

延伸解读

绕过依赖限制的两种JDK内置替代方案

文章指出,在Shiro550利用中,若目标环境缺少CommonsCollections依赖,可使用JDK内置的String.CASE_INSENSITIVE_ORDER或AttrCompare作为BeanComparator的比较器。其中AttrCompare的compare方法接收Attr接口类型,需通过AttrNSImpl实例化;而String.CASE_INSENSITIVE_ORDER则直接可用。这两种方案均无需额外依赖,但需注意构造参数类型匹配。

第三方组件中的潜在替代比较器

作者测试了43个开源项目,发现15个存在可替代的比较器,并重点分析了log4j-api的PropertySource.Comparator和Commons-lang的ObjectToStringComparator。前者compare方法接收PropertySource类型,需实现该接口;后者参数为Object类型,使用更简单。这些发现扩大了Shiro550的利用面,但需确保目标环境包含相应组件。

serialVersionUID版本兼容问题

文章强调,不同版本的CommonsBeanutils可能因serialVersionUID不同导致反序列化失败。作者在集成工具时遇到此问题,并指出目前难以自动判断目标版本,只能通过盲打逐个尝试。此外,CommonsBeanutils 1.9.2虽增加了防护机制,但默认未启用,因此高版本仍存在漏洞,但利用时需注意版本差异。

Q&A

Shiro550漏洞利用中,如何绕过CommonsBeanutils依赖限制?

通过CodeQL分析,找到JDK内置的AttrCompare和String.CASE_INSENSITIVE_ORDER类,以及第三方组件如log4j的PropertySource.Comparator和Commons-lang的ObjectToStringComparator,替代原CommonsBeanutils中的ComparableComparator,从而在无CommonsCollections依赖的情况下构造利用链。

CodeQL在Shiro550漏洞研究中发现了哪些可替代ComparableComparator的JDK内置类?

在JDK8u中,CodeQL共发现7个可替代类,但可直接实例化的只有两个:String.CASE_INSENSITIVE_ORDER和AttrCompare,其余5个类权限为private,只能通过反射调用。

AttrCompare类在Shiro550利用中如何使用?

AttrCompare是JDK内置类,位于com.sun.org.apache.xml.internal.security.c14n.helper包,其compare方法接受Attr类型参数。利用时需使用Attr接口的实现类AttrNSImpl,通过setValues方法初始化,然后作为BeanComparator的比较器传入,构造PriorityQueue触发漏洞。

String.CASE_INSENSITIVE_ORDER在Shiro550利用中如何使用?

String.CASE_INSENSITIVE_ORDER是JDK内置的字符串比较器,可直接作为BeanComparator的比较器。利用时,PriorityQueue初始添加两个字符串(如"1"),然后通过反射将队列元素替换为TemplatesImpl对象,并将BeanComparator的property设置为"outputProperties",触发漏洞。

除了JDK内置类,还有哪些第三方组件中的类可用于Shiro550利用?

第三方组件中,log4j-api的PropertySource.Comparator和Commons-lang的ObjectToStringComparator也可作为比较器。作者测试了43个开源项目,其中15个存在可用类,但文章只详细介绍了这两个。

Shiro550漏洞在什么条件下几乎必然可利用?

在存在CommonsBeanutils组件(无论版本)且已知Shiro密钥的情况下,利用JDK内置的String.CASE_INSENSITIVE_ORDER或AttrCompare,Shiro550漏洞几乎必然可利用。

CommonsBeanutils 1.9.2版本是否修复了反序列化漏洞?

没有。1.9.2版本添加了特殊的BeanIntrospector类来阻止攻击者使用class属性访问classloader,但该保护默认未启用,因此默认情况下仍存在反序列化漏洞。

在Shiro550利用中,遇到不同版本的CommonsBeanutils时,serialVersionUID不一致问题如何解决?

文章指出,目前无法直接判断目标CommonsBeanutils版本,只能通过盲猜,逐个版本尝试,但这种方法耗时耗力。

🏷️

标签

➡️

继续阅读