vlambda博客
学习文章列表

tomcat的AJP协议及漏洞解决



tomcat的AJP协议及漏洞解决


  1. 什么是AJP协议?

tomcat的AJP协议及漏洞解决




HTTP协议:连接器监听8080端口,负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器。  

AJP协议:连接器监听8009端口,负责和其他的HTTP服务器建立连接。在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器。所以它的定位就是 “ Tomcat 与 HTTP 服务器之间通信的协议”


AJP 是一种二进制 TCP 传输协议,通过在网络传输二进制包(packet)来完成 Tomcat 与 http 服务器的请求与响应,显然这种方式比纯文本(如 text、xml等)传输的 http 协议效率要高的多。






2.AJP存在的漏洞


2020 年 1 月 6 日,国家信息安全漏洞共享平台(CNVD)收录了由北京长亭科技有限公司发现并报送的 Apache Tomcat 文件包含漏洞。Tomcat AJP 协议由于存在实现缺陷导致相关参数可控,攻击者利用该漏洞可通过构造特定参数,读取服务器 webapp 下的任意文件。若服务器端同时存在文件上传功能,攻击者可进一步实现远程代码的执行。


漏洞影响版本:


7.*分支7.0.100之前版本,建议更新到7.0.100版本;


8.*分支8.5.51之前版本,建议更新到8.5.51版本;


9.*分支9.0.31之前版本,建议更新到9.0.31版本。



3.springboot中与tomcat相关的依赖

基于 SpringBoot 开发 web 应用时,一定要引入 spring-boot-starter-web 组件,spring-boot-starter-web 的职责是负责 web 应用的启动 、初始化、运行和停止。而 spring-boot-starter-web 组件之所以能够跑起来,少不了 http 协议的支持,典型代表就是 tomcat 服务器。


spring-boot-starter-web 组件的相关 maven 依赖中是包含spring-boot-starter-tomcat 组件的,而spring-boot-starter-tomcat 的 maven 依赖又引入了 tomcat-embed-core 、tomcat-embed-el 、tomcat-annotations-api 等嵌入式组件。


4.springboot解决AJP漏洞方法

springboot中是默认不启用AJP的,如果需要开启还需要手动配置。

这一点可以从下图验证(如果已经开启AJP的话启动的日志信息中会包含以下信息)


tomcat的AJP协议及漏洞解决



springboot 1.x 手动配置AJP:

@Configurationpublic class AJPConfig { private static final String PROTOCOL = "AJP/1.3"; @Value("${tomcat.ajp.port:8009}") private int ajpPort; @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); Connector ajpConnector = new Connector(); ajpConnector.setProtocol(PROTOCOL); ajpConnector.setPort(ajpPort); tomcat.addAdditionalTomcatConnectors(ajpConnector); return tomcat; }}



springboot 2.x 手动配置AJP:


@Beanpublic WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() { return server -> { if (server instanceof TomcatServletWebServerFactory) { ((TomcatServletWebServerFactory) server).addAdditionalTomcatConnectors(redirectConnector()); } };} private Connector redirectConnector() { Connector connector = new Connector("AJP/1.3"); connector.setScheme("http"); connector.setPort(ajpPort); connector.setSecure(false); connector.setAllowTrace(false); return connector;}


如果使用的是外置tomcat


(1)编辑 <CATALINA_BASE>/conf/server.xml,找到如下行(<CATALINA_BASE> 为 Tomcat 的工作目录):

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

(2)将此行注释掉(也可删掉该行):

<!--<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />-->

(3)保存后需重新启动,规则方可生效。


如果springboot(使用默认内置tomcat)并没有手动开启AJP,那么你可以不升级tomcat内置版本。当然你想升级也可以。


如果使用的是springboot的内置tomcat,且手动开启了AJP协议,则需要升级内置tomcat版本。下面贴出一种我亲测可行的方法:


正常情况下每个springboot的版本都会带有一个内置的默认的tomcat,如果需要升级的话,我们可以直接去更改maven库中的该springboot的pom文件中tomcat的版本号即可,以Spring Boot ::  (v1.5.22.RELEASE)为例


我们进入repository/org/springframework/boot/spring-boot-dependencies/1.5.12.RELEASE/目录中


编辑修改spring-boot-dependencies-1.5.12.RELEASE.pom文件的


<tomcat.version>8.5.43</tomcat.version>


改为


<tomcat.version>8.5.51</tomcat.version>










tomcat的AJP协议及漏洞解决

tomcat的AJP协议及漏洞解决

tomcat的AJP协议及漏洞解决


每天分享Java知识点

喜欢的话给小编点个赞呗~





关注加❤不丢失~

求帮忙求鼓励么么哒!