weblogic T3协议的反序列化漏洞,因为这里涉及了weblogic自身的一些链,所以抛去t3协议来分析一下。这里主要的关注点集中在weblogic的反序列化链上。
环境
使用的环境是ismaleiva90/weblogic12的镜像,修改步骤和以前一样,需要开放8453端口,并且修改debugFlag为true,这里和网上给出的有点不一样,建议直接修改setStartupEnv.sh文件而不是修改setDomainEnv.sh文件。
exp使用的是BabyTeam1024的exp,但是这个exp也有点问题,需要做一定的修改。最根本的原因还是TreeMap在添加元素的时候会检测元素类型,估计是对不同版本的jdk兼容没做好。
还有一点需要注意的是,反序列化用的conherence.jar包需要和目标系统一致,不然调试的时候会出现一些奇奇怪怪的问题。
调试
整体调试流程
先把调整好的exp放在这里。
1 | System.out.println("[*] Attacking..."); |
启动完weblogic之后就手动运行CVE_2021_2394.java。
- 首先进入之后会触发AttributeHolder的反序列化,由于是继承了Externalizable的接口,所以实现的反序列化的是readExternal方法,这里会跟着反序列化m_oValue。
- TopNAggregator.PartialResult这里会把一些元素反序列化,调用SortedBag的add方法,并且把元素添加到NavigableMap(这里用的TreeMap)中。
- 跟入add方法,我们发现会对map进行一个put的操作,如果是TreeMap的话,每次调用put方法时的时候都会触发compartor。
- SortedBag的compare方法中会调用f_comparator的compare方法,这里的FilterExtractor和MethodAttributeAccessor是我们要关注的核心,FilterExtractor的compare方法中会调用一个extract方法,这个方法会反射调用配置好的get方法,从而达成反射调用JdbcRowSetImpl的connect方法。extract方法整体如下:
1 | public Object extract(Object obj) { |
- 其中attributeAccessor会初始化比较元素的,并且设置get和set方法,这些被准备好的方法,会在后续的流程中被反射调用get方法,这里的get和set方法有个限制就是,set方法的入参类型要和get方法的返回值类型一致,这点限制了很多反序列化slink点的生效。
1 | protected void initializeAttributes(Class theJavaClass, Class[] getParameterTypes) throws DescriptorException { |
- 完成初始化之后会调用getAttributeValueFromObject方法,这个方法最终会调用设置好的Method对象,从而达成反射执行方法的效果。
并最终的connect中触发lookup方法。
调用链小结
1 | AttributeHolder->readExternal(TopNAggregator.PartialResult) |
一个疑问
如何这里在步骤5中设置isWriteOnly为true,那是不是可以跳过设置set方法?如果可以的话,这意味着我们可以使用TemplatesImpl的getOutputProperties方法,这个方法是可以调用任意java代码的。但是事实是不行的。
因为FilterExtractor继承了ExternalizableLite接口,所以它的反序列化流程是走readExternal。
1 | public void readExternal(DataInput in) throws IOException { |
这里反序列化attributeAccessor用的是readAttributeAccessor,这里反序列化attributeAccessor时只会设置attributeName,getMethodName和setMethodName,writeOnly不能被反序列化,因此,这个思路不行,也正因为这个方法的存在导致MethodAttributeAccessor可以绕过反序列化中的黑名单。
1 | public static AttributeAccessor readAttributeAccessor(DataInput in) throws IOException { |
总结
这个链比较巧妙的地方就在于利用了FilterExtractor的readAttributeAccessor机制来绕过了黑名单对MethodAttributeAccessor的限制。但是也因为这个限制,导致只能使用jndi注入来完成rce。