freeBuf
主站

分類

漏洞 工具 極客 Web安全 系統安全 網絡安全 無線安全 設備/客戶端安全 數據安全 安全管理 企業安全 工控安全

特色

頭條 人物志 活動 視頻 觀點 招聘 報告 資訊 區塊鏈安全 標準與合規 容器安全 公開課

官方公眾號企業安全新浪微博

FreeBuf.COM網絡安全行業門戶,每日發布專業的安全資訊、技術剖析。

FreeBuf+小程序

FreeBuf+小程序

CVE-2020-5405 Spring Cloud Config Server 目錄穿越
2020-03-07 19:00:34

事件背景

Spring Cloud Config為分布式系統的外部配置提供客戶端的服務端的支持。使用了它,開發人員就可以在一個中心倉庫管理應用程序在所有環境中的外部配置。2020-02-26 Spring 收到漏洞報告, Spring Cloud Config Server 存在目錄穿越漏洞。

時間線

2020-02-26 Spring 收到漏洞報告, Spring Cloud Config Server 存在目錄穿越漏洞
2020-03-03 Spring Cloud Config Server 更新 2.1.7 版本
2020-03-04 Spring Cloud Config Server 更新 2.2.2 版本
2020-03-06 斗象應急響應團隊分析出漏洞POC

漏洞挖掘

根據描述該漏洞為目錄穿越 2.2.0-2.2.1,2.1.0-2.1.6 都受到影響, 所以這里直接下載2.2.1和2.2.2的源碼包進行對比

https://github.com/spring-cloud/spring-cloud-config/releases

解壓后直接使用idea Ctrl+D 進行對比

很多開源項目都會在test文件中寫入本次更新涉及的漏洞點
比如這次?spring-cloud-config-2.2.2.RELEASE/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/environment/EnvironmentTests.java

顯而易見的這個漏洞是用?(_)?來代替?/?進行目錄穿越

搭建環境

這里啟動 2.2.1環境, 使用idea 打開 (maven項目)
\spring-cloud-config-2.2.1.RELEASE\spring-cloud-config-server
這里如果速度慢可以修改成阿里源,啟動成功后訪問
http://127.0.0.1:8888/foo/default/master/test.json

補丁對比

根據上一個目錄穿越漏洞

Spring Cloud Config Server 路徑穿越與任意文件讀取漏洞分析 – 【CVE-2019-3799】 – 先知社區
https://xz.aliyun.com/t/4844

這里可以構造一個路徑進行嘗試(看看報錯)

/foo/default/master/..(_)..(_)..(_)..(_)etc(_)passwd

效果不佳,從文中可知請求格式如下

GET /{name}/{profile}/{label}/{path}

繼續看對應實現源碼

org/springframework/cloud/config/server/resource/ResourceController.java

這里可以知道請求的格式,這里決定了POC的基本結構

繼續對比可以可以看出,?(_)?會在 [name/label] 時被處理成?/

再根據新增的測試文件
spring-cloud-config-2.2.2.RELEASE/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/resource/GenericResourceRepositoryTests.java

基本可以構造出來如下格式

由于label中可以解析(_)

根據提示 “Cannot clone or checkout repository” 以及 代碼中的
this.nativeRepository.setSearchLocations("file:./src/test/resources/test/local");
這里考慮可能是得采用本地配置文件方式
玩轉Spring Cloud之配置中心(config server &config client) – 夢在旅途 – 博客園
https://www.cnblogs.com/zuowj/p/10432445.html

更改配置文件為

configserver.yml

info:
  component: Config Server
spring:
  application:
    name: configserver
  autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  profiles:
    active: native
  jmx:
    default_domain: cloud.config.server
  cloud:
    config:
      server:
        #如下是本地文件配置
        native:
          search-locations: classpath:/configs #配置文件存放的目錄

server:
  port: 8888
management:
  context_path: /admin

然后再resources目錄下新建文件夾 configs
隨便放個配置文件

configclient-dev.properties

--configclient-dev.properties內容:

demo-config-profile-env=dev-native
zuowenjun.site=http://www.zuowenjun.cn,http://zuowj.cnblogs.com--20190227
zuowenjun.skills=.net,java,html,js,css,sql,python,vb--20190227
zuowenjun.motto=Learning is endless; Opportunity is for the prepared mind;--20190227

訪問 http://127.0.0.1:8888/configclient/dev

當native本地方式啟動時, {label}無需指定(有用但是對這個漏洞沒有影響), 所以這里可以采取{label}可以生效的方式git后端配置的請求格式進行訪問

