TomcatAJP文件包含漏洞及線上修復漏洞


漏洞概述

2020年2月20日,國家信息安全漏洞共享平台(CNVD)發布關於Apache Tomcat的安全公告,Apache Tomcat文件包含漏洞(CNVD-2020-10487,對應CVE-2020-1938)。

Tomcat AJP協議由於存在實現缺陷導致相關參數可控,攻擊者利用該漏洞可通過構造特定參數,讀取服務器webapp下的任意文件。若服務器端同時存在文件上傳功能,攻擊者可進一步實現遠程代碼的執行。

由於Tomcat在處理AJP請求時,未對請求做任何驗證,通過設置AJP連接器封裝的request對象的屬性, 導致產生任意文件讀取漏洞和代碼執行漏洞

CVE-2020-1938 又名GhostCat, 之前引起了一場風雨,由e長亭科技安全研究員發現的存在於Tomcat中的安全漏洞,由於Tomcat AJP協議設計上存在缺陷,攻擊者通過 Tomcat AJP Connector 可以讀取或包含 Tomcat 上所有 webapp 目錄下的任意文件,例如可以讀取 webapp 配置文件或源代碼。此外在目標應用有文件上傳功能的情況下,配合文件包含的利用還可以達到遠程代碼執行的危害。

影響范圍
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

本次漏洞與三個include屬性有關

javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path
任意文件讀取

任意文件讀取問題出現在org.apache.catalina.servlets.DefaultServlet這個Servlet

構造一個AJP請求,請求會走默認的DefaultServlet並交給DefaultServletdoGet方法處理。
doGet會調用ServeResource方法獲取資源文件,調用getRelativePath方法獲取要讀取資源的相對路徑,通過getResources方法就可以獲取到了對應路徑的Web資源對象。
然后再通過控制ajp控制的上述三個include屬性來讀取文件,通過操控上述三個屬性從而可以讀取到/WEB-INF下面的所有敏感文件,不限於class、xml、jar等文件。

任意代碼執行

任意代碼執行問題出現在org.apache.jasper.servlet.JspServlet這個servlet

構造一個如下的AJP請求,讓Tomcat執行/docs/test.jsp,但實際上它會將code.txt當成jsp來解析執行。

RequestUri:/docs/test.jsp
javax.servlet.include.request_uri: /
javax.servlet.include.path_info: code.txt
javax.servlet.include.servlet_path: /

code.txt內容如下

<%
	java.util.List<String> commands = new java.util.ArrayList<String>();
	commands.add("/bin/bash");
	commands.add("-c");
	commands.add("/Applications/Calculator.app/Contents/MacOS/Calculator");
	java.lang.ProcessBuilder pb = new java.lang.ProcessBuilder(commands);
	pb.start();
%>

發送AJP請求,請求的是/docs/test.jsp這個jsp,但是由於那三個include屬性可控,可以將test.jsp對應的服務器腳本文件改為code.txt,導致tomcat把我們的code.txt當jsp文件編譯運行,導致代碼執行。

TomcatAJP Connector以及AJP協議

Tomcat Connector 是 Tomcat 與外部連接的通道,它使得 Catalina 能夠接收來自外部的請求,傳遞給對應的 Web 應用程序處理,並返回請求的響應結果。

默認情況下,Tomcat 配置了兩個 Connector,它們分別是 HTTP ConnectorAJP Connector:

// HTTP Connector:用於處理 HTTP 協議的請求(HTTP/1.1),默認監聽地址為 0.0.0.0:8080

// AJP Connector:用於處理 AJP 協議的請求(AJP/1.3),默認監聽地址為 0.0.0.0:8009

HTTP Connector 就是用來提供我們經常用到的 HTTP Web 服務。而 AJP Connector,它使用的是 AJP 協議(Apache Jserv Protocol),AJP 協議可以理解為 HTTP 協議的二進制性能優化版本,它能降低 HTTP 請求的處理成本,因此主要在需要集群、反向代理的場景被使用。

AJP是Apache Tomcat web服務器用來與servlet容器通信的一個二進制協議。主要用於集群或逆向代理場景,其中web服務器與應用服務器或servelet容器進行通信。

簡單來說,就是HTTP Connector暴露給客戶端了,AJP是webserver (如Apache HTTPD)和Apache Tomcat服務器之間內部使用的,如下圖所示。AJP在Apache HTTP服務器中是以模塊的形式實現的,表示為mod_jk或mod_proxy_ajp。AJP本身並不會暴露到外部,這也是下一部分要討論的RCE場景的先決條件之一。

漏洞修復

升級版本

將Tomcat立即升級到9.0.31,8.5.51或7.0.100版本進行修復

升級步驟

1.下載要升級的Tomcat版本

wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.51/bin/apache-tomcat-8.5.51.tar.gz

2. 停止舊版本tomcat

cd /home/…/tomcat_8/bin
./shutdown.sh

# 創建新的tomcat路徑,備份舊的tomcat服務
mkdir /home/…/tomcat_8_old
cp -Rf /home/…/tomcat_8/* /home/…/tomcat_8_old/

# 安裝目錄下解壓新的tomcat
tar -zxvf apache-tomcat-8.5.51.tar.gz

# 刪除舊的服務文件,將新的服務名稱改成之前的
rm -rf tomcat_8
mv apache-tomcat-8.5.51 tomcat_8

# 用備份的server.xml替換新的server.xml
cd /home/…/tomcat_8/conf/
cp /home/…/tomcat_8_old/conf/server.xml ./

# 用備份的webapps替換新的webapps
cd /home/…/tomcat_8/
cp /home/…/tomcat_8_old/webapps ./

# 用備份的catalina.sh替換新的
cd /home/…/tomcat_8/bin/
cp /home/…/tomcat_8_old/bin/catalina. sh ./


# 我這里的備份路徑下有一些日志信息也一並移過來
mv /home/…/tomcat_8_old/logs/* /home/…/tomcat_8/logs/


# 啟動tomcat
cd /home/…/tomcat_8/bin
./startup.sh
隱藏版本

可以的話做一下隱藏版本信息

cd cd apache-tomcat-8.5.51/lib
unzip catalina.jar
vim ServerInfo.properties 
# 自定義修改 server.number和server.built的配置  
server.info=Apache Tomcat
server.number=sb
server.built=sb


cd  /opt/apache-tomcat-8.5.51/lib
jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties

# 重啟服務即可

tomcat在8.5.51版本做了如下修復

// 默認不開啟AJP
// 默認只監聽本地ip
// 強制設置認證secret
// 代碼層面主要在AjpProcessor類的prepareRequest方法封裝requst對象時采用了白名單,只添加已知屬性。這樣三個include屬性不再被客戶端控制,漏洞修復。
禁用AJP協議

編輯/conf/server.xml,找到如下行

<Connector port="8009"protocol="AJP/1.3" redirectPort="8443" />

將此行注釋掉(也可刪掉該行)

<!--<Connectorport="8009" protocol="AJP/1.3"redirectPort="8443" />-->
配置secret來設置AJP協議的認證憑證

例如(注意將您的tomcat_ajp_secret更改為一個安全性高,無法被輕易猜解的值)

<Connector port="8009"protocol="AJP/1.3" redirectPort="8443"address="YOUR_TOMCAT_IP_ADDRESS" secret="YOUR_TOMCAT_AJP_SECRET"/>

我的博客即將搬運同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM