CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/lib/metasploit/framework/login_scanner/glassfish.rb
Views: 1904
1require 'metasploit/framework/login_scanner/http'23module Metasploit4module Framework5module LoginScanner67# The Glassfish HTTP LoginScanner class provides methods to do login routines8# for Glassfish 2, 3 and 4.9class Glassfish < HTTP1011DEFAULT_PORT = 484812PRIVATE_TYPES = [ :password ]1314# @!attribute [r] version15# @return [String] Glassfish version16attr_accessor :version1718# @!attribute jsession19# @return [String] Cookie session20attr_accessor :jsession2122# @!attribute http_username23attr_accessor :http_username24# @return [String] HTTP username2526# @!attribute http_password27attr_accessor :http_password2829# (see Base#check_setup)30def check_setup31begin32res = send_request({33'uri' => '/common/index.jsf',34})35return "Connection failed" if res.nil?36if !([200, 302].include?(res.code))37return "Unexpected HTTP response code #{res.code} (is this really Glassfish?)"38end3940# If remote login is enabled on 4.x, it redirects to https on the41# same port.42if !self.ssl && res.headers['Location'] =~ /^https:/43self.ssl = true44res = send_request({45'uri' => '/common/index.jsf',46'cgi' => false47})48if res.nil?49return "Connection failed after SSL redirection"50end51if res.code != 20052return "Unexpected HTTP response code #{res.code} after SSL redirection (is this really Glassfish?)"53end54end5556res = send_request({57'uri' => '/login.jsf',58'cgi' => false59})60return "Connection failed" if res.nil?61extract_version(res.headers['Server'])6263if @version.nil? || @version !~ /^[2349]/64return "Unsupported version ('#{@version}')"65end66rescue ::EOFError, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError, Rex::ConnectionError, ::Timeout::Error67return "Unable to connect to target"68end6970false71end7273# Sends a HTTP request with Rex74#75# @param (see Rex::Proto::Http::Request#request_raw)76# @return [Rex::Proto::Http::Response] The HTTP response77def send_request(opts)78res = super(opts)7980# Found a cookie? Set it. We're going to need it.81if res && res.get_cookies =~ /JSESSIONID=(\w*);/i82self.jsession = $183end8485res86end878889# As of Sep 2014, if Secure Admin is disabled, it simply means the admin isn't allowed90# to login remotely. However, the authentication will still run and hint whether the91# password is correct or not.92#93# @param res [Rex::Proto::Http::Response] The HTTP auth response94# @return [boolean] True if disabled, otherwise false95def is_secure_admin_disabled?(res)96return (res.body =~ /Secure Admin must be enabled/i) ? true : false97end9899100# Sends a login request101#102# @param credential [Metasploit::Framework::Credential] The credential object103# @return [Rex::Proto::Http::Response] The HTTP auth response104def try_login(credential)105data = "j_username=#{Rex::Text.uri_encode(credential.public)}&"106data << "j_password=#{Rex::Text.uri_encode(credential.private)}&"107data << 'loginButton=Login'108109opts = {110'uri' => '/j_security_check',111'method' => 'POST',112'data' => data,113'headers' => {114'Content-Type' => 'application/x-www-form-urlencoded',115'Cookie' => "JSESSIONID=#{self.jsession}",116},117'cgi' => false118}119120send_request(opts)121end122123124# Tries to login to Glassfish version 2125#126# @param credential [Metasploit::Framework::Credential] The credential object127# @return [Hash]128# * :status [Metasploit::Model::Login::Status]129# * :proof [String] the HTTP response body130def try_glassfish_2(credential)131res = try_login(credential)132if res && res.code == 302133opts = {134'uri' => '/applications/upload.jsf',135'method' => 'GET',136'headers' => {137'Cookie' => "JSESSIONID=#{self.jsession}"138},139'cgi' => false140}141res = send_request(opts)142p = /<title>Deploy Enterprise Applications\/Modules/143if (res && res.code.to_i == 200 && res.body.match(p) != nil)144return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}145end146end147148{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.body}149end150151152# Tries to login to Glassfish version 9153#154# @param credential [Metasploit::Framework::Credential] The credential object155# @return [Hash]156# * :status [Metasploit::Model::Login::Status]157# * :proof [String] the HTTP response body158def try_glassfish_9(credential)159res = try_login(credential)160161if res && res.code.to_i == 302 && res.headers['Location'].to_s !~ /loginError\.jsf$/162return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}163end164165{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.body}166end167168169# Tries to login to Glassfish version 3 or 4 (as of now it's the latest)170#171# @param (see #try_glassfish_2)172# @return (see #try_glassfish_2)173def try_glassfish_3(credential)174res = try_login(credential)175if res && res.code == 302176opts = {177'uri' => '/common/applications/uploadFrame.jsf',178'method' => 'GET',179'headers' => {180'Cookie' => "JSESSIONID=#{self.jsession}"181},182'cgi' => false183}184res = send_request(opts)185186p = /<title>Deploy Applications or Modules/187if (res && res.code.to_i == 200 && res.body.match(p) != nil)188return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}189end190elsif res && is_secure_admin_disabled?(res)191return {:status => Metasploit::Model::Login::Status::DENIED_ACCESS, :proof => res.body}192elsif res && res.code == 400193return {:status => Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, :proof => res.body}194end195196{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.body}197end198199200# Decides which login routine and returns the results201#202# @param credential [Metasploit::Framework::Credential] The credential object203# @return [Result]204def attempt_login(credential)205result_opts = { credential: credential }206207begin208case self.version209when /^2\.x$/210status = try_glassfish_2(credential)211result_opts.merge!(status)212when /^[34]\./213status = try_glassfish_3(credential)214result_opts.merge!(status)215when /^9\.x$/216status = try_glassfish_9(credential)217result_opts.merge!(status)218end219rescue ::EOFError, Errno::ECONNRESET, Rex::ConnectionError, OpenSSL::SSL::SSLError, ::Timeout::Error => e220result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)221end222223Result.new(result_opts)224end225226227# Extract the target's glassfish version from the HTTP Server Sun Java System Application Server 9.1header228# (ex: Sun Java System Application Server 9.x)229#230# @param banner [String] `Server` header from a Glassfish service response231# @return [String] version string, e.g. '2.x'232# @return [nil] If the banner did not match any of the expected values233def extract_version(banner)234# Set version. Some GlassFish servers return banner "GlassFish v3".235if banner =~ /(GlassFish Server|Open Source Edition)[[:blank:]]*(\d\.\d)/236@version = $2237elsif banner =~ /GlassFish v(\d)/238@version = $1239elsif banner =~ /Sun GlassFish Enterprise Server v2/240@version = '2.x'241elsif banner =~ /Sun Java System Application Server 9/242@version = '9.x'243else244@version = nil245end246247return @version248end249250251end252end253end254end255256257258