前言
今年8月份sonatype发了一个Nexus Repository Manager 2的内置Yum Repository插件远程命令执行漏洞预警通告,但是没有细节。最近hackerone才公开了漏洞细节,PoC已经公开。
漏洞描述
这里的Yum Repository插件是内置插件,但是需要admin权限才能执行命令。如果默认的admin/admin123
密码没有修改,则可能结合这一点实现命令执行。
漏洞点在于,Yum Repository插件提供了一个createrepo
和mergerepo
命令路径的功能,通过将用户输入的命令与--version
参数进行拼接后执行,用于判断用户提供的createrepo
或者mergerepo
路径的命令是否可用。而这个路径是可控的,可以是任意命令的路径。而且没有对用户输入的命令做过滤。
经测试,部署权限用户(deployment:deployment123
)不能执行命令,响应403 Forbidden
:
匿名用户(anonymous)会响应401 Unauthorized
:
需要admin权限才能触发此漏洞。
Nexus 2的权限管理参考:
https://my.oschina.net/guanzhenxing/blog/209600
DEMO
由于给用户提供的命令后面加了一个--version
,linux/unix下执行比较方便,而在Windows下可以使用C:/Windows/System32/cmd.exe /c tasklist&
来执行命令:
PoC
|
其中basic认证的凭据是admin:admin123
PoC还可以是json形式的(指定createrepoPath或mergerepoPath其中一个的value即可)。可参考:
https://github.com/shadowsock5/Poc/blob/master/nexes-manager/CVE-2019-5475.py
|
漏洞复现
Nexus 2下载:
https://download.sonatype.com/nexus/oss/nexus-2.14.13-01-bundle.zip
或者到这里找一个就行:
https://help.sonatype.com/repomanager2/download/download-archives---repository-manager-oss
注意不要下载pro版(需要license)。
调试参考:
https://blog.csdn.net/zhu19774279/article/details/8697633
修改nexus-2.14.13-01/bin/jsw/conf/wrapper.conf
文件增加调试参数,
取消注释掉这部分:
代码追踪
nexus-public/plugins/yum/nexus-yum-repository-plugin/src/main/java/org/sonatype/nexus/yum/internal/capabilities/YumCapability#validate:
nexus-public/plugins/yum/nexus-yum-repository-plugin/src/main/java/org/sonatype/nexus/yum/internal/task/CommandLineExecutor#exec:
最终调用org.apache.commons.exec.DefaultExecutor#execute
执行命令。
参考:
最终会将这个配置信息写到:../sonatype-work/nexus/conf/capabilities.xml
文件中,下次重启时会载入这个配置。若无法载入则会出错。
|
漏洞修复
下载官方的修复版2.14.14-01,发现修改了以下两个文件。
YumCapability.java
CommandLineExecutor.java
增加了一个关键的getCleanCommand
方法,用于对用户输入的命令进行过滤。
这里的command
为用户指定的命令。其中有两种情况(62行和72行)可以将命令返回进入后续步骤。
第一种情况,只有allowedExecutables.contains(command)
为true之后,才能返回<user_controlled_command> --version
。即用户指定的命令必须createrepo、mergerepo这两个字符串中的其中一个。
否则进入下一个判断逻辑,如果用户指定的命令在this.applicationDirectories.getWorkDirectory().getAbsolutePath()
的值:/Users/Xxx/repos/sonatype-work/nexus
(这个是nexus配置所在目录)之下(即试图执行这个目录下的脚本),也不允许执行。再看下一个逻辑分支,即第二种情况,!this.allowedExecutables.contains(file.getName())
判断提供的命令是否在allowedExecutables(即createrepo、mergerepo)这个集合中。若在此集合中,才把这个命令返回。而满足这一条件的命令需要以/createrepo
或者/mergerepo
结尾。这里想不到如何控制一个以/createrepo
或者/mergerepo
结尾的命令。
最近被绕过了成了CVE-2019-15588
:
https://hackerone.com/reports/688270
PoC:
|
附录
建议修改默认密码admin/admin123
:
|
有人为这一点提了一个CVE-2019-9629
参考
- https://hackerone.com/reports/654888
- https://support.sonatype.com/hc/en-us/articles/360033490774-CVE-2019-5475-Nexus-Repository-Manager-2-OS-Command-Injection-2019-08-09
- https://www.cnblogs.com/blaketairan/p/7136735.html
- http://www.blogjava.net/fancydeepin/archive/2015/06/27/maven-nexus.html