WebLogic Server 10.3.6.0
WebLogic Server 12.1.3.0
漏洞代码位于weblogic.jar中weblogic.wsee.jaxws.persistence.PersistentContext.class文件,它的readObject函数调用了readSubject函数,readSubject函数中使用了ObjectInputStream.readObject来反序列化对象。
查看对应的writeObject的逻辑,只要我们给对应的localObjectOutputStream.writeObject()序列化一个恶意对象,则PersistentContext对象被反序列化时,它的readObject函数被调用,readSubject函数中对恶意对象进行反序列化。因此通过T3发送精心伪造的PersistentContext对象,则可成功绕过黑名单检查。
为了让writeObject函数中的localObjectOutputStream.writeObject()序列化一个恶意对象,我们直接对PersistentContext类进行修改。
打开idea新建一个项目,引入需要的Jar文件。在项目中新建一个package,名为weblogic.wsee.jaxws.persistence,在这个包下创建PersistentContext.class文件,复制原来的内容进行修改。
我们在PersistentContext.class文件中新增一个getObject()函数,用于获取恶意对象。然后把localObjectOutputStream.writeObject()函数的参数替换。
然后在项目中创建一个Poc.class文件,新建PersistentContext对象对其进行序列化操作,序列化后存储到poc文件中。
此时我们使用T3发送payload发现靶机日志提示报错:
根据报错提示定位到代码,发现readSubject函数中有个解密过程:
此时我们再次检查writeSubject函数,猜测序列化时加密没有成功,导致反序列化时解密报错:
跟进加密函数:
由于我们idea建立的项目中没有SerializedSystemIni.dat文件,直接返回null,因此加密没有成功,导致反序列化失败。
因此我们需要修改writeSubject()函数,但由于getEncryptionService属性为private,需再新建EncryptionUtil.class文件,把getEncryptionService()函数属性改成public:
并且把SerializedSystemIni.dat文件复制到我们idea项目中。由于SerializedSystemIni.dat是密钥文件,各不相同且无法猜解,这里也就是这个漏洞需要身份认证的原因。
此时再测试发送payload,可爱的计算器成功弹出。
1、禁用 T3 协议:如果您不依赖 T3 协议进行JVM通信,可通过暂时阻断 T3 协议缓解此漏洞带来的影响。
2、排查弱口令