Spring Cloud Config Server 啟動后, GIT倉庫中的配置文件會被自動轉換成當前項目的web api,若需訪問查看遠程配置數據可以參照以下的規則:
/{application}/{profile}[/{label}]
[/{label}]/{application}-{profile}{.yml|.properties|.json}

規則簡單說明:{application}=配置消費方應用名稱(即:config client的項目名,通俗講:就是誰用這個配置就是誰的名字)

{profile}=配置環境(如:dev開發環境,test測試環境,prod生產環境)

{label}=倉庫分支名(git或svn方式指定,native本地方式無需指定)

.yml|.properties|.json表示指定的響應返回格式,{}表示必需,[]表示可選,|表示或的關系

或者參考
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.2.RELEASE/reference/html/#_placeholders_in_git_uri

https://www.cnblogs.com/zuowj/p/10432445.html

當配置文件中的 search-locations 修改為?file:///c:/?時,即可在在根目錄進行文件讀取

configserver.yml

info:
  component: Config Server
spring:
  application:
    name: configserver
  autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  jmx:
    default_domain: cloud.config.server
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          search-locations: file:///C:\TCC\Spring-cloud-config-server\spring-cloud-config-2.2.1.RELEASE\spring-cloud-config-server\src\main\resources\configs #配置文件存放的目錄
server:
  port: 8888
management:
  context_path: /admin

斷點分析

通過打斷點,我們可以更清晰的看到漏洞的成因

首先根據路由格式,進入?org.springframework.cloud.config.server.resource.ResourceController#retrieve(java.lang.String, java.lang.String, java.lang.String, org.springframework.web.context.request.ServletWebRequest, boolean)?函數中

其中參數分別為我們傳入的

name = blah

profile = local

label = 馬賽克

path = Windows/win.ini

然后進入org.springframework.cloud.config.server.resource.GenericResourceRepository#findOne函數


這里會對?Win[-{label}].ini?也就是?win-label.ini win.ini?在對應目錄搜索,

也就是?{search-locations} + {label}?即

file:///C:\TCC\Spring-cloud-config-server\spring-cloud-config-2.2.1.RELEASE\spring-cloud-config-server\src\main\resources\configs/../../../../../../../../../../../../../../../../../../../../../../../../../../../../..//

也就是進入了C盤根目錄, 即可讀取文件

無后綴文件讀取

但是因為org.springframework.cloud.config.server.resource.ResourceController#retrieve(org.springframework.web.context.request.ServletWebRequest, java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean)中存在對于后綴的匹配導致沒有后綴的文件會讀取失敗

46對應ascii碼的.

當沒有獲取到 “.” 的時候返回 null 導致后續 null.toLowerCase() 報錯異常退出

但是在windows中.當文件名后面加空格或者點號.也可以正確處理

Naming Files, Paths, and Namespaces – Win32 apps | Microsoft Docs
https://docs.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN

Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not. However, it is acceptable to specify a period as the first character of a name. For example, ".temp".

所以在Windows中,我們可以使用文件名加點.的方式進行無后綴文件讀取

漏洞產生根本原因

org.springframework.cloud.config.server.environment.NativeEnvironmentRepository#getLocations
這里產生了直接拼接{label}的行為

所以這里雙重url編碼/%252f還是可以用,因為最后拼接成的路徑是URL類,支持%2f


使用?%252f?請求

Spring修復方式

修復點在
spring-cloud-config-2.2.2.RELEASE/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/resource/GenericResourceRepository.java

org.springframework.cloud.config.server.resource.GenericResourceRepository#findOne函數加入了對路徑的判斷

org.springframework.cloud.config.server.resource.GenericResourceRepository#isInvalidEncodedLocation?會先對路徑進行url解碼

org.springframework.cloud.config.server.resource.GenericResourceRepository#isInvalidLocation?然后檢測是否包含?..

檢測方法

Windows 可以檢測 C:/Windows/win.ini
Linux 可以檢測 /etc/resolv.conf
(這里測試Windows上file協議無法訪問其他盤,如果Spring Cloud Config Server 搜索路徑指定在 classpath,可以嘗試讀取META-INF/下面的文件,這里是個檢測難點)

作者:斗象能力中心 TCC – 小胖虎

本文作者:, 轉載請注明來自FreeBuf.COM

# 漏洞挖掘
被以下專輯收錄,發現更多精彩內容
+ 收入我的專輯
評論 按熱度排序

登錄/注冊后在FreeBuf發布內容哦

相關推薦
  • 0 文章數
  • 0 評論數
  • 0 關注者
登錄 / 注冊后在FreeBuf發布內容哦
收入專輯
四月天小说网