千家信息网

Nexus Repository Manager 2.x命令注入漏洞CVE-2019-5475示例分析

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,Nexus Repository Manager 2.x命令注入漏洞CVE-2019-5475示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解
千家信息网最后更新 2026年11月01日Nexus Repository Manager 2.x命令注入漏洞CVE-2019-5475示例分析

Nexus Repository Manager 2.x命令注入漏洞CVE-2019-5475示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

前言

2019年9月初我们应急了Nexus Repository Manager 2.x 命令注入漏洞(CVE-2019-5475),其大致的原因和复现步骤在 hackerone 上公布了,在应急完这个漏洞之后,我们分析该漏洞的修复补丁,发现修复不完全,仍然可以绕过,本篇文章记录该漏洞的两次绕过。虽然早发布了两次的修复版本,由于官方第二次更新公告太慢https://support.sonatype.com/hc/en-us/articles/360033490774,所以现在才发。

几次更新时间线:

CVE-2019-5475(2019-08-09)

第一次绕过,CVE-2019-15588(2019-10-28)

第二次绕过,未分配CVE,更新了公告影响版本(2020-3-25)

注:原始漏洞分析、第一次绕过分析、第二次绕过分析部分主要由Badcode师傅编写,第二次绕过分析+、最新版本分析主要由Longofo添加。

原始漏洞分析

利用条件

需管理员权限(默认认证:admin/admin123)

漏洞分析

以下分析的代码基于 2.14.9-01 版本。

漏洞点是出现在 Yum Repository 插件中,当配置 Yum 的createrepo或者mergerepo时

代码层面会跳到YumCapability的activationCondition方法中。

在上面Path of "createrepo"中设置的值会通过getConfig().getCreaterepoPath()获取到,获取到该值之后,调用this.validate()方法

传进来的path是用户可控的,之后将path拼接--version之后传递给commandLineExecutor.exec()方法,看起来像是执行命令的方法,而事实也是如此。跟进CommandLineExecutor类的exec方法

在执行命令前先对命令解析,CommandLine.parse(),会以空格作为分隔,获取可执行文件及参数。

最终是调用了Runtime.getRuntime().exec()执行了命令。

例如,用户传入的 command 是cmd.exe /c whoami,最后到getRuntime().exec()方法就是Runtime.getRuntime().exec({"cmd.exe","/c","whoami"})。

所以漏洞的原理也很简单,就是在createrepo或者mergerepo路径设置的时候,该路径可以由用户指定,中途拼接了--version字符串,最终到了getRuntime.exec()执行了命令。

漏洞复现

在Path of "createrepo"里面传入 payload。

在Status栏可以看到执行的结果

第一次绕过分析

第一次补丁分析

官方补丁改了几个地方,关键点在这里

常规做法,在执行命令前对命令进行过滤。新增加了一个getCleanCommand()方法,对命令进行过滤。

allowedExecutables是一个 HashSet,里面只有两个值,createrepo和mergerepo。先判断用户传入的command是否在allowedExecutables里面,如果在,直接拼接params即--version直接返回。接着对用户传入的command进行路径判断,如果是以nexus的工作目录(applicationDirectories.getWorkDirectory().getAbsolutePath())开头的,直接返回 null。继续判断,如果文件名不在allowedExecutables则返回 null,也就是这条命令需要 以/createrepo或者/mergerepo结尾。都通过判断之后,文件的绝对路径拼接--version返回。

第一次补丁绕过

说实话,看到这个补丁的第一眼,我就觉得大概率可以绕。

传入的命令满足两个条件即可,不以nexus的工作目录开头,并且以/createrepo或者/mergerepo结尾即可。

看到补丁中的getCleanCommand()方法,new File(command)是关键,new File()是通过将给定的路径名字符串转换为抽象路径名来创建新的File实例。 值得注意的是,这里面路径字符串是可以使用空格的,也就是


String f = "/etc/passwd /shadow"; File file = new File(f);

