最后更新于2023年8月10日星期四20:54:46 GMT

2023年7月11日,Rapid7和Adobe disclosed CVE-2023-29298, 一个影响ColdFusion的访问控制绕过漏洞, Rapid7在2023年4月向Adobe报告的数据. 该漏洞允许攻击者绕过限制外部访问ColdFusion Administrator的产品功能. Rapid7和Adobe认为CVE-2023-29298在发布我们的 协调披露 (Rapid7在我们的披露中明确指出,我们没有测试Adobe发布的补丁).

在审查了ColdFusion 2021 Update 8中发现的CVE-2023-29298补丁后.0.08.330144), Rapid7发现,7月11日发布的补丁并不能成功修复原始问题,并且可以被攻击者绕过. Adobe 指定的cve - 2023 - 38205 并于2023年7月19日发布了完整的修复程序.

Rapid7已经在多个客户环境中观察到CVE-2023-29298漏洞的利用. Our team published a blog 并于7月17日对客户进行了观察和指导. 我们已经验证了 7月19日发布新补丁 完全修复这个问题.

Affected products

以下产品容易受到攻击 CVE-2023-38205:

  • Adobe ColdFusion 2023 Update 2及更早版本
  • Adobe ColdFusion 2021 Update 8及更早版本
  • Adobe ColdFusion 2018 Update 18及更早版本

Credit

这个问题是由微软首席安全研究员Stephen less发现的 Rapid7,并根据 Rapid7的漏洞披露策略.

Vendor Statement

Adobe向Rapid7提供了以下声明:
Adobe建议将ColdFusion安装更新到最新版本. Please see APSB23-47 for more information. Adobe意识到CVE-2023-38205已经在针对Adobe ColdFusion的有限攻击中被利用."

Analysis

7月11日针对CVE-2023-29298的补丁修改了攻击方法 IPFilterUtils.checkAdminAccess 使用新的助手方法 Utils.canonicalizeURI 在执行访问控制之前将URL转换为规范形式,如下所示.

  private static final String[] RESTRICTED_INTERNAL_PATHS = new String[] {"/restplay", "/cfide/restplay", “cfide /管理员”, "/cfide/adminapi", "/cfide/main", “/ cfide / componentutils”, "/cfide/wizards", “/ cfide / servermanager”, “cfide /锁定”};


  checkAdminAccess(HttpServletRequest)
    String uri = Utils.getServletPath(要求的);
    uri = Utils.canonicalizeURI(uri.toLowerCase()); // <----
    for (String limittedpath: RESTRICTED_INTERNAL_PATHS) {
      if (uri.startsWith (restrictedPath)) {
        String ip = req.getRemoteAddr();
        if (!isAllowedIP(ip))
          抛出新的AdminAccessdeniedException.getSecurityService().getAllowedAdminIPList()、ip);
        break;
      }
    }
  }


The method Utils.canonicalizeURI尝试删除字符序列,比如重复的正斜杠, 双点表示法和冗余的点路径段在url路径, as shown below.

  公共静态字符串canonicalizeURI(字符串uri) {
    如果(uri == null || uri.length() == 0)
      return uri;
    uri = uri.replace('\\', '/');
    uri = trimduplicateslash (uri);
    uri = collapseDotDots(uri); // <----
    uri = trimTrailingDotsSpacesNull(uri);
    if (uri.charAt(0) == '.')
      uri = uri.substring(1);
    Uri = substitute(Uri, "/ ")./", "/");
    if (uri.endsWith("/."))
      uri = uri.substring(0, uri.length() - 2);
    if (uri.length() == 0)
      uri = "/";
    return uri;
  }

值得注意的是Utils方法.collapseDotDots, 哪个将删除所有包含双点的路径段以及前面的路径段. 例如,如果URL路径包含字符串“/hello/”../world/”则方法Utils.通过删除字符序列“/hello/”,collapseDotDots将正确地将此字符串转换为“/world/”..,通过调用StringBuffer.删除如下所示.

  public static String collapseDotDots(String str) {
    if (str.indexOf("/..") == -1)
      return str;
    StringBuffer sb = new StringBuffer(str);
    int i;
    while ((i = str.indexOf("/..")) != -1) {
      int分段start = str.lastIndexOf('/', i - 1);
      sb.delete(segmentStart, i + 3); // <----
      str = sb.toString();
    }
    if (str.length() == 0)
      str = "/";
    return str;
  }  

