影响版本
Nexus Repository Manager OSS/Pro 3.6.2 版本到 3.14.0 版本
环境搭建
下载
https://help.sonatype.com/repomanager3/download/download-archives---repository-manager-3
https://sonatype-download.global.ssl.fastly.net/nexus/3/nexus-3.14.0-04-unix.tar.gz
Nexus 2下载:
https://download.sonatype.com/nexus/professional-bundle/nexus-professional-2.14.13-01-bundle.tar.gz
安装参考:
https://help.sonatype.com/learning/repository-manager-3/first-time-installation-and-setup/lesson-1%3A--installing-and-starting-nexus-repository-manager
在windows上安装成功了。需要执行
|
默认密码:admin/admin123
payload:
|
关键文件通过github的diff找到了,但是没有深入分析,另外的搭建环境的坑是,这个漏洞需要有assets才能执行后续的jexl表达式。自己搭建环境的时候并没有assets,所以没有触发。在windows上搭建环境,并后台登录之后上传assets之后成功执行。
Mac使用docker搭建环境:
如果执行ping或者touch之类的,不会在log中输出,如果执行一个不存在的命令则会抛出异常:
https://pastebin.com/raw/tUFYC0yf
tips:以后可以通过这个来找到漏洞触发点或者调用流程。
Windows下:
复现参考:
https://www.anquanke.com/post/id/171116
https://xz.aliyun.com/t/4136
流程分析
环境搭建(启动jdwp,并在idea中进行远程调试)
在虚拟机中ubuntu-18.04-server搭建nexus运行环境,
在宿主机Mac上使用Idea与虚拟机通信。
第一步,修改nexus的配置:
|
在默认配置的最后一行加上:
|
其中address=12346
为指定的端口号
然后启动nexus
第二步,参考:https://stackify.com/java-remote-debugging/
去Github clone下Nexus-public源码,
然后在Idea中设置如下:
|
然后修改服务器的IP和端口:
然后点击右上角绿色按钮,开启调试。
开启之后会建立连接:
第三步,使用burp构造请求。
把请求弄成json呈现,便于观看,可以知道,在filter的值是一个数组,数组的每个元素是一个字典,每个字典有键值对。property,value。
大致流程
首先入口是哪里,为什么是DelegatingFilter#doFilter
。通过找配置文件,发现etc/jetty/jetty.xml
配置文件中指定了
然后在nexus-web.xml中指定了任意请求对应的过滤器为:org.sonatype.nexus.bootstrap.osgi.DelegatingFilter
。
org/sonatype/nexus/coreui/ComponentComponent.groovy#previewAssets
只要
|
中有一个为空,则返回null了。
进入org/sonatype/nexus/repository/security/RepositorySelector.fromSelector()
这里有
|
可以发现selector也不能为null(这里是*),所以进入53行的new中。
由于我们指定了type为jexl,所以进入198行。
|
在org/sonatype/nexus/selector/JexlExpressionValidator#validate
中
进入48行,即将expression传进去,new一个org/sonatype/nexus/selector/JexlSelector
由于expression不为空,isNullOrEmpty(expression)
返回false,所以执行
|
看这句吧:
|
threadLocalJexl是一个new出来的ThreadLocal<JexlEngine>
对象,而且重写了initialValue()
方法。
在initialValue()
方法中,调用了静态变量jexlBuilder,~/.m2/repository/org/apache/commons/commons-jexl3/3.0/commons-jexl3-3.0.jar!/org/apache/commons/jexl3/JexlBuilder#create
,看看create()方法:
new了一个~/.m2/repository/org/apache/commons/commons-jexl3/3.0/commons-jexl3-3.0.jar!/org/apache/commons/jexl3/internal/Engine
,构造器又不传参,没有仔细看,
以上就是
|
这句的结果,得到一个Engine对象,然后接着org/apache/commons/commons-jexl3/3.0/commons-jexl3-3.0.jar!/org/apache/commons/jexl3/internal/Engine#createExpression
调用
|
trimSource()看名字应该就只是清理了一下空格,然后payload从expression转移到了source。然后调用
|
这个洞当时感觉看的有点多了,今天博哥又认真调了一波,我收博哥鼓舞,又自己回家调试了一下,才按照那个调用栈跟到了下面这些:
7月18日更新
|
调用这一句之后
|
然后通过这一句,在xxx外面加上了“and (xxx)”
变成
|
一步一步,构造sql语句
拼接完之后
然后进入我们关键的
|
这句com/orientechnologies/orientdb-core/2.2.36/orientdb-core-2.2.36.jar!/com/orientechnologies/orient/core/sql/OCommandSQL#OCommandSQL(String iText)
然后执行其父类构造器
其父类只是判断了一下非空,然后trim了一下
以上是
new OCommandSQL(query)
然后db.command(new OCommandSQL(query))
也没啥东西,
关键是后面那句
|
parameters才是payload啊!
在execute中
在这里com/orientechnologies/orientdb-core/2.2.36/orientdb-core-2.2.36.jar!/com/orientechnologies/orient/core/sql/OCommandExecutorSQLSelect#execute
将com.orientechnologies.orient.core.command.OCommandContext中的key为jexlExpression的value设置为payload:
|
然后是接着构造查询语句的其余部分
this.serialIterator(iTarget)中
进入这一行
com/orientechnologies/orientdb-core/2.2.36/orientdb-core-2.2.36.jar!/com/orientechnologies/orient/core/sql/OCommandExecutorSQLResultsetAbstract#filter中,前面没啥,看最后一句return语句
|
其中this.function就是contentExpression()这个函数!!!
所以应该是这里判断,若没有仓库,则直接log.error然后返回false。
(所以如果没有仓库,就不可能有文件,因为文件是放到某个仓库下的,就直接返回false了)
又跟到了这里org/sonatype/nexus/selector/JexlSelector#evaluate
然后就是枯燥的解析表达式了
|
真的是跟的最深的一个漏洞!
弹计算器六个六个的弹,怀疑还有其他地方也触发了?或者是多线程的原因?
[外链图片转存失败(img-lwrD8blU-1563467646666)(https://xzfile.aliyuncs.com/media/upload/picture/20190719003339-cc30e410-a979-1.gif)]
其实没有跟完全,
|
经过一顿invokeMethods之类的,
终于进入了ComponentComponent.groovy
的previewAssets
方法。
//略
发现执行不止一次,这就是为什么弹计算器的时候不止一个对话框。
最终调用JexlSelector的evaluate方法进行的代码执行
调试
最终得到的sql语句为:
|
参考
- https://www.lucifaer.com/2019/02/19/Nexus%20Repository%20Manager%203%20%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%EF%BC%88CVE-2019-7238%EF%BC%89/
- https://www.anquanke.com/post/id/171116
- https://chybeta.github.io/2019/02/18/Nexus-Repository-Manager-3-RCE-%E5%88%86%E6%9E%90-%E3%80%90CVE-2019-7238%E3%80%91/
- https://support.sonatype.com/hc/en-us/articles/360017310793-CVE-2019-7238-Nexus-Repository-Manager-3-Missing-Access-Controls-and-Remote-Code-Execution-February-5th-2019
- https://mp.weixin.qq.com/s/P1KC7wadbEZbHvavYQjbVA