这种是合法的,并且调用file.getName()取到的值是shadow。结合这个特性,就可以绕过补丁里面的判断。


String cmd = "/bin/bash -c whoami /createrepo"; File file = new File(cmd); System.out.println(file.getName()); System.out.println(file.getAbsolutePath());

运行结果

可以看到,file.getName()的值正是createrepo,满足判断。

第一次绕过测试
测试环境

2.14.14-01 版本

Linux

测试步骤

在Path of "createrepo"里面传入 payload。

在Status栏查看执行的结果

可以看到,成功绕过了补丁。

在 Windows 环境下面就麻烦点了,没有办法使用cmd.exe /c whoami这种形式执行命令了,因为cmd.exe /c whoami经过new File()之后变成了cmd.exe \c whoami,后面是执行不了的。可以直接执行exe,注意后面是还会拼接--version的,所以很多命令是执行不了的,但是还是有办法利用能执行任意exe这点来做后续的攻击的。

第二次绕过分析

第二次补丁分析

在我提交上述绕过方式后,官方修复了这种绕过方式,看下官方的补丁

在getCleanCommand()方法中增加了一个file.exists()判断文件是否存在。之前的/bin/bash -c whoami /createrepo这种形式的肯定就不行了,因为这个文件并不存在。所以现在又多了一个判断,难度又加大了。难道就没有办法绕过了?不是的,还是可以绕过的。

第二次补丁绕过

现在传入的命令要满足三个条件了

  • 不以nexus的工作目录开头

  • 以/createrepo或者/mergerepo结尾

  • 并且这createrepo或者mergerepo这个文件存在

看到file.exists()我就想起了 php 中的file_exists(),以前搞 php 的时候也遇到过这种判断。有个系统特性,在 Windows 环境下,目录跳转是允许跳转不存在的目录的,而在Linux下面是不能跳转不存在目录的。

测试一下

Linux

可以看到,file.exists()返回了 false

Windows

file.exists()返回了 true

上面我们说了new File(pathname),pathname 是允许带空格的。在利用上面WIndows环境下的特性,把cmd设置成C:\\Windows\\System32\\calc.exe \\..\\..\\win.ini

经过parse()方法,最终到getRuntime.exec({"C:\\Windows\\System32\\calc.exe","\\..\\..\\win.ini"}),这样就能执行calc了。

在上面这个测试win.ini是确实存在的文件,回到补丁上面,需要判断createrepo或者mergerepo存在。首先从功能上来说,createrepo 命令用于创建 yum 源(软件仓库),即为存放于本地特定位置的众多rpm包建立索引,描述各包所需依赖信息,并形成元数据。也就是这个createrepo在Windows下不太可能存在。如果这个不存在的话是没有办法经过判断的。既然服务器内不存在createrepo,那就想办法创建一个,我首先试的是找个上传点,尝试上传一个createrepo,但是没找到上传之后名字还能保持不变的点。在Artifacts Upload处上传之后,都变成Artifact-Version.Packaging这种形式的名字了,Artifact-Version.Packaging这个是不满足第二个判断的,得以createrepo结尾。

一开始看到file.exists()就走进了思维定势,以为是判断文件存在的,但是看了官方的文档,发现是判断文件或者目录存在的。。这点也就是这个漏洞形成的第二个关键点,我不能创建文件,但是可以创建文件夹啊。在Artifacts Upload上传Artifacts 的时候,可以通过GAV Parameters来定义。

当Group设置为test123,Artifact设置为test123,Version设置成1,当上传Artifacts的时候,是会在服务器中创建对应的目录的。对应的结构如下

如果我们将Group设置为createrepo,那么就会创建对应的createrepo目录。

结合两个特性来测试一下

String cmd = "C:\\Windows\\System32\\calc.exe \\..\\..\\..\\nexus\\sonatype-work\\nexus\\storage\\thirdparty\\createrepo";File file = new File(cmd);System.out.println(file.exists());System.out.println(file.getName());System.out.println(file.getAbsolutePath());