The method Utils.canonicalizeURI 尝试删除字符序列,如重复的正斜杠, 双点表示法和冗余的点路径段在url路径, as shown below.

  公共静态字符串canonicalizeURI(字符串uri) {
    如果(uri == null || uri.length() == 0)
      return uri;
    uri = uri.replace('\\', '/');
    uri = trimduplicateslash (uri);
    uri = collapseDotDots(uri); // <----
    uri = trimTrailingDotsSpacesNull(uri);
    if (uri.charAt(0) == '.')
      uri = uri.substring(1);
    Uri = substitute(Uri, "/ ")./", "/");
    if (uri.endsWith("/."))
      uri = uri.substring(0, uri.length() - 2);
    if (uri.length() == 0)
      uri = "/";
    return uri;
  }

值得注意的是方法Utils.collapseDotDots`, 哪个将删除所有包含双点的路径段以及前面的路径段. 例如,如果URL路径有字符串' " /hello/../world/ " '然后方法' Utils.通过删除字符序列“/hello/”,collapseDotDots '将正确地将此字符串转换为' " /world/ " '..' '通过调用' StringBuffer.删除',如下所示.

  public static String collapseDotDots(String str) {
    if (str.indexOf("/..") == -1)
      return str;
    StringBuffer sb = new StringBuffer(str);
    int i;
    while ((i = str.indexOf("/..")) != -1) {
      int分段start = str.lastIndexOf('/', i - 1);
      sb.delete(segmentStart, i + 3); // <----
      str = sb.toString();
    }
    if (str.length() == 0)
      str = "/";
    return str;
  }  

而以上是正确的, 它暴露了ColdFusion在解析到端点的路径时如何处理ColdFusion模块(CFM)和ColdFusion组件(CFC)端点的问题. 如果攻击者访问的URL路径为 “/hax/..CFIDE /术士/共同/跑龙套.cfc” 可以绕过访问控制,仍然可以到达预期的端点, 即使它不是一个有效的URL路径 (注意,在双点之后和CFIDE之前没有预期的正斜杠).

处理此路径后,方法 Utils.collapseDotDots 将转型之路引向 “cfide /向导/共同/跑龙套.cfc” 通过删除双点路径段和前面的段“/hax/..”. The path “cfide /向导/共同/跑龙套.cfc” 将不会与RESTRICTED_INTERNAL_PATHS中的任何受限路径匹配 IPFilterUtils.checkAdminAccess 因为它不再以正斜杠开头. 这绕过了访问控制. 但是,底层Servlet仍将处理该路径 “/hax/..CFIDE /术士/共同/跑龙套.cfc”,允许调用预期的CFC端点. CFM端点也是如此.

Exploitation

以下是在Adobe ColdFusion 2021 Update 8(2021 .)上进行的测试.0.08.330144)在Windows Server 2022上运行,并配置了生产和安全配置文件.

我们可以通过使用cURL命令来演示补丁绕过. 对象上执行远程方法调用时 / CFIDE向导/共同/跑龙套.cfc endpoint, 可以使用以下cURL命令-注意使用双点表示法,如下所示:

注:与符号(&)已经用插入符号(^)转义,因为这个例子是从Windows运行的, 在Linux上,必须用正斜杠(\)转义与符号。.

c:\> curl -ivk --path-as-is http://172.25.25.0:8500/hax/..CFIDE /术士/共同/跑龙套.cfc?method=wizardHash^&inPassword=foo

我们可以看到CVE-2023-29298的访问控制和补丁都被绕过了,请求成功完成.

Remediation

Adobe于2023年7月19日发布了此漏洞的修复程序. 下面的版本修复了这个问题 Adobe’s advisory:

  • Adobe ColdFusion 2023更新
  • Adobe ColdFusion 2021更新
  • Adobe ColdFusion 2018更新19

自从Rapid7观察到在野外的开发, 我们强烈建议ColdFusion客户尽快更新到最新版本, 无需等待典型的补丁周期发生.

Timeline

  • 4月11日至7月10日, 2023年:Rapid7向Adobe披露CVE-2023-29298, Rapid7和Adobe协调披露
  • 2023年7月11日:Rapid7和Adobe disclose CVE-2023-29298 publicly
  • July 13 - 15, 2023年:Rapid7检测到Adobe ColdFusion在野外的利用, 确定攻击者正在利用以远程代码执行结束的漏洞利用链
  • 2023年7月17日:Rapid7警告客户 ColdFusion剥削 in the wild. Rapid7发现CVE-2023-29298的补丁可以绕过,并通知Adobe. Adobe通知Rapid7他们修复补丁绕过的意图.
  • 2023年7月19日:这个 disclosure.