作者:Longofo@知道创宇404实验室
时间:2020年4月8日
Nexus Repository Manager 3最近曝出两个el表达式解析漏洞,编号为CVE-2020-10199[1],CVE-2020-10204[2],都是由Github Secutiry Lab团队的@pwntester发现。由于之前Nexus3的漏洞没有去跟踪,所以当时diff得很头疼,并且Nexus3 bug与安全修复都是混在一起,更不容易猜到哪个可能是漏洞位置了。后面与@r00t4dm师傅一起复现出了CVE-2020-10204[3],CVE-2020-10204[4]是CVE-2018-16621[5]的绕过,之后又有师傅弄出了CVE-2020-10199[6],这三个漏洞的根源是一样的,其实并不止这三处,官方可能已经修复了好几处这样的漏洞,由于历史不太好追溯回去,所以加了可能,通过后面的分析,就能看到了。还有之前的CVE-2019-7238[7],这是一个jexl表达式解析,一并在这里分析下,以及对它的修复问题,之前看到有的分析文章说这个漏洞是加了个权限来修复,可能那时是真的只加了个权限吧,不过我测试用的较新的版本,加了权限貌似也没用,在Nexus3高版本已经使用了jexl白名单的沙箱。
1 测试环境文中会用到三个Nexus3环境:
nexus-3.14.0-04
nexus-3.21.1-01
nexus-3.21.2-03
nexus-3.14.0-04
用于测试jexl表达式解析,nexus-3.21.1-01
用于测试jexl表达式解析与el表达式解析以及diff,nexus-3.21.2-03
用于测试el表达式解析以及diff。
CVE-2020-10199、CVE-2020-10204漏洞的修复界限是3.21.1与3.21.2,但是github开源的代码分支好像不对应,所以只得去下载压缩包来对比了。在官方下载了nexus-3.21.1-01
与nexus-3.21.2-03
,但是beyond对比需要目录名一样,文件名一样,而不同版本的代码有的文件与文件名都不一样。我是先分别反编译了对应目录下的所有jar包,然后用脚本将nexus-3.21.1-01
中所有的文件与文件名中含有3.21.1-01的替换为了3.21.2-03,同时删除了META文件夹,这个文件夹对漏洞diff没什么用并且影响diff分析,所以都删除了,下面是处理后的效果:
如果没有调试和熟悉之前的Nexus3漏洞,直接去看diff可能会看得很头疼,没有目标的diff。
3 路由以及应对处理类1 一般路由抓下nexus3发的包,随意的点点点,可以看到大多数请求都是POST类型的,URI都是/service/extdirect
:
post内容如下:
{"action":"coreui_Repository","method":"getBrowseableFormats","data":null,"type":"rpc","tid":7}
可以看下其他请求,json中都有action
与method
这两个key,在代码中搜索下coreui_Repository
这个关键字:
可以看到这样的地方,展开看下代码:
通过注解方式注入了action,上面post的method->getBrowseableFormats
也在中,通过注解注入了对应的method:
所以之后这样的请求,我们就很好定位路由与对应的处理类了。
2 API路由Nexus3的API也出现了漏洞,来看下怎么定位API的路由,在后台能看到Nexus3提供的所有API。
点几个看下包,有GET、POST、DELETE、PUT等类型的请求:
没有了之前的action与method,这里用URI来定位,直接搜索/service/rest/beta/security/content-selectors
定位不到,所以缩短关键字,用/beta/security/content-selectors
来定位:
通过@Path注解来注入URI,对应的处理方式也使用了对应的@GET、@POST来注解
可能还有其他类型的路由,不过也可以使用上面类似的方式进行搜索来定位。还有Nexus的权限问题,可以看到上面有的请求通过@RequiresPermissions来设置了权限,不过还是以实际的测试权限为准,有的在到达之前也进行了权限校验,有的操作虽然在web页面的admin页面,不过本不需要admin权限,可能无权限或者只需要普通权限。
4build Constraint Violation With Template造成的几次Java EL 漏洞在跟踪调试了CVE-2018-16621[8]与CVE-2020-10204[9]之后,感觉buildConstraintViolationWithTemplate
这个keyword可以作为这个漏洞的根源,因为从调用栈可以看出这个函数