可以看到,file.exists()返回了true,file.getName()返回了createrepo,都符合判断了。

最后到getRuntime()里面大概就是getRuntime.exec({"C:\Windows\System32\notepad.exe","\..\..\..\nexus\sonatype-work\nexus\storage\thirdparty\createrepo","--version"})

是可以成功执行notepad.exe的。(calc.exe演示看不到进程哈,所以换成Notepad.exe)

第二次绕过测试
测试环境
  • 2.14.15-01 版本

  • Windows

测试步骤

在Path of "createrepo"里面传入 payload。

查看进程,notepad.exe启动了

可以看到,成功绕过了补丁。

第二次绕过分析+

经过Badcode师傅第二次绕过分析,可以看到能成功在Windows系统执行命令了。但是有一个很大的限制:

  1. nexus需要安装在系统盘

  2. 一些带参数的命令无法使用

在上面说到的Artifacts Upload上传处是可以上传任意文件的,并且上传后的文件名都是通过自定义的参数拼接得到,所以都能猜到。那么可以上传自己编写的任意exe文件了。

第二次绕过分析+测试
测试环境
  • 2.14.15-01 版本

  • Windows

测试步骤

导航到Views/Repositories->Repositories->3rd party->Configuration,我们可以看到默认本地存储位置的绝对路径(之后上传的内容也在这个目录下):

导航到Views/Repositories->Repositories->3rd party->Artifact Upload,我们可以上传恶意的exe文件:

该exe文件将被重命名为createrepo-1.exe(自定义的参数拼接的):

同样在Path of "createrepo"里面传入 payload(这时需要注意前面部分这时是以nexus安装目录开头的,这在补丁中会判断,所以这里可以在最顶层加..\或者弄个虚假层aaa\..\等):

可以看到createrepo-1.exe已经执行了:

最新版本分析

最新版本补丁分析

第二次补丁绕过之后,官方又进行了修复,官方补丁主要如下:

删除了之前的修复方式,增加了YumCapabilityUpdateValidator类,在validate中将获取的值与properties中设置的值使用equals进行绝对相等验证。这个值要修改只能通过sonatype-work/nexus/conf/capabilities.xml:

最新版本验证

前端直接禁止修改了,通过抓包修改测试:

在YumCapabilityUpdateValidator.validate断到:

可以看到这种修复方式无法再绕过了,除非有文件覆盖的地方覆盖配置文件,例如解压覆盖那种方式,不过没找到。

不过Artifacts Upload那里可以上传任意文件的地方依然还在,如果其他地方再出现上面的情况依然可以利用到。

看完上述内容,你们掌握Nexus Repository Manager 2.x命令注入漏洞CVE-2019-5475示例分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

分析 命令 文件 补丁 漏洞 测试 方法 目录 版本 官方 路径 环境 第一次 办法 方式 用户 成功 也就是 参数 地方 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 朗新科技与工业互联网 腾讯阿里互联网科技 金融科技与互联网金融 致聘互联网科技 互联网科技视频素材 中国互联网有什么科技含量 银川新华互联网科技职业技术培训学校图片 互联网媒体平台算高科技产业 呼和浩特新华互联网科技学院 国大互联网教育科技有限公司薪资 美国互联网科技实力 江苏苏星互联网科技有限公司 广州百诚互联网科技有限公司官网 互联网科技年终奖 兰石爱特工业互联网科技分公司 银川新华互联网科技学校原画 广西泛欧互联网科技有限公司 互联网科技品牌 北京品多多互联网科技有限公司 每日互联网科技新闻 科技创新与互联网经济 奇酷互联网科技公司 广州宏创互联网科技 时间互联网络科技 承德科技产业互联网发展 烟台灵鸽互联网科技有限公司 四川互联网展示科技馆设计 互联网科技数字货币 易企秀互联网科技是做什么的 玉溪新华互联网科技怎么选
0