JAVA安全之CVE-2020-1938復(fù)現(xiàn)和分析
一、漏洞簡介
Apache Tomcat是由Apache軟件基金會(huì)屬下Jakarta項(xiàng)目開發(fā)的Servlet容器.默認(rèn)情況下,Apache Tomcat會(huì)開啟AJP連接器,方便與其他Web服務(wù)器通過AJP協(xié)議進(jìn)行交互.但Apache Tomcat在AJP協(xié)議的實(shí)現(xiàn)上存在漏洞,導(dǎo)致攻擊者可以通過發(fā)送惡意的AJP請(qǐng)求,可以讀取或者包含Web應(yīng)用根目錄下的任意文件,如果配合文件上傳任意格式文件,將可能導(dǎo)致任意代碼執(zhí)行(RCE).該漏洞利用AJP服務(wù)端口實(shí)現(xiàn)攻擊,未開啟AJP服務(wù)對(duì)外不受漏洞影響(tomcat默認(rèn)將AJP服務(wù)開啟并綁定至0.0.0.0/0).
1、危險(xiǎn)等級(jí)
高危
2、漏洞危害
攻擊者可以讀取 Tomcat所有 webapp目錄下的任意文件。此外如果網(wǎng)站應(yīng)用提供文件上傳的功能,攻擊者可以先向服務(wù)端上傳一個(gè)內(nèi)容含有惡意 JSP 腳本代碼的文件(上傳的文件本身可以是任意類型的文件,比如圖片、純文本文件等),然后利用 Ghostcat 漏洞進(jìn)行文件包含,從而達(dá)到代碼執(zhí)行的危害
3、影響范圍
Apache Tomcat 9.x < 9.0.31
Apache Tomcat 8.x < 8.5.51
Apache Tomcat 7.x < 7.0.100
Apache Tomcat 6.x
4、前提條件
對(duì)于處在漏洞影響版本范圍內(nèi)的 Tomcat 而言,若其開啟 AJP Connector 且攻擊者能夠訪問 AJP Connector 服務(wù)端口的情況下,即存在被 Ghostcat 漏洞利用的風(fēng)險(xiǎn)。注意 Tomcat AJP Connector 默認(rèn)配置下即為開啟狀態(tài),且監(jiān)聽在 0.0.0.0:8009 。
5、漏洞原理
Tomcat 配置了兩個(gè)Connecto,它們分別是 HTTP 和 AJP :HTTP默認(rèn)端口為8080,處理http請(qǐng)求,而AJP默認(rèn)端口8009,用于處理 AJP 協(xié)議的請(qǐng)求,而AJP比http更加優(yōu)化,多用于反向、集群等,漏洞由于Tomcat AJP協(xié)議存在缺陷而導(dǎo)致,攻擊者利用該漏洞可通過構(gòu)造特定參數(shù),讀取服務(wù)器webapp下的任意文件以及可以包含任意文件,如果有某上傳點(diǎn),上傳圖片馬等等,即可以獲取shel
二、漏洞分析
1.漏洞成因分析:
tomcat默認(rèn)的conf/server.xml中配置了2個(gè)Connector,一個(gè)為8080的對(duì)外提供的HTTP協(xié)議端口,另外一個(gè)就是默認(rèn)的8009 AJP協(xié)議端口,兩個(gè)端口默認(rèn)均監(jiān)聽在外網(wǎng)ip。
tomcat在接收ajp請(qǐng)求的時(shí)候調(diào)用org.apache.coyote.ajp.AjpProcessor來處理ajp消息,prepareRequest將ajp里面的內(nèi)容取出來設(shè)置成request對(duì)象的Attribute屬性
如下圖:
在代碼的507行
可以通過此種特性從而可以控制request對(duì)象的下面三個(gè)Attribute屬性
javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path
然后封裝成對(duì)應(yīng)的request之后,繼續(xù)走servlet的映射流程如下圖所示:
接著看第252行。
2.利用方式:
(1)利用DefaultServlet實(shí)現(xiàn)任意文件下載
當(dāng)url請(qǐng)求未在映射的url列表里面則會(huì)通過tomcat默認(rèn)的DefaultServlet會(huì)根據(jù)上面的三個(gè)屬性來讀取文件,如下圖
通過serveResource方法來獲取資源文件
通過getRelativePath來獲取資源文件路徑
然后再通過控制ajp控制的上述三個(gè)屬性來讀取文件,通過操控上述三個(gè)屬性從而可以讀取到/WEB-INF下面的所有敏感文件,不限于class、xml、jar等文件。
(2)通過jspservlet實(shí)現(xiàn)任意后綴文件包含
當(dāng)url(比如http://xxx/xxx/xxx.jsp)請(qǐng)求映射在org.apache.jasper.servlet.JspServlet這個(gè)servlet的時(shí)候也可通過上述三個(gè)屬性來控制訪問的jsp文件如下圖:
控制路徑之后就可以以jsp解析該文件 所以只需要一個(gè)可控文件內(nèi)容的文件即可實(shí)現(xiàn)rce.
代碼段分析1:
tomcat默認(rèn)監(jiān)聽的8009端口用來處理AJP協(xié)議。AJP協(xié)議建立在TCP socket通信之上,tomcat使用該協(xié)議和前級(jí)的Web Server傳遞信息,這次的漏洞就出在客戶端可以利用ajp協(xié)議數(shù)據(jù)包控制request對(duì)象的一些字段。
具體地,tomcat源碼的org.apache.coyote.ajp.AjpProcessor類的service()方法如下:
它調(diào)用的prepareRequest()方法用來解析一些請(qǐng)求頭,部分內(nèi)容如下:
可以看到,當(dāng)ajp數(shù)據(jù)包的頭設(shè)置為SC_REQ_ATTRIBUTE時(shí)(具體數(shù)值可以查詢AJP協(xié)議規(guī)范),Connector會(huì)緊接著讀取變量n(屬性名)和v(值),當(dāng)n不是SC_A_REQ_LOCAL_ADDR、SC_A_REQ_REMOTE_PORT、SC_A_SSL_PROTOCOL時(shí),就會(huì)用v來賦值屬性n。接著,service()方法將修改過的request代入后面的調(diào)用。
=在org.apache.catalina.servlets.DefaultServlet中,當(dāng)我們的請(qǐng)求聲明的是GET方法時(shí),存在調(diào)用service()->doGet()->serveResource(),分析serveResource()代碼如下:
其調(diào)用的getRelativePath()方法內(nèi)容如下:
從javax.servlet.RequestDispatcher中可以看到這三個(gè)屬性的名稱:
所以,我們就能通過AJP協(xié)議改變r(jià)equest的這三個(gè)屬性來控制請(qǐng)求的路徑,serveResource()方法獲得path后的代碼大致如下:
它會(huì)直接把通過path獲取的資源序列化輸出,因此客戶端再按照AJP協(xié)議解析數(shù)據(jù)包就能得到文件內(nèi)容。
代碼段分析2:
同樣的道理,tomcat默認(rèn)將jsp/jspx結(jié)尾的請(qǐng)求交給org.apache.jasper.servlet.JspServlet處理,它的service()方法如下:
可以看到j(luò)spUri也是由兩個(gè)可控的屬性定義的,后續(xù)代碼:
代碼在這里根據(jù)jspUri生成了一個(gè)JspServletWrapper,它會(huì)調(diào)用service()方法完成jsp代碼的編譯,將其轉(zhuǎn)換成一個(gè)servlet。該servlet最終會(huì)以.java文件的形式寫入%CATALINA_HOME%/work/Engine/Host/Context目錄下:
經(jīng)過上述調(diào)用,這就形成了文件包含漏洞。當(dāng)Web應(yīng)用上有某個(gè)文件內(nèi)容可被我們控制時(shí),就可以造成rce漏洞。
三、漏洞復(fù)現(xiàn)
1.環(huán)境的準(zhǔn)備
(1)windows下漏洞復(fù)現(xiàn)環(huán)境準(zhǔn)備,這里以tomcat-8.5.32為例。
https://github.com/backlion/CVE-2020-1938/blob/master/apache-tomcat-8.5.32.zip
(2)安裝jdk并配置JDK環(huán)境
(3)然后啟動(dòng)tomcat,點(diǎn)擊tomcat目錄/bin 文件夾下的startup.bat
root@kali2019:~# git clone https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi root@kali2019:~# cd CNVD-2020-10487-Tomcat-Ajp-lfi/ root@kali2019:~/CNVD-2020-10487-Tomcat-Ajp-lfi# chmod +x CNVD-2020-10487-Tomcat-Ajp-lfi.py root@kali2019:~/CNVD-2020-10487-Tomcat-Ajp-lfi#
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.1.9 -p 8009 -f WEB-INF/web.xm
讀取文件
讀取web-inf/web.xm文件
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 10.10.10.134 -p 8009 -f WEB-INF/web.xml
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 10.10.10.134 -p 8009 -f index.jsp
命令執(zhí)行
執(zhí)行whoami命令
python "文件包含(CVE-2020-1938).py" 10.10.10.134 -p 8009 -f /test.txt
ping dnslog
反彈shell
- 反彈shell用的命令需要進(jìn)行bash編碼
- 在線bash編碼:http://www.jackson-t.ca/runtime-exec-payloads.html
- https://ares-x.com/tools/runtime-exec/
- POC下載地址:https://github.com/sv3nbeast/CVE-2020-1938-Tomact-file_include-file_read
在反彈shell的過程中,我嘗試多次之后失敗了。就放了一張米斯特斯文師傅的一張成功的圖片。
REF
https://www.cnblogs.com/backlion/p/12870365.html
https://xz.aliyun.com/t/7325
https://www.svenbeast.com/post/fqSI9laE8/