10

Apache OFBiz CVE-2021-29200 简要分析

 3 years ago
source link: https://xz.aliyun.com/t/9556
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Apache OFBiz CVE-2021-29200 简要分析

Apache OFBiz CVE-2021-29200 简要分析

r00t4dm / 2021-05-10 17:25:27 / 浏览数 740 安全技术 漏洞分析 顶(0) 踩(0)

本文作者:r00t4dm@Cloud-Penetrating Arrow Lab & Longofo@知道创宇404实验室

OFBiz PMC针对CVE-2021-26295漏洞修复的commit如下:

@Override
    protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
        String className = classDesc.getName();
        // BlackList exploits; eg: don't allow RMI here
        if (className.contains("java.rmi.server")) {
            Debug.logWarning("***Incompatible class***: "
                    + classDesc.getName()
                    + ". java.rmi.server classes are not allowed for security reason",
                    "SafeObjectInputStream");
            return null;
        }
        if (!whitelistPattern.matcher(className).find()) {
            // DiskFileItem, FileItemHeadersImpl are not serializable.
            if (className.contains("org.apache.commons.fileupload")) {
                return null;
            }
            Debug.logWarning("***Incompatible class***: "

我提交给OFBiz社区的利用方式是RemoteObjectInvocationHandler作为JRMPClient,这个补丁代码也刚好解决了RemoteObjectInvocationHandler作为JRMPClient的利用方式,并分配了CVE-2021-26295。

令我感兴趣的是当检测到敏感对象时它并不是抛出异常,而是返回null,我询问了PMC并得到这样的答复

That's purely syntactic (proof it works as is). I used null for a reason and I have to check what it entails to replace null by an exception. Else I'd be happy to replace it

这种返回null的修复方式本身是没有问题的,只是检测边界需要扩大,如果检测边界不变那必须抛出异常。
所以这个补丁的代码是存在问题的,通过使用java.下的代码可以绕过白名单。

private static final String[]DEFAULT_WHITELIST_PATTERN= {
        "byte\\[\\]", "foo", "SerializationInjector",
        "\\[Z", "\\[B", "\\[S", "\\[I", "\\[J", "\\[F", "\\[D", "\\[C",
        "java..*", "sun.util.calendar..*", "org.apache.ofbiz..*",
        "org.codehaus.groovy.runtime.GStringImpl", "groovy.lang.GString"};

接着需要找一个符合白名单并且是远程对象的类,通过使用LiveRef打开通道,值得注意的是sun.rmi.server.UnicastRef是连接的抽象或者封装,所以这里可以直接使用sun.rmi.server.UnicastRef即可。

我第二次交给OFBiz社区的利用对象是javax.management.remote.rmi.RMIConnectionImpl_Stub,因为javax.management.remote.rmi.RMIConnectionImpl_Stub符合白名单正则表达式,又由于反序列化的递归性质,父类反序列化为空不影响子类反序列化流程,所以使用javax.management.remote.rmi.RMIConnectionImpl_Stub可以绕过这个补丁。

后续我针对这个问题给官方提供的补丁代码是

if (className.contains("java.rmi.server")) {
            Debug.logWarning("***Incompatible class***: "
                    + classDesc.getName()
                    + ". java.rmi.server classes are not allowed for security reason",
                    "SafeObjectInputStream");
//            return null;
            throw new InvalidObjectException("no safe!!" + className);
        }

并要求OFBiz社区关闭SOAP和HTTPEngine的入口,我想这个Endpoint应该不会有问题了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK