Nexus Repository Manager历史表达式注入漏洞分析

百家 作者:平安安全应急响应中心 2021-11-01 22:35:15
Java表达式注入漏洞危害严重,通常会导致RCE,且在Java框架组件广泛存在。漏洞形成的本质原因是输入外部可控,导致被注入恶意表达式从而导致任意代码执行。Struts,SpringElasticsearch均爆出过该类漏洞。

我们最近对Nexus Repository Manager(又名NXRM,一款开源的仓库管理应用)的3个历史表达式注入漏洞进行了调试分析,现记录在此。


CVE-2018-16621


影响版本:

Nexus Repository Manager 3.x OSS / Pro <= 3.14.0


环境搭建:下载NXRM OSS

https://help.sonatype.com/repomanager3/download/download-archives---repository-manager-3

本文分析调试的版本是3.13.0-01,下载对应的版本,解压,之后./nexus start运行,默认账号密码:admin/admin123;

为了能够让IDE附加调试,在启动脚本nexus-3.13.0-01-mac/nexus-3.13.0-01/bin/nexus里添加参数:
1INSTALL4J_ADD_VM_PARAMS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5050"

下载 NXRM源码,并切换至 3.13.0-01 分支:


git clone https://github.com/sonatype/nexus-public.gitgit checkout -b release-3.13.0-01 origin/release-3.13.0-01


IDEA导入项目并在Run/Debug Configuration里面配置调试信息:


调试分析:


文章https://securitylab.github.com/research/bean-validation-RCE/指出:

It was soon clear that the root cause of the issue was that one of the properties of a user-controller Java Bean (coming from an HTTP request) was concatenated into a Bean Validation error message, and that this message was later processed and any EL expressions were evaluated and interpolated in the final violation message.

更具体的,在创建用户或角色进行校验时,对于不存在的privilege或role参数会抛出错误,且将privilege或role插入到了报错信息模版中,模版在渲染时会取出其中的表达式并解释执行;对privilege和role的校验分别对应在org.sonatype.nexus.security.privilege.PrivilegesExistValidator和org.sonatype.nexus.security.role.RolesExistValidator中。


漏洞poc如下:


RolesExistValidator#isValid()中调用context#buildConstraintViolationWithTemplate()处下断点,可看到roles参数被放入到报错信息模版中;


回到上层ConstraintTree#validateSingleConstraint(),在调用完RolesExistValidator#isValid()后,接着调用ValidationContext#createConstraintViolations(),参数constraintValidatorContext中包含roles参数;


ValidationContext#createConstraintViolations()继续调用ValidationContext#createConstraintViolation()


跟进ValidationContext#createConstraintViolation(),其调用了ValidationContext#interpolate(),messageTemplate包含roles参数;


ValidationContext#interpolate()继续调用ResourceBundleMessageInterpolator#interpolate()


ResourceBundleMessageInterpolator#interpolate()中,其调用ResourceBundleMessageInterpolator#interpolateMessage(),message包含roles参数;


继续跟进ResourceBundleMessageInterpolator#interpolateMessage(),调用ResourceBundleMessageInterpolator#interpolateExpression()来处理tokens;


ResourceBundleMessageInterpolator#interpolateExpression()调用InterpolationTerm#interpolate(),roles参数在expression中;


跟进InterpolationTerm#interpolate(),继续调用InterpolationTerm#interpolateExpressionLanguageTerm()


最后在InterpolationTerm#interpolateExpressionLanguageTerm()中通过valueExpression.getValue()执行表达式;


修复:


对比patch,新增了EscapeHelper#stripJavaEl()对用户输入正则匹配进行清理,将‘${’替换为‘{ ’,不过该修复方案之后被绕过,详见后文;



CVE-2020-10204


影响版本:

Nexus Repository Manager 3.x OSS / Pro <= 3.21.1

环境搭建:

参照CVE-2018-16621,本文分析调试的版本是3.21.1-01

调试分析:


CVE-2020-10204即是对CVE-2018-16621 patch的绕过;绕过的根本原因是stripJavaEl()中的正则不严谨,未考虑到"$"和"{"之间的字符,pwntester@GHSL发现Hibernate message interpolation parser (org.hibernate.validator.internal.engine.messageinterpolation.parser.TokenCollector)存在bug,使得形如FOO$\A{payload}这样的payload可被正常解析执行,但却绕过了该正则。

虽然版本3.21.1-01和3.13.0-01代码有所不同,但NXRM对参数的校验过程总体一致,故这里不再列出具体的执行步骤,可参考CVE-2018-16621调试分析;我们跟踪一下TokenCollector.parse()解析FOO$\A{payload}的过程;

当parser解析到$时,currentParserState类型为MessageState,调用MessageState#handleELDesignator();


由于interpolationTermType==EL,跳过$,currentParserState转变为ELState;


当parser解析到\\时,currentParserState类型为ELState,调用ELState#handleEscapeCharacter();


跳过\\,currentParserState转变为EscapedState;


当parser解析到A时,currentParserState类型为EscapedState,调用EscapedState#handleNonMetaCharacter();


将A追加到currentToken,currentParserState转变为前一State,即ELState;


当parser解析到{时,currentParserState类型为ELState,调用ELState#handleBeginTerm();


ELState#handleBeginTerm()会将currentToken(为Missing roles: [nx-adminA)加入到tokenList中,并创建空的currentToken,且追加${,currentParserState转变为InterpolationTermState;


parse结束后,tokenList={"Missing roles: [nx-adminA","${'vulnerability'.toUpperCase()}","]"}


修复:


增强了stripJavaEl()的正则匹配,但显然仍存在问题;


调试3.21.2发现,其使用org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator 来解析处理message,而在3.21.1中用到了org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;我们尝试找源码中对应的改动,但未找到。
 

CVE-2020-10199


影响版本:

Nexus Repository Manager 3.x OSS / Pro <= 3.21.1

环境搭建:

参照CVE-2018-16621,本文分析调试的版本是3.21.1-01

调试分析:


根据对CVE-2018-16621的分析可知,如果不可信数据被插入到报错信息模版,被当作参数传给了ConstraintValidatorContext.buildConstraintViolationWithTemplate(),那么极可能会被当作Java表达式执行;pwntester据此特征利用CodeQL对NXRM进行数据流分析,发现stripJavaEl()未被应用到类org.sonatype.nexus.validation.ConstraintViolationFactory。所以当用户可控数据流入createViolation(final String path, final String message) ,将会被当作Java EL执行。


跟踪源码发现 org.sonatype.nexus.repository.rest.api.AbstractGroupRepositoriesApiResource#validateGroupMembers() 在校验失败时调用 createViolation() ,并传入参数repositoryName。


AbstractGroupRepositoriesApiResource#validateGroupMembers()则被AbstractGroupRepositoriesApiResource#createRepository()和AbstractGroupRepositoriesApiResource#updateRepository()调用;


AbstractGroupRepositoriesApiResource有子类GolangGroupRepositoriesApiResource,其在创建仓库,更新仓库时分别调用了父类的createRepository()和updateRepository()

由文章https://www.cnblogs.com/magic-zero/p/12641068.html可知,根据接口文档,可构造出完整URL和数据包如下:


对AbstractGroupRepositoriesApiResource#validateGroupMembers()下断点,repositoryName正是构造的payload;


buildConstraintViolationWithTemplate()下断点,发现payload被插入到了错误信息模版;


修复:


同CVE-2020-10204一样,在3.21.2中修复。

参考

  • https://support.sonatype.com/hc/en-us/articles/360010789153-CVE-2018-16621-Nexus-Repository-Manager-3-Java-Injection-2018-10-17

  • https://support.sonatype.com/hc/en-us/articles/360044882533-CVE-2020-10199-Nexus-Repository-Manager-3-Remote-Code-Execution-2020-03-31

  • https://support.sonatype.com/hc/en-us/articles/360044356194-CVE-2020-10204-Nexus-Repository-Manager-3-Remote-Code-Execution-2020-03-31

  • https://www.cnblogs.com/magic-zero/p/12641068.html

  • https://paper.seebug.org/1166/

  • https://securitylab.github.com/research/bean-validation-RCE/

  • https://securitylab.github.com/advisories/GHSL-2020-020-hibernate-validator/

  • https://securitylab.github.com/advisories/GHSL-2020-011-nxrm-sonatype/



PSRC 公众号欢迎投稿!
请投稿至邮箱:pub_sec@pingan.com.cn

欢迎添加工作人员微信,

进入PSRC白帽子微信群,和其他白帽子交流技术!




【平安健康互联网】福利已到位,漏洞奖励会翻倍!


往期回顾


技术

【平安CTF赛题】解题思路总结

技术

D-Link 816-A2 路由器研究分享

技术

使用Ghidra P-Code对OLLVM控制流平坦化进行反混淆

技术

家用路由器D-LINK DIR-81漏洞挖掘实例分析

公告

防守方视角看漏扫——手把手教你定制自己的漏扫框架(POC部分)


长按识别二维码关注我们

微信号:PSRC_Team



球分享

球点赞

球在看


关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接